refactor, security updates, cv extraction upgrades
This commit is contained in:
+38
-56
@@ -1,13 +1,9 @@
|
||||
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";
|
||||
const AUTH_PERSISTENCE_KEY = "authTokenPersistence";
|
||||
const AUTH_USER_KEY = "authUserKey";
|
||||
const AUTH_CSRF_COOKIE = "XSRF-TOKEN";
|
||||
|
||||
type AuthPersistence = "local" | "session";
|
||||
|
||||
function normalizePersistence(value: string | null | undefined): AuthPersistence {
|
||||
return value === "session" ? "session" : "local";
|
||||
}
|
||||
export type AuthPersistence = "local" | "session";
|
||||
|
||||
function safeGet(storage: Storage, key: string): string | null {
|
||||
try {
|
||||
@@ -33,28 +29,27 @@ function safeRemove(storage: Storage, key: string) {
|
||||
}
|
||||
}
|
||||
|
||||
function emitAuthChanged() {
|
||||
window.dispatchEvent(new Event("auth-changed"));
|
||||
}
|
||||
|
||||
function normalizePersistence(value: string | null | undefined): AuthPersistence {
|
||||
return value === "session" ? "session" : "local";
|
||||
}
|
||||
|
||||
function persistPreference(persistence: AuthPersistence) {
|
||||
safeSet(window.localStorage, AUTH_TOKEN_PERSISTENCE_KEY, persistence);
|
||||
safeSet(window.localStorage, AUTH_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);
|
||||
const explicit = safeGet(window.localStorage, AUTH_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";
|
||||
}
|
||||
@@ -63,53 +58,40 @@ export function setRememberMePref(value: boolean) {
|
||||
persistPreference(value ? "local" : "session");
|
||||
}
|
||||
|
||||
export function getAuthToken(): string | null {
|
||||
const localToken = safeGet(window.localStorage, AUTH_TOKEN_KEY);
|
||||
if (localToken) {
|
||||
persistPreference("local");
|
||||
return localToken;
|
||||
}
|
||||
|
||||
const sessionToken = safeGet(window.sessionStorage, AUTH_TOKEN_KEY);
|
||||
if (sessionToken) {
|
||||
persistPreference("session");
|
||||
return sessionToken;
|
||||
}
|
||||
|
||||
return migrateLegacyToken();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
export function setAuthPersistencePreference(persistence: AuthPersistence) {
|
||||
persistPreference(persistence);
|
||||
emitAuthChanged();
|
||||
}
|
||||
|
||||
export function clearAuthToken() {
|
||||
safeRemove(window.localStorage, AUTH_TOKEN_KEY);
|
||||
safeRemove(window.sessionStorage, AUTH_TOKEN_KEY);
|
||||
export function getAuthUserKey(): string {
|
||||
return safeGet(window.localStorage, AUTH_USER_KEY) ?? "anon";
|
||||
}
|
||||
|
||||
export function decodeJwtPayload(token: string): any {
|
||||
export function setAuthUserKey(value: string | null | undefined, emit = true) {
|
||||
const next = typeof value === "string" ? value.trim() : "";
|
||||
if (!next) {
|
||||
safeRemove(window.localStorage, AUTH_USER_KEY);
|
||||
} else {
|
||||
safeSet(window.localStorage, AUTH_USER_KEY, next);
|
||||
}
|
||||
if (emit) emitAuthChanged();
|
||||
}
|
||||
|
||||
export function clearAuthClientState(emit = true) {
|
||||
safeRemove(window.localStorage, AUTH_USER_KEY);
|
||||
if (emit) emitAuthChanged();
|
||||
}
|
||||
|
||||
export function getCsrfToken(): string | null {
|
||||
try {
|
||||
const parts = token.split(".");
|
||||
if (parts.length < 2) return null;
|
||||
const base64 = parts[1].replaceAll("-", "+").replaceAll("_", "/");
|
||||
const json = atob(base64);
|
||||
return JSON.parse(json);
|
||||
const parts = document.cookie.split(";").map((part) => part.trim());
|
||||
const match = parts.find((part) => part.startsWith(`${AUTH_CSRF_COOKIE}=`));
|
||||
if (!match) return null;
|
||||
return decodeURIComponent(match.slice(AUTH_CSRF_COOKIE.length + 1));
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user