mirror of
https://github.com/TronoSfera/Law.git
synced 2026-05-18 10:03:45 +03:00
fix UI 12
This commit is contained in:
parent
3bff88b38a
commit
253e7d5839
4 changed files with 76 additions and 2 deletions
|
|
@ -2105,6 +2105,7 @@
|
|||
|
||||
// app/web/admin/shared/constants.js
|
||||
var LS_TOKEN = "admin_access_token";
|
||||
var ADMIN_AUTH_REDIRECT_REASON_KEY = "admin_auth_redirect_reason";
|
||||
var PAGE_SIZE = 50;
|
||||
var DEFAULT_FORM_FIELD_TYPES = ["string", "text", "number", "boolean", "date"];
|
||||
var ALL_OPERATORS = ["=", "!=", ">", "<", ">=", "<=", "~"];
|
||||
|
|
@ -5843,6 +5844,21 @@
|
|||
}
|
||||
if (!response.ok) {
|
||||
const message = payload && (payload.detail || payload.error || payload.raw) || "HTTP " + response.status;
|
||||
if (response.status === 401 && opts.auth !== false) {
|
||||
try {
|
||||
localStorage.removeItem(LS_TOKEN);
|
||||
sessionStorage.setItem(ADMIN_AUTH_REDIRECT_REASON_KEY, "expired");
|
||||
} catch (_) {
|
||||
}
|
||||
if (typeof window !== "undefined") {
|
||||
const target = "/admin.html";
|
||||
if (window.location.pathname !== target || window.location.search) {
|
||||
window.location.replace(target);
|
||||
} else {
|
||||
window.location.reload();
|
||||
}
|
||||
}
|
||||
}
|
||||
const error = new Error(translateApiError(String(message)));
|
||||
error.httpStatus = Number(response.status || 0);
|
||||
throw error;
|
||||
|
|
@ -7627,6 +7643,13 @@
|
|||
setStatusMap((prev) => ({ ...prev, [key]: { message: message || "", kind: kind || "" } }));
|
||||
}, []);
|
||||
const getStatus = useCallback((key) => statusMap[key] || { message: "", kind: "" }, [statusMap]);
|
||||
const isAdminTokenExpired = useCallback((rawToken) => {
|
||||
const payload = decodeJwtPayload(rawToken || "");
|
||||
const exp = Number((payload == null ? void 0 : payload.exp) || 0);
|
||||
if (!payload || !payload.role || !payload.email) return true;
|
||||
if (!Number.isFinite(exp) || exp <= 0) return true;
|
||||
return exp * 1e3 <= Date.now();
|
||||
}, []);
|
||||
const api = useAdminApi(token);
|
||||
const {
|
||||
requestModal,
|
||||
|
|
@ -9657,6 +9680,7 @@
|
|||
const nextToken = data.access_token;
|
||||
const payload = decodeJwtPayload(nextToken || "");
|
||||
if (!payload || !payload.role || !payload.email) throw new Error("\u041D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u043F\u0440\u043E\u0447\u0438\u0442\u0430\u0442\u044C \u0434\u0430\u043D\u043D\u044B\u0435 \u0442\u043E\u043A\u0435\u043D\u0430");
|
||||
sessionStorage.removeItem(ADMIN_AUTH_REDIRECT_REASON_KEY);
|
||||
localStorage.setItem(LS_TOKEN, nextToken);
|
||||
setToken(nextToken);
|
||||
setRole(payload.role);
|
||||
|
|
@ -9674,18 +9698,29 @@
|
|||
[api, bootstrapReferenceData, loadDashboard, loadTotpStatus, setStatus]
|
||||
);
|
||||
useEffect(() => {
|
||||
const authRedirectReason = sessionStorage.getItem(ADMIN_AUTH_REDIRECT_REASON_KEY) || "";
|
||||
if (authRedirectReason === "expired") {
|
||||
setStatus("login", "\u0421\u0435\u0441\u0441\u0438\u044F \u0438\u0441\u0442\u0435\u043A\u043B\u0430. \u0412\u043E\u0439\u0434\u0438\u0442\u0435 \u0441\u043D\u043E\u0432\u0430.", "error");
|
||||
sessionStorage.removeItem(ADMIN_AUTH_REDIRECT_REASON_KEY);
|
||||
}
|
||||
const saved = localStorage.getItem(LS_TOKEN) || "";
|
||||
if (!saved) return;
|
||||
if (isAdminTokenExpired(saved)) {
|
||||
localStorage.removeItem(LS_TOKEN);
|
||||
setStatus("login", "\u0421\u0435\u0441\u0441\u0438\u044F \u0438\u0441\u0442\u0435\u043A\u043B\u0430. \u0412\u043E\u0439\u0434\u0438\u0442\u0435 \u0441\u043D\u043E\u0432\u0430.", "error");
|
||||
return;
|
||||
}
|
||||
const payload = decodeJwtPayload(saved);
|
||||
if (!payload || !payload.role || !payload.email) {
|
||||
localStorage.removeItem(LS_TOKEN);
|
||||
setStatus("login", "\u0421\u0435\u0441\u0441\u0438\u044F \u0438\u0441\u0442\u0435\u043A\u043B\u0430. \u0412\u043E\u0439\u0434\u0438\u0442\u0435 \u0441\u043D\u043E\u0432\u0430.", "error");
|
||||
return;
|
||||
}
|
||||
setToken(saved);
|
||||
setRole(payload.role);
|
||||
setEmail(payload.email);
|
||||
setUserId(String(payload.sub || ""));
|
||||
}, []);
|
||||
}, [isAdminTokenExpired, setStatus]);
|
||||
useEffect(() => {
|
||||
if (!token || !role) return;
|
||||
let cancelled = false;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import {
|
||||
DEFAULT_FORM_FIELD_TYPES,
|
||||
ADMIN_AUTH_REDIRECT_REASON_KEY,
|
||||
INVOICE_STATUS_LABELS,
|
||||
LS_TOKEN,
|
||||
OPERATOR_LABELS,
|
||||
|
|
@ -1263,6 +1264,13 @@ const NEW_REQUEST_CLIENT_OPTION = "__new_client__";
|
|||
}, []);
|
||||
|
||||
const getStatus = useCallback((key) => statusMap[key] || { message: "", kind: "" }, [statusMap]);
|
||||
const isAdminTokenExpired = useCallback((rawToken) => {
|
||||
const payload = decodeJwtPayload(rawToken || "");
|
||||
const exp = Number(payload?.exp || 0);
|
||||
if (!payload || !payload.role || !payload.email) return true;
|
||||
if (!Number.isFinite(exp) || exp <= 0) return true;
|
||||
return exp * 1000 <= Date.now();
|
||||
}, []);
|
||||
|
||||
const api = useAdminApi(token);
|
||||
|
||||
|
|
@ -3465,6 +3473,7 @@ const NEW_REQUEST_CLIENT_OPTION = "__new_client__";
|
|||
const payload = decodeJwtPayload(nextToken || "");
|
||||
if (!payload || !payload.role || !payload.email) throw new Error("Не удалось прочитать данные токена");
|
||||
|
||||
sessionStorage.removeItem(ADMIN_AUTH_REDIRECT_REASON_KEY);
|
||||
localStorage.setItem(LS_TOKEN, nextToken);
|
||||
setToken(nextToken);
|
||||
setRole(payload.role);
|
||||
|
|
@ -3485,18 +3494,30 @@ const NEW_REQUEST_CLIENT_OPTION = "__new_client__";
|
|||
);
|
||||
|
||||
useEffect(() => {
|
||||
const authRedirectReason = sessionStorage.getItem(ADMIN_AUTH_REDIRECT_REASON_KEY) || "";
|
||||
if (authRedirectReason === "expired") {
|
||||
setStatus("login", "Сессия истекла. Войдите снова.", "error");
|
||||
sessionStorage.removeItem(ADMIN_AUTH_REDIRECT_REASON_KEY);
|
||||
}
|
||||
|
||||
const saved = localStorage.getItem(LS_TOKEN) || "";
|
||||
if (!saved) return;
|
||||
if (isAdminTokenExpired(saved)) {
|
||||
localStorage.removeItem(LS_TOKEN);
|
||||
setStatus("login", "Сессия истекла. Войдите снова.", "error");
|
||||
return;
|
||||
}
|
||||
const payload = decodeJwtPayload(saved);
|
||||
if (!payload || !payload.role || !payload.email) {
|
||||
localStorage.removeItem(LS_TOKEN);
|
||||
setStatus("login", "Сессия истекла. Войдите снова.", "error");
|
||||
return;
|
||||
}
|
||||
setToken(saved);
|
||||
setRole(payload.role);
|
||||
setEmail(payload.email);
|
||||
setUserId(String(payload.sub || ""));
|
||||
}, []);
|
||||
}, [isAdminTokenExpired, setStatus]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!token || !role) return;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { ADMIN_AUTH_REDIRECT_REASON_KEY, LS_TOKEN } from "../shared/constants.js";
|
||||
import { translateApiError } from "../shared/utils.js";
|
||||
|
||||
export function useAdminApi(token) {
|
||||
|
|
@ -30,6 +31,22 @@ export function useAdminApi(token) {
|
|||
|
||||
if (!response.ok) {
|
||||
const message = (payload && (payload.detail || payload.error || payload.raw)) || "HTTP " + response.status;
|
||||
if (response.status === 401 && opts.auth !== false) {
|
||||
try {
|
||||
localStorage.removeItem(LS_TOKEN);
|
||||
sessionStorage.setItem(ADMIN_AUTH_REDIRECT_REASON_KEY, "expired");
|
||||
} catch (_) {
|
||||
// noop
|
||||
}
|
||||
if (typeof window !== "undefined") {
|
||||
const target = "/admin.html";
|
||||
if (window.location.pathname !== target || window.location.search) {
|
||||
window.location.replace(target);
|
||||
} else {
|
||||
window.location.reload();
|
||||
}
|
||||
}
|
||||
}
|
||||
const error = new Error(translateApiError(String(message)));
|
||||
error.httpStatus = Number(response.status || 0);
|
||||
throw error;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
export const LS_TOKEN = "admin_access_token";
|
||||
export const ADMIN_AUTH_REDIRECT_REASON_KEY = "admin_auth_redirect_reason";
|
||||
export const PAGE_SIZE = 50;
|
||||
export const DEFAULT_FORM_FIELD_TYPES = ["string", "text", "number", "boolean", "date"];
|
||||
export const ALL_OPERATORS = ["=", "!=", ">", "<", ">=", "<=", "~"];
|
||||
|
|
|
|||
Loading…
Reference in a new issue