abc / web /src /lib /auth-session.ts
xiaolongmr
init
85270f9
Raw History Blame Contribute Delete
3.02 kB
"use client";
import { refreshSession } 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(options: { force?: boolean } = {}): Promise<StoredAuthSession | null> {
const storedSession = await getStoredAuthSession();
if (!storedSession) {
cachedSession = null;
cachedAt = 0;
return null;
}
const now = Date.now();
if (!options.force && 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 refreshSession(storedSession.key);
const nextSession: StoredAuthSession = {
key: storedSession.key,
role: data.role,
subjectId: data.subject_id,
name: data.name,
accountPoolEnabled: Boolean(data.account_pool_enabled),
imageMemoryButtonEnabled: data.image_memory_button_enabled === true,
imageShareEvidenceEnabled: data.image_share_evidence_enabled === true,
wechatOpenid: storedSession.wechatOpenid,
expiresAt: storedSession.expiresAt || buildSessionExpiresAt(data.login_session_duration_hours),
};
const sessionChanged =
storedSession.role !== nextSession.role
|| storedSession.subjectId !== nextSession.subjectId
|| storedSession.name !== nextSession.name
|| storedSession.accountPoolEnabled !== nextSession.accountPoolEnabled
|| storedSession.imageMemoryButtonEnabled !== nextSession.imageMemoryButtonEnabled
|| storedSession.imageShareEvidenceEnabled !== nextSession.imageShareEvidenceEnabled
|| storedSession.wechatOpenid !== nextSession.wechatOpenid
|| storedSession.expiresAt !== nextSession.expiresAt;
if (sessionChanged) {
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;
}
}