|
|
|
@@ -21,8 +21,38 @@
|
|
|
|
|
})();
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
{% with request_host=request.get_host %}
|
|
|
|
|
{% if request_host|slice:":11" != "auth-admin." and request_host|slice:":9" != "id-admin." and request_host|slice:":12" != "172.22.0.222" %}
|
|
|
|
|
{% if request.path|slice:":9" == "/if/flow/" or request.path|slice:":7" == "/flows/" or request.path|slice:":7" == "/login/" %}
|
|
|
|
|
<script data-id="nodedc-auth-flow-scope">
|
|
|
|
|
"use strict";
|
|
|
|
|
|
|
|
|
|
(function () {
|
|
|
|
|
const isAuthentikAdminHost =
|
|
|
|
|
window.location.hostname.startsWith("auth-admin.") ||
|
|
|
|
|
window.location.hostname.startsWith("id-admin.") ||
|
|
|
|
|
window.location.hostname === "172.22.0.222";
|
|
|
|
|
const isAuthExperiencePage =
|
|
|
|
|
!isAuthentikAdminHost &&
|
|
|
|
|
(
|
|
|
|
|
window.location.pathname.includes("/if/flow/") ||
|
|
|
|
|
window.location.pathname.includes("/flows/") ||
|
|
|
|
|
window.location.pathname.includes("/login/")
|
|
|
|
|
);
|
|
|
|
|
document.documentElement.classList.toggle("nodedc-auth-flow-page", isAuthExperiencePage);
|
|
|
|
|
|
|
|
|
|
window.addEventListener("DOMContentLoaded", function () {
|
|
|
|
|
document.body?.classList.toggle("nodedc-auth-flow-page", isAuthExperiencePage);
|
|
|
|
|
}, { once: true });
|
|
|
|
|
})();
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style data-id="nodedc-auth-login-css">
|
|
|
|
|
{% include "branding/nodedc-login.css" %}
|
|
|
|
|
</style>
|
|
|
|
|
|
|
|
|
|
<style data-id="nodedc-auth-critical-loader">
|
|
|
|
|
:root {
|
|
|
|
|
html.nodedc-auth-flow-page {
|
|
|
|
|
--ak-global--primary: rgb(195, 255, 102) !important;
|
|
|
|
|
--ak-global--background: #0e0f10 !important;
|
|
|
|
|
--ak-global--background-image: none !important;
|
|
|
|
@@ -37,22 +67,22 @@
|
|
|
|
|
--nodedc-auth-bg: #0e0f10 !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
html,
|
|
|
|
|
body,
|
|
|
|
|
html body .pf-c-login {
|
|
|
|
|
html.nodedc-auth-flow-page,
|
|
|
|
|
html.nodedc-auth-flow-page body,
|
|
|
|
|
html.nodedc-auth-flow-page body .pf-c-login {
|
|
|
|
|
background: #0e0f10 !important;
|
|
|
|
|
color-scheme: dark !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
html body ak-flow-executor::part(main),
|
|
|
|
|
html body .pf-c-login__main,
|
|
|
|
|
html body .pf-c-empty-state,
|
|
|
|
|
html body .pf-v5-c-empty-state,
|
|
|
|
|
html body .pf-v6-c-empty-state,
|
|
|
|
|
html body .pf-c-card,
|
|
|
|
|
html body .pf-v5-c-card,
|
|
|
|
|
html body .pf-v6-c-card,
|
|
|
|
|
html body [class*="empty-state"] {
|
|
|
|
|
html.nodedc-auth-flow-page body ak-flow-executor::part(main),
|
|
|
|
|
html.nodedc-auth-flow-page body .pf-c-login__main,
|
|
|
|
|
html.nodedc-auth-flow-page body .pf-c-empty-state,
|
|
|
|
|
html.nodedc-auth-flow-page body .pf-v5-c-empty-state,
|
|
|
|
|
html.nodedc-auth-flow-page body .pf-v6-c-empty-state,
|
|
|
|
|
html.nodedc-auth-flow-page body .pf-c-card,
|
|
|
|
|
html.nodedc-auth-flow-page body .pf-v5-c-card,
|
|
|
|
|
html.nodedc-auth-flow-page body .pf-v6-c-card,
|
|
|
|
|
html.nodedc-auth-flow-page body [class*="empty-state"] {
|
|
|
|
|
background: transparent !important;
|
|
|
|
|
box-shadow: none !important;
|
|
|
|
|
border: 0 !important;
|
|
|
|
@@ -60,11 +90,11 @@
|
|
|
|
|
backdrop-filter: none !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
html body .pf-c-spinner,
|
|
|
|
|
html body .pf-v5-c-spinner,
|
|
|
|
|
html body .pf-v6-c-spinner,
|
|
|
|
|
html body [role="progressbar"],
|
|
|
|
|
html body ak-spinner {
|
|
|
|
|
html.nodedc-auth-flow-page body .pf-c-spinner,
|
|
|
|
|
html.nodedc-auth-flow-page body .pf-v5-c-spinner,
|
|
|
|
|
html.nodedc-auth-flow-page body .pf-v6-c-spinner,
|
|
|
|
|
html.nodedc-auth-flow-page body [role="progressbar"],
|
|
|
|
|
html.nodedc-auth-flow-page body ak-spinner {
|
|
|
|
|
--pf-c-spinner--Color: rgb(195, 255, 102) !important;
|
|
|
|
|
--pf-v5-c-spinner--Color: rgb(195, 255, 102) !important;
|
|
|
|
|
--pf-v6-c-spinner--Color: rgb(195, 255, 102) !important;
|
|
|
|
@@ -74,8 +104,8 @@
|
|
|
|
|
color: rgb(195, 255, 102) !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
html body #ak-placeholder.ak-c-placeholder,
|
|
|
|
|
html body .ak-c-placeholder[slot="placeholder"] {
|
|
|
|
|
html.nodedc-auth-flow-page body #ak-placeholder.ak-c-placeholder,
|
|
|
|
|
html.nodedc-auth-flow-page body .ak-c-placeholder[slot="placeholder"] {
|
|
|
|
|
position: fixed !important;
|
|
|
|
|
top: 50% !important;
|
|
|
|
|
left: 50% !important;
|
|
|
|
@@ -98,16 +128,16 @@
|
|
|
|
|
overflow: visible !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
html body #ak-placeholder.ak-c-placeholder .pf-c-spinner,
|
|
|
|
|
html body .ak-c-placeholder[slot="placeholder"] .pf-c-spinner,
|
|
|
|
|
html body #ak-placeholder.ak-c-placeholder [role="progressbar"],
|
|
|
|
|
html body .ak-c-placeholder[slot="placeholder"] [role="progressbar"] {
|
|
|
|
|
html.nodedc-auth-flow-page body #ak-placeholder.ak-c-placeholder .pf-c-spinner,
|
|
|
|
|
html.nodedc-auth-flow-page body .ak-c-placeholder[slot="placeholder"] .pf-c-spinner,
|
|
|
|
|
html.nodedc-auth-flow-page body #ak-placeholder.ak-c-placeholder [role="progressbar"],
|
|
|
|
|
html.nodedc-auth-flow-page body .ak-c-placeholder[slot="placeholder"] [role="progressbar"] {
|
|
|
|
|
opacity: 0 !important;
|
|
|
|
|
visibility: hidden !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
html body #ak-placeholder.ak-c-placeholder::before,
|
|
|
|
|
html body .ak-c-placeholder[slot="placeholder"]::before {
|
|
|
|
|
html.nodedc-auth-flow-page body #ak-placeholder.ak-c-placeholder::before,
|
|
|
|
|
html.nodedc-auth-flow-page body .ak-c-placeholder[slot="placeholder"]::before {
|
|
|
|
|
content: "";
|
|
|
|
|
position: absolute;
|
|
|
|
|
inset: 0;
|
|
|
|
@@ -118,14 +148,14 @@
|
|
|
|
|
pointer-events: none;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
html body.nodedc-auth-loading ak-flow-executor::part(main),
|
|
|
|
|
html body.nodedc-auth-loading .pf-c-login__main {
|
|
|
|
|
html.nodedc-auth-flow-page body.nodedc-auth-loading ak-flow-executor::part(main),
|
|
|
|
|
html.nodedc-auth-flow-page body.nodedc-auth-loading .pf-c-login__main {
|
|
|
|
|
opacity: 0 !important;
|
|
|
|
|
visibility: hidden !important;
|
|
|
|
|
pointer-events: none !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
html body.nodedc-auth-loading::before {
|
|
|
|
|
html.nodedc-auth-flow-page body.nodedc-auth-loading::before {
|
|
|
|
|
content: "";
|
|
|
|
|
position: fixed;
|
|
|
|
|
top: 50%;
|
|
|
|
@@ -141,7 +171,7 @@
|
|
|
|
|
pointer-events: none;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
html body.nodedc-auth-card-ready::before {
|
|
|
|
|
html.nodedc-auth-flow-page body.nodedc-auth-card-ready::before {
|
|
|
|
|
display: none !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -165,14 +195,38 @@
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|
{% endif %}
|
|
|
|
|
{% endif %}
|
|
|
|
|
{% endwith %}
|
|
|
|
|
|
|
|
|
|
<script data-id="authentik-config">
|
|
|
|
|
"use strict";
|
|
|
|
|
|
|
|
|
|
const isAuthentikAdminHost =
|
|
|
|
|
window.location.hostname.startsWith("auth-admin.") ||
|
|
|
|
|
window.location.hostname.startsWith("id-admin.") ||
|
|
|
|
|
window.location.hostname === "172.22.0.222";
|
|
|
|
|
const isAuthExperiencePage =
|
|
|
|
|
!isAuthentikAdminHost &&
|
|
|
|
|
(
|
|
|
|
|
window.location.pathname.includes("/if/flow/") ||
|
|
|
|
|
window.location.pathname.includes("/flows/") ||
|
|
|
|
|
window.location.pathname.includes("/login/")
|
|
|
|
|
);
|
|
|
|
|
const authentikBrand = JSON.parse('{{ brand_json|escapejs }}' || "{}");
|
|
|
|
|
if (isAuthExperiencePage) {
|
|
|
|
|
const nodedcAuthLoginCss = document.querySelector('style[data-id="nodedc-auth-login-css"]')?.textContent || "";
|
|
|
|
|
authentikBrand.branding_custom_css = nodedcAuthLoginCss;
|
|
|
|
|
authentikBrand.brandingCustomCss = nodedcAuthLoginCss;
|
|
|
|
|
} else {
|
|
|
|
|
authentikBrand.branding_custom_css = "";
|
|
|
|
|
authentikBrand.brandingCustomCss = "";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
window.authentik = {
|
|
|
|
|
locale: "ru",
|
|
|
|
|
config: JSON.parse('{{ config_json|escapejs }}' || "{}"),
|
|
|
|
|
brand: JSON.parse('{{ brand_json|escapejs }}' || "{}"),
|
|
|
|
|
brand: authentikBrand,
|
|
|
|
|
versionFamily: "{{ version_family }}",
|
|
|
|
|
versionSubdomain: "{{ version_subdomain }}",
|
|
|
|
|
build: "{{ build }}",
|
|
|
|
@@ -197,10 +251,31 @@
|
|
|
|
|
});
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
{% with request_host=request.get_host %}
|
|
|
|
|
{% if request_host|slice:":11" != "auth-admin." and request_host|slice:":9" != "id-admin." and request_host|slice:":12" != "172.22.0.222" %}
|
|
|
|
|
{% if request.path|slice:":9" == "/if/flow/" or request.path|slice:":7" == "/flows/" or request.path|slice:":7" == "/login/" %}
|
|
|
|
|
<script data-id="nodedc-auth-field-enhancements">
|
|
|
|
|
"use strict";
|
|
|
|
|
|
|
|
|
|
(function () {
|
|
|
|
|
const isAuthentikAdminHost =
|
|
|
|
|
window.location.hostname.startsWith("auth-admin.") ||
|
|
|
|
|
window.location.hostname.startsWith("id-admin.") ||
|
|
|
|
|
window.location.hostname === "172.22.0.222";
|
|
|
|
|
const isAuthExperiencePage =
|
|
|
|
|
!isAuthentikAdminHost &&
|
|
|
|
|
(
|
|
|
|
|
window.location.pathname.includes("/if/flow/") ||
|
|
|
|
|
window.location.pathname.includes("/flows/") ||
|
|
|
|
|
window.location.pathname.includes("/login/")
|
|
|
|
|
);
|
|
|
|
|
if (!isAuthExperiencePage) return;
|
|
|
|
|
|
|
|
|
|
document.documentElement.classList.add("nodedc-auth-flow-page");
|
|
|
|
|
window.addEventListener("DOMContentLoaded", function () {
|
|
|
|
|
document.body?.classList.add("nodedc-auth-flow-page");
|
|
|
|
|
}, { once: true });
|
|
|
|
|
|
|
|
|
|
const logoSvg = `
|
|
|
|
|
<svg id="nodedc-logo" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 220.82 54.55" aria-hidden="true">
|
|
|
|
|
<defs>
|
|
|
|
@@ -254,9 +329,11 @@
|
|
|
|
|
["Continue", "Продолжить"],
|
|
|
|
|
["Show password", "Показать пароль"],
|
|
|
|
|
["Hide password", "Скрыть пароль"],
|
|
|
|
|
["Permission denied", "Доступ ограничен"],
|
|
|
|
|
["Permission denied", "Доступ запрещён"],
|
|
|
|
|
["Not you?", "Сменить пользователя"],
|
|
|
|
|
["Request has been denied.", "Доступ к модулю ограничен."],
|
|
|
|
|
["Request has been denied.", "Доступ запрещён."],
|
|
|
|
|
["The request has been denied.", "Доступ запрещён."],
|
|
|
|
|
["В произведении запроса было отказано.", "Доступ запрещён."],
|
|
|
|
|
["Go home", "Вернуться назад"],
|
|
|
|
|
["Response returned an error code", "Не удалось завершить операцию."],
|
|
|
|
|
]);
|
|
|
|
@@ -366,7 +443,11 @@
|
|
|
|
|
denied = [
|
|
|
|
|
"Permission denied",
|
|
|
|
|
"Доступ ограничен",
|
|
|
|
|
"Доступ запрещен",
|
|
|
|
|
"Доступ запрещён",
|
|
|
|
|
"Request has been denied.",
|
|
|
|
|
"The request has been denied.",
|
|
|
|
|
"В произведении запроса было отказано.",
|
|
|
|
|
"Доступ к модулю ограничен.",
|
|
|
|
|
].some((message) => text.includes(message));
|
|
|
|
|
});
|
|
|
|
@@ -387,8 +468,8 @@
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function applyPermissionDeniedLayout(root) {
|
|
|
|
|
const deniedTitleMessages = ["Permission denied", "Доступ ограничен"];
|
|
|
|
|
const deniedSubtitle = "Доступ к модулю NODE.DC ограничен.";
|
|
|
|
|
const deniedTitleMessages = ["Permission denied", "Доступ ограничен", "Доступ запрещен", "Доступ запрещён"];
|
|
|
|
|
const deniedSubtitle = "Доступ запрещён.";
|
|
|
|
|
const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, {
|
|
|
|
|
acceptNode(node) {
|
|
|
|
|
const text = node.nodeValue?.trim() || "";
|
|
|
|
@@ -426,7 +507,19 @@
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function hidePermissionDeniedReason(root) {
|
|
|
|
|
const deniedMessages = ["Request has been denied.", "Доступ к модулю ограничен."];
|
|
|
|
|
const deniedMessages = [
|
|
|
|
|
"Request has been denied.",
|
|
|
|
|
"The request has been denied.",
|
|
|
|
|
"В произведении запроса было отказано.",
|
|
|
|
|
"Доступ к модулю ограничен.",
|
|
|
|
|
"Объяснение:",
|
|
|
|
|
"Reason:",
|
|
|
|
|
"Привязка политики",
|
|
|
|
|
"Policy binding",
|
|
|
|
|
"returned result",
|
|
|
|
|
"returned a result",
|
|
|
|
|
"'None' вернула результат",
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
root.querySelectorAll(".pf-c-alert, .pf-v5-c-alert, .pf-c-empty-state__body, [class*='alert']").forEach((element) => {
|
|
|
|
|
const text = element.textContent || "";
|
|
|
|
@@ -547,12 +640,35 @@
|
|
|
|
|
enhancePasswordFields(root);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function dispatchSyntheticInput(input) {
|
|
|
|
|
if (!input) return;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
input.dispatchEvent(new InputEvent("input", {
|
|
|
|
|
bubbles: true,
|
|
|
|
|
composed: true,
|
|
|
|
|
inputType: "insertReplacementText",
|
|
|
|
|
data: input.value || "",
|
|
|
|
|
}));
|
|
|
|
|
} catch {
|
|
|
|
|
input.dispatchEvent(new Event("input", { bubbles: true, composed: true }));
|
|
|
|
|
}
|
|
|
|
|
input.dispatchEvent(new Event("change", { bubbles: true, composed: true }));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function syncFormFieldsBeforeSubmit(form) {
|
|
|
|
|
form.querySelectorAll("#ak-identifier-input, #ak-stage-identification-password, #ak-stage-password-input").forEach((input) => {
|
|
|
|
|
dispatchSyntheticInput(input);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function enhanceSubmitHandoff(root) {
|
|
|
|
|
root.querySelectorAll("form").forEach((form) => {
|
|
|
|
|
if (form.dataset.nodedcSubmitBound === "true") return;
|
|
|
|
|
|
|
|
|
|
form.dataset.nodedcSubmitBound = "true";
|
|
|
|
|
form.addEventListener("submit", () => {
|
|
|
|
|
syncFormFieldsBeforeSubmit(form);
|
|
|
|
|
document.body?.classList.add("nodedc-auth-submitting");
|
|
|
|
|
}, true);
|
|
|
|
|
});
|
|
|
|
@@ -823,3 +939,6 @@
|
|
|
|
|
});
|
|
|
|
|
})();
|
|
|
|
|
</script>
|
|
|
|
|
{% endif %}
|
|
|
|
|
{% endif %}
|
|
|
|
|
{% endwith %}
|
|
|
|
|