Files
photo-editor/public/js/auth.js
Coder 401969cfdb
Some checks failed
test / test (push) Failing after 24s
v2: модульный монолит — очередь, персистентность, безопасность, SSE, тесты
Реализация целевого дизайна (docs/architecture/target-design.md):
- src/: модульная структура (config, logger, errors, http, core: auth/history/jobs/engines/comfy/codex/images)
- Очередь заданий: FIFO, кониурентность codex=1 / comfy-upscale=2, MAX_QUEUED_JOBS=5, JSONL-журнал и восстановление после рестарта (running → interrupted, upscale requeue)
- Персистентные сессии (sha256-хеши токенов), scrypt-хеш пароля, rate-limit входа, Origin-проверка, magic-byte валидация аплоадов
- Атомарная запись манифеста истории, каскадное удаление, URL с фактическим расширением + 302-алиас /image.jpg, миграция history/ → data/history
- Даунскейл sharp до 1024px перед Codex + масштабирование области референса
- SSE /api/events с фолбэком на polling, фронтенд переведён на ES-модули (public/js/)
- Тесты node:test + supertest (27), CI workflow test.yml, Docker/деплой: том kadr-data
- Документация: README, docs/architecture/
2026-08-27 12:52:27 +07:00

112 lines
3.0 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* auth.js — Управление авторизацией владельца
*/
import { apiFetch, readJsonResponse } from "./api.js";
export function showAuthOverlay() {
const overlay = document.querySelector("#auth-overlay");
const loginPassword = document.querySelector("#login-password");
const loginError = document.querySelector("#login-error");
if (overlay) overlay.hidden = false;
if (loginError) {
loginError.hidden = true;
loginError.textContent = "";
}
if (loginPassword) {
loginPassword.value = "";
loginPassword.focus();
}
}
export function hideAuthOverlay() {
const overlay = document.querySelector("#auth-overlay");
if (overlay) overlay.hidden = true;
}
export async function checkAuth() {
try {
const res = await fetch("/api/me");
if (res.ok) {
hideAuthOverlay();
const logoutBtn = document.querySelector("#logout-button");
if (logoutBtn) logoutBtn.hidden = false;
return true;
}
} catch {
// Network or server error
}
showAuthOverlay();
const logoutBtn = document.querySelector("#logout-button");
if (logoutBtn) logoutBtn.hidden = true;
return false;
}
export async function submitLogin(event) {
event.preventDefault();
const loginUsername = document.querySelector("#login-username");
const loginPassword = document.querySelector("#login-password");
const loginError = document.querySelector("#login-error");
const loginSubmit = document.querySelector("#login-submit");
const username = String(loginUsername?.value || "").trim();
const password = String(loginPassword?.value || "");
if (!username || !password) {
if (loginError) {
loginError.textContent = "Укажите логин и пароль.";
loginError.hidden = false;
}
return;
}
if (loginSubmit) loginSubmit.disabled = true;
if (loginError) loginError.hidden = true;
try {
const res = await fetch("/api/login", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ username, password }),
});
const data = await readJsonResponse(res);
if (!res.ok || !data || !data.ok) {
if (loginError) {
loginError.textContent = data?.error || "Неверный логин или пароль.";
loginError.hidden = false;
}
return;
}
hideAuthOverlay();
const logoutBtn = document.querySelector("#logout-button");
if (logoutBtn) logoutBtn.hidden = false;
// Reload page or refresh state
window.location.reload();
} catch (err) {
if (loginError) {
loginError.textContent = err.message || "Не удалось подключиться к серверу.";
loginError.hidden = false;
}
} finally {
if (loginSubmit) loginSubmit.disabled = false;
}
}
export async function logout() {
try {
await apiFetch("/api/logout", { method: "POST" });
} catch {
// ignore
}
showAuthOverlay();
const logoutBtn = document.querySelector("#logout-button");
if (logoutBtn) logoutBtn.hidden = true;
}