Alle ausstehenden Aenderungen (Bilder, Texte) fuer den Server-Umzug uebernommen
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
/* =====================================================================
|
||||
admin-auth.js — gemeinsame Session-Logik fürs interne Team-Login
|
||||
(dasselbe Owner-/Rollen-System wie schon fürs frühere Bewerbungs-
|
||||
Postfach).
|
||||
|
||||
Session (Token + Rolle/Rechte) liegt in localStorage (Nutzer-Wunsch
|
||||
04.08.2026: "den Zugangscode auf der Verwaltungsseite nur einmal am Tag
|
||||
eingeben müssen") — localStorage übersteht anders als sessionStorage
|
||||
auch das Schließen des Tabs/Browsers, sonst wäre "einmal am Tag" nicht
|
||||
möglich. Eigener 24-Stunden-Ablauf hier im Client (siehe SESSION_MAX_AGE_MS)
|
||||
zusätzlich zum server-seitigen Session-Timeout (lib/auth.js, ebenfalls
|
||||
24 Std) — beide zusammen sorgen dafür, dass wirklich niemand länger als
|
||||
einen Tag mit einem alten Code eingeloggt bleiben kann.
|
||||
|
||||
Ursprünglich für postfach.html/zugaenge.html gebaut (Bewerbungs-
|
||||
Verwaltung) — die wurden am 01.08.2026 auf Dogis Wunsch entfernt ("nicht
|
||||
mehr gebraucht"). Diese Datei selbst ist aber ein reines, seitenneutrales
|
||||
Login-Werkzeug (kein Bewerbungscode) und wurde am 04.08.2026 reaktiviert
|
||||
für verwaltung.html (Supporter-Abo-Administration) — nutzt exakt
|
||||
denselben, weiterhin voll funktionsfähigen Backend-Login
|
||||
(POST /auth/login), nur eine neue Seite drumherum.
|
||||
===================================================================== */
|
||||
|
||||
const SESSION_KEY = "dogfather_admin_session";
|
||||
const SESSION_MAX_AGE_MS = 24 * 60 * 60 * 1000;
|
||||
|
||||
function getSession() {
|
||||
try {
|
||||
const session = JSON.parse(localStorage.getItem(SESSION_KEY) || "null");
|
||||
if (!session) return null;
|
||||
if (!session.loggedInAt || Date.now() - session.loggedInAt > SESSION_MAX_AGE_MS) {
|
||||
clearSession(); // älter als 24 Std -> als abgelaufen behandeln, neuer Code nötig
|
||||
return null;
|
||||
}
|
||||
return session;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function setSession(data) {
|
||||
localStorage.setItem(SESSION_KEY, JSON.stringify({ ...data, loggedInAt: Date.now() }));
|
||||
}
|
||||
|
||||
function clearSession() {
|
||||
localStorage.removeItem(SESSION_KEY);
|
||||
}
|
||||
|
||||
/** Prüft, ob die aktuelle Session (Owner oder Rolle+Overrides) ein Recht hat. */
|
||||
function sessionHasPermission(session, key) {
|
||||
if (!session) return false;
|
||||
if (session.isOwner) return true;
|
||||
const overrides = session.overrides || {};
|
||||
if (Object.prototype.hasOwnProperty.call(overrides, key)) return !!overrides[key];
|
||||
return Array.isArray(session.permissions) && session.permissions.includes(key);
|
||||
}
|
||||
|
||||
async function apiCall(apiBaseUrl, path, body, { auth = true } = {}) {
|
||||
const session = getSession();
|
||||
const headers = { "Content-Type": "application/json" };
|
||||
if (auth && session?.token) headers["Authorization"] = `Bearer ${session.token}`;
|
||||
|
||||
const res = await fetch(`${apiBaseUrl}${path}`, {
|
||||
method: "POST",
|
||||
headers,
|
||||
body: JSON.stringify(body || {}),
|
||||
});
|
||||
let data;
|
||||
try {
|
||||
data = await res.json();
|
||||
} catch {
|
||||
data = { ok: false, error: "Ungültige Antwort vom Server." };
|
||||
}
|
||||
if (res.status === 401 && auth) {
|
||||
clearSession(); // Session ist abgelaufen/ungültig -> zurück zum Login zwingen
|
||||
}
|
||||
return { httpOk: res.ok, ...data };
|
||||
}
|
||||
|
||||
async function doLogin(apiBaseUrl, code) {
|
||||
const res = await apiCall(apiBaseUrl, "/auth/login", { code }, { auth: false });
|
||||
if (res.ok) {
|
||||
setSession({
|
||||
token: res.token,
|
||||
isOwner: res.isOwner,
|
||||
name: res.name,
|
||||
username: res.username,
|
||||
roleName: res.roleName,
|
||||
permissions: res.permissions || [],
|
||||
overrides: res.overrides || {},
|
||||
});
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
async function doLogout(apiBaseUrl) {
|
||||
await apiCall(apiBaseUrl, "/auth/logout", {});
|
||||
clearSession();
|
||||
}
|
||||
|
||||
// Für Einbindung ohne Modul-Bundler global verfügbar machen.
|
||||
if (typeof window !== "undefined") {
|
||||
window.AdminAuth = { getSession, setSession, clearSession, sessionHasPermission, apiCall, doLogin, doLogout };
|
||||
}
|
||||
Reference in New Issue
Block a user