Spaces:
Running
Running
File size: 1,885 Bytes
c52f47a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | import { useEffect, useState } from "react";
const ADMIN_TOKEN_KEY = "topobench:admin-token";
const ADMIN_CHANGE_EVENT = "topobench:admin-change";
export function getAdminToken(): string | null {
if (typeof window === "undefined") {
return null;
}
return window.sessionStorage.getItem(ADMIN_TOKEN_KEY);
}
function emitChange(): void {
if (typeof window !== "undefined") {
window.dispatchEvent(new Event(ADMIN_CHANGE_EVENT));
}
}
export async function validateAdminToken(token: string): Promise<boolean> {
try {
const response = await fetch("/api/admin/check", {
headers: { Authorization: `Bearer ${token}` },
});
return response.ok;
} catch {
return false;
}
}
export async function unlockAdmin(token: string): Promise<boolean> {
const trimmed = token.trim();
if (!trimmed) {
return false;
}
const ok = await validateAdminToken(trimmed);
if (!ok) {
return false;
}
window.sessionStorage.setItem(ADMIN_TOKEN_KEY, trimmed);
emitChange();
return true;
}
export function lockAdmin(): void {
if (typeof window !== "undefined") {
window.sessionStorage.removeItem(ADMIN_TOKEN_KEY);
emitChange();
}
}
export function useAdmin(): { enabled: boolean; token: string | null } {
const [token, setToken] = useState<string | null>(getAdminToken);
useEffect(() => {
const handler = () => setToken(getAdminToken());
window.addEventListener(ADMIN_CHANGE_EVENT, handler);
return () => window.removeEventListener(ADMIN_CHANGE_EVENT, handler);
}, []);
return { enabled: Boolean(token), token };
}
export async function adminFetch(
input: string,
init: RequestInit = {},
): Promise<Response> {
const token = getAdminToken();
const headers = new Headers(init.headers);
if (token) {
headers.set("Authorization", `Bearer ${token}`);
}
return fetch(input, { ...init, headers });
}
|