Compare commits
No commits in common. "9d7f8167d3b8845691423885dafcea264703f996" and "2a9b9f2e5eb36f8f711a9b292a623a78ec31236a" have entirely different histories.
9d7f8167d3
...
2a9b9f2e5e
|
|
@ -1,151 +1,6 @@
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% get_current_language as LANGUAGE_CODE %}
|
{% get_current_language as LANGUAGE_CODE %}
|
||||||
|
|
||||||
<style data-id="nodedc-auth-critical-loader">
|
|
||||||
:root {
|
|
||||||
--ak-global--primary: rgb(195, 255, 102) !important;
|
|
||||||
--ak-global--background: #0e0f10 !important;
|
|
||||||
--ak-global--background-image: none !important;
|
|
||||||
--pf-global--primary-color--100: rgb(195, 255, 102) !important;
|
|
||||||
--pf-v5-global--primary-color--100: rgb(195, 255, 102) !important;
|
|
||||||
--pf-v6-global--primary-color--100: rgb(195, 255, 102) !important;
|
|
||||||
--pf-v4-global--palette--blue-300: rgb(195, 255, 102) !important;
|
|
||||||
--ak-global--palette--blue-300: rgb(195, 255, 102) !important;
|
|
||||||
--pf-global--active-color--100: rgb(195, 255, 102) !important;
|
|
||||||
--pf-global--link--Color: rgb(195, 255, 102) !important;
|
|
||||||
--nodedc-auth-primary: rgb(195, 255, 102) !important;
|
|
||||||
--nodedc-auth-bg: #0e0f10 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html,
|
|
||||||
body,
|
|
||||||
html 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"] {
|
|
||||||
background: transparent !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
border: 0 !important;
|
|
||||||
-webkit-backdrop-filter: none !important;
|
|
||||||
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 {
|
|
||||||
--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;
|
|
||||||
--pf-c-spinner__clipper--after--BoxShadowColor: rgb(195, 255, 102) !important;
|
|
||||||
--pf-c-spinner__lead-ball--after--BackgroundColor: rgb(195, 255, 102) !important;
|
|
||||||
--pf-c-spinner__tail-ball--after--BackgroundColor: rgb(195, 255, 102) !important;
|
|
||||||
color: rgb(195, 255, 102) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #ak-placeholder.ak-c-placeholder,
|
|
||||||
html body .ak-c-placeholder[slot="placeholder"] {
|
|
||||||
position: fixed !important;
|
|
||||||
top: 50% !important;
|
|
||||||
left: 50% !important;
|
|
||||||
display: block !important;
|
|
||||||
width: 2.5rem !important;
|
|
||||||
height: 2.5rem !important;
|
|
||||||
min-width: 2.5rem !important;
|
|
||||||
min-height: 2.5rem !important;
|
|
||||||
margin: 0 !important;
|
|
||||||
padding: 0 !important;
|
|
||||||
border: 0 !important;
|
|
||||||
border-radius: 999px !important;
|
|
||||||
background: transparent !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
opacity: 1 !important;
|
|
||||||
visibility: visible !important;
|
|
||||||
-webkit-backdrop-filter: none !important;
|
|
||||||
backdrop-filter: none !important;
|
|
||||||
transform: translate(-50%, -50%) !important;
|
|
||||||
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"] {
|
|
||||||
opacity: 0 !important;
|
|
||||||
visibility: hidden !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body #ak-placeholder.ak-c-placeholder::before,
|
|
||||||
html body .ak-c-placeholder[slot="placeholder"]::before {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
inset: 0;
|
|
||||||
border: 2px solid rgba(195, 255, 102, 0.22);
|
|
||||||
border-top-color: rgb(195, 255, 102);
|
|
||||||
border-radius: 999px;
|
|
||||||
animation: nodedc-auth-placeholder-spin 0.72s linear infinite;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body.nodedc-auth-loading ak-flow-executor::part(main),
|
|
||||||
html body.nodedc-auth-loading .pf-c-login__main {
|
|
||||||
opacity: 0 !important;
|
|
||||||
visibility: hidden !important;
|
|
||||||
pointer-events: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body.nodedc-auth-loading::before {
|
|
||||||
content: "";
|
|
||||||
position: fixed;
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
z-index: 1200;
|
|
||||||
width: 2.5rem;
|
|
||||||
height: 2.5rem;
|
|
||||||
border: 2px solid rgba(195, 255, 102, 0.22);
|
|
||||||
border-top-color: rgb(195, 255, 102);
|
|
||||||
border-radius: 999px;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
animation: nodedc-auth-loader-spin 0.72s linear infinite;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
html body.nodedc-auth-card-ready::before {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes nodedc-auth-loader-spin {
|
|
||||||
from {
|
|
||||||
transform: translate(-50%, -50%) rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
to {
|
|
||||||
transform: translate(-50%, -50%) rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes nodedc-auth-placeholder-spin {
|
|
||||||
from {
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
to {
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<script data-id="authentik-config">
|
<script data-id="authentik-config">
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
|
@ -205,20 +60,12 @@
|
||||||
<path d="M9 9l6 6M15 9l-6 6" stroke="currentColor" stroke-width="2" stroke-linecap="round"></path>
|
<path d="M9 9l6 6M15 9l-6 6" stroke="currentColor" stroke-width="2" stroke-linecap="round"></path>
|
||||||
</svg>
|
</svg>
|
||||||
`;
|
`;
|
||||||
const genericLoginError = "Не удалось выполнить вход. Проверьте email и пароль или запросите доступ.";
|
|
||||||
const revokedLoginError = "Аккаунт больше не активен. Запросите доступ, если хотите подключиться снова.";
|
|
||||||
const genericFlowErrorMessages = [
|
|
||||||
"Response returned an error code",
|
|
||||||
"Response returned an error",
|
|
||||||
"Не удалось завершить операцию.",
|
|
||||||
];
|
|
||||||
const accountStatusCache = new Map();
|
|
||||||
const authTranslations = new Map([
|
const authTranslations = new Map([
|
||||||
["Failed to authenticate.", genericLoginError],
|
["Failed to authenticate.", "Не удалось выполнить вход."],
|
||||||
["Invalid credentials.", genericLoginError],
|
["Invalid credentials.", "Неверная почта или пароль."],
|
||||||
["Invalid password.", genericLoginError],
|
["Invalid password.", "Неверный пароль."],
|
||||||
["Incorrect password.", genericLoginError],
|
["Incorrect password.", "Неверный пароль."],
|
||||||
["Authentication failed.", genericLoginError],
|
["Authentication failed.", "Не удалось выполнить вход."],
|
||||||
["This field is required.", "Заполните это поле."],
|
["This field is required.", "Заполните это поле."],
|
||||||
["Please enter your password", "Введите пароль"],
|
["Please enter your password", "Введите пароль"],
|
||||||
["Please enter your password.", "Введите пароль."],
|
["Please enter your password.", "Введите пароль."],
|
||||||
|
|
@ -234,11 +81,6 @@
|
||||||
["Continue", "Продолжить"],
|
["Continue", "Продолжить"],
|
||||||
["Show password", "Показать пароль"],
|
["Show password", "Показать пароль"],
|
||||||
["Hide password", "Скрыть пароль"],
|
["Hide password", "Скрыть пароль"],
|
||||||
["Permission denied", "Доступ ограничен"],
|
|
||||||
["Not you?", "Сменить пользователя"],
|
|
||||||
["Request has been denied.", "Доступ к модулю ограничен."],
|
|
||||||
["Go home", "Вернуться назад"],
|
|
||||||
["Response returned an error code", "Не удалось завершить операцию."],
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
function visitRoots(root, callback) {
|
function visitRoots(root, callback) {
|
||||||
|
|
@ -326,113 +168,6 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasPermissionDeniedScreen() {
|
|
||||||
let denied = false;
|
|
||||||
visitRoots(document, (root) => {
|
|
||||||
if (denied) return;
|
|
||||||
const text = root.textContent || "";
|
|
||||||
denied = [
|
|
||||||
"Permission denied",
|
|
||||||
"Доступ ограничен",
|
|
||||||
"Request has been denied.",
|
|
||||||
"Доступ к модулю ограничен.",
|
|
||||||
].some((message) => text.includes(message));
|
|
||||||
});
|
|
||||||
return denied;
|
|
||||||
}
|
|
||||||
|
|
||||||
function syncPermissionDeniedState() {
|
|
||||||
document.body?.classList.toggle("nodedc-auth-permission-denied", hasPermissionDeniedScreen());
|
|
||||||
}
|
|
||||||
|
|
||||||
function findAncestor(element, predicate, maxDepth = 8) {
|
|
||||||
let current = element;
|
|
||||||
for (let depth = 0; current && depth < maxDepth; depth += 1) {
|
|
||||||
if (predicate(current)) return current;
|
|
||||||
current = current.parentElement;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function applyPermissionDeniedLayout(root) {
|
|
||||||
const deniedTitleMessages = ["Permission denied", "Доступ ограничен"];
|
|
||||||
const deniedSubtitle = "Доступ к модулю NODE.DC ограничен.";
|
|
||||||
const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, {
|
|
||||||
acceptNode(node) {
|
|
||||||
const text = node.nodeValue?.trim() || "";
|
|
||||||
return deniedTitleMessages.some((message) => text === message)
|
|
||||||
? NodeFilter.FILTER_ACCEPT
|
|
||||||
: NodeFilter.FILTER_REJECT;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const textNodes = [];
|
|
||||||
while (walker.nextNode()) {
|
|
||||||
textNodes.push(walker.currentNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
textNodes.forEach((node) => {
|
|
||||||
const titleElement = findAncestor(
|
|
||||||
node.parentElement,
|
|
||||||
(element) =>
|
|
||||||
element.matches?.(".pf-c-title, .pf-v5-c-title, h1, h2") ||
|
|
||||||
element.getAttribute?.("slot") === "title",
|
|
||||||
);
|
|
||||||
const header =
|
|
||||||
titleElement?.closest?.(".pf-c-login__main-header") ||
|
|
||||||
findAncestor(titleElement || node.parentElement, (element) => element.matches?.(".pf-c-login__main-header"), 10) ||
|
|
||||||
root.querySelector?.(".pf-c-login__main-header");
|
|
||||||
|
|
||||||
if (titleElement) {
|
|
||||||
titleElement.style.display = "none";
|
|
||||||
}
|
|
||||||
if (header) {
|
|
||||||
header.setAttribute("data-nodedc-permission-denied", "true");
|
|
||||||
header.setAttribute("data-nodedc-denied-subtitle", deniedSubtitle);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function hidePermissionDeniedReason(root) {
|
|
||||||
const deniedMessages = ["Request has been denied.", "Доступ к модулю ограничен."];
|
|
||||||
|
|
||||||
root.querySelectorAll(".pf-c-alert, .pf-v5-c-alert, .pf-c-empty-state__body, [class*='alert']").forEach((element) => {
|
|
||||||
const text = element.textContent || "";
|
|
||||||
if (deniedMessages.some((message) => text.includes(message))) {
|
|
||||||
element.style.display = "none";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, {
|
|
||||||
acceptNode(node) {
|
|
||||||
const text = node.nodeValue?.trim() || "";
|
|
||||||
return deniedMessages.some((message) => text.includes(message))
|
|
||||||
? NodeFilter.FILTER_ACCEPT
|
|
||||||
: NodeFilter.FILTER_REJECT;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const textNodes = [];
|
|
||||||
while (walker.nextNode()) {
|
|
||||||
textNodes.push(walker.currentNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
textNodes.forEach((node) => {
|
|
||||||
let element = node.parentElement;
|
|
||||||
for (let depth = 0; element && depth < 6; depth += 1) {
|
|
||||||
const text = (element.textContent || "").trim();
|
|
||||||
if (deniedMessages.some((message) => text === message || text.endsWith(message)) && text.length <= 96) {
|
|
||||||
element.style.display = "none";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
element = element.parentElement;
|
|
||||||
}
|
|
||||||
if (node.parentElement) {
|
|
||||||
node.parentElement.style.display = "none";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function enhanceIdentifierField(root) {
|
function enhanceIdentifierField(root) {
|
||||||
const input = root.querySelector("#ak-identifier-input");
|
const input = root.querySelector("#ak-identifier-input");
|
||||||
if (!input || input.dataset.nodedcClearBound === "true") return;
|
if (!input || input.dataset.nodedcClearBound === "true") return;
|
||||||
|
|
@ -526,100 +261,6 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function ensureAccessRequestLink(root) {
|
|
||||||
const input = root.querySelector("#ak-identifier-input, #ak-stage-identification-password, #ak-stage-password-input");
|
|
||||||
const form = input?.closest("form") || root.querySelector("form");
|
|
||||||
if (!input || !form || form.querySelector("[data-nodedc-access-request='true']")) return;
|
|
||||||
|
|
||||||
const link = document.createElement("a");
|
|
||||||
link.className = "nodedc-auth-request-access";
|
|
||||||
link.dataset.nodedcAccessRequest = "true";
|
|
||||||
link.href = new URL("/request-access", getLauncherBaseUrl()).toString();
|
|
||||||
link.textContent = "Запросить доступ";
|
|
||||||
form.appendChild(link);
|
|
||||||
}
|
|
||||||
|
|
||||||
function normalizeEmail(value) {
|
|
||||||
return typeof value === "string" ? value.trim().toLowerCase() : "";
|
|
||||||
}
|
|
||||||
|
|
||||||
function getLoginEmail(root) {
|
|
||||||
return normalizeEmail(root.querySelector("#ak-identifier-input")?.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getLoginErrorMessages() {
|
|
||||||
return [
|
|
||||||
"Failed to authenticate.",
|
|
||||||
"Invalid credentials.",
|
|
||||||
"Invalid password.",
|
|
||||||
"Incorrect password.",
|
|
||||||
"Authentication failed.",
|
|
||||||
"Не удалось выполнить вход.",
|
|
||||||
"Неверная почта или пароль.",
|
|
||||||
"Неверный пароль.",
|
|
||||||
genericLoginError,
|
|
||||||
revokedLoginError,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
function replaceLoginErrorText(root, message) {
|
|
||||||
const errorMessages = getLoginErrorMessages();
|
|
||||||
const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, {
|
|
||||||
acceptNode(node) {
|
|
||||||
const text = node.nodeValue?.trim() || "";
|
|
||||||
return errorMessages.some((errorMessage) => text.includes(errorMessage))
|
|
||||||
? NodeFilter.FILTER_ACCEPT
|
|
||||||
: NodeFilter.FILTER_REJECT;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const textNodes = [];
|
|
||||||
|
|
||||||
while (walker.nextNode()) {
|
|
||||||
textNodes.push(walker.currentNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
textNodes.forEach((node) => {
|
|
||||||
const currentValue = node.nodeValue || "";
|
|
||||||
const trimmed = currentValue.trim();
|
|
||||||
if (!trimmed) return;
|
|
||||||
node.nodeValue = currentValue.replace(trimmed, message);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function syncLoginErrorReason(root) {
|
|
||||||
if (!hasAuthError(root)) return;
|
|
||||||
|
|
||||||
replaceLoginErrorText(root, genericLoginError);
|
|
||||||
const email = getLoginEmail(root);
|
|
||||||
if (!email) return;
|
|
||||||
|
|
||||||
const cachedStatus = accountStatusCache.get(email);
|
|
||||||
if (cachedStatus === "revoked") {
|
|
||||||
replaceLoginErrorText(root, revokedLoginError);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cachedStatus === "unknown" || cachedStatus === "loading") return;
|
|
||||||
|
|
||||||
accountStatusCache.set(email, "loading");
|
|
||||||
const statusUrl = new URL("/api/public/login-account-status", getLauncherBaseUrl());
|
|
||||||
statusUrl.searchParams.set("email", email);
|
|
||||||
|
|
||||||
fetch(statusUrl.toString(), { cache: "no-store" })
|
|
||||||
.then((response) => (response.ok ? response.json() : null))
|
|
||||||
.then((payload) => {
|
|
||||||
const status = payload?.status === "revoked" ? "revoked" : "unknown";
|
|
||||||
accountStatusCache.set(email, status);
|
|
||||||
if (status !== "revoked") return;
|
|
||||||
visitRoots(document, (candidateRoot) => {
|
|
||||||
replaceLoginErrorText(candidateRoot, revokedLoginError);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
accountStatusCache.set(email, "unknown");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function hasAuthError(root) {
|
function hasAuthError(root) {
|
||||||
const hasErrorElement = root.querySelector(
|
const hasErrorElement = root.querySelector(
|
||||||
".pf-c-alert, .pf-m-error, .pf-c-helper-text__item.pf-m-error, [aria-invalid='true']"
|
".pf-c-alert, .pf-m-error, .pf-c-helper-text__item.pf-m-error, [aria-invalid='true']"
|
||||||
|
|
@ -627,44 +268,14 @@
|
||||||
if (hasErrorElement) return true;
|
if (hasErrorElement) return true;
|
||||||
|
|
||||||
const text = root.textContent || "";
|
const text = root.textContent || "";
|
||||||
return getLoginErrorMessages().some((message) => text.includes(message));
|
return [
|
||||||
}
|
"Failed to authenticate.",
|
||||||
|
"Не удалось выполнить вход.",
|
||||||
function hasGenericFlowError(root) {
|
"Invalid credentials.",
|
||||||
const text = root.textContent || "";
|
"Неверная почта или пароль.",
|
||||||
return genericFlowErrorMessages.some((message) => text.includes(message));
|
"Invalid password.",
|
||||||
}
|
"Неверный пароль.",
|
||||||
|
].some((message) => text.includes(message));
|
||||||
function hasLoadingOnlyScreen(root) {
|
|
||||||
const isFlowExecutorRoot = root.host?.tagName?.toLowerCase() === "ak-flow-executor";
|
|
||||||
const hasProgress =
|
|
||||||
root.querySelector?.(".pf-c-spinner, .pf-v5-c-spinner, [role='progressbar'], ak-spinner");
|
|
||||||
const isEmptyFlowExecutor = isFlowExecutorRoot && (root.textContent || "").trim() === "";
|
|
||||||
const hasInteractiveAuth =
|
|
||||||
root.querySelector?.("input, textarea, select, button[type='submit'], .pf-c-alert, .pf-v5-c-alert") ||
|
|
||||||
hasGenericFlowError(root);
|
|
||||||
|
|
||||||
return Boolean((hasProgress || isEmptyFlowExecutor) && !hasInteractiveAuth);
|
|
||||||
}
|
|
||||||
|
|
||||||
function syncLoadingState() {
|
|
||||||
let isLoadingOnly = false;
|
|
||||||
let hasAuthContent = false;
|
|
||||||
visitRoots(document, (root) => {
|
|
||||||
if (hasLoadingOnlyScreen(root)) {
|
|
||||||
isLoadingOnly = true;
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
root.querySelector?.("input, textarea, select, button[type='submit'], .pf-c-alert, .pf-v5-c-alert") ||
|
|
||||||
hasGenericFlowError(root)
|
|
||||||
) {
|
|
||||||
hasAuthContent = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
const shouldShowLoader = isLoadingOnly && !hasAuthContent;
|
|
||||||
|
|
||||||
document.body?.classList.toggle("nodedc-auth-loading", shouldShowLoader);
|
|
||||||
document.body?.classList.toggle("nodedc-auth-card-ready", hasAuthContent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function restoreCardOnErrors(root) {
|
function restoreCardOnErrors(root) {
|
||||||
|
|
@ -708,22 +319,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildLoggedOutRedirectUrl() {
|
|
||||||
return new URL("/auth/logged-out", getLauncherBaseUrl()).toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
function redirectGenericFlowError(root) {
|
|
||||||
if (document.body?.dataset.nodedcFlowErrorRedirected === "true") return;
|
|
||||||
if (!window.location.pathname.includes("/if/flow/")) return;
|
|
||||||
if (!hasGenericFlowError(root)) return;
|
|
||||||
|
|
||||||
document.body.dataset.nodedcFlowErrorRedirected = "true";
|
|
||||||
document.body.classList.add("nodedc-auth-submitting");
|
|
||||||
window.setTimeout(() => {
|
|
||||||
window.location.replace(getSafePostLogoutRedirect() || buildLoggedOutRedirectUrl());
|
|
||||||
}, 120);
|
|
||||||
}
|
|
||||||
|
|
||||||
function redirectCompletedLogout(root) {
|
function redirectCompletedLogout(root) {
|
||||||
if (!isOidcLogoutFlow() || document.body?.dataset.nodedcLogoutRedirected === "true") return;
|
if (!isOidcLogoutFlow() || document.body?.dataset.nodedcLogoutRedirected === "true") return;
|
||||||
|
|
||||||
|
|
@ -759,17 +354,10 @@
|
||||||
enhanceIdentifierField(root);
|
enhanceIdentifierField(root);
|
||||||
normalizePasswordFields(root);
|
normalizePasswordFields(root);
|
||||||
enhanceSubmitHandoff(root);
|
enhanceSubmitHandoff(root);
|
||||||
ensureAccessRequestLink(root);
|
|
||||||
translateAuthText(root);
|
translateAuthText(root);
|
||||||
syncLoginErrorReason(root);
|
|
||||||
applyPermissionDeniedLayout(root);
|
|
||||||
hidePermissionDeniedReason(root);
|
|
||||||
restoreCardOnErrors(root);
|
restoreCardOnErrors(root);
|
||||||
redirectCompletedLogout(root);
|
redirectCompletedLogout(root);
|
||||||
redirectGenericFlowError(root);
|
|
||||||
});
|
});
|
||||||
syncPermissionDeniedState();
|
|
||||||
syncLoadingState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function scheduleEnhancement() {
|
function scheduleEnhancement() {
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,6 @@
|
||||||
--ak-c-login__footer--PaddingBlock: 0;
|
--ak-c-login__footer--PaddingBlock: 0;
|
||||||
--pf-global--primary-color--100: rgb(195, 255, 102);
|
--pf-global--primary-color--100: rgb(195, 255, 102);
|
||||||
--pf-global--primary-color--200: rgb(218, 255, 139);
|
--pf-global--primary-color--200: rgb(218, 255, 139);
|
||||||
--pf-v4-global--palette--blue-300: rgb(195, 255, 102);
|
|
||||||
--ak-global--palette--blue-300: rgb(195, 255, 102);
|
|
||||||
--pf-global--active-color--100: rgb(195, 255, 102);
|
|
||||||
--pf-global--link--Color: rgb(195, 255, 102);
|
--pf-global--link--Color: rgb(195, 255, 102);
|
||||||
--pf-global--link--Color--hover: rgb(218, 255, 139);
|
--pf-global--link--Color--hover: rgb(218, 255, 139);
|
||||||
--pf-global--BackgroundColor--100: #0e0f10;
|
--pf-global--BackgroundColor--100: #0e0f10;
|
||||||
|
|
@ -184,19 +181,12 @@ ak-flow-executor::part(main),
|
||||||
outline: none !important;
|
outline: none !important;
|
||||||
box-shadow: none !important;
|
box-shadow: none !important;
|
||||||
border-radius: 1.9rem !important;
|
border-radius: 1.9rem !important;
|
||||||
background: transparent !important;
|
|
||||||
-webkit-backdrop-filter: none !important;
|
|
||||||
backdrop-filter: none !important;
|
|
||||||
justify-content: flex-start !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.nodedc-auth-card-ready ak-flow-executor::part(main),
|
|
||||||
body.nodedc-auth-card-ready .pf-c-login__main {
|
|
||||||
background:
|
background:
|
||||||
linear-gradient(180deg, rgba(255, 255, 255, 0.048) 0%, rgba(255, 255, 255, 0.015) 100%),
|
linear-gradient(180deg, rgba(255, 255, 255, 0.048) 0%, rgba(255, 255, 255, 0.015) 100%),
|
||||||
var(--nodedc-auth-card-bg) !important;
|
var(--nodedc-auth-card-bg) !important;
|
||||||
-webkit-backdrop-filter: blur(40px) !important;
|
-webkit-backdrop-filter: blur(40px);
|
||||||
backdrop-filter: blur(40px) !important;
|
backdrop-filter: blur(40px);
|
||||||
|
justify-content: flex-start !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
ak-flow-card,
|
ak-flow-card,
|
||||||
|
|
@ -214,16 +204,7 @@ ak-stage-password {
|
||||||
.pf-c-input-group,
|
.pf-c-input-group,
|
||||||
.pf-c-input-group__item,
|
.pf-c-input-group__item,
|
||||||
.pf-c-card,
|
.pf-c-card,
|
||||||
.pf-c-card__body,
|
.pf-c-card__body {
|
||||||
.pf-c-empty-state,
|
|
||||||
.pf-c-empty-state__content,
|
|
||||||
.pf-c-empty-state__body,
|
|
||||||
.pf-v5-c-empty-state,
|
|
||||||
.pf-v5-c-empty-state__content,
|
|
||||||
.pf-v5-c-empty-state__body,
|
|
||||||
.pf-v6-c-empty-state,
|
|
||||||
.pf-v6-c-empty-state__content,
|
|
||||||
.pf-v6-c-empty-state__body {
|
|
||||||
background: transparent !important;
|
background: transparent !important;
|
||||||
box-shadow: none !important;
|
box-shadow: none !important;
|
||||||
border: 0 !important;
|
border: 0 !important;
|
||||||
|
|
@ -273,25 +254,6 @@ h1.pf-c-title {
|
||||||
text-transform: none;
|
text-transform: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-login__main-header[data-nodedc-permission-denied="true"]::after,
|
|
||||||
body.nodedc-auth-permission-denied .pf-c-login__main-header::after {
|
|
||||||
content: attr(data-nodedc-denied-subtitle) !important;
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.nodedc-auth-permission-denied .pf-c-login__main-header::after {
|
|
||||||
content: "Доступ к модулю NODE.DC ограничен." !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pf-c-login__main-header[data-nodedc-permission-denied="true"] .pf-c-title,
|
|
||||||
.pf-c-login__main-header[data-nodedc-permission-denied="true"] .pf-c-title.pf-m-3xl,
|
|
||||||
.pf-c-login__main-header[data-nodedc-permission-denied="true"] h1.pf-c-title,
|
|
||||||
body.nodedc-auth-permission-denied .pf-c-login__main-header .pf-c-title,
|
|
||||||
body.nodedc-auth-permission-denied .pf-c-title.pf-m-3xl,
|
|
||||||
body.nodedc-auth-permission-denied h1.pf-c-title {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pf-c-login__main-body {
|
.pf-c-login__main-body {
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
@ -495,9 +457,6 @@ input.pf-c-form-control:-webkit-autofill:focus {
|
||||||
button.pf-m-primary,
|
button.pf-m-primary,
|
||||||
button[type="submit"],
|
button[type="submit"],
|
||||||
.pf-c-form .pf-c-button.pf-m-primary {
|
.pf-c-form .pf-c-button.pf-m-primary {
|
||||||
display: inline-flex !important;
|
|
||||||
align-items: center !important;
|
|
||||||
justify-content: center !important;
|
|
||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
min-height: 3.25rem !important;
|
min-height: 3.25rem !important;
|
||||||
margin-top: 1.25rem !important;
|
margin-top: 1.25rem !important;
|
||||||
|
|
@ -509,9 +468,7 @@ button[type="submit"],
|
||||||
color: var(--nodedc-auth-on-primary) !important;
|
color: var(--nodedc-auth-on-primary) !important;
|
||||||
font-size: 0.95rem !important;
|
font-size: 0.95rem !important;
|
||||||
font-weight: 600 !important;
|
font-weight: 600 !important;
|
||||||
line-height: 1 !important;
|
|
||||||
letter-spacing: -0.02em !important;
|
letter-spacing: -0.02em !important;
|
||||||
text-align: center !important;
|
|
||||||
text-transform: none !important;
|
text-transform: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -522,25 +479,6 @@ button[type="submit"]:hover {
|
||||||
color: var(--nodedc-auth-on-primary) !important;
|
color: var(--nodedc-auth-on-primary) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nodedc-auth-request-access {
|
|
||||||
display: inline-flex !important;
|
|
||||||
justify-content: center !important;
|
|
||||||
width: 100% !important;
|
|
||||||
margin-top: -0.35rem !important;
|
|
||||||
color: var(--nodedc-auth-primary) !important;
|
|
||||||
font-size: 0.75rem !important;
|
|
||||||
line-height: 1rem !important;
|
|
||||||
font-weight: 650 !important;
|
|
||||||
letter-spacing: -0.01em !important;
|
|
||||||
text-decoration: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nodedc-auth-request-access:hover,
|
|
||||||
.nodedc-auth-request-access:focus {
|
|
||||||
color: var(--nodedc-auth-primary-hover) !important;
|
|
||||||
text-decoration: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pf-c-alert,
|
.pf-c-alert,
|
||||||
.pf-c-alert.pf-m-inline {
|
.pf-c-alert.pf-m-inline {
|
||||||
border: 0 !important;
|
border: 0 !important;
|
||||||
|
|
@ -561,12 +499,6 @@ button[type="submit"]:hover {
|
||||||
font-weight: 600 !important;
|
font-weight: 600 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
body.nodedc-auth-permission-denied .pf-c-alert,
|
|
||||||
body.nodedc-auth-permission-denied .pf-v5-c-alert,
|
|
||||||
body.nodedc-auth-permission-denied .pf-c-alert.pf-m-inline {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
a,
|
a,
|
||||||
.pf-c-button.pf-m-link,
|
.pf-c-button.pf-m-link,
|
||||||
button.pf-m-link {
|
button.pf-m-link {
|
||||||
|
|
@ -578,118 +510,15 @@ button.pf-m-link {
|
||||||
}
|
}
|
||||||
|
|
||||||
body.nodedc-auth-submitting ak-flow-executor::part(main),
|
body.nodedc-auth-submitting ak-flow-executor::part(main),
|
||||||
body.nodedc-auth-loading ak-flow-executor::part(main),
|
|
||||||
body.nodedc-auth-submitting .pf-c-login__main,
|
body.nodedc-auth-submitting .pf-c-login__main,
|
||||||
body.nodedc-auth-loading .pf-c-login__main,
|
|
||||||
body.nodedc-auth-submitting .pf-c-empty-state,
|
body.nodedc-auth-submitting .pf-c-empty-state,
|
||||||
body.nodedc-auth-loading .pf-c-empty-state,
|
|
||||||
body.nodedc-auth-submitting .pf-c-spinner,
|
body.nodedc-auth-submitting .pf-c-spinner,
|
||||||
body.nodedc-auth-loading .pf-c-spinner,
|
|
||||||
body.nodedc-auth-submitting [role="progressbar"] {
|
body.nodedc-auth-submitting [role="progressbar"] {
|
||||||
opacity: 0 !important;
|
opacity: 0 !important;
|
||||||
visibility: hidden !important;
|
visibility: hidden !important;
|
||||||
pointer-events: none !important;
|
pointer-events: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
body.nodedc-auth-loading [role="progressbar"] {
|
|
||||||
opacity: 0 !important;
|
|
||||||
visibility: hidden !important;
|
|
||||||
pointer-events: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pf-c-spinner,
|
|
||||||
.pf-v5-c-spinner,
|
|
||||||
[role="progressbar"],
|
|
||||||
ak-spinner {
|
|
||||||
--pf-c-spinner--Color: var(--nodedc-auth-primary) !important;
|
|
||||||
--pf-v5-c-spinner--Color: var(--nodedc-auth-primary) !important;
|
|
||||||
--pf-c-spinner__clipper--after--BoxShadowColor: var(--nodedc-auth-primary) !important;
|
|
||||||
--pf-c-spinner__lead-ball--after--BackgroundColor: var(--nodedc-auth-primary) !important;
|
|
||||||
--pf-c-spinner__tail-ball--after--BackgroundColor: var(--nodedc-auth-primary) !important;
|
|
||||||
color: var(--nodedc-auth-primary) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ak-placeholder.ak-c-placeholder,
|
|
||||||
.ak-c-placeholder[slot="placeholder"] {
|
|
||||||
position: fixed !important;
|
|
||||||
top: 50% !important;
|
|
||||||
left: 50% !important;
|
|
||||||
display: block !important;
|
|
||||||
width: 2.5rem !important;
|
|
||||||
height: 2.5rem !important;
|
|
||||||
min-width: 2.5rem !important;
|
|
||||||
min-height: 2.5rem !important;
|
|
||||||
margin: 0 !important;
|
|
||||||
padding: 0 !important;
|
|
||||||
border: 0 !important;
|
|
||||||
border-radius: 999px !important;
|
|
||||||
background: transparent !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
opacity: 1 !important;
|
|
||||||
visibility: visible !important;
|
|
||||||
-webkit-backdrop-filter: none !important;
|
|
||||||
backdrop-filter: none !important;
|
|
||||||
transform: translate(-50%, -50%) !important;
|
|
||||||
overflow: visible !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ak-placeholder.ak-c-placeholder .pf-c-spinner,
|
|
||||||
.ak-c-placeholder[slot="placeholder"] .pf-c-spinner,
|
|
||||||
#ak-placeholder.ak-c-placeholder [role="progressbar"],
|
|
||||||
.ak-c-placeholder[slot="placeholder"] [role="progressbar"] {
|
|
||||||
opacity: 0 !important;
|
|
||||||
visibility: hidden !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ak-placeholder.ak-c-placeholder::before,
|
|
||||||
.ak-c-placeholder[slot="placeholder"]::before {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
inset: 0;
|
|
||||||
border: 2px solid rgba(186, 255, 74, 0.22);
|
|
||||||
border-top-color: var(--nodedc-auth-primary);
|
|
||||||
border-radius: 999px;
|
|
||||||
animation: nodedc-auth-placeholder-spin 0.72s linear infinite;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.nodedc-auth-submitting::before,
|
|
||||||
body.nodedc-auth-loading::before {
|
|
||||||
content: "";
|
|
||||||
position: fixed;
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
z-index: 1200;
|
|
||||||
width: 2.5rem;
|
|
||||||
height: 2.5rem;
|
|
||||||
border: 2px solid rgba(186, 255, 74, 0.22);
|
|
||||||
border-top-color: var(--nodedc-auth-primary);
|
|
||||||
border-radius: 999px;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
animation: nodedc-auth-loader-spin 0.72s linear infinite;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes nodedc-auth-loader-spin {
|
|
||||||
from {
|
|
||||||
transform: translate(-50%, -50%) rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
to {
|
|
||||||
transform: translate(-50%, -50%) rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes nodedc-auth-placeholder-spin {
|
|
||||||
from {
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
to {
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ak-library-application,
|
ak-library-application,
|
||||||
ak-application-wizard,
|
ak-application-wizard,
|
||||||
ak-user-interface,
|
ak-user-interface,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue