From 2c5320dd1f45412ef9ea7587caf5a4cb5cb5e16f Mon Sep 17 00:00:00 2001 From: Zerebos Date: Sun, 17 May 2026 03:31:17 -0400 Subject: [PATCH] Some debug logging --- src/core/auth.ts | 79 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 75 insertions(+), 4 deletions(-) diff --git a/src/core/auth.ts b/src/core/auth.ts index a310727..3d36600 100644 --- a/src/core/auth.ts +++ b/src/core/auth.ts @@ -12,6 +12,7 @@ export class AuthRequiredError extends Error { const TOKEN_KEY = "moku_access_token"; const UI_SESSION_KEY = "moku_ui_auth_session"; const TOKEN_REFRESH_SKEW_MS = 30_000; +const AUTH_DEBUG = Boolean((import.meta as ImportMeta & { env?: { DEV?: boolean } }).env?.DEV); interface StoredAccessToken { base: string; @@ -33,6 +34,20 @@ interface JwtSettings { jwtTokenExpiry?: number | null; } +export interface UiAuthDebugStatus { + mode: AuthMode; + serverBase: string; + hasSession: boolean; + hasRefreshToken: boolean; + accessExpiresAt: number | null; + refreshExpiresAt: number | null; + accessExpiresInMs: number | null; + refreshExpiresInMs: number | null; + shouldRefreshSoon: boolean; + refreshInFlight: boolean; + skewMs: number; +} + let _accessToken: string | null = null; let _accessTokenBase: string | null = null; let _uiSession: StoredUiAuthSession | null = null; @@ -41,6 +56,15 @@ let _jwtSettingsBase: string | null = null; let _jwtSettings: JwtSettings | null = null; let _jwtSettingsFetchedAt = 0; +function authDebug(event: string, fields?: Record) { + if (!AUTH_DEBUG) return; + if (fields) { + console.debug(`[auth] ${event}`, fields); + return; + } + console.debug(`[auth] ${event}`); +} + function decodeJwtExpiryMs(token: string): number | null { try { const payload = token.split(".")[1]; @@ -364,11 +388,24 @@ export async function refreshUiAccessToken(force = false): Promise { const base = getServerBase(); @@ -392,9 +429,11 @@ export async function refreshUiAccessToken(force = false): Promise { - _refreshPromise = null; - }); + })() + .catch((e: unknown) => { + authDebug("refresh threw error", { + message: e instanceof Error ? e.message : String(e), + }); + throw e; + }) + .finally(() => { + _refreshPromise = null; + }); return _refreshPromise; } +export function getUiAuthDebugStatus(now = Date.now()): UiAuthDebugStatus { + const session = uiAuth.getSession(); + const accessExpiresAt = session?.accessExpiresAt ?? null; + const refreshExpiresAt = session?.refreshExpiresAt ?? null; + + return { + mode: (store.settings.serverAuthMode ?? "NONE") as AuthMode, + serverBase: getServerBase(), + hasSession: !!session, + hasRefreshToken: !!session?.refreshToken, + accessExpiresAt, + refreshExpiresAt, + accessExpiresInMs: accessExpiresAt ? accessExpiresAt - now : null, + refreshExpiresInMs: refreshExpiresAt ? refreshExpiresAt - now : null, + shouldRefreshSoon: isExpired(accessExpiresAt), + refreshInFlight: _refreshPromise !== null, + skewMs: TOKEN_REFRESH_SKEW_MS, + }; +} + export async function loginUI(user: string, pass: string): Promise { const res = await fetch(`${getServerBase()}/api/graphql`, { method: "POST", credentials: "omit",