Polish settings and auth flows

This commit is contained in:
2026-03-27 21:51:15 +01:00
parent b46a0c121d
commit b53b2b5a35
10 changed files with 315 additions and 156 deletions
+76 -44
View File
@@ -1,74 +1,106 @@
export const AUTH_TOKEN_KEY = "authToken";
export const AUTH_REMEMBER_ME_KEY = "authRememberMe";
const LEGACY_AUTH_TOKEN_KEY = "googleIdToken";
const AUTH_TOKEN_PERSISTENCE_KEY = "authTokenPersistence";
function getStoredToken(storage: Storage): string | null {
type AuthPersistence = "local" | "session";
function normalizePersistence(value: string | null | undefined): AuthPersistence {
return value === "session" ? "session" : "local";
}
function safeGet(storage: Storage, key: string): string | null {
try {
return storage.getItem(AUTH_TOKEN_KEY);
return storage.getItem(key);
} catch {
return null;
}
}
export function getRememberMePref(): boolean {
function safeSet(storage: Storage, key: string, value: string) {
try {
return window.localStorage.getItem(AUTH_REMEMBER_ME_KEY) === "1";
storage.setItem(key, value);
} catch {
return false;
// ignore storage failures
}
}
function safeRemove(storage: Storage, key: string) {
try {
storage.removeItem(key);
} catch {
// ignore storage failures
}
}
function persistPreference(persistence: AuthPersistence) {
safeSet(window.localStorage, AUTH_TOKEN_PERSISTENCE_KEY, persistence);
safeSet(window.localStorage, AUTH_REMEMBER_ME_KEY, persistence === "local" ? "1" : "0");
}
function getStoredPersistence(): AuthPersistence {
const explicit = safeGet(window.localStorage, AUTH_TOKEN_PERSISTENCE_KEY);
if (explicit) return normalizePersistence(explicit);
const rememberMe = safeGet(window.localStorage, AUTH_REMEMBER_ME_KEY);
if (rememberMe === "0") return "session";
return "local";
}
function migrateLegacyToken(): string | null {
const legacy = safeGet(window.localStorage, LEGACY_AUTH_TOKEN_KEY) ?? safeGet(window.sessionStorage, LEGACY_AUTH_TOKEN_KEY);
if (!legacy) return null;
safeRemove(window.localStorage, LEGACY_AUTH_TOKEN_KEY);
safeRemove(window.sessionStorage, LEGACY_AUTH_TOKEN_KEY);
setAuthToken(legacy, getStoredPersistence());
return legacy;
}
export function getRememberMePref(): boolean {
return getAuthPersistencePreference() === "local";
}
export function setRememberMePref(value: boolean) {
try {
window.localStorage.setItem(AUTH_REMEMBER_ME_KEY, value ? "1" : "0");
} catch {
// ignore storage failures
}
persistPreference(value ? "local" : "session");
}
export function getAuthToken(): string | null {
const current = getStoredToken(window.localStorage) || getStoredToken(window.sessionStorage);
if (current) return current;
// Backward compat for older builds that stored Google ID tokens under a different key.
const legacy = window.localStorage.getItem(LEGACY_AUTH_TOKEN_KEY) || window.sessionStorage.getItem(LEGACY_AUTH_TOKEN_KEY);
if (legacy) {
const remember = getRememberMePref();
setAuthToken(legacy, { remember });
try {
window.localStorage.removeItem(LEGACY_AUTH_TOKEN_KEY);
window.sessionStorage.removeItem(LEGACY_AUTH_TOKEN_KEY);
} catch {
// ignore storage failures
}
return legacy;
const localToken = safeGet(window.localStorage, AUTH_TOKEN_KEY);
if (localToken) {
persistPreference("local");
return localToken;
}
return null;
const sessionToken = safeGet(window.sessionStorage, AUTH_TOKEN_KEY);
if (sessionToken) {
persistPreference("session");
return sessionToken;
}
return migrateLegacyToken();
}
export function setAuthToken(token: string, options?: { remember?: boolean }) {
const remember = options?.remember ?? getRememberMePref();
try {
if (remember) {
window.localStorage.setItem(AUTH_TOKEN_KEY, token);
window.sessionStorage.removeItem(AUTH_TOKEN_KEY);
} else {
window.sessionStorage.setItem(AUTH_TOKEN_KEY, token);
window.localStorage.removeItem(AUTH_TOKEN_KEY);
}
} catch {
window.localStorage.setItem(AUTH_TOKEN_KEY, token);
export function getAuthPersistencePreference(): AuthPersistence {
if (safeGet(window.sessionStorage, AUTH_TOKEN_KEY)) return "session";
if (safeGet(window.localStorage, AUTH_TOKEN_KEY)) return "local";
return getStoredPersistence();
}
export function setAuthToken(token: string, persistence: AuthPersistence = "local") {
safeRemove(window.localStorage, AUTH_TOKEN_KEY);
safeRemove(window.sessionStorage, AUTH_TOKEN_KEY);
if (persistence === "session") {
safeSet(window.sessionStorage, AUTH_TOKEN_KEY, token);
} else {
safeSet(window.localStorage, AUTH_TOKEN_KEY, token);
}
persistPreference(persistence);
}
export function clearAuthToken() {
try {
window.localStorage.removeItem(AUTH_TOKEN_KEY);
window.sessionStorage.removeItem(AUTH_TOKEN_KEY);
} catch {
// ignore storage failures
}
safeRemove(window.localStorage, AUTH_TOKEN_KEY);
safeRemove(window.sessionStorage, AUTH_TOKEN_KEY);
}
export function decodeJwtPayload(token: string): any {