/** * Maps Firebase Auth error codes to user-facing messages instead of * discarding them. Two categories: * * - misconfiguration: something is wrong with *our* deployment (a domain * not on the authorized list, a sign-in provider not enabled in the * Firebase console). Retrying can never fix these — the message says so * instead of "try again", which would send a user into a retry loop * against a config problem only we can fix. * - everything else: the user's own situation (blocked/closed popup, bad * password, a network blip) — retrying might well work. * * Always logs the raw error so it isn't silently discarded — the point of * this file is to stop swallowing that information, not just relabel it. */ export interface AuthErrorInfo { message: string; misconfiguration: boolean; } const MISCONFIGURATION_MESSAGES: Record = { "auth/unauthorized-domain": "This domain isn't authorized for sign-in yet. That's a configuration issue on our end (Firebase Console → Authentication → Settings → Authorized domains) — retrying won't fix it. Please report this.", "auth/operation-not-allowed": "This sign-in method isn't enabled for this app yet. That's a configuration issue on our end (Firebase Console → Authentication → Sign-in method) — retrying won't fix it. Please report this.", }; const USER_MESSAGES: Record = { "auth/popup-blocked": "Your browser blocked the sign-in popup. Allow popups for this site and try again.", "auth/popup-closed-by-user": "Sign-in window was closed before finishing. Try again.", "auth/cancelled-popup-request": "Sign-in was interrupted by another sign-in attempt. Try again.", "auth/network-request-failed": "Network error — check your connection and try again.", "auth/invalid-credential": "Invalid email or password.", "auth/wrong-password": "Invalid email or password.", "auth/user-not-found": "Invalid email or password.", "auth/too-many-requests": "Too many attempts. Wait a few minutes and try again.", "auth/email-already-in-use": "An account with this email already exists. Try signing in instead.", "auth/weak-password": "Password is too weak — use at least 6 characters.", }; export function describeAuthError(err: unknown, fallback: string): AuthErrorInfo { const code = (err as { code?: string } | null | undefined)?.code; // eslint-disable-next-line no-console console.error("[auth]", code ?? "(no error code)", err); if (code && MISCONFIGURATION_MESSAGES[code]) { return { message: MISCONFIGURATION_MESSAGES[code], misconfiguration: true }; } if (code && USER_MESSAGES[code]) { return { message: USER_MESSAGES[code], misconfiguration: false }; } return { message: fallback, misconfiguration: false }; }