Fix sessions fetching order from database + Enhance Profile and Instances pages + Start working on Global Config page in web UI

This commit is contained in:
Théophile Diot 2024-09-02 11:00:06 +02:00
parent d65b28bd21
commit ffc9b3dcf0
No known key found for this signature in database
GPG key ID: FA995104A0BA376A
16 changed files with 498 additions and 256 deletions

View file

@ -483,12 +483,15 @@ class UIDatabase(Database):
"""Get ui user sessions."""
with self._db_session() as session:
if current_session_id:
return (
current_session_query = session.query(UserSessions).filter_by(user_name=username, id=current_session_id)
other_sessions_query = (
session.query(UserSessions)
.filter_by(user_name=username)
.order_by(UserSessions.id == current_session_id, UserSessions.creation_date.desc())
.all()
.filter(UserSessions.id != current_session_id)
.order_by(UserSessions.creation_date.desc())
)
combined_query = current_session_query.union_all(other_sessions_query)
return combined_query.all()
else:
return session.query(UserSessions).filter_by(user_name=username).order_by(UserSessions.creation_date.desc()).all()

View file

@ -79,8 +79,6 @@ def global_config_page():
)
)
# global_config = BW_CONFIG.get_config(global_only=True, methods=True)
# plugins = BW_CONFIG.get_plugins()
# builder = global_config_builder({}, plugins, global_config)
# return render_template("global-config.html", data_server_builder=b64encode(dumps(builder).encode("utf-8")).decode("ascii"))
return render_template("global-config.html") # TODO
global_config = BW_CONFIG.get_config(global_only=True, methods=True)
plugins = BW_CONFIG.get_plugins()
return render_template("plugins_settings.html", config=global_config, plugins=plugins)

View file

@ -142,7 +142,7 @@ def totp_refresh():
session["decrypted_recovery_codes"] = totp_recovery_codes
flash("The recovery codes have been successfully refreshed. The old ones are no longer valid.")
return redirect(url_for("profile.profile_page"))
return redirect(url_for("profile.profile_page") + "#security")
@profile.route("/profile/totp-disable", methods=["POST"])
@ -173,7 +173,7 @@ def totp_disable():
session["totp_validated"] = False
flash("The two-factor authentication has been successfully disabled.")
return redirect(url_for("profile.profile_page"))
return redirect(url_for("profile.profile_page") + "#security")
@profile.route("/profile/totp-enable", methods=["POST"])
@ -214,7 +214,7 @@ def totp_enable():
session["decrypted_recovery_codes"] = totp_recovery_codes
flash("The two-factor authentication has been successfully enabled.")
return redirect(url_for("profile.profile_page"))
return redirect(url_for("profile.profile_page") + "#security")
@profile.route("/profile/edit", methods=["POST"])

View file

@ -190,23 +190,7 @@
}
.bg-bw-green {
background-color: #2eac68;
}
@media (max-width: 768px) {
.btn-responsive {
padding: 4px 9px;
font-size: 80%;
line-height: 1;
}
}
@media (min-width: 769px) and (max-width: 992px) {
.btn-responsive {
padding: 8px 18px;
font-size: 90%;
line-height: 1.2;
}
background-color: var(--bs-bw-green);
}
.pro-icon {
@ -241,6 +225,27 @@
animation: fadeIn 1.5s infinite alternate;
}
@media (max-width: 768px) {
.btn-responsive {
padding: 4px 9px;
font-size: 80%;
line-height: 1;
}
.pro-icon {
width: 9px;
height: 7.75px;
}
}
@media (min-width: 769px) and (max-width: 992px) {
.btn-responsive {
padding: 8px 18px;
font-size: 90%;
line-height: 1.2;
}
}
@keyframes fadeOut {
0% {
opacity: 1;
@ -263,10 +268,55 @@
min-height: 70vh !important;
}
.max-vh-60 {
max-height: 60vh !important;
}
td.highlight {
background-color: rgba(var(--bs-primary-rgb), 0.1) !important;
}
.text-bw-green {
color: #2eac68 !important;
color: var(--bs-bw-green) !important;
}
.btn-outline-bw-green {
color: var(--bs-bw-green);
border-color: var(--bs-bw-green);
}
.btn-outline-bw-green:hover {
color: #fff;
background-color: var(--bs-primary);
}
.col.form-floating > .form-control-sm,
.col-auto.form-floating > .form-select.form-select-sm {
height: calc(1.9em + 0.9rem + 1px);
min-height: calc(1.9em + 0.9rem + 1px);
font-size: 0.85rem;
line-height: 1;
}
.form-floating > .form-control:focus ~ label {
transform: scale(0.8) translateY(-0.7rem) translateX(0.15rem);
}
.col.form-floating > label,
.col-auto.form-floating > label {
padding: 0.8rem 0.9375rem;
font-size: 0.8rem;
}
.form-floating > .form-select:focus {
padding-top: 1.2rem;
}
.col-auto.form-floating > .form-select.form-select-sm,
.col-auto.form-floating > .form-select.form-select-sm:focus {
padding-top: calc(-2px + 1.2rem);
}
.form-floating > .form-control.form-control-sm:focus {
padding-top: 1.1rem !important;
}

View file

@ -131,7 +131,7 @@ let menu, animate;
* Custom
*/
document.addEventListener("DOMContentLoaded", function onContentLoaded() {
$(document).ready(function () {
// Generic Copy to Clipboard with Tooltip
$(".copy-to-clipboard").on("click", function () {
const input = $(this).closest(".input-group").find("input")[0];
@ -153,4 +153,48 @@ document.addEventListener("DOMContentLoaded", function onContentLoaded() {
console.error("Failed to copy text: ", err);
});
});
$("#select-plugin").on("click", function () {
$("#plugin-search").focus();
});
$("#plugin-search").on("input", function () {
const inputValue = $(this).val().toLowerCase();
const dropdownItems = $("#plugins-dropdown-menu li.nav-item");
dropdownItems.each(function () {
const item = $(this);
const text = item.text().toLowerCase();
console.log(item);
const pluginId = item
.find("button")
.data("bs-target")
.replace("#navs-plugins-", "");
if (text.includes(inputValue) || pluginId.includes(inputValue)) {
item.show();
} else {
item.hide();
}
});
// Show "No Item" message if no items match
if (dropdownItems.filter(":visible").length === 0) {
if ($(".no-items").length === 0) {
$("#plugins-dropdown-menu").append(
'<li class="no-items dropdown-item text-muted">No Item</li>',
);
}
} else {
$(".no-items").remove();
}
});
$(document).on("click", function (event) {
if (!$(event.target).closest(".card").length) {
$("#plugins-dropdown-menu").removeClass("show");
$("#plugin-search").val("");
$("#plugin-search").trigger("input");
}
});
});

View file

@ -143,6 +143,9 @@ $(document).ready(function () {
setTimeout(() => {
if (actionLock) {
$("#loadingModal").modal("show");
setTimeout(() => {
$("#loadingModal").modal("hide");
}, 5300);
}
}, 500);

View file

@ -82,10 +82,15 @@ $(document).ready(function () {
function handleTabChange(targetClass) {
const target = targetClass.substring(1).replace("navs-pills-", "");
const isProfileTab = target === "profile";
const isSessionsTab = target === "sessions";
if (isProfileTab) {
if (!isSessionsTab) {
$("#navs-pills-sessions-pagination").removeClass("show active");
setTimeout(() => {
$("#navs-pills-sessions-pagination").parent().addClass("d-none");
}, 200);
} else {
$("#navs-pills-sessions-pagination").parent().removeClass("d-none");
setTimeout(() => {
$("#navs-pills-sessions-pagination").addClass("show active");
}, 200);
@ -320,4 +325,28 @@ $(document).ready(function () {
"<p>Error loading data. Please try again.</p>",
);
}
function initializeAccountImageHandling() {
const accountUserImage = $("#uploadedAvatar");
const fileInput = $(".account-file-input");
const resetFileInput = $(".account-image-reset");
if (accountUserImage.length === 0) return;
const originalImageSrc = accountUserImage.attr("src");
fileInput.on("change", function () {
const file = this.files[0];
if (file) {
accountUserImage.attr("src", URL.createObjectURL(file));
}
});
resetFileInput.on("click", function () {
fileInput.val("");
accountUserImage.attr("src", originalImageSrc);
});
}
initializeAccountImageHandling();
});

View file

@ -35,8 +35,7 @@
<link rel="stylesheet"
href="libs/apexcharts/apexcharts.css"
nonce="{{ style_nonce }}" />
{% endif %}
{% if current_endpoint == "instances" %}
{% elif current_endpoint == "instances" %}
<link rel="stylesheet"
href="libs/datatables/datatables.min.css"
nonce="{{ style_nonce }}" />

View file

@ -13,27 +13,70 @@
<!-- prettier-ignore -->
<div class="d-flex justify-content-between align-items-center mb-5">
{% include "breadcrumb.html" %}
{% if "services" in request.path %}
<ul class="nav nav-pills flex-column flex-md-row" role="tablist">
<li class="nav-item me-0 me-sm-3" role="presentation">
<button type="button"
class="rounded-pill nav-link d-flex align-items-center active"
role="tab"
data-bs-toggle="tab"
data-bs-target="#navs-pills-easy"
aria-controls="navs-pills-easy"
aria-selected="true">
<i class="bx bx-customize bx-sm"></i>
&nbsp;
<span class="d-none d-sm-inline">Easy</span>
</button>
</li>
<li class="nav-item me-0 me-sm-3" role="presentation">
<button type="button"
class="rounded-pill nav-link d-flex align-items-center"
role="tab"
data-bs-toggle="tab"
data-bs-target="#navs-pills-advanced"
aria-controls="navs-pills-advanced">
<i class="bx bx-shield-quarter bx-sm"></i>
&nbsp;
<span class="d-none d-sm-inline">Advanced</span>
</button>
</li>
<li class="nav-item" role="presentation">
<button type="button"
class="rounded-pill nav-link d-flex align-items-center"
role="tab"
data-bs-toggle="tab"
data-bs-target="#navs-pills-raw"
aria-controls="navs-pills-raw">
<i class="bx bx-notepad bx-sm"></i>
&nbsp;
<span class="d-none d-sm-inline">Raw</span>
</button>
</li>
</ul>
{% endif %}
<ul class="d-flex mb-0 list-unstyled">
<li class="me-3">
<a role="button"
class="btn btn-sm btn-outline-dark d-flex align-items-center"
class="btn btn-sm btn-outline-dark d-flex align-items-center h-100"
aria-pressed="true"
href="https://panel.bunkerweb.io/order/support/?utm_campaign=self&utm_source=ui"
target="_blank"
rel="noopener">
<span class="tf-icons bx bx-help-circle bx-18px me-2"></span>
Need Help?
<span class="bx bx-help-circle bx-18px me-0 me-md-2"></span>
<span class="d-none d-md-inline">Need help?</span>
</a>
</li>
<li>
<a id="news-button"
role="button"
class="btn btn-sm btn-dark text-uppercase d-flex align-items-center position-relative"
aria-pressed="true"
href="javascript:void(0)"
data-bs-toggle="offcanvas"
data-bs-target="#side-offcanvas"
aria-controls="side-offcanvas">News</a>
<button id="news-button"
type="button"
class="btn btn-sm btn-dark text-uppercase d-flex align-items-center"
aria-pressed="true"
data-bs-toggle="offcanvas"
data-bs-target="#side-offcanvas"
aria-controls="side-offcanvas">
<span class="bx bx-news bx-18px me-0 me-md-2"></span>
<span class="d-none d-md-inline">News</span>
</button>
</li>
</ul>
</div>
@ -50,7 +93,7 @@
href="https://panel.bunkerweb.io/order/bunkerweb-pro/?utm_campaign=self&utm_source=ui"
target="_blank"
rel="noopener">
<span class="tf-icons me-2 d-flex h-100 justify-content-center align-items-center">
<span class="me-1 me-md-2 d-flex h-100 justify-content-center align-items-center">
<div class="pro-icon"></div>
</span>
Upgrade to Pro</a>

View file

@ -1,4 +1,5 @@
<div id="feedback-toast-container" class="toast-container position-fixed bottom-0 end-0 mb-3 me-3">
<div id="feedback-toast-container"
class="toast-container position-fixed bottom-0 end-0 mb-3 me-3">
<!-- prettier-ignore -->
{% with messages = get_flashed_messages(with_categories=true) %}
{% if pro_overlapped %}

View file

@ -18,9 +18,7 @@
</div>
</div>
<div class="card table-responsive text-nowrap p-4 min-vh-70">
<input type="hidden"
id="instances_number"
value="{{ instances|length }}" />
<input type="hidden" id="instances_number" value="{{ instances|length }}" />
<input type="hidden"
id="csrf_token"
name="csrf_token"
@ -28,13 +26,27 @@
<table id="instances" class="table w-100">
<thead>
<tr>
<th data-bs-toggle="tooltip" data-bs-placement="top" data-bs-original-title="The hostname of the Instance">Hostname</th>
<th data-bs-toggle="tooltip" data-bs-placement="top" data-bs-original-title="The user defined or auto-generated Instance's name">Name</th>
<th data-bs-toggle="tooltip" data-bs-placement="top" data-bs-original-title="The creation method of the Instance">Method</th>
<th data-bs-toggle="tooltip" data-bs-placement="top" data-bs-original-title="The Instance's health status">Health</th>
<th data-bs-toggle="tooltip" data-bs-placement="top" data-bs-original-title="The Instance's type">Type</th>
<th data-bs-toggle="tooltip" data-bs-placement="top" data-bs-original-title="The date and time when the Instance was created">Created</th>
<th data-bs-toggle="tooltip" data-bs-placement="top" data-bs-original-title="The date and time when the Instance was last seen">Last Seen</th>
<th data-bs-toggle="tooltip"
data-bs-placement="top"
data-bs-original-title="The hostname of the Instance">Hostname</th>
<th data-bs-toggle="tooltip"
data-bs-placement="top"
data-bs-original-title="The user defined or auto-generated Instance's name">Name</th>
<th data-bs-toggle="tooltip"
data-bs-placement="top"
data-bs-original-title="The creation method of the Instance">Method</th>
<th data-bs-toggle="tooltip"
data-bs-placement="top"
data-bs-original-title="The Instance's health status">Health</th>
<th data-bs-toggle="tooltip"
data-bs-placement="top"
data-bs-original-title="The Instance's type">Type</th>
<th data-bs-toggle="tooltip"
data-bs-placement="top"
data-bs-original-title="The date and time when the Instance was created">Created</th>
<th data-bs-toggle="tooltip"
data-bs-placement="top"
data-bs-original-title="The date and time when the Instance was last seen">Last Seen</th>
</tr>
</thead>
<tbody>
@ -57,11 +69,11 @@
</td>
<td>
{% if instance.type == "container" %}
<i class="bx bx-18px bxl-docker"></i>&nbsp;Container
<i class="bx bx-18px bxl-docker"></i>&nbsp;Container
{% elif instance.type == "pod" %}
<i class="bx bx-18px bxl-kubernetes"></i>&nbsp;Pod
{% else %}
<i class="bx bx-18px bx-microchip"></i>&nbsp;Static
<i class="bx bx-18px bx-microchip"></i>&nbsp;Static
{% endif %}
</td>
<td>{{ instance.creation_date.astimezone().strftime("%Y-%m-%d %H:%M:%S %Z") }}</td>
@ -126,7 +138,9 @@
maxlength="256"
required />
</div>
<div class="alert alert-primary text-center" role="alert">You don't need to provide the port or the server_name as the values of both <code>API_HTTP_PORT</code> and <code>API_SERVER_NAME</code> will be used for the instance configuration.</div>
<div class="alert alert-primary text-center" role="alert">
You don't need to provide the port or the server_name as the values of both <code>API_HTTP_PORT</code> and <code>API_SERVER_NAME</code> will be used for the instance configuration.
</div>
</div>
<div class="modal-footer justify-content-center">
<button type="submit" class="btn btn-outline-primary me-2">Create Instance</button>

View file

@ -13,56 +13,8 @@
target="_blank"
rel="noopener"
class="app-brand-link gap-2">
<span class="app-brand-logo login">
<svg version="1.1"
width="25"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
x="0px"
y="0px"
viewBox="0 0 272.68 76.37"
xml:space="preserve">
<style type="text/css" nonce="{{ style_nonce }}">
.st0 {
fill: #ffffff;
}
.st1 {
fill: #2eac68;
}
.st2 {
fill: #0b5577;
}
</style>
<g>
<path class="st2" d="M244.87,44.46c0.16-1.27,1.3-2.12,2.59-1.95c1.01,0.13,1.85,0.96,1.92,2.05c0.14,1.52,0.26,2.71,0.36,3.85 h16.02c-0.24-1.79-0.49-3.61-0.82-6c-0.1-0.8,0.25-1.61,0.9-2.02c3.4-2.43,5.46-6.75,6.49-12.5c2.34-13.05-7.24-18.86-18.92-20.2 c-7.49-1-11.24-1.45-18.75-2.29c-1.35-0.15-2.51,0.72-2.65,2c-1.48,13.67-2.97,27.34-4.45,41.01h16.79 C244.51,47.22,244.66,46.05,244.87,44.46z M243.31,21.88c2.52,0.56,3.78,0.85,6.29,1.43c0.87-0.8,2.08-1.22,3.37-1.03 c2.21,0.32,3.75,2.31,3.43,4.42c-0.32,2.11-2.36,3.55-4.55,3.23c-1.27-0.19-2.31-0.93-2.91-1.94c-2.56-0.14-3.84-0.2-6.41-0.32 C242.84,25.36,242.99,24.2,243.31,21.88z" />
<g>
<path class="st2" d="M224.95,41c0.11-1.06-0.73-2.08-1.81-2.19c-6.15-0.63-9.23-0.91-15.38-1.43c-1.16-0.1-2.02-1.09-1.93-2.23 c0.01-0.08,0.01-0.13,0.02-0.21c0.09-1.06,1.11-1.91,2.27-1.81c4.44,0.37,6.67,0.57,11.11,1c1.09,0.11,2.12-0.72,2.24-1.85 c0.35-3.56,0.53-5.34,0.88-8.91c0.1-1.06-0.76-2.07-1.87-2.18c-4.51-0.44-6.76-0.64-11.28-1.02c-1.18-0.1-2.06-1.1-1.97-2.23 c0.09-1.06,1.12-1.9,2.31-1.8c6.31,0.53,9.47,0.82,15.77,1.46c1.11,0.11,2.17-0.7,2.28-1.84c0.38-3.62,0.57-5.43,0.94-9.04 c0.11-1.06-0.77-2.08-1.9-2.19c-11.16-1.06-22.29-1.98-33.47-2.77c-1.2-0.08-2.24,0.79-2.3,1.85 c-0.89,14.49-1.77,28.97-2.66,43.46c-0.03,0.5,0.13,0.96,0.4,1.33h35.57C224.45,45.8,224.63,44.03,224.95,41z" />
<g>
<path class="st2" d="M185.93,46.8c-2.49-8.91-3.77-13.36-6.42-22.25c-0.06-0.29-0.04-0.71,0.05-0.99 c3.19-8.01,4.82-12,8.14-19.98c0.44-1.04-0.33-2.15-1.53-2.22c-5.45-0.3-8.18-0.43-13.64-0.65c-0.75-0.03-1.45,0.44-1.7,1.07 c-2.18,5.75-3.25,8.62-5.37,14.38c-0.24,0.63-0.92,1.11-1.66,1.08c-0.96-0.03-1.68-0.76-1.65-1.68 c0.16-5.42,0.23-8.14,0.39-13.56c0.03-0.92-0.71-1.65-1.69-1.68c-5.61-0.15-8.41-0.2-14.02-0.26c-0.98-0.01-1.74,0.69-1.75,1.62 c-0.13,14.77-0.26,29.55-0.39,44.32c-0.01,0.92,0.7,1.64,1.63,1.65c5.31,0.06,7.96,0.11,13.26,0.25 c0.93,0.02,1.66-0.66,1.69-1.59c0.14-5.03,0.22-7.54,0.36-12.57c0.03-0.92,0.77-1.61,1.72-1.58c0.06,0,0.09,0,0.15,0 c0.73,0.02,1.29,0.47,1.56,1.12c1.82,5.55,2.72,8.32,4.48,13.88c0.26,0.65,0.81,1.1,1.53,1.13c1.23,0.05,2.31,0.1,3.32,0.14 h11.12C185.9,48,186.1,47.41,185.93,46.8z" />
<g>
<path class="st2" d="M109.16,48.06c1.64-0.06,2.95-1.44,2.9-3.08c-0.14-4.49-0.2-6.73-0.34-11.22 c-0.03-0.92,0.68-1.51,1.48-1.54c0.51-0.01,0.95,0.19,1.25,0.68c3.54,5.28,5.29,7.92,8.72,13.24c0.52,0.99,1.52,1.54,2.67,1.52 c4.62-0.06,6.93-0.08,11.55-0.08c1.64,0,3-1.34,3.01-2.98c0.05-13.87,0.1-27.75,0.16-41.62c0.01-1.63-1.42-2.99-3.16-2.99 c-4.46,0-6.7,0.01-11.16,0.07c-1.73,0.02-3.14,1.39-3.12,3.03c0.07,4.09,0.1,6.14,0.17,10.23c0.01,0.85-0.72,1.43-1.53,1.45 c-0.45,0.01-0.97-0.2-1.27-0.62c-3.6-4.96-5.42-7.43-9.12-12.35c-0.55-0.84-1.62-1.37-2.76-1.34 c-4.88,0.16-7.33,0.26-12.21,0.48c-1.73,0.08-3.1,1.5-3.01,3.13c0.69,13.86,1.39,27.71,2.08,41.57 c0.07,1.37,1.09,2.48,2.38,2.76h2.4C103.45,48.26,105.53,48.18,109.16,48.06z" />
<g>
<path class="st2" d="M90.68,31.54c-0.59-10.75-0.89-16.13-1.48-26.88c-0.1-1.84-1.76-3.25-3.72-3.13 C81.33,1.77,79.25,1.91,75.1,2.2c-1.96,0.14-3.43,1.74-3.29,3.59c0.83,11.11,1.25,16.66,2.08,27.76 c0.23,3.05-1.38,3.88-4.2,4.1c-2.82,0.23-4.61-0.33-4.87-3.37c-0.95-11.1-1.43-16.64-2.38-27.74 c-0.16-1.84-1.86-3.19-3.82-3.02c-4.12,0.37-6.18,0.57-10.29,0.98c-2.03,0.21-3.45,1.86-3.25,3.69 c1.14,10.82,1.72,16.23,2.86,27.05c0.61,6.46,3.39,10.67,7.45,13.16H81.6C87.6,45.46,91.41,40.09,90.68,31.54z" />
<g>
<path class="st2" d="M45.57,39.08c-0.36-3.32-1.02-6.96-4.2-8.75c-1.34-0.76-1.85-2.58-0.95-3.82 c1.9-2.86,1.84-6.21,1.48-9.46c-0.87-7.84-7.46-11.1-19.67-9.49c-7.79,1.03-11.68,1.58-19.45,2.79 c-1.79,0.28-3,1.84-2.74,3.52c1.82,11.52,3.65,23.04,5.47,34.55h37.72C45.2,45.98,45.98,42.89,45.57,39.08z M19.57,41.45 c-0.16-3.39-0.24-5.08-0.39-8.47c-1.42-0.79-2.47-2.16-2.7-3.84c-0.41-2.91,1.72-5.62,4.76-6.03 c3.04-0.41,5.81,1.63,6.19,4.55c0.22,1.69-0.43,3.28-1.59,4.42c0.76,3.31,1.13,4.96,1.88,8.27 C24.46,40.77,22.83,40.99,19.57,41.45z" />
</g>
</g>
<path class="st2" d="M100.25,48.41h-2.4c0.25,0.05,0.5,0.09,0.76,0.08C99.2,48.46,99.73,48.43,100.25,48.41z" />
</g>
</g>
</g>
</g>
<g>
<rect x="89.49" y="51.91" class="st1" width="93.69" height="24.46" />
<g>
<g>
<path class="st0" d="M121.14,73.93l-1.91,0.03l-3.43-9.9l-3.34,9.93l-1.91-0.01l-3.25-14.33l-0.75,0c-0.37,0-0.63-0.07-0.79-0.22 s-0.24-0.34-0.24-0.57c0-0.22,0.08-0.4,0.24-0.55c0.16-0.15,0.42-0.22,0.79-0.22l4.24-0.02c0.37,0,0.63,0.07,0.79,0.22 c0.16,0.15,0.24,0.34,0.24,0.57c0,0.22-0.08,0.4-0.24,0.55s-0.42,0.22-0.79,0.22l-1.96,0.01l2.78,12.22l3.25-9.78l1.84-0.01 l3.42,9.76l2.58-12.24l-1.95,0.01c-0.37,0-0.63-0.07-0.8-0.22c-0.16-0.15-0.25-0.34-0.25-0.57c0-0.22,0.08-0.4,0.24-0.55 c0.16-0.15,0.43-0.22,0.81-0.22l4.22-0.02c0.38,0,0.65,0.07,0.81,0.22c0.16,0.15,0.24,0.34,0.24,0.57c0,0.22-0.08,0.4-0.24,0.55 s-0.43,0.22-0.81,0.22l-0.73,0L121.14,73.93z" />
<path class="st0" d="M146.71,66.25l-15.72,0.06c0.28,1.99,1.12,3.6,2.52,4.81c1.41,1.21,3.14,1.82,5.21,1.81 c1.15,0,2.36-0.2,3.62-0.58c1.26-0.38,2.29-0.89,3.08-1.52c0.23-0.18,0.43-0.28,0.6-0.28c0.2,0,0.37,0.08,0.51,0.23 c0.15,0.15,0.22,0.33,0.22,0.54s-0.1,0.41-0.29,0.61c-0.59,0.61-1.63,1.19-3.12,1.73c-1.5,0.54-3.04,0.81-4.62,0.82 c-2.64,0.01-4.85-0.85-6.63-2.57c-1.78-1.72-2.67-3.82-2.68-6.28c-0.01-2.24,0.81-4.17,2.47-5.78s3.7-2.42,6.15-2.43 c2.52-0.01,4.6,0.81,6.23,2.45C145.91,61.5,146.72,63.63,146.71,66.25z M145.14,64.7c-0.31-1.7-1.12-3.08-2.43-4.14 c-1.31-1.06-2.86-1.59-4.66-1.58c-1.8,0.01-3.35,0.54-4.64,1.6s-2.1,2.45-2.41,4.18L145.14,64.7z" />
<path class="st0" d="M155.06,50.76l0.04,10.23c1.85-2.43,4.09-3.65,6.73-3.66c2.25-0.01,4.18,0.8,5.79,2.43 c1.61,1.63,2.42,3.63,2.43,6.01c0.01,2.4-0.8,4.43-2.41,6.11c-1.62,1.67-3.53,2.51-5.75,2.52c-2.69,0.01-4.94-1.19-6.75-3.61 l0.01,3.03l-3.62,0.01c-0.37,0-0.63-0.07-0.79-0.22c-0.16-0.15-0.24-0.33-0.24-0.55c0-0.23,0.08-0.42,0.24-0.56 c0.16-0.14,0.42-0.21,0.79-0.21l2.07-0.01l-0.07-19.94l-2.07,0.01c-0.37,0-0.63-0.07-0.79-0.22c-0.16-0.15-0.24-0.34-0.24-0.57 c0-0.22,0.08-0.4,0.24-0.55c0.16-0.15,0.42-0.22,0.79-0.22L155.06,50.76z M168.5,65.84c-0.01-1.95-0.68-3.59-2.02-4.94 c-1.34-1.35-2.9-2.02-4.69-2.01s-3.35,0.69-4.67,2.05c-1.33,1.36-1.99,3.01-1.98,4.96c0.01,1.95,0.68,3.59,2.02,4.94 c1.34,1.35,2.9,2.02,4.69,2.01c1.79-0.01,3.35-0.69,4.67-2.05C167.85,69.44,168.51,67.79,168.5,65.84z" />
</g>
</g>
</g>
</svg>
<span class="app-brand-logo login w-75">
<img class="img-fluid" src="img/logo-menu.png" alt="BunkerWeb logo">
</span>
</a>
</div>

View file

@ -0,0 +1,75 @@
{% extends "dashboard.html" %}
{% block content %}
<!-- Content -->
<div class="d-flex row">
<div class="card p-1">
<div class="d-flex flex-wrap justify-content-around align-items-center">
<div class="btn-group">
<button id="select-plugin"
type="button"
class="btn btn-outline-primary dropdown-toggle"
data-bs-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false">
<i class="bx bx-extension"></i>
<span class="d-none d-md-inline">&nbsp;Plugins</span>
</button>
<ul id="plugins-dropdown-menu"
class="dropdown-menu nav-pills max-vh-60 overflow-auto"
role="tablist">
<input id="plugin-search"
type="text"
class="form-control border-0 border-bottom shadow-none mb-2"
placeholder="Search...">
{% for plugin in plugins %}
<li class="nav-item">
<button type="button"
class="dropdown-item{% if loop.index == 1 %} active{% endif %}"
role="tab"
data-bs-toggle="tab"
data-bs-target="#navs-plugins-{{ plugin['id'] }}"
aria-controls="navs-plugins-{{ plugin['id'] }}"
{% if loop.index == 1 %}aria-selected="true"{% endif %}>
{{ plugin["name"] }}
</button>
</li>
{% endfor %}
</ul>
</div>
<div class="row align-items-center">
<div class="col form-floating ps-0 pe-0 pe-md-1">
<input id="plugin-keyword-search"
type="text"
class="form-control form-control-sm border-0 border-primary border-bottom shadow-none"
placeholder="Keywords...">
<label for="plugin-keyword-search">Keywords</label>
</div>
<div class="col form-floating ps-0 pe-1 d-none d-md-block">
<input id="plugin-context-search"
type="text"
class="form-control form-control-sm border-0 border-primary border-bottom shadow-none"
placeholder="Context...">
<label for="plugin-context-search">Context</label>
</div>
<div class="col-auto form-floating ps-0 pe-0 d-none d-md-block">
<select id="plugin-type-select"
class="form-select form-select-sm border-0 border-primary border-bottom shadow-none">
<option selected>All</option>
<option value="core">Core</option>
<option value="external">External</option>
<option value="pro">Pro</option>
</select>
<label for="plugin-type-select">Type</label>
</div>
</div>
<button id="save-settings"
type="button"
class="btn btn-sm btn-outline-bw-green">
<i class="bx bx-save bx-sm"></i>
<span class="d-none d-md-inline">&nbsp;Save</span>
</button>
</div>
</div>
</div>
<!-- / Content -->
{% endblock %}

View file

@ -6,7 +6,7 @@
<div class="d-flex row">
<div class="col-md-4">
<ul class="nav nav-pills flex-column flex-md-row mb-6">
<li class="nav-item me-0 me-sm-3" role="presentation">
<li class="nav-item me-0 me-sm-2" role="presentation">
<button type="button"
class="nav-link d-flex align-items-center active"
role="tab"
@ -15,8 +15,18 @@
aria-controls="navs-pills-profile"
aria-selected="true">
<i class="tf-icons bx bx-user bx-sm"></i>
&nbsp;
<span class="d-none d-sm-inline">Profile</span>
<span class="d-none d-sm-inline">&nbsp;Profile</span>
</button>
</li>
<li class="nav-item me-0 me-sm-2" role="presentation">
<button type="button"
class="nav-link d-flex align-items-center"
role="tab"
data-bs-toggle="tab"
data-bs-target="#navs-pills-security"
aria-controls="navs-pills-security">
<i class="tf-icons bx bx-check-shield bx-sm"></i>
<span class="d-none d-sm-inline">&nbsp;Security</span>
</button>
</li>
<li class="nav-item" role="presentation">
@ -27,14 +37,13 @@
data-bs-target="#navs-pills-sessions"
aria-controls="navs-pills-sessions">
<i class="tf-icons bx bx-link-alt bx-sm"></i>
&nbsp;
<span class="d-none d-sm-inline">Sessions</span>
<span class="d-none d-sm-inline">&nbsp;Sessions</span>
</button>
</li>
</ul>
</div>
{% if total_pages > 1 %}
<div class="col-md-8">
<div class="col-md-8 d-none">
<div class="tab-pane fade"
id="navs-pills-sessions-pagination"
role="tabpanel">
@ -66,15 +75,44 @@
</div>
{% endif %}
</div>
<div class="tab-content position-relative">
<div class="tab-content p-0 position-relative">
<div class="tab-pane fade show active"
id="navs-pills-profile"
role="tabpanel">
<div class="d-flex row">
<div class="col-md-6">
<!-- Profile -->
<div class="card mb-4">
<div class="card">
<h5 class="card-header">Edit Profile</h5>
<div class="card-body pb-2">
<div class="d-flex align-items-start align-items-sm-center gap-6 pb-4 border-bottom">
<img src="img/avatar_profil_BW.png"
alt="Admin Avatar"
class="d-block w-px-100 h-px-100 rounded"
id="uploadedAvatar">
<div class="button-wrapper"
data-bs-toggle="tooltip"
data-bs-placement="top"
data-bs-html="true"
title="<i class='bx bx-rocket bx-xs'></i><span>Coming soon</span>">
<label for="upload" class="btn btn-primary me-3 mb-4 disabled" tabindex="0">
<i class="bx bx-upload me-0 me-sm-1"></i>
<span class="d-none d-sm-block">Upload new photo</span>
<input type="file"
id="upload"
class="account-file-input"
hidden=""
accept="image/png, image/jpeg, image/gif">
</label>
<button type="button"
class="btn btn-outline-secondary account-image-reset mb-4 disabled">
<i class="bx bx-reset me-0 me-sm-1"></i>
<span class="d-none d-sm-block">Reset</span>
</button>
<div>Allowed JPG, GIF or PNG. Max size of 800K</div>
</div>
</div>
</div>
<div class="card-body pb-4">
<form method="POST" action="{{ profile_url }}/edit">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
@ -122,6 +160,128 @@
</div>
</div>
<!-- /Profile -->
</div>
<div class="col-md-6">
<!-- Theme -->
<div class="card">
<h5 class="card-header">Change Theme</h5>
<div class="card-body pb-4">
<!-- <form method="POST" action="{{ profile_url }}/edit"> -->
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
<div class="row g-3">
<div class="col-md-12 form-floating">
<select class="form-select"
id="theme"
name="theme"
disabled
data-bs-toggle="tooltip"
data-bs-placement="top"
data-bs-html="true"
title="<i class='bx bx-rocket bx-xs'></i><span>Coming soon</span>">
<option value="light"
{% if current_user.theme == "light" %}selected{% endif %}>
Light
</option>
<option value="dark" {% if current_user.theme == "dark" %}selected{% endif %}>Dark</option>
</select>
<label for="theme">Theme</label>
</div>
</div>
<div class="mt-4 justify-content-center d-flex">
<button type="submit" class="btn btn-primary me-2">Save Changes</button>
<button type="reset" class="btn btn-outline-secondary">Cancel</button>
</div>
<!-- </form> -->
</div>
</div>
<!-- /Theme -->
</div>
</div>
</div>
<div class="tab-pane fade" id="navs-pills-security" role="tabpanel">
<div class="d-flex row">
<div class="col-md-6">
<!-- Password -->
<div class="card mb-4">
<h5 class="card-header">Change Password</h5>
<div class="card-body pb-4">
<form method="POST" action="{{ profile_url }}/edit" autocomplete="off">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
<div class="row g-3">
<div class="col-md-12 form-password-toggle">
<label for="new_password" class="form-label">New Password</label>
<div class="input-group input-group-merge">
<input class="form-control"
type="password"
id="new_password"
name="new_password"
placeholder="&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;"
aria-label="New Password"
autocomplete="off"
required
pattern="^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[ !&quot;#$%&'()*+,./:;<=>?@[\\\]^_`{|}~-]).{8,}$" />
<span class="input-group-text cursor-pointer"><i class="bx bx-hide"></i></span>
</div>
<div class="mt-3">
<ul class="list-unstyled" id="password-requirements">
<li id="length-check">
<i class="bx bx-x text-danger"></i> Your password must
have at least 8 characters.
</li>
<li id="uppercase-check">
<i class="bx bx-x text-danger"></i> Your password must
have at least 1 uppercase letter.
</li>
<li id="number-check">
<i class="bx bx-x text-danger"></i> Your password must
have at least 1 number.
</li>
<li id="special-check">
<i class="bx bx-x text-danger"></i> Your password must
have at least 1 special character.
</li>
</ul>
</div>
</div>
<div class="col-md-12 form-password-toggle">
<label for="new_password_confirm" class="form-label">Confirm Password</label>
<div class="input-group input-group-merge">
<input class="form-control"
type="password"
id="new_password_confirm"
name="new_password_confirm"
placeholder="&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;"
aria-label="Confirm Password"
autocomplete="off"
required
pattern="^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[ !&quot;#$%&'()*+,./:;<=>?@[\\\]^_`{|}~-]).{8,}$" />
<span class="input-group-text cursor-pointer"><i class="bx bx-hide"></i></span>
</div>
</div>
<div class="col-md-12 form-password-toggle">
<label class="form-label" for="password">Current password</label>
<div class="input-group input-group-merge">
<input type="password"
id="password"
class="form-control"
name="password"
placeholder="&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;"
aria-describedby="Current password"
required />
<span class="input-group-text cursor-pointer"><i class="bx bx-hide"></i></span>
</div>
</div>
</div>
<div class="mt-4 justify-content-center d-flex">
<button type="submit" class="btn btn-primary me-2">Save Changes</button>
<button type="reset" class="btn btn-outline-secondary">Cancel</button>
</div>
</form>
</div>
</div>
<!-- /Password -->
</div>
<div class="col-md-6">
<!-- Two-Factor Authentication (2FA) -->
<div class="card mb-4">
<h5 class="card-header text-center">Two-Factor Authentication (2FA)</h5>
@ -234,87 +394,6 @@
</div>
</div>
<!-- /Two-Factor Authentication (2FA) -->
</div>
<div class="col-md-6">
<!-- Password -->
<div class="card mb-4">
<h5 class="card-header">Change Password</h5>
<div class="card-body pb-4">
<form method="POST" action="{{ profile_url }}/edit" autocomplete="off">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
<div class="row g-3">
<div class="col-md-12 form-password-toggle">
<label for="new_password" class="form-label">New Password</label>
<div class="input-group input-group-merge">
<input class="form-control"
type="password"
id="new_password"
name="new_password"
placeholder="&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;"
aria-label="New Password"
autocomplete="off"
required
pattern="^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[ !&quot;#$%&'()*+,./:;<=>?@[\\\]^_`{|}~-]).{8,}$" />
<span class="input-group-text cursor-pointer"><i class="bx bx-hide"></i></span>
</div>
<div class="mt-3">
<ul class="list-unstyled" id="password-requirements">
<li id="length-check">
<i class="bx bx-x text-danger"></i> Your password must
have at least 8 characters.
</li>
<li id="uppercase-check">
<i class="bx bx-x text-danger"></i> Your password must
have at least 1 uppercase letter.
</li>
<li id="number-check">
<i class="bx bx-x text-danger"></i> Your password must
have at least 1 number.
</li>
<li id="special-check">
<i class="bx bx-x text-danger"></i> Your password must
have at least 1 special character.
</li>
</ul>
</div>
</div>
<div class="col-md-12 form-password-toggle">
<label for="new_password_confirm" class="form-label">Confirm Password</label>
<div class="input-group input-group-merge">
<input class="form-control"
type="password"
id="new_password_confirm"
name="new_password_confirm"
placeholder="&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;"
aria-label="Confirm Password"
autocomplete="off"
required
pattern="^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[ !&quot;#$%&'()*+,./:;<=>?@[\\\]^_`{|}~-]).{8,}$" />
<span class="input-group-text cursor-pointer"><i class="bx bx-hide"></i></span>
</div>
</div>
<div class="col-md-12 form-password-toggle">
<label class="form-label" for="password">Current password</label>
<div class="input-group input-group-merge">
<input type="password"
id="password"
class="form-control"
name="password"
placeholder="&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;"
aria-describedby="Current password"
required />
<span class="input-group-text cursor-pointer"><i class="bx bx-hide"></i></span>
</div>
</div>
</div>
<div class="mt-4 justify-content-center d-flex">
<button type="submit" class="btn btn-primary me-2">Save Changes</button>
<button type="reset" class="btn btn-outline-secondary">Cancel</button>
</div>
</form>
</div>
</div>
<!-- /Password -->
{% if is_totp %}
<!-- Refresh Recovery Codes -->
<div class="card mb-4">
@ -386,7 +465,7 @@
</div>
<div class="col-md-8">
<div id="sessions-page-content"
class="tab-content position-relative pt-0 ps-3 pe-3">
class="tab-content position-relative p-0 ps-md-2 pe-md-2">
{% for session in last_sessions %}
{% if session["current"] %}
{% set card_classes = "border-primary border-1 position-relative" %}
@ -417,19 +496,19 @@
<strong>
<i class="bx bx-window-alt {{ items_classes }}"></i>
Browser:</strong>
&nbsp; {{ session["browser"]|safe }}
&nbsp;{{ session["browser"]|safe }}
</div>
<div class="list-group-item d-flex align-items-center">
<strong>
<i class="bx bx-layer {{ items_classes }}"></i>
Operating System:</strong>
&nbsp; {{ session["os"]|safe }}
&nbsp;{{ session["os"]|safe }}
</div>
<div class="list-group-item d-flex align-items-center">
<strong>
<i class="bx bx-devices {{ items_classes }}"></i>
Device:</strong>
&nbsp; {{ session["device"]|safe }}
&nbsp;{{ session["device"]|safe }}
</div>
<div class="d-flex list-group-item form-password-toggle align-items-center">
<strong>
@ -453,13 +532,13 @@
<strong>
<i class="bx bx-time {{ items_classes }}"></i>
Creation date:</strong>
&nbsp; {{ session["creation_date"] }}
&nbsp;{{ session["creation_date"] }}
</div>
<div class="list-group-item d-flex align-items-center">
<strong>
<i class="bx bx-time {{ items_classes }}"></i>
Last Activity:</strong>
&nbsp; {{ session["last_activity"] }}
&nbsp;{{ session["last_activity"] }}
</div>
</div>
</div>
@ -493,7 +572,7 @@
</div>
<div class="alert alert-primary text-center" role="alert">
<strong>Important:</strong> Please save these recovery codes in a
secure location. You can use them to access your account if you lose
secure location (like a bunker). You can use them to access your account if you lose
your authentication device.
</div>
<div class="row g-3">

View file

@ -16,56 +16,8 @@
target="_blank"
rel="noopener"
class="app-brand-link gap-2">
<span class="app-brand-logo login">
<svg version="1.1"
width="25"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
x="0px"
y="0px"
viewBox="0 0 272.68 76.37"
xml:space="preserve">
<style type="text/css" nonce="{{ style_nonce }}">
.st0 {
fill: #ffffff;
}
.st1 {
fill: #2eac68;
}
.st2 {
fill: #0b5577;
}
</style>
<g>
<path class="st2" d="M244.87,44.46c0.16-1.27,1.3-2.12,2.59-1.95c1.01,0.13,1.85,0.96,1.92,2.05c0.14,1.52,0.26,2.71,0.36,3.85 h16.02c-0.24-1.79-0.49-3.61-0.82-6c-0.1-0.8,0.25-1.61,0.9-2.02c3.4-2.43,5.46-6.75,6.49-12.5c2.34-13.05-7.24-18.86-18.92-20.2 c-7.49-1-11.24-1.45-18.75-2.29c-1.35-0.15-2.51,0.72-2.65,2c-1.48,13.67-2.97,27.34-4.45,41.01h16.79 C244.51,47.22,244.66,46.05,244.87,44.46z M243.31,21.88c2.52,0.56,3.78,0.85,6.29,1.43c0.87-0.8,2.08-1.22,3.37-1.03 c2.21,0.32,3.75,2.31,3.43,4.42c-0.32,2.11-2.36,3.55-4.55,3.23c-1.27-0.19-2.31-0.93-2.91-1.94c-2.56-0.14-3.84-0.2-6.41-0.32 C242.84,25.36,242.99,24.2,243.31,21.88z" />
<g>
<path class="st2" d="M224.95,41c0.11-1.06-0.73-2.08-1.81-2.19c-6.15-0.63-9.23-0.91-15.38-1.43c-1.16-0.1-2.02-1.09-1.93-2.23 c0.01-0.08,0.01-0.13,0.02-0.21c0.09-1.06,1.11-1.91,2.27-1.81c4.44,0.37,6.67,0.57,11.11,1c1.09,0.11,2.12-0.72,2.24-1.85 c0.35-3.56,0.53-5.34,0.88-8.91c0.1-1.06-0.76-2.07-1.87-2.18c-4.51-0.44-6.76-0.64-11.28-1.02c-1.18-0.1-2.06-1.1-1.97-2.23 c0.09-1.06,1.12-1.9,2.31-1.8c6.31,0.53,9.47,0.82,15.77,1.46c1.11,0.11,2.17-0.7,2.28-1.84c0.38-3.62,0.57-5.43,0.94-9.04 c0.11-1.06-0.77-2.08-1.9-2.19c-11.16-1.06-22.29-1.98-33.47-2.77c-1.2-0.08-2.24,0.79-2.3,1.85 c-0.89,14.49-1.77,28.97-2.66,43.46c-0.03,0.5,0.13,0.96,0.4,1.33h35.57C224.45,45.8,224.63,44.03,224.95,41z" />
<g>
<path class="st2" d="M185.93,46.8c-2.49-8.91-3.77-13.36-6.42-22.25c-0.06-0.29-0.04-0.71,0.05-0.99 c3.19-8.01,4.82-12,8.14-19.98c0.44-1.04-0.33-2.15-1.53-2.22c-5.45-0.3-8.18-0.43-13.64-0.65c-0.75-0.03-1.45,0.44-1.7,1.07 c-2.18,5.75-3.25,8.62-5.37,14.38c-0.24,0.63-0.92,1.11-1.66,1.08c-0.96-0.03-1.68-0.76-1.65-1.68 c0.16-5.42,0.23-8.14,0.39-13.56c0.03-0.92-0.71-1.65-1.69-1.68c-5.61-0.15-8.41-0.2-14.02-0.26c-0.98-0.01-1.74,0.69-1.75,1.62 c-0.13,14.77-0.26,29.55-0.39,44.32c-0.01,0.92,0.7,1.64,1.63,1.65c5.31,0.06,7.96,0.11,13.26,0.25 c0.93,0.02,1.66-0.66,1.69-1.59c0.14-5.03,0.22-7.54,0.36-12.57c0.03-0.92,0.77-1.61,1.72-1.58c0.06,0,0.09,0,0.15,0 c0.73,0.02,1.29,0.47,1.56,1.12c1.82,5.55,2.72,8.32,4.48,13.88c0.26,0.65,0.81,1.1,1.53,1.13c1.23,0.05,2.31,0.1,3.32,0.14 h11.12C185.9,48,186.1,47.41,185.93,46.8z" />
<g>
<path class="st2" d="M109.16,48.06c1.64-0.06,2.95-1.44,2.9-3.08c-0.14-4.49-0.2-6.73-0.34-11.22 c-0.03-0.92,0.68-1.51,1.48-1.54c0.51-0.01,0.95,0.19,1.25,0.68c3.54,5.28,5.29,7.92,8.72,13.24c0.52,0.99,1.52,1.54,2.67,1.52 c4.62-0.06,6.93-0.08,11.55-0.08c1.64,0,3-1.34,3.01-2.98c0.05-13.87,0.1-27.75,0.16-41.62c0.01-1.63-1.42-2.99-3.16-2.99 c-4.46,0-6.7,0.01-11.16,0.07c-1.73,0.02-3.14,1.39-3.12,3.03c0.07,4.09,0.1,6.14,0.17,10.23c0.01,0.85-0.72,1.43-1.53,1.45 c-0.45,0.01-0.97-0.2-1.27-0.62c-3.6-4.96-5.42-7.43-9.12-12.35c-0.55-0.84-1.62-1.37-2.76-1.34 c-4.88,0.16-7.33,0.26-12.21,0.48c-1.73,0.08-3.1,1.5-3.01,3.13c0.69,13.86,1.39,27.71,2.08,41.57 c0.07,1.37,1.09,2.48,2.38,2.76h2.4C103.45,48.26,105.53,48.18,109.16,48.06z" />
<g>
<path class="st2" d="M90.68,31.54c-0.59-10.75-0.89-16.13-1.48-26.88c-0.1-1.84-1.76-3.25-3.72-3.13 C81.33,1.77,79.25,1.91,75.1,2.2c-1.96,0.14-3.43,1.74-3.29,3.59c0.83,11.11,1.25,16.66,2.08,27.76 c0.23,3.05-1.38,3.88-4.2,4.1c-2.82,0.23-4.61-0.33-4.87-3.37c-0.95-11.1-1.43-16.64-2.38-27.74 c-0.16-1.84-1.86-3.19-3.82-3.02c-4.12,0.37-6.18,0.57-10.29,0.98c-2.03,0.21-3.45,1.86-3.25,3.69 c1.14,10.82,1.72,16.23,2.86,27.05c0.61,6.46,3.39,10.67,7.45,13.16H81.6C87.6,45.46,91.41,40.09,90.68,31.54z" />
<g>
<path class="st2" d="M45.57,39.08c-0.36-3.32-1.02-6.96-4.2-8.75c-1.34-0.76-1.85-2.58-0.95-3.82 c1.9-2.86,1.84-6.21,1.48-9.46c-0.87-7.84-7.46-11.1-19.67-9.49c-7.79,1.03-11.68,1.58-19.45,2.79 c-1.79,0.28-3,1.84-2.74,3.52c1.82,11.52,3.65,23.04,5.47,34.55h37.72C45.2,45.98,45.98,42.89,45.57,39.08z M19.57,41.45 c-0.16-3.39-0.24-5.08-0.39-8.47c-1.42-0.79-2.47-2.16-2.7-3.84c-0.41-2.91,1.72-5.62,4.76-6.03 c3.04-0.41,5.81,1.63,6.19,4.55c0.22,1.69-0.43,3.28-1.59,4.42c0.76,3.31,1.13,4.96,1.88,8.27 C24.46,40.77,22.83,40.99,19.57,41.45z" />
</g>
</g>
<path class="st2" d="M100.25,48.41h-2.4c0.25,0.05,0.5,0.09,0.76,0.08C99.2,48.46,99.73,48.43,100.25,48.41z" />
</g>
</g>
</g>
</g>
<g>
<rect x="89.49" y="51.91" class="st1" width="93.69" height="24.46" />
<g>
<g>
<path class="st0" d="M121.14,73.93l-1.91,0.03l-3.43-9.9l-3.34,9.93l-1.91-0.01l-3.25-14.33l-0.75,0c-0.37,0-0.63-0.07-0.79-0.22 s-0.24-0.34-0.24-0.57c0-0.22,0.08-0.4,0.24-0.55c0.16-0.15,0.42-0.22,0.79-0.22l4.24-0.02c0.37,0,0.63,0.07,0.79,0.22 c0.16,0.15,0.24,0.34,0.24,0.57c0,0.22-0.08,0.4-0.24,0.55s-0.42,0.22-0.79,0.22l-1.96,0.01l2.78,12.22l3.25-9.78l1.84-0.01 l3.42,9.76l2.58-12.24l-1.95,0.01c-0.37,0-0.63-0.07-0.8-0.22c-0.16-0.15-0.25-0.34-0.25-0.57c0-0.22,0.08-0.4,0.24-0.55 c0.16-0.15,0.43-0.22,0.81-0.22l4.22-0.02c0.38,0,0.65,0.07,0.81,0.22c0.16,0.15,0.24,0.34,0.24,0.57c0,0.22-0.08,0.4-0.24,0.55 s-0.43,0.22-0.81,0.22l-0.73,0L121.14,73.93z" />
<path class="st0" d="M146.71,66.25l-15.72,0.06c0.28,1.99,1.12,3.6,2.52,4.81c1.41,1.21,3.14,1.82,5.21,1.81 c1.15,0,2.36-0.2,3.62-0.58c1.26-0.38,2.29-0.89,3.08-1.52c0.23-0.18,0.43-0.28,0.6-0.28c0.2,0,0.37,0.08,0.51,0.23 c0.15,0.15,0.22,0.33,0.22,0.54s-0.1,0.41-0.29,0.61c-0.59,0.61-1.63,1.19-3.12,1.73c-1.5,0.54-3.04,0.81-4.62,0.82 c-2.64,0.01-4.85-0.85-6.63-2.57c-1.78-1.72-2.67-3.82-2.68-6.28c-0.01-2.24,0.81-4.17,2.47-5.78s3.7-2.42,6.15-2.43 c2.52-0.01,4.6,0.81,6.23,2.45C145.91,61.5,146.72,63.63,146.71,66.25z M145.14,64.7c-0.31-1.7-1.12-3.08-2.43-4.14 c-1.31-1.06-2.86-1.59-4.66-1.58c-1.8,0.01-3.35,0.54-4.64,1.6s-2.1,2.45-2.41,4.18L145.14,64.7z" />
<path class="st0" d="M155.06,50.76l0.04,10.23c1.85-2.43,4.09-3.65,6.73-3.66c2.25-0.01,4.18,0.8,5.79,2.43 c1.61,1.63,2.42,3.63,2.43,6.01c0.01,2.4-0.8,4.43-2.41,6.11c-1.62,1.67-3.53,2.51-5.75,2.52c-2.69,0.01-4.94-1.19-6.75-3.61 l0.01,3.03l-3.62,0.01c-0.37,0-0.63-0.07-0.79-0.22c-0.16-0.15-0.24-0.33-0.24-0.55c0-0.23,0.08-0.42,0.24-0.56 c0.16-0.14,0.42-0.21,0.79-0.21l2.07-0.01l-0.07-19.94l-2.07,0.01c-0.37,0-0.63-0.07-0.79-0.22c-0.16-0.15-0.24-0.34-0.24-0.57 c0-0.22,0.08-0.4,0.24-0.55c0.16-0.15,0.42-0.22,0.79-0.22L155.06,50.76z M168.5,65.84c-0.01-1.95-0.68-3.59-2.02-4.94 c-1.34-1.35-2.9-2.02-4.69-2.01s-3.35,0.69-4.67,2.05c-1.33,1.36-1.99,3.01-1.98,4.96c0.01,1.95,0.68,3.59,2.02,4.94 c1.34,1.35,2.9,2.02,4.69,2.01c1.79-0.01,3.35-0.69,4.67-2.05C167.85,69.44,168.51,67.79,168.5,65.84z" />
</g>
</g>
</g>
</svg>
<span class="app-brand-logo login w-75">
<img class="img-fluid" src="img/logo-menu.png" alt="BunkerWeb logo">
</span>
</a>
</div>

View file

@ -338,7 +338,7 @@ def set_security_headers(response):
+ " default-src 'self' https://www.bunkerweb.io https://assets.bunkerity.com https://bunkerity.us1.list-manage.com https://api.github.com;"
+ f" script-src 'self' 'nonce-{app.config['SCRIPT_NONCE']}';"
+ " style-src 'self' 'unsafe-inline';"
+ " img-src 'self' data: https://assets.bunkerity.com;"
+ " img-src 'self' data: blob: https://assets.bunkerity.com;"
+ " font-src 'self' data:;"
+ " base-uri 'self';"
+ " block-all-mixed-content;"