li / web /src /lib /auth-session.ts
xiaolongmr
Add configurable branding and login sessions
519f85d
Raw
History Blame Contribute Delete
2.2 kB
"use client";
import { login } from "@/lib/api";
import { buildSessionExpiresAt, clearStoredAuthSession, getStoredAuthSession, setStoredAuthSession, type StoredAuthSession } from "@/store/auth";
const VALIDATION_CACHE_MS = 10_000;
let cachedSession: StoredAuthSession | null = null;
let cachedAt = 0;
let validationPromise: Promise<StoredAuthSession | null> | null = null;
let validationKey = "";
function isUnauthorizedError(error: unknown) {
if (!error || typeof error !== "object") {
return false;
}
const item = error as { status?: unknown };
return item.status === 401;
}
export async function getValidatedAuthSession(): Promise<StoredAuthSession | null> {
const storedSession = await getStoredAuthSession();
if (!storedSession) {
cachedSession = null;
cachedAt = 0;
return null;
}
const now = Date.now();
if (cachedSession?.key === storedSession.key && now - cachedAt < VALIDATION_CACHE_MS) {
return cachedSession;
}
if (validationPromise && validationKey === storedSession.key) {
return validationPromise;
}
validationKey = storedSession.key;
validationPromise = validateStoredSession(storedSession).finally(() => {
validationPromise = null;
validationKey = "";
});
return validationPromise;
}
async function validateStoredSession(storedSession: StoredAuthSession): Promise<StoredAuthSession | null> {
try {
const data = await login(storedSession.key);
const nextSession: StoredAuthSession = {
key: storedSession.key,
role: data.role,
subjectId: data.subject_id,
name: data.name,
accountPoolEnabled: Boolean(data.account_pool_enabled),
wechatOpenid: storedSession.wechatOpenid,
expiresAt: storedSession.expiresAt || buildSessionExpiresAt(data.login_session_duration_hours),
};
await setStoredAuthSession(nextSession);
cachedSession = nextSession;
cachedAt = Date.now();
return nextSession;
} catch (error) {
if (isUnauthorizedError(error)) {
await clearStoredAuthSession();
cachedSession = null;
cachedAt = 0;
return null;
}
cachedSession = storedSession;
cachedAt = Date.now();
return storedSession;
}
}