@ttt-productions/auth-core 1.6.12 → 1.6.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/errors.d.ts
CHANGED
|
@@ -5,6 +5,8 @@ export type NormalizedAuthError = {
|
|
|
5
5
|
firebaseCode?: string;
|
|
6
6
|
details?: Record<string, unknown>;
|
|
7
7
|
};
|
|
8
|
+
/** The copy for every auth failure no mapped code covers. */
|
|
9
|
+
export declare const UNKNOWN_AUTH_ERROR_MESSAGE = "Authentication error. Please try again.";
|
|
8
10
|
export declare function normalizeAuthError(err: unknown, details?: Record<string, unknown>): NormalizedAuthError;
|
|
9
11
|
/** Convenience: returns just the user-facing message string */
|
|
10
12
|
export declare function getErrorMessage(error: unknown): string;
|
package/dist/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GACrB,cAAc,GACd,oBAAoB,GACpB,wBAAwB,GACxB,mBAAmB,GACnB,oBAAoB,GACpB,gBAAgB,GAChB,oBAAoB,GACpB,qBAAqB,GACrB,qBAAqB,GACrB,oBAAoB,GACpB,2BAA2B,GAC3B,oBAAoB,GACpB,4BAA4B,GAC5B,yBAAyB,GACzB,+CAA+C,GAC/C,8BAA8B,GAC9B,gCAAgC,GAChC,0BAA0B,GAC1B,0BAA0B,CAAC;AAE/B,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,aAAa,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC,CAAC;AAwFF,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,mBAAmB,
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GACrB,cAAc,GACd,oBAAoB,GACpB,wBAAwB,GACxB,mBAAmB,GACnB,oBAAoB,GACpB,gBAAgB,GAChB,oBAAoB,GACpB,qBAAqB,GACrB,qBAAqB,GACrB,oBAAoB,GACpB,2BAA2B,GAC3B,oBAAoB,GACpB,4BAA4B,GAC5B,yBAAyB,GACzB,+CAA+C,GAC/C,8BAA8B,GAC9B,gCAAgC,GAChC,0BAA0B,GAC1B,0BAA0B,CAAC;AAE/B,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,aAAa,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC,CAAC;AAwFF,6DAA6D;AAC7D,eAAO,MAAM,0BAA0B,4CAA4C,CAAC;AAEpF,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,mBAAmB,CAsBvG;AAED,+DAA+D;AAC/D,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEtD"}
|
package/dist/errors.js
CHANGED
|
@@ -82,6 +82,8 @@ const MAP = {
|
|
|
82
82
|
message: "This email action link is invalid or has already been used. Request a new link and try again."
|
|
83
83
|
}
|
|
84
84
|
};
|
|
85
|
+
/** The copy for every auth failure no mapped code covers. */
|
|
86
|
+
export const UNKNOWN_AUTH_ERROR_MESSAGE = "Authentication error. Please try again.";
|
|
85
87
|
export function normalizeAuthError(err, details) {
|
|
86
88
|
const firebaseCode = pickFirebaseCode(err);
|
|
87
89
|
const mapped = firebaseCode ? MAP[firebaseCode] : undefined;
|
|
@@ -93,13 +95,12 @@ export function normalizeAuthError(err, details) {
|
|
|
93
95
|
details
|
|
94
96
|
};
|
|
95
97
|
}
|
|
96
|
-
//
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
: "Authentication error. Please try again.";
|
|
98
|
+
// Never the error's own message: for an unclassified failure it is the SDK's internal diagnostic
|
|
99
|
+
// ("Firebase: Cloud function deadline exceeded. (auth/internal-error)."), not an answer the person
|
|
100
|
+
// can act on. The consumer reports the error itself to its monitoring.
|
|
100
101
|
return {
|
|
101
102
|
code: "AUTH_UNKNOWN",
|
|
102
|
-
message:
|
|
103
|
+
message: UNKNOWN_AUTH_ERROR_MESSAGE,
|
|
103
104
|
firebaseCode,
|
|
104
105
|
details
|
|
105
106
|
};
|
package/dist/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AA4BA,SAAS,gBAAgB,CAAC,GAAY;IACpC,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IACtD,MAAM,MAAM,GAAG,GAAU,CAAC;IAC1B,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC;IACtB,OAAO,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC/C,CAAC;AAED,MAAM,GAAG,GAA6D;IACpE,6BAA6B,EAAE;QAC7B,IAAI,EAAE,oBAAoB;QAC1B,OAAO,EAAE,4DAA4D;KACtE;IACD,wBAAwB,EAAE;QACxB,IAAI,EAAE,wBAAwB;QAC9B,OAAO,EAAE,wDAAwD;KAClE;IACD,2BAA2B,EAAE;QAC3B,IAAI,EAAE,mBAAmB;QACzB,OAAO,EAAE,2BAA2B;KACrC;IACD,oBAAoB,EAAE;QACpB,IAAI,EAAE,oBAAoB;QAC1B,OAAO,EAAE,2CAA2C;KACrD;IACD,8BAA8B,EAAE;QAC9B,IAAI,EAAE,gBAAgB;QACtB,OAAO,EAAE,wBAAwB;KAClC;IACD,oBAAoB,EAAE;QACpB,IAAI,EAAE,oBAAoB;QAC1B,OAAO,EAAE,iCAAiC;KAC3C;IACD,qBAAqB,EAAE;QACrB,IAAI,EAAE,qBAAqB;QAC3B,OAAO,EAAE,mCAAmC;KAC7C;IACD,qBAAqB,EAAE;QACrB,IAAI,EAAE,qBAAqB;QAC3B,OAAO,EAAE,qBAAqB;KAC/B;IACD,oBAAoB,EAAE;QACpB,IAAI,EAAE,oBAAoB;QAC1B,OAAO,EAAE,wBAAwB;KAClC;IACD,2BAA2B,EAAE;QAC3B,IAAI,EAAE,2BAA2B;QACjC,OAAO,EAAE,+BAA+B;KACzC;IACD,oBAAoB,EAAE;QACpB,IAAI,EAAE,oBAAoB;QAC1B,OAAO,EAAE,uBAAuB;KACjC;IACD,4BAA4B,EAAE;QAC5B,IAAI,EAAE,4BAA4B;QAClC,OAAO,EAAE,uCAAuC;KACjD;IACD,yBAAyB,EAAE;QACzB,IAAI,EAAE,yBAAyB;QAC/B,OAAO,EAAE,wCAAwC;KAClD;IACD,+CAA+C,EAAE;QAC/C,IAAI,EAAE,+CAA+C;QACrD,OAAO,EAAE,4DAA4D;KACtE;IACD,8BAA8B,EAAE;QAC9B,IAAI,EAAE,8BAA8B;QACpC,OAAO,EAAE,kDAAkD;KAC5D;IACD,gCAAgC,EAAE;QAChC,IAAI,EAAE,gCAAgC;QACtC,OAAO,EAAE,gEAAgE;KAC1E;IACD,qFAAqF;IACrF,uFAAuF;IACvF,uEAAuE;IACvE,0BAA0B,EAAE;QAC1B,IAAI,EAAE,0BAA0B;QAChC,OAAO,EAAE,uEAAuE;KACjF;IACD,0BAA0B,EAAE;QAC1B,IAAI,EAAE,0BAA0B;QAChC,OAAO,EACL,+FAA+F;KAClG;CACF,CAAC;AAEF,MAAM,UAAU,kBAAkB,CAAC,GAAY,EAAE,OAAiC;IAChF,MAAM,YAAY,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAE3C,MAAM,MAAM,GAAG,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5D,IAAI,MAAM,EAAE,CAAC;QACX,OAAO;YACL,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,YAAY;YACZ,OAAO;SACR,CAAC;IACJ,CAAC;IAED,
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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","sourcesContent":["export type AuthErrorCode =\n | \"AUTH_UNKNOWN\"\n | \"AUTH_NETWORK_ERROR\"\n | \"AUTH_TOO_MANY_REQUESTS\"\n | \"AUTH_POPUP_CLOSED\"\n | \"AUTH_POPUP_BLOCKED\"\n | \"AUTH_CANCELLED\"\n | \"AUTH_USER_DISABLED\"\n | \"AUTH_USER_NOT_FOUND\"\n | \"AUTH_WRONG_PASSWORD\"\n | \"AUTH_INVALID_EMAIL\"\n | \"AUTH_EMAIL_ALREADY_IN_USE\"\n | \"AUTH_WEAK_PASSWORD\"\n | \"AUTH_REQUIRES_RECENT_LOGIN\"\n | \"AUTH_INVALID_CREDENTIAL\"\n | \"AUTH_ACCOUNT_EXISTS_WITH_DIFFERENT_CREDENTIAL\"\n | \"AUTH_PROVIDER_ALREADY_LINKED\"\n | \"AUTH_CREDENTIAL_ALREADY_IN_USE\"\n | \"AUTH_EXPIRED_ACTION_CODE\"\n | \"AUTH_INVALID_ACTION_CODE\";\n\nexport type NormalizedAuthError = {\n code: AuthErrorCode;\n message: string;\n firebaseCode?: string;\n details?: Record<string, unknown>;\n};\n\nfunction pickFirebaseCode(err: unknown): string | undefined {\n if (!err || typeof err !== \"object\") return undefined;\n const anyErr = err as any;\n const c = anyErr.code;\n return typeof c === \"string\" ? c : undefined;\n}\n\nconst MAP: Record<string, { code: AuthErrorCode; message: string }> = {\n \"auth/network-request-failed\": {\n code: \"AUTH_NETWORK_ERROR\",\n message: \"Network error. Please check your connection and try again.\"\n },\n \"auth/too-many-requests\": {\n code: \"AUTH_TOO_MANY_REQUESTS\",\n message: \"Too many attempts. Please wait a moment and try again.\"\n },\n \"auth/popup-closed-by-user\": {\n code: \"AUTH_POPUP_CLOSED\",\n message: \"Sign-in popup was closed.\"\n },\n \"auth/popup-blocked\": {\n code: \"AUTH_POPUP_BLOCKED\",\n message: \"Sign-in popup was blocked by the browser.\"\n },\n \"auth/cancelled-popup-request\": {\n code: \"AUTH_CANCELLED\",\n message: \"Sign-in was cancelled.\"\n },\n \"auth/user-disabled\": {\n code: \"AUTH_USER_DISABLED\",\n message: \"This account has been disabled.\"\n },\n \"auth/user-not-found\": {\n code: \"AUTH_USER_NOT_FOUND\",\n message: \"No account found with that email.\"\n },\n \"auth/wrong-password\": {\n code: \"AUTH_WRONG_PASSWORD\",\n message: \"Incorrect password.\"\n },\n \"auth/invalid-email\": {\n code: \"AUTH_INVALID_EMAIL\",\n message: \"Invalid email address.\"\n },\n \"auth/email-already-in-use\": {\n code: \"AUTH_EMAIL_ALREADY_IN_USE\",\n message: \"That email is already in use.\"\n },\n \"auth/weak-password\": {\n code: \"AUTH_WEAK_PASSWORD\",\n message: \"Password is too weak.\"\n },\n \"auth/requires-recent-login\": {\n code: \"AUTH_REQUIRES_RECENT_LOGIN\",\n message: \"Please re-authenticate and try again.\"\n },\n \"auth/invalid-credential\": {\n code: \"AUTH_INVALID_CREDENTIAL\",\n message: \"Invalid credentials. Please try again.\"\n },\n \"auth/account-exists-with-different-credential\": {\n code: \"AUTH_ACCOUNT_EXISTS_WITH_DIFFERENT_CREDENTIAL\",\n message: \"An account already exists with a different sign-in method.\"\n },\n \"auth/provider-already-linked\": {\n code: \"AUTH_PROVIDER_ALREADY_LINKED\",\n message: \"That provider is already linked to this account.\"\n },\n \"auth/credential-already-in-use\": {\n code: \"AUTH_CREDENTIAL_ALREADY_IN_USE\",\n message: \"Those credentials are already associated with another account.\"\n },\n // Email-action (oobCode) links — password reset, email verification, email recovery.\n // The copy is deliberately generic: it never reveals whether an account exists, and it\n // always points at the one recovery affordance (request a fresh link).\n \"auth/expired-action-code\": {\n code: \"AUTH_EXPIRED_ACTION_CODE\",\n message: \"This email action link has expired. Request a new link and try again.\"\n },\n \"auth/invalid-action-code\": {\n code: \"AUTH_INVALID_ACTION_CODE\",\n message:\n \"This email action link is invalid or has already been used. Request a new link and try again.\"\n }\n};\n\n/** The copy for every auth failure no mapped code covers. */\nexport const UNKNOWN_AUTH_ERROR_MESSAGE = \"Authentication error. Please try again.\";\n\nexport function normalizeAuthError(err: unknown, details?: Record<string, unknown>): NormalizedAuthError {\n const firebaseCode = pickFirebaseCode(err);\n\n const mapped = firebaseCode ? MAP[firebaseCode] : undefined;\n if (mapped) {\n return {\n code: mapped.code,\n message: mapped.message,\n firebaseCode,\n details\n };\n }\n\n // Never the error's own message: for an unclassified failure it is the SDK's internal diagnostic\n // (\"Firebase: Cloud function deadline exceeded. (auth/internal-error).\"), not an answer the person\n // can act on. The consumer reports the error itself to its monitoring.\n return {\n code: \"AUTH_UNKNOWN\",\n message: UNKNOWN_AUTH_ERROR_MESSAGE,\n firebaseCode,\n details\n };\n}\n\n/** Convenience: returns just the user-facing message string */\nexport function getErrorMessage(error: unknown): string {\n return normalizeAuthError(error).message;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthProvider.d.ts","sourceRoot":"","sources":["../../src/react/AuthProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,EAOL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAIf,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAavE,eAAO,MAAM,WAAW,uDAAoD,CAAC;AAE7E,UAAU,iBAAiB,CAAC,OAAO;IACjC,MAAM,EAAE,kBAAkB,CAAC,OAAO,CAAC,CAAC;IACpC,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,wBAAgB,YAAY,CAAC,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5D,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,iBAAiB,CAAC,OAAO,CAAC,+
|
|
1
|
+
{"version":3,"file":"AuthProvider.d.ts","sourceRoot":"","sources":["../../src/react/AuthProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,EAOL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAIf,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAavE,eAAO,MAAM,WAAW,uDAAoD,CAAC;AAE7E,UAAU,iBAAiB,CAAC,OAAO;IACjC,MAAM,EAAE,kBAAkB,CAAC,OAAO,CAAC,CAAC;IACpC,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,wBAAgB,YAAY,CAAC,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5D,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,iBAAiB,CAAC,OAAO,CAAC,+BAyHjD"}
|
|
@@ -74,10 +74,15 @@ export function AuthProvider({ config, children }) {
|
|
|
74
74
|
}, [user, authLoading, readClaims]);
|
|
75
75
|
// --- refreshClaims ---
|
|
76
76
|
const refreshClaims = useCallback(async () => {
|
|
77
|
-
|
|
77
|
+
// The LIVE signed-in user, never the one this render saw: a caller can hold this callback from
|
|
78
|
+
// before its own sign-in (a registration's submit handler creates the account and then asks for
|
|
79
|
+
// the claims the server just set), and a refresh of that render's `null` user would do nothing —
|
|
80
|
+
// leaving the new account on its pre-claim token until the hourly refresh.
|
|
81
|
+
const liveUser = configRef.current.auth.currentUser;
|
|
82
|
+
if (!liveUser)
|
|
78
83
|
return;
|
|
79
|
-
await readClaims(
|
|
80
|
-
}, [
|
|
84
|
+
await readClaims(liveUser, async () => ((await liveUser.getIdTokenResult(true)).claims ?? {}), "refreshClaims");
|
|
85
|
+
}, [readClaims]);
|
|
81
86
|
// --- Derived at render: only the current session's claims are ever exposed ---
|
|
82
87
|
const sessionClaims = user && resolved?.user === user ? resolved : null;
|
|
83
88
|
const claims = sessionClaims ? sessionClaims.claims : config.defaultClaims;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthProvider.js","sourceRoot":"","sources":["../../src/react/AuthProvider.tsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"AuthProvider.js","sourceRoot":"","sources":["../../src/react/AuthProvider.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\n\nimport {\n createContext,\n useEffect,\n useRef,\n useState,\n useCallback,\n useMemo,\n type ReactNode,\n} from \"react\";\nimport type { User } from \"firebase/auth\";\nimport { useAuthState } from \"./useAuthState.js\";\nimport { getIdTokenClaims } from \"../claims.js\";\nimport type { AuthProviderConfig, AuthContextValue } from \"./types.js\";\n\n/**\n * Claims resolved for one signed-in session. `user` is the Firebase `User` instance (it carries\n * the uid and is replaced on every sign-in), and `generation` orders the reads that produced it.\n */\ninterface ResolvedClaims<TClaims> {\n user: User;\n generation: number;\n claims: TClaims;\n}\n\n \nexport const AuthContext = createContext<AuthContextValue<any> | null>(null);\n\ninterface AuthProviderProps<TClaims> {\n config: AuthProviderConfig<TClaims>;\n children: ReactNode;\n}\n\nexport function AuthProvider<TClaims = Record<string, unknown>>(\n { config, children }: AuthProviderProps<TClaims>,\n) {\n const { user, loading: authLoading } = useAuthState(config.auth);\n\n // Claims are held with the session they were read for and derived at render (below), so a\n // render can never pair one account's `user` with another account's claims, and a read that\n // settles after the session changed (a late refresh, a slow initial read) is dropped.\n const [resolved, setResolved] = useState<ResolvedClaims<TClaims> | null>(null);\n const generationRef = useRef(0);\n const appliedGenerationRef = useRef(0);\n const currentUserRef = useRef<User | null>(user);\n currentUserRef.current = user;\n\n // Stable config ref so effects don't re-fire on config object identity changes\n const configRef = useRef(config);\n configRef.current = config;\n\n /**\n * Read `forUser`'s claims under a new generation and apply them only if `forUser` is still\n * the signed-in session and no newer read has applied. A failed read leaves the session's\n * claims as they are, or settles an unread session on the default claims.\n */\n const readClaims = useCallback(\n async (forUser: User, read: () => Promise<Record<string, unknown> | null>, context: string) => {\n const generation = ++generationRef.current;\n try {\n const raw = await read();\n if (currentUserRef.current !== forUser || generation <= appliedGenerationRef.current) return;\n appliedGenerationRef.current = generation;\n setResolved({ user: forUser, generation, claims: configRef.current.parseClaims(raw ?? {}) });\n } catch (err) {\n if (currentUserRef.current !== forUser) return;\n configRef.current.onError?.(err, context);\n setResolved((prev) =>\n prev && prev.user === forUser\n ? prev\n : { user: forUser, generation, claims: configRef.current.defaultClaims },\n );\n }\n },\n [],\n );\n\n // --- Optional readiness gate (see AuthProviderConfig.readyGate) ---\n // Open immediately when no gate is configured; otherwise held closed until the\n // gate settles. Fail-open: a rejected gate is reported and then treated as open.\n const [gateOpen, setGateOpen] = useState(() => !config.readyGate);\n useEffect(() => {\n const gate = configRef.current.readyGate;\n if (!gate) return;\n let cancelled = false;\n Promise.resolve()\n .then(() => gate())\n .catch((err) => configRef.current.onError?.(err, \"readyGate\"))\n .finally(() => {\n if (!cancelled) setGateOpen(true);\n });\n return () => { cancelled = true; };\n // Mount-only by design (reads only the stable configRef): the gate is a\n // one-time client readiness signal.\n }, []);\n\n // --- Claims fetching ---\n useEffect(() => {\n if (authLoading) return;\n\n if (!user) {\n setResolved(null);\n configRef.current.onAuthStateChange?.(null);\n return;\n }\n\n configRef.current.onAuthStateChange?.(user);\n void readClaims(\n user,\n async () => ((await getIdTokenClaims(user)) ?? {}) as Record<string, unknown>,\n \"getIdTokenClaims\",\n );\n }, [user, authLoading, readClaims]);\n\n // --- refreshClaims ---\n const refreshClaims = useCallback(async () => {\n // The LIVE signed-in user, never the one this render saw: a caller can hold this callback from\n // before its own sign-in (a registration's submit handler creates the account and then asks for\n // the claims the server just set), and a refresh of that render's `null` user would do nothing —\n // leaving the new account on its pre-claim token until the hourly refresh.\n const liveUser = configRef.current.auth.currentUser;\n if (!liveUser) return;\n await readClaims(\n liveUser,\n async () => ((await liveUser.getIdTokenResult(true)).claims ?? {}) as Record<string, unknown>,\n \"refreshClaims\",\n );\n }, [readClaims]);\n\n // --- Derived at render: only the current session's claims are ever exposed ---\n const sessionClaims = user && resolved?.user === user ? resolved : null;\n const claims = sessionClaims ? sessionClaims.claims : config.defaultClaims;\n const claimsLoading = authLoading || (user !== null && sessionClaims === null);\n\n // --- Context value ---\n const loading = authLoading || claimsLoading || !gateOpen;\n\n const value = useMemo<AuthContextValue<TClaims>>(\n () => ({\n user,\n claims,\n loading,\n authLoading,\n claimsLoading,\n isAuthenticated: !!user,\n refreshClaims,\n }),\n [user, claims, loading, authLoading, claimsLoading, refreshClaims],\n );\n\n return (\n <AuthContext.Provider value={value}>\n {children}\n </AuthContext.Provider>\n );\n}\n"]}
|