@civic/auth 0.7.0-beta.1 → 0.7.0
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/nextjs/config.d.ts.map +1 -1
- package/dist/nextjs/config.js +1 -3
- package/dist/nextjs/config.js.map +1 -1
- package/dist/nextjs/hooks/useUserCookie.d.ts.map +1 -1
- package/dist/nextjs/hooks/useUserCookie.js.map +1 -1
- package/dist/nextjs/providers/NextAuthProvider.d.ts.map +1 -1
- package/dist/nextjs/providers/NextAuthProvider.js +4 -3
- package/dist/nextjs/providers/NextAuthProvider.js.map +1 -1
- package/dist/reactjs/providers/CivicAuthProvider.d.ts.map +1 -1
- package/dist/reactjs/providers/CivicAuthProvider.js +3 -2
- package/dist/reactjs/providers/CivicAuthProvider.js.map +1 -1
- package/dist/shared/hooks/useSignIn.d.ts +4 -9
- package/dist/shared/hooks/useSignIn.d.ts.map +1 -1
- package/dist/shared/hooks/useSignIn.js +42 -75
- package/dist/shared/hooks/useSignIn.js.map +1 -1
- package/dist/shared/providers/AuthContext.d.ts +2 -7
- package/dist/shared/providers/AuthContext.d.ts.map +1 -1
- package/dist/shared/providers/AuthContext.js.map +1 -1
- package/dist/shared/providers/UserProvider.d.ts +1 -5
- package/dist/shared/providers/UserProvider.d.ts.map +1 -1
- package/dist/shared/providers/UserProvider.js.map +1 -1
- package/dist/shared/version.d.ts +1 -1
- package/dist/shared/version.d.ts.map +1 -1
- package/dist/shared/version.js +1 -1
- package/dist/shared/version.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/nextjs/config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAGvC,OAAO,EAEL,KAAK,YAAY,EAEjB,KAAK,kBAAkB,EACxB,MAAM,uBAAuB,CAAC;AAO/B,MAAM,MAAM,mBAAmB,GAAG;IAChC,MAAM,EAAE,kBAAkB,CAAC;IAC3B,IAAI,EAAE,YAAY,CAAC;CACpB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,mBAAmB,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,OAAO,CACpC,sBAAsB,GACtB;IACE,OAAO,CAAC,EAAE;QACR,MAAM,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC;QACrC,IAAI,CAAC,EAAE,YAAY,CAAC;KACrB,CAAC;CACH,CACJ,GAAG;IAGF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG,kBAAkB,GAAG;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/nextjs/config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAGvC,OAAO,EAEL,KAAK,YAAY,EAEjB,KAAK,kBAAkB,EACxB,MAAM,uBAAuB,CAAC;AAO/B,MAAM,MAAM,mBAAmB,GAAG;IAChC,MAAM,EAAE,kBAAkB,CAAC;IAC3B,IAAI,EAAE,YAAY,CAAC;CACpB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,mBAAmB,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,OAAO,CACpC,sBAAsB,GACtB;IACE,OAAO,CAAC,EAAE;QACR,MAAM,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC;QACrC,IAAI,CAAC,EAAE,YAAY,CAAC;KACrB,CAAC;CACH,CACJ,GAAG;IAGF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG,kBAAkB,GAAG;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB,CAAC;AAKF;;GAEG;AACH,eAAO,MAAM,iBAAiB,EAAE,IAAI,CAAC,sBAAsB,EAAE,UAAU,CAiEtE,CAAC;AAEF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,iBAAiB,YACpB,OAAO,CAAC,UAAU,CAAC,KAC1B,sBA2CF,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,eAAO,MAAM,qBAAqB,eAAgB,UAAU,mBACrC,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAyDsmU,CAAC;6BAAsG,CAAC;;;sBAAke,CAAC;yBAA4H,CAAC;;;qBAA+H,CAAC;;;;;;;;;;;;;;;;;;iBAA8pE,CAAC;;;;;;;6BAAg6C,CAAC;sBAAoC,CAAC;;aAAoC,CAAC;;6BAA0D,CAAC;oBAA8B,CAAC;0BAAkE,CAAC;;qBAA2C,CAAC;mBAAiC,CAAC;;wBAA+C,CAAC;eAAmD,CAAC;iBAA4C,CAAC;2BAAyC,CAAC;;;;;;;;;yBAA4zC,CAAC;6BAAwC,CAAC;;;eAAkD,CAAC;mBAAuB,CAAC;;;;CAD/6gB,CAAC"}
|
package/dist/nextjs/config.js
CHANGED
|
@@ -7,8 +7,6 @@ import { sanitizeBasePath } from "./utils.js";
|
|
|
7
7
|
const logger = loggers.nextjs.handlers.auth;
|
|
8
8
|
const defaultServerSecure = !(process.env.NODE_ENV === "development");
|
|
9
9
|
const defaultCookiesMaxAge = 60 * 60; // 1 hour
|
|
10
|
-
// In development, allow client-side reading of ID token for easier debugging and testing
|
|
11
|
-
const defaultIdTokenHttpOnly = process.env.NODE_ENV === "development" ? false : true;
|
|
12
10
|
/**
|
|
13
11
|
* Default configuration values that will be used if not overridden
|
|
14
12
|
*/
|
|
@@ -28,7 +26,7 @@ export const defaultAuthConfig = {
|
|
|
28
26
|
tokens: {
|
|
29
27
|
[OAuthTokenTypes.ID_TOKEN]: {
|
|
30
28
|
secure: defaultServerSecure,
|
|
31
|
-
httpOnly:
|
|
29
|
+
httpOnly: true,
|
|
32
30
|
sameSite: "strict",
|
|
33
31
|
path: "/",
|
|
34
32
|
maxAge: defaultCookiesMaxAge,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/nextjs/config.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable turbo/no-undeclared-env-vars */\nimport type { NextConfig } from \"next\";\nimport { loggers } from \"@/lib/logger.js\";\nimport { withoutUndefined } from \"@/utils.js\";\nimport {\n CodeVerifier,\n type CookieConfig,\n OAuthTokenTypes,\n type TokensCookieConfig,\n} from \"@/shared/lib/types.js\";\nimport { DEFAULT_AUTH_SERVER } from \"@/constants.js\";\nimport { merge } from \"ts-deepmerge\";\nimport { sanitizeBasePath } from \"./utils.js\";\n\nconst logger = loggers.nextjs.handlers.auth;\n\nexport type CookiesConfigObject = {\n tokens: TokensCookieConfig;\n user: CookieConfig;\n};\n\n/**\n * Configuration values for Civic Auth.\n * Only clientId is required, all others are optional.\n */\nexport type AuthConfigWithDefaults = {\n clientId: string;\n oauthServer: string;\n callbackUrl: string; // where Civic's internal OAuth callback is hosted\n loginSuccessUrl?: string; // where the user should be sent after the entire login completes, including the token exchange\n loginUrl: string;\n logoutUrl: string;\n logoutCallbackUrl: string;\n challengeUrl: string;\n refreshUrl: string;\n include: string[];\n exclude: string[];\n cookies: CookiesConfigObject;\n basePath?: string;\n};\n\n/**\n * All possible config values for Civic Auth\n */\nexport type OptionalAuthConfig = Partial<\n | AuthConfigWithDefaults\n | {\n cookies?: {\n tokens?: Partial<TokensCookieConfig>;\n user?: CookieConfig;\n };\n }\n> & {\n // Ensure TypeScript understands these properties are available\n // This doesn't change the public API, just helps TypeScript internally\n callbackUrl?: string; // where Civic's internal OAuth callback is hosted\n loginSuccessUrl?: string; // where the user should be sent after the entire login completes, including the token exchange\n loginUrl?: string;\n logoutUrl?: string;\n logoutCallbackUrl?: string;\n challengeUrl?: string;\n refreshUrl?: string;\n include?: string[];\n exclude?: string[];\n basePath?: string;\n oauthServer?: string;\n};\n\n/**\n * Configuration values for Civic Auth.\n * Only clientId is required, all others are optional.\n */\nexport type AuthConfig = OptionalAuthConfig & {\n clientId: string;\n exclude?: string[];\n};\n\nconst defaultServerSecure = !(process.env.NODE_ENV === \"development\");\nconst defaultCookiesMaxAge = 60 * 60; // 1 hour\n// In development, allow client-side reading of ID token for easier debugging and testing\nconst defaultIdTokenHttpOnly =\n process.env.NODE_ENV === \"development\" ? false : true;\n\n/**\n * Default configuration values that will be used if not overridden\n */\nexport const defaultAuthConfig: Omit<AuthConfigWithDefaults, \"clientId\"> = {\n oauthServer: DEFAULT_AUTH_SERVER,\n callbackUrl: \"/api/auth/callback\",\n loginSuccessUrl: undefined, // By default, the user is sent to the redirect_url\n challengeUrl: \"/api/auth/challenge\",\n refreshUrl: \"/api/auth/refresh\",\n logoutUrl: \"/api/auth/logout\",\n logoutCallbackUrl: \"/api/auth/logoutcallback\",\n loginUrl: \"/\",\n include: [\"/**\"],\n exclude: [\"/api/auth/**\"],\n basePath: \"\",\n cookies: {\n tokens: {\n [OAuthTokenTypes.ID_TOKEN]: {\n secure: defaultServerSecure,\n httpOnly: defaultIdTokenHttpOnly,\n sameSite: \"strict\",\n path: \"/\",\n maxAge: defaultCookiesMaxAge,\n },\n [OAuthTokenTypes.ACCESS_TOKEN]: {\n secure: defaultServerSecure,\n httpOnly: true,\n sameSite: \"strict\",\n path: \"/\",\n maxAge: defaultCookiesMaxAge,\n },\n [OAuthTokenTypes.REFRESH_TOKEN]: {\n secure: defaultServerSecure,\n httpOnly: true,\n sameSite: \"strict\",\n path: \"/\",\n maxAge: defaultCookiesMaxAge,\n },\n [OAuthTokenTypes.ACCESS_TOKEN_EXPIRES_AT]: {\n secure: defaultServerSecure,\n httpOnly: false, // we need this to be available client-side\n sameSite: \"strict\",\n path: \"/\",\n maxAge: defaultCookiesMaxAge,\n },\n [CodeVerifier.COOKIE_NAME]: {\n secure: defaultServerSecure,\n httpOnly: true,\n sameSite: \"strict\",\n path: \"/\",\n maxAge: defaultCookiesMaxAge,\n },\n [CodeVerifier.APP_URL]: {\n secure: defaultServerSecure,\n httpOnly: true,\n sameSite: \"strict\",\n path: \"/\",\n maxAge: defaultCookiesMaxAge,\n },\n },\n user: {\n secure: defaultServerSecure,\n httpOnly: false, // we need this to be available client-side\n sameSite: \"strict\",\n path: \"/\",\n maxAge: defaultCookiesMaxAge,\n },\n },\n};\n\n/**\n * Resolves the authentication configuration by combining:\n * 1. Default values\n * 2. Environment variables (set internally by the plugin)\n * 3. Explicitly passed configuration\n *\n * Config will be merged deeply, with arrays not merged, so that the\n * default include list (for example) [\"/*\"] will not be added\n *\n * Note: Developers should not set _civic_auth_* environment variables directly.\n * Instead, pass configuration to the createCivicAuthPlugin in next.config.js:\n *\n * @example\n * ```js\n * // next.config.js\n * export default createCivicAuthPlugin({\n * callbackUrl: '/custom/callback',\n * })\n * ```\n */\nexport const resolveAuthConfig = (\n config: Partial<AuthConfig> = {},\n): AuthConfigWithDefaults => {\n // Read configuration that was set by the plugin via environment variables\n const configFromEnv = withoutUndefined({\n clientId: process.env._civic_auth_client_id,\n oauthServer: process.env._civic_oauth_server,\n callbackUrl: process.env._civic_auth_callback_url,\n loginSuccessUrl: process.env._civic_auth_login_success_url,\n challengeUrl: process.env._civic_auth_challenge_url,\n loginUrl: process.env._civic_auth_login_url,\n logoutUrl: process.env._civic_auth_logout_url,\n logoutCallbackUrl: process.env._civic_auth_logout_callback_url,\n refreshUrl: process.env._civic_auth_refresh_url,\n include: process.env._civic_auth_includes?.split(\",\"),\n exclude: process.env._civic_auth_excludes?.split(\",\"),\n cookies: process.env._civic_auth_cookie_config\n ? JSON.parse(process.env._civic_auth_cookie_config)\n : undefined,\n basePath: process.env._civic_auth_base_path || \"\",\n }) as AuthConfig;\n\n // Ensure \"/api/auth/**\" is always excluded\n const finalExclude = new Set([\n ...defaultAuthConfig.exclude,\n ...(configFromEnv.exclude || []),\n ...(config.exclude ?? []),\n ]);\n\n // Perform a deep merge of the configurations\n const mergedConfig = merge.withOptions(\n { mergeArrays: false },\n defaultAuthConfig,\n configFromEnv,\n config,\n );\n\n // Override the exclude list with the ensured list\n mergedConfig.exclude = Array.from(finalExclude);\n\n if (mergedConfig.clientId === undefined) {\n throw new Error(\"Civic Auth client ID is required\");\n }\n\n return mergedConfig as AuthConfigWithDefaults & { clientId: string };\n};\n\n/**\n * Creates a Next.js plugin that handles auth configuration.\n *\n * This is the main configuration point for the auth system.\n * Do not set _civic_auth_* environment variables directly - instead,\n * pass your configuration here.\n *\n * The only required field is clientId.\n *\n * Notes:\n * - If you provide explicit URLs, they will be used exactly as provided.\n * - Default URLs will automatically include the basePath from your Next.js config.\n *\n * @example\n * ```js\n * // next.config.js\n * export default createCivicAuthPlugin({\n * clientId: 'my-client-id',\n * });\n * ```\n *\n * @example\n * ```js\n * // next.config.js\n * export default createCivicAuthPlugin({\n * clientId: 'my-client-id',\n * callbackUrl: '/custom/callback',\n * loginUrl: '/custom/login',\n * logoutUrl: '/custom/logout',\n * logoutCallbackUrl: '/custom/logoutcallback',\n * include: ['/protected/*'],\n * exclude: ['/public/*']\n * })\n * ```\n *\n * The plugin sets internal environment variables that are used by\n * the auth system. These variables should not be set manually.\n */\nexport const createCivicAuthPlugin = (authConfig: AuthConfig) => {\n return (nextConfig?: NextConfig) => {\n logger.debug(\n \"createCivicAuthPlugin nextConfig\",\n JSON.stringify(nextConfig, null, 2),\n );\n\n // Extract basePath from Next.js config\n const basePath = sanitizeBasePath(nextConfig?.basePath || \"\");\n\n // Create a copy of default URLs with basePath added\n const defaultUrlsWithBasePath: Partial<AuthConfig> = {};\n\n // Only apply to URLs that aren't explicitly set in authConfig\n if (basePath) {\n if (!authConfig.callbackUrl)\n defaultUrlsWithBasePath.callbackUrl = `${basePath}/api/auth/callback`;\n if (!authConfig.challengeUrl)\n defaultUrlsWithBasePath.challengeUrl = `${basePath}/api/auth/challenge`;\n if (!authConfig.refreshUrl)\n defaultUrlsWithBasePath.refreshUrl = `${basePath}/api/auth/refresh`;\n if (!authConfig.logoutUrl)\n defaultUrlsWithBasePath.logoutUrl = `${basePath}/api/auth/logout`;\n if (!authConfig.logoutCallbackUrl)\n defaultUrlsWithBasePath.logoutCallbackUrl = `${basePath}/api/auth/logoutcallback`;\n if (!authConfig.loginUrl && authConfig.loginUrl !== \"\")\n defaultUrlsWithBasePath.loginUrl = basePath;\n }\n\n // Create final config with basePath and possibly modified URLs\n const resolvedConfig = resolveAuthConfig({\n ...defaultUrlsWithBasePath,\n ...authConfig,\n basePath,\n });\n\n return {\n ...nextConfig,\n env: {\n ...nextConfig?.env,\n // Internal environment variables - do not set these manually\n _civic_auth_client_id: resolvedConfig.clientId,\n _civic_oauth_server: resolvedConfig.oauthServer,\n _civic_auth_callback_url: resolvedConfig.callbackUrl,\n _civic_auth_login_success_url: resolvedConfig.loginSuccessUrl,\n _civic_auth_challenge_url: resolvedConfig.challengeUrl,\n _civic_auth_login_url: resolvedConfig.loginUrl,\n _civic_auth_logout_url: resolvedConfig.logoutUrl,\n _civic_auth_logout_callback_url: resolvedConfig.logoutCallbackUrl,\n _civic_auth_refresh_url: resolvedConfig.refreshUrl,\n _civic_auth_includes: resolvedConfig.include.join(\",\"),\n _civic_auth_excludes: resolvedConfig.exclude.join(\",\"),\n _civic_auth_cookie_config: JSON.stringify(resolvedConfig.cookies),\n _civic_auth_base_path: resolvedConfig.basePath,\n },\n };\n };\n};\n"]}
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/nextjs/config.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable turbo/no-undeclared-env-vars */\nimport type { NextConfig } from \"next\";\nimport { loggers } from \"@/lib/logger.js\";\nimport { withoutUndefined } from \"@/utils.js\";\nimport {\n CodeVerifier,\n type CookieConfig,\n OAuthTokenTypes,\n type TokensCookieConfig,\n} from \"@/shared/lib/types.js\";\nimport { DEFAULT_AUTH_SERVER } from \"@/constants.js\";\nimport { merge } from \"ts-deepmerge\";\nimport { sanitizeBasePath } from \"./utils.js\";\n\nconst logger = loggers.nextjs.handlers.auth;\n\nexport type CookiesConfigObject = {\n tokens: TokensCookieConfig;\n user: CookieConfig;\n};\n\n/**\n * Configuration values for Civic Auth.\n * Only clientId is required, all others are optional.\n */\nexport type AuthConfigWithDefaults = {\n clientId: string;\n oauthServer: string;\n callbackUrl: string; // where Civic's internal OAuth callback is hosted\n loginSuccessUrl?: string; // where the user should be sent after the entire login completes, including the token exchange\n loginUrl: string;\n logoutUrl: string;\n logoutCallbackUrl: string;\n challengeUrl: string;\n refreshUrl: string;\n include: string[];\n exclude: string[];\n cookies: CookiesConfigObject;\n basePath?: string;\n};\n\n/**\n * All possible config values for Civic Auth\n */\nexport type OptionalAuthConfig = Partial<\n | AuthConfigWithDefaults\n | {\n cookies?: {\n tokens?: Partial<TokensCookieConfig>;\n user?: CookieConfig;\n };\n }\n> & {\n // Ensure TypeScript understands these properties are available\n // This doesn't change the public API, just helps TypeScript internally\n callbackUrl?: string; // where Civic's internal OAuth callback is hosted\n loginSuccessUrl?: string; // where the user should be sent after the entire login completes, including the token exchange\n loginUrl?: string;\n logoutUrl?: string;\n logoutCallbackUrl?: string;\n challengeUrl?: string;\n refreshUrl?: string;\n include?: string[];\n exclude?: string[];\n basePath?: string;\n oauthServer?: string;\n};\n\n/**\n * Configuration values for Civic Auth.\n * Only clientId is required, all others are optional.\n */\nexport type AuthConfig = OptionalAuthConfig & {\n clientId: string;\n exclude?: string[];\n};\n\nconst defaultServerSecure = !(process.env.NODE_ENV === \"development\");\nconst defaultCookiesMaxAge = 60 * 60; // 1 hour\n\n/**\n * Default configuration values that will be used if not overridden\n */\nexport const defaultAuthConfig: Omit<AuthConfigWithDefaults, \"clientId\"> = {\n oauthServer: DEFAULT_AUTH_SERVER,\n callbackUrl: \"/api/auth/callback\",\n loginSuccessUrl: undefined, // By default, the user is sent to the redirect_url\n challengeUrl: \"/api/auth/challenge\",\n refreshUrl: \"/api/auth/refresh\",\n logoutUrl: \"/api/auth/logout\",\n logoutCallbackUrl: \"/api/auth/logoutcallback\",\n loginUrl: \"/\",\n include: [\"/**\"],\n exclude: [\"/api/auth/**\"],\n basePath: \"\",\n cookies: {\n tokens: {\n [OAuthTokenTypes.ID_TOKEN]: {\n secure: defaultServerSecure,\n httpOnly: true,\n sameSite: \"strict\",\n path: \"/\",\n maxAge: defaultCookiesMaxAge,\n },\n [OAuthTokenTypes.ACCESS_TOKEN]: {\n secure: defaultServerSecure,\n httpOnly: true,\n sameSite: \"strict\",\n path: \"/\",\n maxAge: defaultCookiesMaxAge,\n },\n [OAuthTokenTypes.REFRESH_TOKEN]: {\n secure: defaultServerSecure,\n httpOnly: true,\n sameSite: \"strict\",\n path: \"/\",\n maxAge: defaultCookiesMaxAge,\n },\n [OAuthTokenTypes.ACCESS_TOKEN_EXPIRES_AT]: {\n secure: defaultServerSecure,\n httpOnly: false, // we need this to be available client-side\n sameSite: \"strict\",\n path: \"/\",\n maxAge: defaultCookiesMaxAge,\n },\n [CodeVerifier.COOKIE_NAME]: {\n secure: defaultServerSecure,\n httpOnly: true,\n sameSite: \"strict\",\n path: \"/\",\n maxAge: defaultCookiesMaxAge,\n },\n [CodeVerifier.APP_URL]: {\n secure: defaultServerSecure,\n httpOnly: true,\n sameSite: \"strict\",\n path: \"/\",\n maxAge: defaultCookiesMaxAge,\n },\n },\n user: {\n secure: defaultServerSecure,\n httpOnly: false, // we need this to be available client-side\n sameSite: \"strict\",\n path: \"/\",\n maxAge: defaultCookiesMaxAge,\n },\n },\n};\n\n/**\n * Resolves the authentication configuration by combining:\n * 1. Default values\n * 2. Environment variables (set internally by the plugin)\n * 3. Explicitly passed configuration\n *\n * Config will be merged deeply, with arrays not merged, so that the\n * default include list (for example) [\"/*\"] will not be added\n *\n * Note: Developers should not set _civic_auth_* environment variables directly.\n * Instead, pass configuration to the createCivicAuthPlugin in next.config.js:\n *\n * @example\n * ```js\n * // next.config.js\n * export default createCivicAuthPlugin({\n * callbackUrl: '/custom/callback',\n * })\n * ```\n */\nexport const resolveAuthConfig = (\n config: Partial<AuthConfig> = {},\n): AuthConfigWithDefaults => {\n // Read configuration that was set by the plugin via environment variables\n const configFromEnv = withoutUndefined({\n clientId: process.env._civic_auth_client_id,\n oauthServer: process.env._civic_oauth_server,\n callbackUrl: process.env._civic_auth_callback_url,\n loginSuccessUrl: process.env._civic_auth_login_success_url,\n challengeUrl: process.env._civic_auth_challenge_url,\n loginUrl: process.env._civic_auth_login_url,\n logoutUrl: process.env._civic_auth_logout_url,\n logoutCallbackUrl: process.env._civic_auth_logout_callback_url,\n refreshUrl: process.env._civic_auth_refresh_url,\n include: process.env._civic_auth_includes?.split(\",\"),\n exclude: process.env._civic_auth_excludes?.split(\",\"),\n cookies: process.env._civic_auth_cookie_config\n ? JSON.parse(process.env._civic_auth_cookie_config)\n : undefined,\n basePath: process.env._civic_auth_base_path || \"\",\n }) as AuthConfig;\n\n // Ensure \"/api/auth/**\" is always excluded\n const finalExclude = new Set([\n ...defaultAuthConfig.exclude,\n ...(configFromEnv.exclude || []),\n ...(config.exclude ?? []),\n ]);\n\n // Perform a deep merge of the configurations\n const mergedConfig = merge.withOptions(\n { mergeArrays: false },\n defaultAuthConfig,\n configFromEnv,\n config,\n );\n\n // Override the exclude list with the ensured list\n mergedConfig.exclude = Array.from(finalExclude);\n\n if (mergedConfig.clientId === undefined) {\n throw new Error(\"Civic Auth client ID is required\");\n }\n\n return mergedConfig as AuthConfigWithDefaults & { clientId: string };\n};\n\n/**\n * Creates a Next.js plugin that handles auth configuration.\n *\n * This is the main configuration point for the auth system.\n * Do not set _civic_auth_* environment variables directly - instead,\n * pass your configuration here.\n *\n * The only required field is clientId.\n *\n * Notes:\n * - If you provide explicit URLs, they will be used exactly as provided.\n * - Default URLs will automatically include the basePath from your Next.js config.\n *\n * @example\n * ```js\n * // next.config.js\n * export default createCivicAuthPlugin({\n * clientId: 'my-client-id',\n * });\n * ```\n *\n * @example\n * ```js\n * // next.config.js\n * export default createCivicAuthPlugin({\n * clientId: 'my-client-id',\n * callbackUrl: '/custom/callback',\n * loginUrl: '/custom/login',\n * logoutUrl: '/custom/logout',\n * logoutCallbackUrl: '/custom/logoutcallback',\n * include: ['/protected/*'],\n * exclude: ['/public/*']\n * })\n * ```\n *\n * The plugin sets internal environment variables that are used by\n * the auth system. These variables should not be set manually.\n */\nexport const createCivicAuthPlugin = (authConfig: AuthConfig) => {\n return (nextConfig?: NextConfig) => {\n logger.debug(\n \"createCivicAuthPlugin nextConfig\",\n JSON.stringify(nextConfig, null, 2),\n );\n\n // Extract basePath from Next.js config\n const basePath = sanitizeBasePath(nextConfig?.basePath || \"\");\n\n // Create a copy of default URLs with basePath added\n const defaultUrlsWithBasePath: Partial<AuthConfig> = {};\n\n // Only apply to URLs that aren't explicitly set in authConfig\n if (basePath) {\n if (!authConfig.callbackUrl)\n defaultUrlsWithBasePath.callbackUrl = `${basePath}/api/auth/callback`;\n if (!authConfig.challengeUrl)\n defaultUrlsWithBasePath.challengeUrl = `${basePath}/api/auth/challenge`;\n if (!authConfig.refreshUrl)\n defaultUrlsWithBasePath.refreshUrl = `${basePath}/api/auth/refresh`;\n if (!authConfig.logoutUrl)\n defaultUrlsWithBasePath.logoutUrl = `${basePath}/api/auth/logout`;\n if (!authConfig.logoutCallbackUrl)\n defaultUrlsWithBasePath.logoutCallbackUrl = `${basePath}/api/auth/logoutcallback`;\n if (!authConfig.loginUrl && authConfig.loginUrl !== \"\")\n defaultUrlsWithBasePath.loginUrl = basePath;\n }\n\n // Create final config with basePath and possibly modified URLs\n const resolvedConfig = resolveAuthConfig({\n ...defaultUrlsWithBasePath,\n ...authConfig,\n basePath,\n });\n\n return {\n ...nextConfig,\n env: {\n ...nextConfig?.env,\n // Internal environment variables - do not set these manually\n _civic_auth_client_id: resolvedConfig.clientId,\n _civic_oauth_server: resolvedConfig.oauthServer,\n _civic_auth_callback_url: resolvedConfig.callbackUrl,\n _civic_auth_login_success_url: resolvedConfig.loginSuccessUrl,\n _civic_auth_challenge_url: resolvedConfig.challengeUrl,\n _civic_auth_login_url: resolvedConfig.loginUrl,\n _civic_auth_logout_url: resolvedConfig.logoutUrl,\n _civic_auth_logout_callback_url: resolvedConfig.logoutCallbackUrl,\n _civic_auth_refresh_url: resolvedConfig.refreshUrl,\n _civic_auth_includes: resolvedConfig.include.join(\",\"),\n _civic_auth_excludes: resolvedConfig.exclude.join(\",\"),\n _civic_auth_cookie_config: JSON.stringify(resolvedConfig.cookies),\n _civic_auth_base_path: resolvedConfig.basePath,\n },\n };\n };\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useUserCookie.d.ts","sourceRoot":"","sources":["../../../src/nextjs/hooks/useUserCookie.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"useUserCookie.d.ts","sourceRoot":"","sources":["../../../src/nextjs/hooks/useUserCookie.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAwBpD,eAAO,MAAM,aAAa,GAAI,CAAC,SAAS,WAAW;;;;kCAuBA,eAAe;;CA+EjE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useUserCookie.js","sourceRoot":"","sources":["../../../src/nextjs/hooks/useUserCookie.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AACb,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEjE,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAM1C,MAAM,oBAAoB,GAAG,IAAI,oBAAoB,EAAE,CAAC;AACxD,MAAM,yBAAyB,GAAG,GAA2B,EAAE;IAC7D,MAAM,UAAU,GAAG,oBAAoB,CAAC,OAAO,CAC7C,WAAW,CAAC,IAAI,CACW,CAAC;IAC9B,MAAM,aAAa,GAAG,oBAAoB,CAAC,OAAO,CAChD,eAAe,CAAC,QAAQ,CACG,CAAC;
|
|
1
|
+
{"version":3,"file":"useUserCookie.js","sourceRoot":"","sources":["../../../src/nextjs/hooks/useUserCookie.ts"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { EmptyObject, User } from \"@/types.js\";\nimport { OAuthTokenTypes, UserStorage } from \"@/shared/lib/types.js\";\nimport { objectsAreEqual } from \"@/lib/obj.js\";\nimport { BrowserCookieStorage } from \"@/shared/index.js\";\nimport { useIsClient } from \"usehooks-ts\";\n\ntype UserAndTokenFromCookie = {\n [UserStorage.USER]: User | undefined;\n [OAuthTokenTypes.ID_TOKEN]: string | undefined;\n};\nconst browserCookieStorage = new BrowserCookieStorage();\nconst getUserAndTokenFromCookie = (): UserAndTokenFromCookie => {\n const userCookie = browserCookieStorage.getSync(\n UserStorage.USER,\n ) as unknown as string | null;\n const idTokenCookie = browserCookieStorage.getSync(\n OAuthTokenTypes.ID_TOKEN,\n ) as unknown as string | null;\n return {\n [UserStorage.USER]: userCookie ? JSON.parse(userCookie) : undefined,\n [OAuthTokenTypes.ID_TOKEN]: idTokenCookie || undefined,\n };\n};\n\nexport const useUserCookie = <T extends EmptyObject>() => {\n // need to make sure this is only run on the client\n // because it uses cookies that expect a document object to be present to read from\n const isClient = useIsClient();\n const response =\n (isClient && getUserAndTokenFromCookie()) || ({} as UserAndTokenFromCookie);\n // initialise user and token from cookies so that we don't\n // have to wait for the first fetch to expose these values\n const userData = response[UserStorage.USER] as User<T>;\n const tokenData = response[OAuthTokenTypes.ID_TOKEN];\n\n // we need both a ref and state for the user and token\n // because the ref is used to compare the previous value\n // to the new value to see if it has changed\n // and the state is used to trigger a re-render\n // when the value changes\n const userRef = useRef(userData);\n const tokenRef = useRef(tokenData);\n const [user, setUser] = useState<User<T> | null>(userData);\n const [idToken, setToken] = useState<string | undefined>(tokenData);\n const [userChanged, setUserChanged] = useState<boolean>(false);\n const [initialFetchComplete, setInitialFetchComplete] = useState(!!userData);\n\n const fetchUser = useCallback((abortController?: AbortController) => {\n if (abortController?.signal.aborted) {\n setInitialFetchComplete(true);\n return;\n }\n\n const response = getUserAndTokenFromCookie() || {};\n const userData = response[UserStorage.USER] as User<T>;\n const tokenData = response[OAuthTokenTypes.ID_TOKEN];\n\n if (abortController?.signal.aborted) {\n setInitialFetchComplete(true);\n return;\n }\n\n // we use objectsAreEqual here comparing the object references could trigger\n // unnecessary re-renders if the object is the same but a new reference is created\n if (!objectsAreEqual(userData, userRef.current)) {\n userRef.current = userData || null;\n setUser(userData || null);\n setUserChanged(true);\n }\n if (tokenData !== tokenRef.current) {\n tokenRef.current = tokenData;\n setToken(tokenData);\n }\n setInitialFetchComplete(true);\n }, []);\n\n /**\n * Set up a listener for when the user cookies change which will be triggered\n * by server-side during token exchange. We are able to receive these updates as the auth\n * calls will be running in the iframe and the cookies will be set in the parent window.\n */\n useEffect(() => {\n let abortController = new AbortController();\n const cookieListener = () => {\n // pass an abort controller to fetchUser to cancel any in-flight requests\n // that might have been triggered before re-render\n abortController = new AbortController();\n fetchUser(abortController);\n };\n\n document.addEventListener(\"visibilitychange\", cookieListener);\n window.addEventListener(\"storage\", cookieListener);\n window.addEventListener(\"focus\", cookieListener);\n\n // set the user and token ref from cookies again as the component has now mounted\n // so cookies might be available that weren't there at initialisation above\n const response =\n getUserAndTokenFromCookie() || ({} as UserAndTokenFromCookie);\n const userData = response[UserStorage.USER] as User<T>;\n const tokenData = response[OAuthTokenTypes.ID_TOKEN];\n userRef.current = userData;\n tokenRef.current = tokenData;\n setUser(userData);\n setToken(tokenData);\n fetchUser(abortController);\n\n // poll for changes to the cookies every 2 seconds\n // this is required as react doesn't have a built-in hook that will change on cookie changes\n const intervalId = setInterval(cookieListener, 2000);\n\n return () => {\n abortController.abort();\n document.removeEventListener(\"visibilitychange\", cookieListener);\n window.removeEventListener(\"storage\", cookieListener);\n window.removeEventListener(\"focus\", cookieListener);\n clearInterval(intervalId);\n };\n }, [fetchUser]);\n\n return {\n user,\n idToken,\n userChanged,\n fetchUser,\n isLoading: !initialFetchComplete,\n };\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NextAuthProvider.d.ts","sourceRoot":"","sources":["../../../src/nextjs/providers/NextAuthProvider.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"NextAuthProvider.d.ts","sourceRoot":"","sources":["../../../src/nextjs/providers/NextAuthProvider.tsx"],"names":[],"mappings":"AAYA,OAAO,EAEL,KAAK,sBAAsB,EAC5B,MAAM,oBAAoB,CAAC;AAe5B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAkBrE,KAAK,kCAAkC,GAAG,IAAI,CAC5C,iBAAiB,EACjB,UAAU,CACX,GAAG;IACF,cAAc,EAAE,sBAAsB,CAAC;CACxC,CAAC;AACF,KAAK,0BAA0B,GAAG,IAAI,CACpC,kCAAkC,EAClC,UAAU,GAAG,gBAAgB,GAAG,aAAa,CAC9C,CAAC;AA0JF,QAAA,MAAM,qBAAqB,2BAGxB,0BAA0B,qDA8C5B,CAAC;AAEF,OAAO,EAAE,qBAAqB,EAAE,KAAK,0BAA0B,EAAE,CAAC"}
|
|
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
|
|
|
3
3
|
/**
|
|
4
4
|
* A very small context provider for the user object - it takes the user object from the cookie and provides it to the app.
|
|
5
5
|
*/
|
|
6
|
-
import React, { startTransition, useCallback, useEffect, useRef, useState, } from "react";
|
|
6
|
+
import React, { startTransition, useCallback, useEffect, useRef, useState, useMemo, } from "react";
|
|
7
7
|
import { resolveAuthConfig, } from "../../nextjs/config.js";
|
|
8
8
|
import { resolveCallbackUrl } from "../../nextjs/utils.js";
|
|
9
9
|
import { ConfidentialClientPKCEConsumer } from "../../services/PKCE.js";
|
|
@@ -49,11 +49,12 @@ const CivicNextAuthTokenProviderInternal = ({ children, displayMode = "iframe",
|
|
|
49
49
|
fetchUser();
|
|
50
50
|
await props?.onSignOut?.();
|
|
51
51
|
}, [fetchUser, props]);
|
|
52
|
+
// Memoize storage to prevent recreation on every render
|
|
53
|
+
const storage = useMemo(() => new BrowserCookieStorage(), []);
|
|
52
54
|
const { signIn, startSignIn, signOut, authStatus } = useSignIn({
|
|
53
55
|
postSignOut,
|
|
54
56
|
pkceConsumer,
|
|
55
57
|
displayMode,
|
|
56
|
-
storage: new BrowserCookieStorage(),
|
|
57
58
|
});
|
|
58
59
|
const { error: refreshError } = useRefresh();
|
|
59
60
|
useEffect(() => {
|
|
@@ -91,7 +92,7 @@ const CivicNextAuthTokenProviderInternal = ({ children, displayMode = "iframe",
|
|
|
91
92
|
// we need this as server-side rendering will not have a window object
|
|
92
93
|
// and will throw an error if we try to access it
|
|
93
94
|
const isClient = useIsClient();
|
|
94
|
-
return !isClient ? null : (_jsx(TokenProvider, { children: _jsxs(UserProvider, { storage:
|
|
95
|
+
return !isClient ? null : (_jsx(TokenProvider, { children: _jsxs(UserProvider, { storage: storage, user: user, signOut: signOut, signIn: signIn, displayMode: displayMode, authStatus: authStatus, children: [_jsx(IFrameAndLoading, { error: null, isLoading: isInIframe }), isInIframe && (_jsx(BlockDisplay, { children: _jsx(LoadingIcon, {}) })), children] }) }));
|
|
95
96
|
};
|
|
96
97
|
const CivicNextAuthProviderInternal = ({ children, ...props }) => {
|
|
97
98
|
const { user, idToken, fetchUser, isLoading, userChanged } = useUserCookie();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NextAuthProvider.js","sourceRoot":"","sources":["../../../src/nextjs/providers/NextAuthProvider.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\n/**\n * A very small context provider for the user object - it takes the user object from the cookie and provides it to the app.\n */\nimport React, {\n startTransition,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport {\n resolveAuthConfig,\n type AuthConfigWithDefaults,\n} from \"@/nextjs/config.js\";\nimport { resolveCallbackUrl } from \"@/nextjs/utils.js\";\nimport { ConfidentialClientPKCEConsumer } from \"@/services/PKCE.js\";\nimport { UserProvider } from \"@/shared/providers/UserProvider.js\";\nimport { useUserCookie } from \"@/nextjs/hooks/useUserCookie.js\";\nimport { CivicAuthConfigProvider } from \"@/shared/providers/CivicAuthConfigContext.js\";\nimport { SessionProvider } from \"@/shared/providers/SessionProvider.js\";\nimport { IframeProvider } from \"@/shared/providers/IframeProvider.js\";\nimport { TokenProvider } from \"@/shared/providers/TokenProvider.js\";\nimport { useSignIn } from \"@/shared/hooks/useSignIn.js\";\nimport { useCivicAuthConfig } from \"@/shared/hooks/useCivicAuthConfig.js\";\nimport { IFrameAndLoading } from \"@/shared/components/IFrameAndLoading.js\";\nimport { BlockDisplay } from \"@/shared/components/BlockDisplay.js\";\nimport { LoadingIcon } from \"@/shared/components/LoadingIcon.js\";\nimport { useIframe } from \"@/shared/hooks/useIframe.js\";\nimport type { AuthProviderProps } from \"@/shared/providers/types.js\";\nimport { useIsInIframe } from \"@/shared/hooks/useIsInIframe.js\";\nimport { AuthStatus, type UnknownObject, type User } from \"@/types.js\";\nimport { useRefresh } from \"@/nextjs/hooks/useRefresh.js\";\nimport { useCurrentUrl, useSession } from \"@/shared/hooks/index.js\";\nimport { BrowserCookieStorage } from \"@/shared/index.js\";\nimport { getIframeRef } from \"@/shared/lib/iframeUtils.js\";\nimport { AuthStatusProvider } from \"@/shared/providers/AuthStatusContext.js\";\nimport { useIsClient } from \"usehooks-ts\";\nimport { useRouter } from \"next/navigation.js\";\n\ntype CivicNextAuthTokenProviderInternalProps<TUser extends UnknownObject> =\n NextCivicAuthProviderInternalProps & {\n isLoading: boolean;\n idToken?: string;\n user: User<TUser> | null;\n fetchUser: () => void;\n };\ntype NextCivicAuthProviderInternalProps = Omit<\n AuthProviderProps,\n \"clientId\"\n> & {\n resolvedConfig: AuthConfigWithDefaults;\n};\ntype NextCivicAuthProviderProps = Omit<\n NextCivicAuthProviderInternalProps,\n \"clientId\" | \"resolvedConfig\" | \"redirectUrl\"\n>;\n\nconst CivicNextAuthTokenProviderInternal = <\n TUser extends UnknownObject = UnknownObject,\n>({\n children,\n displayMode = \"iframe\",\n user,\n fetchUser,\n ...props\n}: CivicNextAuthTokenProviderInternalProps<TUser>) => {\n const { iframeMode, resolvedConfig } = props;\n const { iframeRef, setIframeIsVisible, isIframeMounted, setIframeMounted } =\n useIframe();\n const civicAuthConfig = useCivicAuthConfig();\n const { challengeUrl } = resolvedConfig;\n const pkceConsumer = new ConfidentialClientPKCEConsumer(\n challengeUrl,\n resolvedConfig.basePath,\n );\n const { data: session } = useSession();\n const currentUrl = useCurrentUrl();\n\n useEffect(() => {\n if (session?.authenticated) {\n setIframeMounted(false);\n // the session is authenticated, so don't show the login iframe\n setIframeIsVisible(false);\n return;\n }\n }, [session?.authenticated, setIframeIsVisible, setIframeMounted]);\n\n const postSignOut = useCallback(async () => {\n // user is signed out, manually update the user from cookies to not wait for polling\n fetchUser();\n await props?.onSignOut?.();\n }, [fetchUser, props]);\n\n const { signIn, startSignIn, signOut, authStatus } = useSignIn({\n postSignOut,\n pkceConsumer,\n displayMode,\n storage: new BrowserCookieStorage(),\n });\n\n const { error: refreshError } = useRefresh();\n\n useEffect(() => {\n const ref = getIframeRef(iframeRef?.current, true);\n if (\n isIframeMounted &&\n civicAuthConfig &&\n !session?.authenticated &&\n ref &&\n authStatus === AuthStatus.UNAUTHENTICATED &&\n displayMode === \"iframe\" &&\n !currentUrl?.includes(\"code=\")\n ) {\n startSignIn();\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n isIframeMounted,\n currentUrl,\n iframeMode,\n iframeRef,\n civicAuthConfig,\n session?.authenticated,\n authStatus,\n startSignIn,\n displayMode,\n ]);\n\n useEffect(() => {\n if (refreshError) {\n console.error(\"Error refreshing token, signing out...\", refreshError);\n signOut();\n }\n }, [refreshError, signOut]);\n\n // if the SDK loads in an iframe, we show the loading spinner as the iframe\n // will be waiting to be minimized\n const isInIframe = useIsInIframe();\n // we need this as server-side rendering will not have a window object\n // and will throw an error if we try to access it\n const isClient = useIsClient();\n return !isClient ? null : (\n <TokenProvider>\n <UserProvider\n storage={new BrowserCookieStorage()}\n user={user}\n signOut={signOut}\n signIn={signIn}\n displayMode={displayMode}\n authStatus={authStatus}\n >\n <IFrameAndLoading error={null} isLoading={isInIframe} />\n {isInIframe && (\n <BlockDisplay>\n <LoadingIcon />\n </BlockDisplay>\n )}\n {children}\n </UserProvider>\n </TokenProvider>\n );\n};\n\nconst CivicNextAuthProviderInternal = ({\n children,\n ...props\n}: NextCivicAuthProviderInternalProps) => {\n const { user, idToken, fetchUser, isLoading, userChanged } = useUserCookie();\n const hasRunRef = useRef(false);\n const router = useRouter();\n\n // if there are any changes in the user object, we need to refresh the page\n // to handle both login and logout cases. We use a 'hasRun' ref to prevent\n // the refresh from running multiple times in a row\n useEffect(() => {\n if (userChanged) {\n if (!hasRunRef.current) {\n hasRunRef.current = true;\n startTransition(() => {\n router.refresh();\n });\n }\n } else {\n hasRunRef.current = false;\n }\n }, [userChanged, router]);\n\n const session = {\n authenticated: !!user,\n idToken,\n };\n\n return (\n <SessionProvider data={session} isLoading={isLoading}>\n <CivicNextAuthTokenProviderInternal\n {...props}\n user={user}\n idToken={idToken}\n fetchUser={fetchUser}\n isLoading={isLoading}\n >\n {children}\n </CivicNextAuthTokenProviderInternal>\n </SessionProvider>\n );\n};\n\nconst CivicNextAuthProvider = ({\n children,\n ...props\n}: NextCivicAuthProviderProps) => {\n const resolvedConfig = resolveAuthConfig();\n const {\n clientId,\n oauthServer,\n callbackUrl,\n loginSuccessUrl,\n challengeUrl,\n logoutUrl,\n refreshUrl,\n logoutCallbackUrl,\n } = resolvedConfig;\n const [redirectUrl, setRedirectUrl] = useState<string>(\"\");\n\n useEffect(() => {\n if (typeof globalThis.window !== \"undefined\") {\n const appUrl = globalThis.window.location.origin;\n setRedirectUrl(resolveCallbackUrl(resolvedConfig, appUrl));\n }\n }, [callbackUrl, resolvedConfig]);\n\n return (\n <CivicAuthConfigProvider\n oauthServer={oauthServer}\n clientId={clientId}\n loginSuccessUrl={loginSuccessUrl}\n redirectUrl={redirectUrl}\n logoutRedirectUrl={logoutCallbackUrl}\n nonce={props?.nonce}\n challengeUrl={challengeUrl}\n refreshUrl={refreshUrl}\n logoutUrl={logoutUrl}\n logoutCallbackUrl={logoutCallbackUrl}\n >\n <AuthStatusProvider>\n <IframeProvider iframeMode={props.iframeMode}>\n <CivicNextAuthProviderInternal\n {...props}\n resolvedConfig={resolvedConfig}\n >\n {children}\n </CivicNextAuthProviderInternal>\n </IframeProvider>\n </AuthStatusProvider>\n </CivicAuthConfigProvider>\n );\n};\n\nexport { CivicNextAuthProvider, type NextCivicAuthProviderProps };\n"]}
|
|
1
|
+
{"version":3,"file":"NextAuthProvider.js","sourceRoot":"","sources":["../../../src/nextjs/providers/NextAuthProvider.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\n/**\n * A very small context provider for the user object - it takes the user object from the cookie and provides it to the app.\n */\nimport React, {\n startTransition,\n useCallback,\n useEffect,\n useRef,\n useState,\n useMemo,\n} from \"react\";\nimport {\n resolveAuthConfig,\n type AuthConfigWithDefaults,\n} from \"@/nextjs/config.js\";\nimport { resolveCallbackUrl } from \"@/nextjs/utils.js\";\nimport { ConfidentialClientPKCEConsumer } from \"@/services/PKCE.js\";\nimport { UserProvider } from \"@/shared/providers/UserProvider.js\";\nimport { useUserCookie } from \"@/nextjs/hooks/useUserCookie.js\";\nimport { CivicAuthConfigProvider } from \"@/shared/providers/CivicAuthConfigContext.js\";\nimport { SessionProvider } from \"@/shared/providers/SessionProvider.js\";\nimport { IframeProvider } from \"@/shared/providers/IframeProvider.js\";\nimport { TokenProvider } from \"@/shared/providers/TokenProvider.js\";\nimport { useSignIn } from \"@/shared/hooks/useSignIn.js\";\nimport { useCivicAuthConfig } from \"@/shared/hooks/useCivicAuthConfig.js\";\nimport { IFrameAndLoading } from \"@/shared/components/IFrameAndLoading.js\";\nimport { BlockDisplay } from \"@/shared/components/BlockDisplay.js\";\nimport { LoadingIcon } from \"@/shared/components/LoadingIcon.js\";\nimport { useIframe } from \"@/shared/hooks/useIframe.js\";\nimport type { AuthProviderProps } from \"@/shared/providers/types.js\";\nimport { useIsInIframe } from \"@/shared/hooks/useIsInIframe.js\";\nimport { AuthStatus, type UnknownObject, type User } from \"@/types.js\";\nimport { useRefresh } from \"@/nextjs/hooks/useRefresh.js\";\nimport { useCurrentUrl, useSession } from \"@/shared/hooks/index.js\";\nimport { BrowserCookieStorage } from \"@/shared/index.js\";\nimport { getIframeRef } from \"@/shared/lib/iframeUtils.js\";\nimport { AuthStatusProvider } from \"@/shared/providers/AuthStatusContext.js\";\nimport { useIsClient } from \"usehooks-ts\";\nimport { useRouter } from \"next/navigation.js\";\n\ntype CivicNextAuthTokenProviderInternalProps<TUser extends UnknownObject> =\n NextCivicAuthProviderInternalProps & {\n isLoading: boolean;\n idToken?: string;\n user: User<TUser> | null;\n fetchUser: () => void;\n };\ntype NextCivicAuthProviderInternalProps = Omit<\n AuthProviderProps,\n \"clientId\"\n> & {\n resolvedConfig: AuthConfigWithDefaults;\n};\ntype NextCivicAuthProviderProps = Omit<\n NextCivicAuthProviderInternalProps,\n \"clientId\" | \"resolvedConfig\" | \"redirectUrl\"\n>;\n\nconst CivicNextAuthTokenProviderInternal = <\n TUser extends UnknownObject = UnknownObject,\n>({\n children,\n displayMode = \"iframe\",\n user,\n fetchUser,\n ...props\n}: CivicNextAuthTokenProviderInternalProps<TUser>) => {\n const { iframeMode, resolvedConfig } = props;\n const { iframeRef, setIframeIsVisible, isIframeMounted, setIframeMounted } =\n useIframe();\n const civicAuthConfig = useCivicAuthConfig();\n const { challengeUrl } = resolvedConfig;\n const pkceConsumer = new ConfidentialClientPKCEConsumer(\n challengeUrl,\n resolvedConfig.basePath,\n );\n const { data: session } = useSession();\n const currentUrl = useCurrentUrl();\n\n useEffect(() => {\n if (session?.authenticated) {\n setIframeMounted(false);\n // the session is authenticated, so don't show the login iframe\n setIframeIsVisible(false);\n return;\n }\n }, [session?.authenticated, setIframeIsVisible, setIframeMounted]);\n\n const postSignOut = useCallback(async () => {\n // user is signed out, manually update the user from cookies to not wait for polling\n fetchUser();\n await props?.onSignOut?.();\n }, [fetchUser, props]);\n\n // Memoize storage to prevent recreation on every render\n const storage = useMemo(() => new BrowserCookieStorage(), []);\n\n const { signIn, startSignIn, signOut, authStatus } = useSignIn({\n postSignOut,\n pkceConsumer,\n displayMode,\n });\n\n const { error: refreshError } = useRefresh();\n\n useEffect(() => {\n const ref = getIframeRef(iframeRef?.current, true);\n if (\n isIframeMounted &&\n civicAuthConfig &&\n !session?.authenticated &&\n ref &&\n authStatus === AuthStatus.UNAUTHENTICATED &&\n displayMode === \"iframe\" &&\n !currentUrl?.includes(\"code=\")\n ) {\n startSignIn();\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n isIframeMounted,\n currentUrl,\n iframeMode,\n iframeRef,\n civicAuthConfig,\n session?.authenticated,\n authStatus,\n startSignIn,\n displayMode,\n ]);\n\n useEffect(() => {\n if (refreshError) {\n console.error(\"Error refreshing token, signing out...\", refreshError);\n signOut();\n }\n }, [refreshError, signOut]);\n\n // if the SDK loads in an iframe, we show the loading spinner as the iframe\n // will be waiting to be minimized\n const isInIframe = useIsInIframe();\n // we need this as server-side rendering will not have a window object\n // and will throw an error if we try to access it\n const isClient = useIsClient();\n return !isClient ? null : (\n <TokenProvider>\n <UserProvider\n storage={storage}\n user={user}\n signOut={signOut}\n signIn={signIn}\n displayMode={displayMode}\n authStatus={authStatus}\n >\n <IFrameAndLoading error={null} isLoading={isInIframe} />\n {isInIframe && (\n <BlockDisplay>\n <LoadingIcon />\n </BlockDisplay>\n )}\n {children}\n </UserProvider>\n </TokenProvider>\n );\n};\n\nconst CivicNextAuthProviderInternal = ({\n children,\n ...props\n}: NextCivicAuthProviderInternalProps) => {\n const { user, idToken, fetchUser, isLoading, userChanged } = useUserCookie();\n const hasRunRef = useRef(false);\n const router = useRouter();\n\n // if there are any changes in the user object, we need to refresh the page\n // to handle both login and logout cases. We use a 'hasRun' ref to prevent\n // the refresh from running multiple times in a row\n useEffect(() => {\n if (userChanged) {\n if (!hasRunRef.current) {\n hasRunRef.current = true;\n startTransition(() => {\n router.refresh();\n });\n }\n } else {\n hasRunRef.current = false;\n }\n }, [userChanged, router]);\n\n const session = {\n authenticated: !!user,\n idToken,\n };\n\n return (\n <SessionProvider data={session} isLoading={isLoading}>\n <CivicNextAuthTokenProviderInternal\n {...props}\n user={user}\n idToken={idToken}\n fetchUser={fetchUser}\n isLoading={isLoading}\n >\n {children}\n </CivicNextAuthTokenProviderInternal>\n </SessionProvider>\n );\n};\n\nconst CivicNextAuthProvider = ({\n children,\n ...props\n}: NextCivicAuthProviderProps) => {\n const resolvedConfig = resolveAuthConfig();\n const {\n clientId,\n oauthServer,\n callbackUrl,\n loginSuccessUrl,\n challengeUrl,\n logoutUrl,\n refreshUrl,\n logoutCallbackUrl,\n } = resolvedConfig;\n const [redirectUrl, setRedirectUrl] = useState<string>(\"\");\n\n useEffect(() => {\n if (typeof globalThis.window !== \"undefined\") {\n const appUrl = globalThis.window.location.origin;\n setRedirectUrl(resolveCallbackUrl(resolvedConfig, appUrl));\n }\n }, [callbackUrl, resolvedConfig]);\n\n return (\n <CivicAuthConfigProvider\n oauthServer={oauthServer}\n clientId={clientId}\n loginSuccessUrl={loginSuccessUrl}\n redirectUrl={redirectUrl}\n logoutRedirectUrl={logoutCallbackUrl}\n nonce={props?.nonce}\n challengeUrl={challengeUrl}\n refreshUrl={refreshUrl}\n logoutUrl={logoutUrl}\n logoutCallbackUrl={logoutCallbackUrl}\n >\n <AuthStatusProvider>\n <IframeProvider iframeMode={props.iframeMode}>\n <CivicNextAuthProviderInternal\n {...props}\n resolvedConfig={resolvedConfig}\n >\n {children}\n </CivicNextAuthProviderInternal>\n </IframeProvider>\n </AuthStatusProvider>\n </CivicAuthConfigProvider>\n );\n};\n\nexport { CivicNextAuthProvider, type NextCivicAuthProviderProps };\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CivicAuthProvider.d.ts","sourceRoot":"","sources":["../../../src/reactjs/providers/CivicAuthProvider.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAGrE,KAAK,sBAAsB,GAAG,IAAI,CAAC,iBAAiB,EAAE,cAAc,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"CivicAuthProvider.d.ts","sourceRoot":"","sources":["../../../src/reactjs/providers/CivicAuthProvider.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAGrE,KAAK,sBAAsB,GAAG,IAAI,CAAC,iBAAiB,EAAE,cAAc,CAAC,CAAC;AAsCtE,QAAA,MAAM,iBAAiB,2BAA4B,sBAAsB,qDAqBxE,CAAC;AAEF,OAAO,EAAE,iBAAiB,EAAE,KAAK,sBAAsB,EAAE,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx } from "@emotion/react/jsx-runtime";
|
|
3
|
-
import React from "react";
|
|
3
|
+
import React, { useMemo } from "react";
|
|
4
4
|
import { AuthProvider } from "../../reactjs/providers/AuthProvider.js";
|
|
5
5
|
import { BrowserPublicClientPKCEProducer } from "../../services/PKCE.js";
|
|
6
6
|
import { UserProvider } from "../../shared/providers/UserProvider.js";
|
|
@@ -15,7 +15,8 @@ import { useAuth } from "../../shared/hooks/useAuth.js";
|
|
|
15
15
|
import { AuthStatusProvider } from "../../shared/providers/AuthStatusContext.js";
|
|
16
16
|
const WrapperUserProvider = ({ children }) => {
|
|
17
17
|
const { signIn, signOut, displayMode, authStatus } = useAuth();
|
|
18
|
-
|
|
18
|
+
const storage = useMemo(() => new LocalStorageAdapter(), []);
|
|
19
|
+
return (_jsx(UserProvider, { storage: storage, signIn: signIn, signOut: signOut, user: null, authStatus: authStatus, displayMode: displayMode, children: children }));
|
|
19
20
|
};
|
|
20
21
|
const WrapperSessionAuthProvider = ({ children, ...props }) => {
|
|
21
22
|
const sessionData = useClientTokenExchangeSession();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CivicAuthProvider.js","sourceRoot":"","sources":["../../../src/reactjs/providers/CivicAuthProvider.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AACb,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"CivicAuthProvider.js","sourceRoot":"","sources":["../../../src/reactjs/providers/CivicAuthProvider.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AACb,OAAO,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,qCAAqC,CAAC;AACnE,OAAO,EAAE,+BAA+B,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,uBAAuB,EAAE,MAAM,8CAA8C,CAAC;AACvF,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AACtE,OAAO,EAAE,kCAAkC,EAAE,MAAM,2DAA2D,CAAC;AAC/G,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AACxE,OAAO,EAAE,6BAA6B,EAAE,MAAM,kDAAkD,CAAC;AACjG,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AACpE,OAAO,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAEpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAI7E,MAAM,mBAAmB,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE;IAC1E,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,OAAO,EAAE,CAAC;IAE/D,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,mBAAmB,EAAE,EAAE,EAAE,CAAC,CAAC;IAE7D,OAAO,CACL,KAAC,YAAY,IACX,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,IAAI,EACV,UAAU,EAAE,UAAU,EACtB,WAAW,EAAE,WAAW,YAEvB,QAAQ,GACI,CAChB,CAAC;AACJ,CAAC,CAAC;AACF,MAAM,0BAA0B,GAAG,CAAC,EAClC,QAAQ,EACR,GAAG,KAAK,EACe,EAAE,EAAE;IAC3B,MAAM,WAAW,GAAG,6BAA6B,EAAE,CAAC;IACpD,OAAO,CACL,KAAC,eAAe,OAAK,WAAW,YAC9B,KAAC,YAAY,OACP,KAAK,EACT,YAAY,EAAE,IAAI,+BAA+B,EAAE,YAEnD,KAAC,aAAa,cACZ,KAAC,mBAAmB,cAAE,QAAQ,GAAuB,GACvC,GACH,GACC,CACnB,CAAC;AACJ,CAAC,CAAC;AACF,MAAM,iBAAiB,GAAG,CAAC,EAAE,QAAQ,EAAE,GAAG,KAAK,EAA0B,EAAE,EAAE;IAC3E,OAAO,CACL,KAAC,uBAAuB,IACtB,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EACvC,QAAQ,EAAE,KAAK,EAAE,QAAQ,EACzB,WAAW,EAAE,KAAK,EAAE,WAAW,EAC/B,KAAK,EAAE,KAAK,EAAE,KAAK,EACnB,iBAAiB,EAAE,KAAK,EAAE,iBAAiB,EAC3C,WAAW,EAAE,KAAK,EAAE,WAAW,YAE/B,KAAC,kBAAkB,cACjB,KAAC,cAAc,IAAC,UAAU,EAAE,KAAK,CAAC,UAAU,YAC1C,KAAC,kCAAkC,cACjC,KAAC,0BAA0B,OAAK,KAAK,YAClC,QAAQ,GACkB,GACM,GACtB,GACE,GACG,CAC3B,CAAC;AACJ,CAAC,CAAC;AAEF,OAAO,EAAE,iBAAiB,EAA+B,CAAC","sourcesContent":["\"use client\";\nimport React, { useMemo } from \"react\";\nimport { AuthProvider } from \"@/reactjs/providers/AuthProvider.js\";\nimport { BrowserPublicClientPKCEProducer } from \"@/services/PKCE.js\";\nimport { UserProvider } from \"@/shared/providers/UserProvider.js\";\nimport { LocalStorageAdapter } from \"@/browser/storage.js\";\nimport { CivicAuthConfigProvider } from \"@/shared/providers/CivicAuthConfigContext.js\";\nimport { IframeProvider } from \"@/shared/providers/IframeProvider.js\";\nimport { ClientTokenExchangeSessionProvider } from \"@/reactjs/providers/ClientTokenExchangeSessionProvider.js\";\nimport { SessionProvider } from \"@/shared/providers/SessionProvider.js\";\nimport { useClientTokenExchangeSession } from \"@/reactjs/hooks/useClientTokenExchangeSession.js\";\nimport { TokenProvider } from \"@/shared/providers/TokenProvider.js\";\nimport { useAuth } from \"@/shared/hooks/useAuth.js\";\nimport type { AuthProviderProps } from \"@/shared/providers/types.js\";\nimport { AuthStatusProvider } from \"@/shared/providers/AuthStatusContext.js\";\n\ntype CivicAuthProviderProps = Omit<AuthProviderProps, \"pkceConsumer\">;\n\nconst WrapperUserProvider = ({ children }: { children: React.ReactNode }) => {\n const { signIn, signOut, displayMode, authStatus } = useAuth();\n\n const storage = useMemo(() => new LocalStorageAdapter(), []);\n\n return (\n <UserProvider\n storage={storage}\n signIn={signIn}\n signOut={signOut}\n user={null}\n authStatus={authStatus}\n displayMode={displayMode}\n >\n {children}\n </UserProvider>\n );\n};\nconst WrapperSessionAuthProvider = ({\n children,\n ...props\n}: CivicAuthProviderProps) => {\n const sessionData = useClientTokenExchangeSession();\n return (\n <SessionProvider {...sessionData}>\n <AuthProvider\n {...props}\n pkceConsumer={new BrowserPublicClientPKCEProducer()}\n >\n <TokenProvider>\n <WrapperUserProvider>{children}</WrapperUserProvider>\n </TokenProvider>\n </AuthProvider>\n </SessionProvider>\n );\n};\nconst CivicAuthProvider = ({ children, ...props }: CivicAuthProviderProps) => {\n return (\n <CivicAuthConfigProvider\n oauthServer={props?.config?.oauthServer}\n clientId={props?.clientId}\n redirectUrl={props?.redirectUrl}\n nonce={props?.nonce}\n logoutRedirectUrl={props?.logoutRedirectUrl}\n displayMode={props?.displayMode}\n >\n <AuthStatusProvider>\n <IframeProvider iframeMode={props.iframeMode}>\n <ClientTokenExchangeSessionProvider>\n <WrapperSessionAuthProvider {...props}>\n {children}\n </WrapperSessionAuthProvider>\n </ClientTokenExchangeSessionProvider>\n </IframeProvider>\n </AuthStatusProvider>\n </CivicAuthConfigProvider>\n );\n};\n\nexport { CivicAuthProvider, type CivicAuthProviderProps };\n"]}
|
|
@@ -1,23 +1,18 @@
|
|
|
1
|
-
import { AuthStatus, type
|
|
1
|
+
import { AuthStatus, type DisplayMode } from "../../types.js";
|
|
2
2
|
import { type PKCEConsumer } from "../../services/types.js";
|
|
3
3
|
type SignInProps = {
|
|
4
4
|
pkceConsumer?: PKCEConsumer;
|
|
5
5
|
preSignOut?: () => Promise<void>;
|
|
6
6
|
postSignOut?: () => Promise<void>;
|
|
7
7
|
displayMode: DisplayMode;
|
|
8
|
-
storage?: AuthStorage;
|
|
9
|
-
};
|
|
10
|
-
type SignInResult = {
|
|
11
|
-
user: User | null;
|
|
12
|
-
error: Error | null;
|
|
13
8
|
};
|
|
14
9
|
/**
|
|
15
10
|
* Hook to manage authentication flow.
|
|
16
11
|
*/
|
|
17
|
-
declare const useSignIn: ({ pkceConsumer, preSignOut, postSignOut, displayMode
|
|
18
|
-
signIn: () => Promise<
|
|
12
|
+
declare const useSignIn: ({ pkceConsumer, preSignOut, postSignOut, displayMode }?: SignInProps) => {
|
|
13
|
+
signIn: () => Promise<void>;
|
|
19
14
|
signOut: () => Promise<void>;
|
|
20
|
-
startSignIn: () => Promise<
|
|
15
|
+
startSignIn: () => Promise<void>;
|
|
21
16
|
authStatus: AuthStatus;
|
|
22
17
|
displayMode: DisplayMode;
|
|
23
18
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useSignIn.d.ts","sourceRoot":"","sources":["../../../src/shared/hooks/useSignIn.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,UAAU,EACV,KAAK,WAAW,
|
|
1
|
+
{"version":3,"file":"useSignIn.d.ts","sourceRoot":"","sources":["../../../src/shared/hooks/useSignIn.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,UAAU,EACV,KAAK,WAAW,EAEjB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAc,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAQpE,KAAK,WAAW,GAAG;IACjB,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,WAAW,EAAE,WAAW,CAAC;CAC1B,CAAC;AAcF;;GAEG;AACH,QAAA,MAAM,SAAS,4DAC2C,WAAW;kBA+P9B,OAAO,CAAC,IAAI,CAAC;;uBAxGR,OAAO,CAAC,IAAI,CAAC;;;CAoSxD,CAAC;AAEF,OAAO,EAAE,SAAS,EAAE,CAAC"}
|
|
@@ -8,7 +8,6 @@ import { PopupError } from "../../services/types.js";
|
|
|
8
8
|
import { useSession } from "./useSession.js";
|
|
9
9
|
import { LocalStorageAdapter } from "../../browser/storage.js";
|
|
10
10
|
import { clearTokens, clearUser } from "../lib/util.js";
|
|
11
|
-
import { getUser } from "../../shared/lib/session.js";
|
|
12
11
|
import { useLocalStorage } from "usehooks-ts";
|
|
13
12
|
import { LOGOUT_STATE } from "../../constants.js";
|
|
14
13
|
import { useAuthStatus } from "../../shared/providers/AuthStatusContext.js";
|
|
@@ -16,7 +15,7 @@ const SIGN_IN_TIMEOUT_MS = 9 * 60 * 1000; // 9 minutes in milliseconds
|
|
|
16
15
|
/**
|
|
17
16
|
* Hook to manage authentication flow.
|
|
18
17
|
*/
|
|
19
|
-
const useSignIn = ({ pkceConsumer, preSignOut, postSignOut, displayMode
|
|
18
|
+
const useSignIn = ({ pkceConsumer, preSignOut, postSignOut, displayMode } = {
|
|
20
19
|
displayMode: "iframe",
|
|
21
20
|
}) => {
|
|
22
21
|
// Config and external state
|
|
@@ -32,42 +31,35 @@ const useSignIn = ({ pkceConsumer, preSignOut, postSignOut, displayMode, storage
|
|
|
32
31
|
// Promise handling
|
|
33
32
|
const signInPromiseRef = useRef();
|
|
34
33
|
const signInResolveRef = useRef(null);
|
|
34
|
+
const signInRejectRef = useRef(null);
|
|
35
35
|
// Event handlers
|
|
36
36
|
const handlersRef = useRef({
|
|
37
37
|
handleSignInComplete: null,
|
|
38
38
|
handleSignInError: null,
|
|
39
39
|
});
|
|
40
|
-
// Helper to resolve sign-in promise with
|
|
41
|
-
const
|
|
40
|
+
// Helper to resolve/reject sign-in promise with cleanup
|
|
41
|
+
const resolveSignInPromise = useCallback(() => {
|
|
42
42
|
if (signInResolveRef.current) {
|
|
43
43
|
setAuthStatus(AuthStatus.AUTHENTICATED);
|
|
44
44
|
authStatusRef.current = AuthStatus.AUTHENTICATED;
|
|
45
45
|
isSigningInRef.current = false;
|
|
46
|
-
|
|
47
|
-
let user = null;
|
|
48
|
-
try {
|
|
49
|
-
user = await getUser(storage || new LocalStorageAdapter());
|
|
50
|
-
}
|
|
51
|
-
catch (error) {
|
|
52
|
-
console.warn("Failed to retrieve user data after successful sign-in:", error);
|
|
53
|
-
}
|
|
54
|
-
signInResolveRef.current({ user, error: null });
|
|
46
|
+
signInResolveRef.current();
|
|
55
47
|
// Clean up after resolving
|
|
56
48
|
signInResolveRef.current = null;
|
|
49
|
+
signInRejectRef.current = null;
|
|
57
50
|
signInPromiseRef.current = undefined;
|
|
58
51
|
if (timeoutRef.current !== null) {
|
|
59
52
|
window.clearTimeout(timeoutRef.current);
|
|
60
53
|
timeoutRef.current = null;
|
|
61
54
|
}
|
|
62
55
|
}
|
|
63
|
-
}, [setAuthStatus
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
//
|
|
68
|
-
signInResolveRef.current({ user: null, error });
|
|
69
|
-
// Clean up after resolving
|
|
56
|
+
}, [setAuthStatus]);
|
|
57
|
+
const rejectSignInPromise = useCallback((error, newStatus = AuthStatus.ERROR) => {
|
|
58
|
+
if (signInRejectRef.current) {
|
|
59
|
+
signInRejectRef.current(error);
|
|
60
|
+
// Clean up after rejecting
|
|
70
61
|
signInResolveRef.current = null;
|
|
62
|
+
signInRejectRef.current = null;
|
|
71
63
|
signInPromiseRef.current = undefined;
|
|
72
64
|
isSigningInRef.current = false;
|
|
73
65
|
setAuthStatus(newStatus);
|
|
@@ -129,51 +121,31 @@ const useSignIn = ({ pkceConsumer, preSignOut, postSignOut, displayMode, storage
|
|
|
129
121
|
// Main sign-in logic
|
|
130
122
|
const startSignIn = useCallback(async () => {
|
|
131
123
|
if (!authInitiator)
|
|
132
|
-
return
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
124
|
+
return;
|
|
125
|
+
// Create the promise and store its handlers
|
|
126
|
+
const promise = new Promise((resolve, reject) => {
|
|
127
|
+
signInResolveRef.current = resolve;
|
|
128
|
+
signInRejectRef.current = reject;
|
|
129
|
+
});
|
|
130
|
+
signInPromiseRef.current = promise;
|
|
131
|
+
// Check if sign-in is already in progress using the ref, if so, return signIn promise
|
|
132
|
+
if (isSigningInRef.current) {
|
|
133
|
+
return promise;
|
|
139
134
|
}
|
|
140
|
-
// State machine for sign-in flow
|
|
135
|
+
// State machine for sign-in flow
|
|
141
136
|
switch (authStatus) {
|
|
142
|
-
case AuthStatus.AUTHENTICATED:
|
|
143
|
-
|
|
144
|
-
const currentStorage = storage || new LocalStorageAdapter();
|
|
145
|
-
try {
|
|
146
|
-
const user = await getUser(currentStorage);
|
|
147
|
-
return { user, error: null };
|
|
148
|
-
}
|
|
149
|
-
catch (error) {
|
|
150
|
-
return {
|
|
151
|
-
user: null,
|
|
152
|
-
error: error instanceof Error ? error : new Error(String(error)),
|
|
153
|
-
};
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
case AuthStatus.AUTHENTICATING:
|
|
157
|
-
// if we're already authenticating, return the existing promise if it exists
|
|
158
|
-
if (signInPromiseRef.current) {
|
|
159
|
-
return signInPromiseRef.current;
|
|
160
|
-
}
|
|
161
|
-
break;
|
|
137
|
+
case AuthStatus.AUTHENTICATED:
|
|
138
|
+
return Promise.resolve();
|
|
162
139
|
case AuthStatus.UNAUTHENTICATED:
|
|
163
140
|
case AuthStatus.ERROR:
|
|
164
141
|
break;
|
|
142
|
+
case AuthStatus.AUTHENTICATING:
|
|
143
|
+
// if we're already authenticating, return the existing promise
|
|
144
|
+
return promise;
|
|
165
145
|
default:
|
|
166
|
-
return {
|
|
167
|
-
user: null,
|
|
168
|
-
error: new Error(`Invalid state for sign-in: ${authStatus}`),
|
|
169
|
-
};
|
|
146
|
+
return Promise.reject(new Error(`Invalid state for sign-in: ${authStatus}`));
|
|
170
147
|
}
|
|
171
|
-
//
|
|
172
|
-
const promise = new Promise((resolve) => {
|
|
173
|
-
signInResolveRef.current = resolve;
|
|
174
|
-
});
|
|
175
|
-
signInPromiseRef.current = promise;
|
|
176
|
-
// Set signing in flag
|
|
148
|
+
// Set signing in flag first
|
|
177
149
|
isSigningInRef.current = true;
|
|
178
150
|
// Clear any existing timeout
|
|
179
151
|
if (timeoutRef.current !== null) {
|
|
@@ -185,10 +157,10 @@ const useSignIn = ({ pkceConsumer, preSignOut, postSignOut, displayMode, storage
|
|
|
185
157
|
setAuthStatus(AuthStatus.AUTHENTICATING);
|
|
186
158
|
authStatusRef.current = AuthStatus.AUTHENTICATING;
|
|
187
159
|
authInitiator.setDisplayMode(displayMode);
|
|
188
|
-
// Set a timeout to
|
|
160
|
+
// Set a timeout to reject the promise if authentication takes too long
|
|
189
161
|
timeoutRef.current = window.setTimeout(() => {
|
|
190
162
|
if (authStatusRef.current === AuthStatus.AUTHENTICATING) {
|
|
191
|
-
|
|
163
|
+
rejectSignInPromise(new Error("Sign-in timeout"));
|
|
192
164
|
}
|
|
193
165
|
}, SIGN_IN_TIMEOUT_MS);
|
|
194
166
|
// Start the authentication process
|
|
@@ -209,14 +181,14 @@ const useSignIn = ({ pkceConsumer, preSignOut, postSignOut, displayMode, storage
|
|
|
209
181
|
}
|
|
210
182
|
catch (retryError) {
|
|
211
183
|
console.error("[useSignIn] Redirect sign-in initiation error", retryError);
|
|
212
|
-
|
|
184
|
+
rejectSignInPromise(retryError instanceof Error
|
|
213
185
|
? retryError
|
|
214
186
|
: new Error(String(retryError)));
|
|
215
187
|
return promise;
|
|
216
188
|
}
|
|
217
189
|
}
|
|
218
190
|
else {
|
|
219
|
-
|
|
191
|
+
rejectSignInPromise(error instanceof Error ? error : new Error(String(error)));
|
|
220
192
|
return promise;
|
|
221
193
|
}
|
|
222
194
|
}
|
|
@@ -228,8 +200,7 @@ const useSignIn = ({ pkceConsumer, preSignOut, postSignOut, displayMode, storage
|
|
|
228
200
|
setIframeIsVisible,
|
|
229
201
|
authStatus,
|
|
230
202
|
setAuthStatus,
|
|
231
|
-
|
|
232
|
-
storage,
|
|
203
|
+
rejectSignInPromise,
|
|
233
204
|
]);
|
|
234
205
|
// Public sign-in method
|
|
235
206
|
const signIn = useCallback(async () => {
|
|
@@ -287,13 +258,13 @@ const useSignIn = ({ pkceConsumer, preSignOut, postSignOut, displayMode, storage
|
|
|
287
258
|
handlersRef.current = {
|
|
288
259
|
handleSignInComplete: () => {
|
|
289
260
|
if (authStatusRef.current === AuthStatus.AUTHENTICATING) {
|
|
290
|
-
|
|
261
|
+
resolveSignInPromise();
|
|
291
262
|
}
|
|
292
263
|
},
|
|
293
264
|
handleSignInError: (event) => {
|
|
294
265
|
if (authStatusRef.current === AuthStatus.AUTHENTICATING) {
|
|
295
266
|
const error = event.detail.error;
|
|
296
|
-
|
|
267
|
+
rejectSignInPromise(error instanceof Error
|
|
297
268
|
? error
|
|
298
269
|
: new Error(error.message || "Sign-in failed"));
|
|
299
270
|
}
|
|
@@ -321,11 +292,7 @@ const useSignIn = ({ pkceConsumer, preSignOut, postSignOut, displayMode, storage
|
|
|
321
292
|
LocalStorageAdapter.emitter.off("civic-auth-signin-error", handlersRef.current.handleSignInError);
|
|
322
293
|
}
|
|
323
294
|
};
|
|
324
|
-
}, [
|
|
325
|
-
authStatus,
|
|
326
|
-
resolveSignInPromiseWithSuccess,
|
|
327
|
-
resolveSignInPromiseWithError,
|
|
328
|
-
]);
|
|
295
|
+
}, [authStatus, resolveSignInPromise, rejectSignInPromise]);
|
|
329
296
|
// Effect to handle session updates and iframe aborts
|
|
330
297
|
useEffect(() => {
|
|
331
298
|
// If session becomes authenticated, update state and resolve pending promises
|
|
@@ -335,14 +302,14 @@ const useSignIn = ({ pkceConsumer, preSignOut, postSignOut, displayMode, storage
|
|
|
335
302
|
// If we have a pending sign-in promise, resolve it
|
|
336
303
|
if (authStatusRef.current === AuthStatus.AUTHENTICATING &&
|
|
337
304
|
signInResolveRef.current) {
|
|
338
|
-
|
|
305
|
+
resolveSignInPromise();
|
|
339
306
|
}
|
|
340
307
|
}
|
|
341
308
|
// Handle iframe abortion
|
|
342
309
|
if (displayMode === "iframe" && iframeAborted) {
|
|
343
310
|
setIframeAborted(false);
|
|
344
311
|
if (authStatusRef.current === AuthStatus.AUTHENTICATING) {
|
|
345
|
-
|
|
312
|
+
rejectSignInPromise(new Error("Sign-in aborted by user"), AuthStatus.UNAUTHENTICATED);
|
|
346
313
|
}
|
|
347
314
|
}
|
|
348
315
|
// Update unauthenticated state when session is absent
|
|
@@ -357,8 +324,8 @@ const useSignIn = ({ pkceConsumer, preSignOut, postSignOut, displayMode, storage
|
|
|
357
324
|
iframeAborted,
|
|
358
325
|
session?.authenticated,
|
|
359
326
|
setIframeAborted,
|
|
360
|
-
|
|
361
|
-
|
|
327
|
+
resolveSignInPromise,
|
|
328
|
+
rejectSignInPromise,
|
|
362
329
|
setAuthStatus,
|
|
363
330
|
]);
|
|
364
331
|
// Handle logout completion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useSignIn.js","sourceRoot":"","sources":["../../../src/shared/hooks/useSignIn.ts"],"names":[],"mappings":"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","sourcesContent":["import { BrowserAuthenticationInitiator } from \"@/services/AuthenticationService.js\";\nimport { BrowserPublicClientPKCEProducer } from \"@/services/PKCE.js\";\nimport { useCivicAuthConfig } from \"@/shared/hooks/useCivicAuthConfig.js\";\nimport {\n AuthStatus,\n type AuthStorage,\n type DisplayMode,\n type LoginAppDesignOptions,\n type User,\n} from \"@/types.js\";\nimport { useIframe } from \"@/shared/hooks/useIframe.js\";\nimport { useCallback, useEffect, useMemo, useRef } from \"react\";\nimport { PopupError, type PKCEConsumer } from \"@/services/types.js\";\nimport { useSession } from \"./useSession.js\";\nimport { LocalStorageAdapter } from \"@/browser/storage.js\";\nimport { clearTokens, clearUser } from \"../lib/util.js\";\nimport { getUser } from \"@/shared/lib/session.js\";\nimport { useLocalStorage } from \"usehooks-ts\";\nimport { LOGOUT_STATE } from \"@/constants.js\";\nimport { useAuthStatus } from \"@/shared/providers/AuthStatusContext.js\";\n\ntype SignInProps = {\n pkceConsumer?: PKCEConsumer;\n preSignOut?: () => Promise<void>;\n postSignOut?: () => Promise<void>;\n displayMode: DisplayMode;\n storage?: AuthStorage; // Optional storage parameter\n};\n\ntype SignInError = Error | { message: string; [key: string]: unknown };\n\ninterface SignInEventDetail {\n error: SignInError;\n}\n\ninterface SignInErrorEvent {\n detail: SignInEventDetail;\n}\n\ntype SignInResult = {\n user: User | null;\n error: Error | null;\n};\n\nconst SIGN_IN_TIMEOUT_MS = 9 * 60 * 1000; // 9 minutes in milliseconds\n\n/**\n * Hook to manage authentication flow.\n */\nconst useSignIn = (\n {\n pkceConsumer,\n preSignOut,\n postSignOut,\n displayMode,\n storage,\n }: SignInProps = {\n displayMode: \"iframe\",\n },\n) => {\n // Config and external state\n const civicAuthConfig = useCivicAuthConfig();\n const {\n iframeRef,\n logoutIframeRef,\n setIframeIsVisible,\n setLogoutIframeIsVisible,\n iframeAborted,\n setIframeAborted,\n } = useIframe();\n const { data: session } = useSession();\n const { authStatus, setAuthStatus } = useAuthStatus();\n const [, setDesignOption] = useLocalStorage<LoginAppDesignOptions>(\n `loginAppDesign`,\n { colorMode: \"auto\" },\n );\n\n // Internal state tracking\n const timeoutRef = useRef<number | null>(null);\n const authStatusRef = useRef<AuthStatus>(AuthStatus.UNAUTHENTICATED);\n const isSigningInRef = useRef<boolean>(false);\n\n // Promise handling\n const signInPromiseRef = useRef<Promise<SignInResult>>();\n const signInResolveRef = useRef<\n ((value: SignInResult | PromiseLike<SignInResult>) => void) | null\n >(null);\n\n // Event handlers\n const handlersRef = useRef<{\n handleSignInComplete: (() => void) | null;\n handleSignInError: ((event: SignInErrorEvent) => void) | null;\n }>({\n handleSignInComplete: null,\n handleSignInError: null,\n });\n\n // Helper to resolve sign-in promise with success\n const resolveSignInPromiseWithSuccess = useCallback(async () => {\n if (signInResolveRef.current) {\n setAuthStatus(AuthStatus.AUTHENTICATED);\n authStatusRef.current = AuthStatus.AUTHENTICATED;\n isSigningInRef.current = false;\n\n // Get user data from storage\n let user: User | null = null;\n try {\n user = await getUser(storage || new LocalStorageAdapter());\n } catch (error) {\n console.warn(\n \"Failed to retrieve user data after successful sign-in:\",\n error,\n );\n }\n\n signInResolveRef.current({ user, error: null });\n\n // Clean up after resolving\n signInResolveRef.current = null;\n signInPromiseRef.current = undefined;\n\n if (timeoutRef.current !== null) {\n window.clearTimeout(timeoutRef.current);\n timeoutRef.current = null;\n }\n }\n }, [setAuthStatus, storage]);\n\n // Helper to resolve sign-in promise with error\n const resolveSignInPromiseWithError = useCallback(\n (error: Error, newStatus: AuthStatus = AuthStatus.ERROR) => {\n if (signInResolveRef.current) {\n // Always resolve, but with error set and user as null\n signInResolveRef.current({ user: null, error });\n\n // Clean up after resolving\n signInResolveRef.current = null;\n signInPromiseRef.current = undefined;\n isSigningInRef.current = false;\n setAuthStatus(newStatus);\n\n if (timeoutRef.current !== null) {\n window.clearTimeout(timeoutRef.current);\n timeoutRef.current = null;\n }\n }\n },\n [setAuthStatus],\n );\n\n // Create authentication initiator\n const authInitiator = useMemo(() => {\n if (!civicAuthConfig) return null;\n\n const {\n clientId,\n redirectUrl,\n logoutUrl,\n loginSuccessUrl,\n logoutRedirectUrl,\n nonce,\n oauthServer,\n endpoints,\n scopes,\n } = civicAuthConfig;\n\n return new BrowserAuthenticationInitiator(\n {\n pkceConsumer: pkceConsumer || new BrowserPublicClientPKCEProducer(),\n clientId,\n redirectUrl,\n loginSuccessUrl,\n logoutUrl,\n logoutRedirectUrl,\n scopes,\n displayMode,\n oauthServer,\n endpointOverrides: endpoints,\n nonce,\n },\n setDesignOption,\n );\n }, [civicAuthConfig, displayMode, pkceConsumer, setDesignOption]);\n\n // Cleanup resources when component unmounts\n useEffect(() => {\n return () => {\n if (authInitiator) {\n authInitiator.cleanup();\n }\n if (timeoutRef.current !== null) {\n window.clearTimeout(timeoutRef.current);\n timeoutRef.current = null;\n }\n };\n }, [authInitiator]);\n\n // Handle logout state cleanup\n useEffect(() => {\n const params = new URLSearchParams(window.location.search);\n const state = params.get(\"state\");\n const localStorage = new LocalStorageAdapter();\n localStorage.get(LOGOUT_STATE).then((storedLogoutState) => {\n if (state && state === storedLogoutState) {\n // Clear storage\n clearTokens(localStorage);\n clearUser(localStorage);\n LocalStorageAdapter.emitter.emit(\"signOut\");\n\n // Clean up storage and URL\n sessionStorage.removeItem(LOGOUT_STATE);\n const cleanUrl = window.location.href.split(\"?\")[0];\n window.history.replaceState({}, document.title, cleanUrl);\n }\n });\n }, []);\n\n // Main sign-in logic\n const startSignIn = useCallback(async (): Promise<SignInResult> => {\n if (!authInitiator)\n return {\n user: null,\n error: new Error(\"Authentication initiator not available\"),\n };\n\n // Check if sign-in is already in progress using the ref, if so, return existing promise\n if (isSigningInRef.current && signInPromiseRef.current) {\n return signInPromiseRef.current;\n }\n\n // State machine for sign-in flow - check early states before creating promise\n switch (authStatus) {\n case AuthStatus.AUTHENTICATED: {\n // Get current user if already authenticated\n const currentStorage = storage || new LocalStorageAdapter();\n try {\n const user = await getUser(currentStorage);\n return { user, error: null };\n } catch (error) {\n return {\n user: null,\n error: error instanceof Error ? error : new Error(String(error)),\n };\n }\n }\n\n case AuthStatus.AUTHENTICATING:\n // if we're already authenticating, return the existing promise if it exists\n if (signInPromiseRef.current) {\n return signInPromiseRef.current;\n }\n break;\n\n case AuthStatus.UNAUTHENTICATED:\n case AuthStatus.ERROR:\n break;\n\n default:\n return {\n user: null,\n error: new Error(`Invalid state for sign-in: ${authStatus}`),\n };\n }\n\n // Create the promise and store its handlers ONLY if we're starting a new sign-in\n const promise = new Promise<SignInResult>((resolve) => {\n signInResolveRef.current = resolve;\n });\n signInPromiseRef.current = promise;\n\n // Set signing in flag\n isSigningInRef.current = true;\n\n // Clear any existing timeout\n if (timeoutRef.current !== null) {\n window.clearTimeout(timeoutRef.current);\n timeoutRef.current = null;\n }\n\n try {\n // Set authenticating status before any async operations\n setAuthStatus(AuthStatus.AUTHENTICATING);\n authStatusRef.current = AuthStatus.AUTHENTICATING;\n authInitiator.setDisplayMode(displayMode);\n\n // Set a timeout to resolve the promise with error if authentication takes too long\n timeoutRef.current = window.setTimeout(() => {\n if (authStatusRef.current === AuthStatus.AUTHENTICATING) {\n resolveSignInPromiseWithError(new Error(\"Sign-in timeout\"));\n }\n }, SIGN_IN_TIMEOUT_MS);\n\n // Start the authentication process\n const useIframeRef = iframeRef?.current || null;\n\n await authInitiator.signIn(useIframeRef);\n } catch (error) {\n // Reset the signing in flag on error\n isSigningInRef.current = false;\n\n if (error instanceof PopupError) {\n // Fallback to redirect if popup fails\n setIframeIsVisible(false);\n authInitiator.cleanup();\n authInitiator.setDisplayMode(\"redirect\");\n try {\n // Call signIn again with redirect mode\n await authInitiator.signIn(iframeRef?.current || null);\n } catch (retryError) {\n console.error(\n \"[useSignIn] Redirect sign-in initiation error\",\n retryError,\n );\n resolveSignInPromiseWithError(\n retryError instanceof Error\n ? retryError\n : new Error(String(retryError)),\n );\n return promise;\n }\n } else {\n resolveSignInPromiseWithError(\n error instanceof Error ? error : new Error(String(error)),\n );\n return promise;\n }\n }\n\n return promise;\n }, [\n authInitiator,\n displayMode,\n iframeRef,\n setIframeIsVisible,\n authStatus,\n setAuthStatus,\n resolveSignInPromiseWithError,\n storage,\n ]);\n\n // Public sign-in method\n const signIn = useCallback(async (): Promise<SignInResult> => {\n if (displayMode === \"iframe\") {\n setIframeIsVisible(true);\n }\n return startSignIn();\n }, [startSignIn, displayMode, setIframeIsVisible]);\n\n // Sign-out method\n const signOut = useCallback(async () => {\n const idToken = session?.idToken;\n if (!authInitiator) return;\n\n setAuthStatus(AuthStatus.SIGNING_OUT);\n if (displayMode === \"iframe\") {\n setIframeIsVisible(false);\n setLogoutIframeIsVisible(true);\n }\n\n try {\n await preSignOut?.();\n\n const useIframeRef = logoutIframeRef?.current || null;\n await authInitiator.signOut(idToken, useIframeRef).catch((error) => {\n setAuthStatus(AuthStatus.ERROR);\n console.error(\"signOut error\", {\n error,\n isPopupError: error instanceof PopupError,\n });\n\n if (error instanceof PopupError) {\n setLogoutIframeIsVisible(false);\n authInitiator.cleanup();\n authInitiator.setDisplayMode(\"redirect\");\n authInitiator.signOut(idToken, useIframeRef); // Retry sign out\n }\n });\n } catch (error) {\n console.error(\"Signout error:\", error);\n setAuthStatus(AuthStatus.ERROR);\n }\n }, [\n session?.idToken,\n authInitiator,\n displayMode,\n setLogoutIframeIsVisible,\n setIframeIsVisible,\n preSignOut,\n logoutIframeRef,\n setAuthStatus,\n ]);\n\n // Set up event listeners for authentication status\n useEffect(() => {\n // Update the ref with current auth status\n authStatusRef.current = authStatus;\n\n // Define handlers\n handlersRef.current = {\n handleSignInComplete: () => {\n if (authStatusRef.current === AuthStatus.AUTHENTICATING) {\n resolveSignInPromiseWithSuccess();\n }\n },\n handleSignInError: (event: SignInErrorEvent) => {\n if (authStatusRef.current === AuthStatus.AUTHENTICATING) {\n const error = event.detail.error;\n resolveSignInPromiseWithError(\n error instanceof Error\n ? error\n : new Error(error.message || \"Sign-in failed\"),\n );\n }\n },\n };\n\n // Add listeners only when in authenticating state\n if (\n authStatus === AuthStatus.AUTHENTICATING &&\n handlersRef.current.handleSignInComplete &&\n handlersRef.current.handleSignInError\n ) {\n LocalStorageAdapter.emitter.on(\n \"civic-auth-signin-complete\",\n handlersRef.current.handleSignInComplete,\n );\n LocalStorageAdapter.emitter.on(\n \"civic-auth-signin-error\",\n handlersRef.current.handleSignInError,\n );\n } else if (\n authStatus !== AuthStatus.AUTHENTICATING &&\n timeoutRef.current !== null\n ) {\n // Clean up timeout when not in authenticating state\n window.clearTimeout(timeoutRef.current);\n timeoutRef.current = null;\n }\n\n // Cleanup listeners\n return () => {\n if (handlersRef.current.handleSignInComplete) {\n LocalStorageAdapter.emitter.off(\n \"civic-auth-signin-complete\",\n handlersRef.current.handleSignInComplete,\n );\n }\n if (handlersRef.current.handleSignInError) {\n LocalStorageAdapter.emitter.off(\n \"civic-auth-signin-error\",\n handlersRef.current.handleSignInError,\n );\n }\n };\n }, [\n authStatus,\n resolveSignInPromiseWithSuccess,\n resolveSignInPromiseWithError,\n ]);\n\n // Effect to handle session updates and iframe aborts\n useEffect(() => {\n // If session becomes authenticated, update state and resolve pending promises\n if (\n session?.authenticated &&\n authStatusRef.current !== AuthStatus.AUTHENTICATED\n ) {\n setAuthStatus(AuthStatus.AUTHENTICATED);\n\n // If we have a pending sign-in promise, resolve it\n if (\n authStatusRef.current === AuthStatus.AUTHENTICATING &&\n signInResolveRef.current\n ) {\n resolveSignInPromiseWithSuccess();\n }\n }\n\n // Handle iframe abortion\n if (displayMode === \"iframe\" && iframeAborted) {\n setIframeAborted(false);\n if (authStatusRef.current === AuthStatus.AUTHENTICATING) {\n resolveSignInPromiseWithError(\n new Error(\"Sign-in aborted by user\"),\n AuthStatus.UNAUTHENTICATED,\n );\n }\n }\n\n // Update unauthenticated state when session is absent\n if (\n !session?.authenticated &&\n ![AuthStatus.AUTHENTICATING, AuthStatus.SIGNING_OUT].includes(\n authStatusRef.current,\n )\n ) {\n if (authStatusRef.current !== AuthStatus.UNAUTHENTICATED) {\n setAuthStatus(AuthStatus.UNAUTHENTICATED);\n }\n }\n }, [\n displayMode,\n iframeAborted,\n session?.authenticated,\n setIframeAborted,\n resolveSignInPromiseWithSuccess,\n resolveSignInPromiseWithError,\n setAuthStatus,\n ]);\n\n // Handle logout completion\n useEffect(() => {\n if (authStatus === AuthStatus.SIGNING_OUT && !session?.authenticated) {\n setAuthStatus(AuthStatus.UNAUTHENTICATED);\n postSignOut?.().then(() => {\n setLogoutIframeIsVisible(false);\n });\n }\n }, [\n session,\n postSignOut,\n setLogoutIframeIsVisible,\n authStatus,\n setAuthStatus,\n ]);\n\n return {\n signIn,\n signOut,\n startSignIn,\n authStatus,\n displayMode,\n };\n};\n\nexport { useSignIn };\n"]}
|
|
1
|
+
{"version":3,"file":"useSignIn.js","sourceRoot":"","sources":["../../../src/shared/hooks/useSignIn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,8BAA8B,EAAE,MAAM,qCAAqC,CAAC;AACrF,OAAO,EAAE,+BAA+B,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAC1E,OAAO,EACL,UAAU,GAGX,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAChE,OAAO,EAAE,UAAU,EAAqB,MAAM,qBAAqB,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAmBxE,MAAM,kBAAkB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,4BAA4B;AAEtE;;GAEG;AACH,MAAM,SAAS,GAAG,CAChB,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,KAAkB;IACpE,WAAW,EAAE,QAAQ;CACtB,EACD,EAAE;IACF,4BAA4B;IAC5B,MAAM,eAAe,GAAG,kBAAkB,EAAE,CAAC;IAC7C,MAAM,EACJ,SAAS,EACT,eAAe,EACf,kBAAkB,EAClB,wBAAwB,EACxB,aAAa,EACb,gBAAgB,GACjB,GAAG,SAAS,EAAE,CAAC;IAChB,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,UAAU,EAAE,CAAC;IACvC,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,GAAG,aAAa,EAAE,CAAC;IACtD,MAAM,CAAC,EAAE,eAAe,CAAC,GAAG,eAAe,CACzC,gBAAgB,EAChB,EAAE,SAAS,EAAE,MAAM,EAAE,CACtB,CAAC;IAEF,0BAA0B;IAC1B,MAAM,UAAU,GAAG,MAAM,CAAgB,IAAI,CAAC,CAAC;IAC/C,MAAM,aAAa,GAAG,MAAM,CAAa,UAAU,CAAC,eAAe,CAAC,CAAC;IACrE,MAAM,cAAc,GAAG,MAAM,CAAU,KAAK,CAAC,CAAC;IAE9C,mBAAmB;IACnB,MAAM,gBAAgB,GAAG,MAAM,EAAiB,CAAC;IACjD,MAAM,gBAAgB,GAAG,MAAM,CAE7B,IAAI,CAAC,CAAC;IACR,MAAM,eAAe,GAAG,MAAM,CAAmC,IAAI,CAAC,CAAC;IAEvE,iBAAiB;IACjB,MAAM,WAAW,GAAG,MAAM,CAGvB;QACD,oBAAoB,EAAE,IAAI;QAC1B,iBAAiB,EAAE,IAAI;KACxB,CAAC,CAAC;IAEH,wDAAwD;IACxD,MAAM,oBAAoB,GAAG,WAAW,CAAC,GAAG,EAAE;QAC5C,IAAI,gBAAgB,CAAC,OAAO,EAAE,CAAC;YAC7B,aAAa,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;YACxC,aAAa,CAAC,OAAO,GAAG,UAAU,CAAC,aAAa,CAAC;YACjD,cAAc,CAAC,OAAO,GAAG,KAAK,CAAC;YAC/B,gBAAgB,CAAC,OAAO,EAAE,CAAC;YAE3B,2BAA2B;YAC3B,gBAAgB,CAAC,OAAO,GAAG,IAAI,CAAC;YAChC,eAAe,CAAC,OAAO,GAAG,IAAI,CAAC;YAC/B,gBAAgB,CAAC,OAAO,GAAG,SAAS,CAAC;YAErC,IAAI,UAAU,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;gBAChC,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;gBACxC,UAAU,CAAC,OAAO,GAAG,IAAI,CAAC;YAC5B,CAAC;QACH,CAAC;IACH,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC;IAEpB,MAAM,mBAAmB,GAAG,WAAW,CACrC,CAAC,KAAY,EAAE,YAAwB,UAAU,CAAC,KAAK,EAAE,EAAE;QACzD,IAAI,eAAe,CAAC,OAAO,EAAE,CAAC;YAC5B,eAAe,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAE/B,2BAA2B;YAC3B,gBAAgB,CAAC,OAAO,GAAG,IAAI,CAAC;YAChC,eAAe,CAAC,OAAO,GAAG,IAAI,CAAC;YAC/B,gBAAgB,CAAC,OAAO,GAAG,SAAS,CAAC;YACrC,cAAc,CAAC,OAAO,GAAG,KAAK,CAAC;YAC/B,aAAa,CAAC,SAAS,CAAC,CAAC;YAEzB,IAAI,UAAU,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;gBAChC,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;gBACxC,UAAU,CAAC,OAAO,GAAG,IAAI,CAAC;YAC5B,CAAC;QACH,CAAC;IACH,CAAC,EACD,CAAC,aAAa,CAAC,CAChB,CAAC;IAEF,kCAAkC;IAClC,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,EAAE;QACjC,IAAI,CAAC,eAAe;YAAE,OAAO,IAAI,CAAC;QAElC,MAAM,EACJ,QAAQ,EACR,WAAW,EACX,SAAS,EACT,eAAe,EACf,iBAAiB,EACjB,KAAK,EACL,WAAW,EACX,SAAS,EACT,MAAM,GACP,GAAG,eAAe,CAAC;QAEpB,OAAO,IAAI,8BAA8B,CACvC;YACE,YAAY,EAAE,YAAY,IAAI,IAAI,+BAA+B,EAAE;YACnE,QAAQ;YACR,WAAW;YACX,eAAe;YACf,SAAS;YACT,iBAAiB;YACjB,MAAM;YACN,WAAW;YACX,WAAW;YACX,iBAAiB,EAAE,SAAS;YAC5B,KAAK;SACN,EACD,eAAe,CAChB,CAAC;IACJ,CAAC,EAAE,CAAC,eAAe,EAAE,WAAW,EAAE,YAAY,EAAE,eAAe,CAAC,CAAC,CAAC;IAElE,4CAA4C;IAC5C,SAAS,CAAC,GAAG,EAAE;QACb,OAAO,GAAG,EAAE;YACV,IAAI,aAAa,EAAE,CAAC;gBAClB,aAAa,CAAC,OAAO,EAAE,CAAC;YAC1B,CAAC;YACD,IAAI,UAAU,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;gBAChC,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;gBACxC,UAAU,CAAC,OAAO,GAAG,IAAI,CAAC;YAC5B,CAAC;QACH,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC;IAEpB,8BAA8B;IAC9B,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC3D,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAClC,MAAM,YAAY,GAAG,IAAI,mBAAmB,EAAE,CAAC;QAC/C,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,iBAAiB,EAAE,EAAE;YACxD,IAAI,KAAK,IAAI,KAAK,KAAK,iBAAiB,EAAE,CAAC;gBACzC,gBAAgB;gBAChB,WAAW,CAAC,YAAY,CAAC,CAAC;gBAC1B,SAAS,CAAC,YAAY,CAAC,CAAC;gBACxB,mBAAmB,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBAE5C,2BAA2B;gBAC3B,cAAc,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;gBACxC,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBACpD,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,EAAE,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;YAC5D,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,qBAAqB;IACrB,MAAM,WAAW,GAAG,WAAW,CAAC,KAAK,IAAmB,EAAE;QACxD,IAAI,CAAC,aAAa;YAAE,OAAO;QAE3B,4CAA4C;QAC5C,MAAM,OAAO,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACpD,gBAAgB,CAAC,OAAO,GAAG,OAAO,CAAC;YACnC,eAAe,CAAC,OAAO,GAAG,MAAM,CAAC;QACnC,CAAC,CAAC,CAAC;QACH,gBAAgB,CAAC,OAAO,GAAG,OAAO,CAAC;QAEnC,sFAAsF;QACtF,IAAI,cAAc,CAAC,OAAO,EAAE,CAAC;YAC3B,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,iCAAiC;QACjC,QAAQ,UAAU,EAAE,CAAC;YACnB,KAAK,UAAU,CAAC,aAAa;gBAC3B,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;YAE3B,KAAK,UAAU,CAAC,eAAe,CAAC;YAChC,KAAK,UAAU,CAAC,KAAK;gBACnB,MAAM;YAER,KAAK,UAAU,CAAC,cAAc;gBAC5B,+DAA+D;gBAC/D,OAAO,OAAO,CAAC;YAEjB;gBACE,OAAO,OAAO,CAAC,MAAM,CACnB,IAAI,KAAK,CAAC,8BAA8B,UAAU,EAAE,CAAC,CACtD,CAAC;QACN,CAAC;QAED,4BAA4B;QAC5B,cAAc,CAAC,OAAO,GAAG,IAAI,CAAC;QAE9B,6BAA6B;QAC7B,IAAI,UAAU,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;YAChC,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YACxC,UAAU,CAAC,OAAO,GAAG,IAAI,CAAC;QAC5B,CAAC;QAED,IAAI,CAAC;YACH,wDAAwD;YACxD,aAAa,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;YACzC,aAAa,CAAC,OAAO,GAAG,UAAU,CAAC,cAAc,CAAC;YAClD,aAAa,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;YAE1C,uEAAuE;YACvE,UAAU,CAAC,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE;gBAC1C,IAAI,aAAa,CAAC,OAAO,KAAK,UAAU,CAAC,cAAc,EAAE,CAAC;oBACxD,mBAAmB,CAAC,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;gBACpD,CAAC;YACH,CAAC,EAAE,kBAAkB,CAAC,CAAC;YAEvB,mCAAmC;YACnC,MAAM,YAAY,GAAG,SAAS,EAAE,OAAO,IAAI,IAAI,CAAC;YAEhD,MAAM,aAAa,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAC3C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,qCAAqC;YACrC,cAAc,CAAC,OAAO,GAAG,KAAK,CAAC;YAE/B,IAAI,KAAK,YAAY,UAAU,EAAE,CAAC;gBAChC,sCAAsC;gBACtC,kBAAkB,CAAC,KAAK,CAAC,CAAC;gBAC1B,aAAa,CAAC,OAAO,EAAE,CAAC;gBACxB,aAAa,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;gBACzC,IAAI,CAAC;oBACH,uCAAuC;oBACvC,MAAM,aAAa,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,IAAI,IAAI,CAAC,CAAC;gBACzD,CAAC;gBAAC,OAAO,UAAU,EAAE,CAAC;oBACpB,OAAO,CAAC,KAAK,CACX,+CAA+C,EAC/C,UAAU,CACX,CAAC;oBACF,mBAAmB,CACjB,UAAU,YAAY,KAAK;wBACzB,CAAC,CAAC,UAAU;wBACZ,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAClC,CAAC;oBACF,OAAO,OAAO,CAAC;gBACjB,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,mBAAmB,CACjB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAC1D,CAAC;gBACF,OAAO,OAAO,CAAC;YACjB,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC,EAAE;QACD,aAAa;QACb,WAAW;QACX,SAAS;QACT,kBAAkB;QAClB,UAAU;QACV,aAAa;QACb,mBAAmB;KACpB,CAAC,CAAC;IAEH,wBAAwB;IACxB,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,IAAmB,EAAE;QACnD,IAAI,WAAW,KAAK,QAAQ,EAAE,CAAC;YAC7B,kBAAkB,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;QACD,OAAO,WAAW,EAAE,CAAC;IACvB,CAAC,EAAE,CAAC,WAAW,EAAE,WAAW,EAAE,kBAAkB,CAAC,CAAC,CAAC;IAEnD,kBAAkB;IAClB,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QACrC,MAAM,OAAO,GAAG,OAAO,EAAE,OAAO,CAAC;QACjC,IAAI,CAAC,aAAa;YAAE,OAAO;QAE3B,aAAa,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;QACtC,IAAI,WAAW,KAAK,QAAQ,EAAE,CAAC;YAC7B,kBAAkB,CAAC,KAAK,CAAC,CAAC;YAC1B,wBAAwB,CAAC,IAAI,CAAC,CAAC;QACjC,CAAC;QAED,IAAI,CAAC;YACH,MAAM,UAAU,EAAE,EAAE,CAAC;YAErB,MAAM,YAAY,GAAG,eAAe,EAAE,OAAO,IAAI,IAAI,CAAC;YACtD,MAAM,aAAa,CAAC,OAAO,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;gBACjE,aAAa,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;gBAChC,OAAO,CAAC,KAAK,CAAC,eAAe,EAAE;oBAC7B,KAAK;oBACL,YAAY,EAAE,KAAK,YAAY,UAAU;iBAC1C,CAAC,CAAC;gBAEH,IAAI,KAAK,YAAY,UAAU,EAAE,CAAC;oBAChC,wBAAwB,CAAC,KAAK,CAAC,CAAC;oBAChC,aAAa,CAAC,OAAO,EAAE,CAAC;oBACxB,aAAa,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;oBACzC,aAAa,CAAC,OAAO,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,iBAAiB;gBACjE,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;YACvC,aAAa,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAClC,CAAC;IACH,CAAC,EAAE;QACD,OAAO,EAAE,OAAO;QAChB,aAAa;QACb,WAAW;QACX,wBAAwB;QACxB,kBAAkB;QAClB,UAAU;QACV,eAAe;QACf,aAAa;KACd,CAAC,CAAC;IAEH,mDAAmD;IACnD,SAAS,CAAC,GAAG,EAAE;QACb,0CAA0C;QAC1C,aAAa,CAAC,OAAO,GAAG,UAAU,CAAC;QAEnC,kBAAkB;QAClB,WAAW,CAAC,OAAO,GAAG;YACpB,oBAAoB,EAAE,GAAG,EAAE;gBACzB,IAAI,aAAa,CAAC,OAAO,KAAK,UAAU,CAAC,cAAc,EAAE,CAAC;oBACxD,oBAAoB,EAAE,CAAC;gBACzB,CAAC;YACH,CAAC;YACD,iBAAiB,EAAE,CAAC,KAAuB,EAAE,EAAE;gBAC7C,IAAI,aAAa,CAAC,OAAO,KAAK,UAAU,CAAC,cAAc,EAAE,CAAC;oBACxD,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC;oBACjC,mBAAmB,CACjB,KAAK,YAAY,KAAK;wBACpB,CAAC,CAAC,KAAK;wBACP,CAAC,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,IAAI,gBAAgB,CAAC,CACjD,CAAC;gBACJ,CAAC;YACH,CAAC;SACF,CAAC;QAEF,kDAAkD;QAClD,IACE,UAAU,KAAK,UAAU,CAAC,cAAc;YACxC,WAAW,CAAC,OAAO,CAAC,oBAAoB;YACxC,WAAW,CAAC,OAAO,CAAC,iBAAiB,EACrC,CAAC;YACD,mBAAmB,CAAC,OAAO,CAAC,EAAE,CAC5B,4BAA4B,EAC5B,WAAW,CAAC,OAAO,CAAC,oBAAoB,CACzC,CAAC;YACF,mBAAmB,CAAC,OAAO,CAAC,EAAE,CAC5B,yBAAyB,EACzB,WAAW,CAAC,OAAO,CAAC,iBAAiB,CACtC,CAAC;QACJ,CAAC;aAAM,IACL,UAAU,KAAK,UAAU,CAAC,cAAc;YACxC,UAAU,CAAC,OAAO,KAAK,IAAI,EAC3B,CAAC;YACD,oDAAoD;YACpD,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YACxC,UAAU,CAAC,OAAO,GAAG,IAAI,CAAC;QAC5B,CAAC;QAED,oBAAoB;QACpB,OAAO,GAAG,EAAE;YACV,IAAI,WAAW,CAAC,OAAO,CAAC,oBAAoB,EAAE,CAAC;gBAC7C,mBAAmB,CAAC,OAAO,CAAC,GAAG,CAC7B,4BAA4B,EAC5B,WAAW,CAAC,OAAO,CAAC,oBAAoB,CACzC,CAAC;YACJ,CAAC;YACD,IAAI,WAAW,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC;gBAC1C,mBAAmB,CAAC,OAAO,CAAC,GAAG,CAC7B,yBAAyB,EACzB,WAAW,CAAC,OAAO,CAAC,iBAAiB,CACtC,CAAC;YACJ,CAAC;QACH,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,UAAU,EAAE,oBAAoB,EAAE,mBAAmB,CAAC,CAAC,CAAC;IAE5D,qDAAqD;IACrD,SAAS,CAAC,GAAG,EAAE;QACb,8EAA8E;QAC9E,IACE,OAAO,EAAE,aAAa;YACtB,aAAa,CAAC,OAAO,KAAK,UAAU,CAAC,aAAa,EAClD,CAAC;YACD,aAAa,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;YAExC,mDAAmD;YACnD,IACE,aAAa,CAAC,OAAO,KAAK,UAAU,CAAC,cAAc;gBACnD,gBAAgB,CAAC,OAAO,EACxB,CAAC;gBACD,oBAAoB,EAAE,CAAC;YACzB,CAAC;QACH,CAAC;QAED,yBAAyB;QACzB,IAAI,WAAW,KAAK,QAAQ,IAAI,aAAa,EAAE,CAAC;YAC9C,gBAAgB,CAAC,KAAK,CAAC,CAAC;YACxB,IAAI,aAAa,CAAC,OAAO,KAAK,UAAU,CAAC,cAAc,EAAE,CAAC;gBACxD,mBAAmB,CACjB,IAAI,KAAK,CAAC,yBAAyB,CAAC,EACpC,UAAU,CAAC,eAAe,CAC3B,CAAC;YACJ,CAAC;QACH,CAAC;QAED,sDAAsD;QACtD,IACE,CAAC,OAAO,EAAE,aAAa;YACvB,CAAC,CAAC,UAAU,CAAC,cAAc,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC,QAAQ,CAC3D,aAAa,CAAC,OAAO,CACtB,EACD,CAAC;YACD,IAAI,aAAa,CAAC,OAAO,KAAK,UAAU,CAAC,eAAe,EAAE,CAAC;gBACzD,aAAa,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;YAC5C,CAAC;QACH,CAAC;IACH,CAAC,EAAE;QACD,WAAW;QACX,aAAa;QACb,OAAO,EAAE,aAAa;QACtB,gBAAgB;QAChB,oBAAoB;QACpB,mBAAmB;QACnB,aAAa;KACd,CAAC,CAAC;IAEH,2BAA2B;IAC3B,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,UAAU,KAAK,UAAU,CAAC,WAAW,IAAI,CAAC,OAAO,EAAE,aAAa,EAAE,CAAC;YACrE,aAAa,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;YAC1C,WAAW,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;gBACxB,wBAAwB,CAAC,KAAK,CAAC,CAAC;YAClC,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC,EAAE;QACD,OAAO;QACP,WAAW;QACX,wBAAwB;QACxB,UAAU;QACV,aAAa;KACd,CAAC,CAAC;IAEH,OAAO;QACL,MAAM;QACN,OAAO;QACP,WAAW;QACX,UAAU;QACV,WAAW;KACZ,CAAC;AACJ,CAAC,CAAC;AAEF,OAAO,EAAE,SAAS,EAAE,CAAC","sourcesContent":["import { BrowserAuthenticationInitiator } from \"@/services/AuthenticationService.js\";\nimport { BrowserPublicClientPKCEProducer } from \"@/services/PKCE.js\";\nimport { useCivicAuthConfig } from \"@/shared/hooks/useCivicAuthConfig.js\";\nimport {\n AuthStatus,\n type DisplayMode,\n type LoginAppDesignOptions,\n} from \"@/types.js\";\nimport { useIframe } from \"@/shared/hooks/useIframe.js\";\nimport { useCallback, useEffect, useMemo, useRef } from \"react\";\nimport { PopupError, type PKCEConsumer } from \"@/services/types.js\";\nimport { useSession } from \"./useSession.js\";\nimport { LocalStorageAdapter } from \"@/browser/storage.js\";\nimport { clearTokens, clearUser } from \"../lib/util.js\";\nimport { useLocalStorage } from \"usehooks-ts\";\nimport { LOGOUT_STATE } from \"@/constants.js\";\nimport { useAuthStatus } from \"@/shared/providers/AuthStatusContext.js\";\n\ntype SignInProps = {\n pkceConsumer?: PKCEConsumer;\n preSignOut?: () => Promise<void>;\n postSignOut?: () => Promise<void>;\n displayMode: DisplayMode;\n};\n\ntype SignInError = Error | { message: string; [key: string]: unknown };\n\ninterface SignInEventDetail {\n error: SignInError;\n}\n\ninterface SignInErrorEvent {\n detail: SignInEventDetail;\n}\n\nconst SIGN_IN_TIMEOUT_MS = 9 * 60 * 1000; // 9 minutes in milliseconds\n\n/**\n * Hook to manage authentication flow.\n */\nconst useSignIn = (\n { pkceConsumer, preSignOut, postSignOut, displayMode }: SignInProps = {\n displayMode: \"iframe\",\n },\n) => {\n // Config and external state\n const civicAuthConfig = useCivicAuthConfig();\n const {\n iframeRef,\n logoutIframeRef,\n setIframeIsVisible,\n setLogoutIframeIsVisible,\n iframeAborted,\n setIframeAborted,\n } = useIframe();\n const { data: session } = useSession();\n const { authStatus, setAuthStatus } = useAuthStatus();\n const [, setDesignOption] = useLocalStorage<LoginAppDesignOptions>(\n `loginAppDesign`,\n { colorMode: \"auto\" },\n );\n\n // Internal state tracking\n const timeoutRef = useRef<number | null>(null);\n const authStatusRef = useRef<AuthStatus>(AuthStatus.UNAUTHENTICATED);\n const isSigningInRef = useRef<boolean>(false);\n\n // Promise handling\n const signInPromiseRef = useRef<Promise<void>>();\n const signInResolveRef = useRef<\n ((value: void | PromiseLike<void>) => void) | null\n >(null);\n const signInRejectRef = useRef<((reason: Error) => void) | null>(null);\n\n // Event handlers\n const handlersRef = useRef<{\n handleSignInComplete: (() => void) | null;\n handleSignInError: ((event: SignInErrorEvent) => void) | null;\n }>({\n handleSignInComplete: null,\n handleSignInError: null,\n });\n\n // Helper to resolve/reject sign-in promise with cleanup\n const resolveSignInPromise = useCallback(() => {\n if (signInResolveRef.current) {\n setAuthStatus(AuthStatus.AUTHENTICATED);\n authStatusRef.current = AuthStatus.AUTHENTICATED;\n isSigningInRef.current = false;\n signInResolveRef.current();\n\n // Clean up after resolving\n signInResolveRef.current = null;\n signInRejectRef.current = null;\n signInPromiseRef.current = undefined;\n\n if (timeoutRef.current !== null) {\n window.clearTimeout(timeoutRef.current);\n timeoutRef.current = null;\n }\n }\n }, [setAuthStatus]);\n\n const rejectSignInPromise = useCallback(\n (error: Error, newStatus: AuthStatus = AuthStatus.ERROR) => {\n if (signInRejectRef.current) {\n signInRejectRef.current(error);\n\n // Clean up after rejecting\n signInResolveRef.current = null;\n signInRejectRef.current = null;\n signInPromiseRef.current = undefined;\n isSigningInRef.current = false;\n setAuthStatus(newStatus);\n\n if (timeoutRef.current !== null) {\n window.clearTimeout(timeoutRef.current);\n timeoutRef.current = null;\n }\n }\n },\n [setAuthStatus],\n );\n\n // Create authentication initiator\n const authInitiator = useMemo(() => {\n if (!civicAuthConfig) return null;\n\n const {\n clientId,\n redirectUrl,\n logoutUrl,\n loginSuccessUrl,\n logoutRedirectUrl,\n nonce,\n oauthServer,\n endpoints,\n scopes,\n } = civicAuthConfig;\n\n return new BrowserAuthenticationInitiator(\n {\n pkceConsumer: pkceConsumer || new BrowserPublicClientPKCEProducer(),\n clientId,\n redirectUrl,\n loginSuccessUrl,\n logoutUrl,\n logoutRedirectUrl,\n scopes,\n displayMode,\n oauthServer,\n endpointOverrides: endpoints,\n nonce,\n },\n setDesignOption,\n );\n }, [civicAuthConfig, displayMode, pkceConsumer, setDesignOption]);\n\n // Cleanup resources when component unmounts\n useEffect(() => {\n return () => {\n if (authInitiator) {\n authInitiator.cleanup();\n }\n if (timeoutRef.current !== null) {\n window.clearTimeout(timeoutRef.current);\n timeoutRef.current = null;\n }\n };\n }, [authInitiator]);\n\n // Handle logout state cleanup\n useEffect(() => {\n const params = new URLSearchParams(window.location.search);\n const state = params.get(\"state\");\n const localStorage = new LocalStorageAdapter();\n localStorage.get(LOGOUT_STATE).then((storedLogoutState) => {\n if (state && state === storedLogoutState) {\n // Clear storage\n clearTokens(localStorage);\n clearUser(localStorage);\n LocalStorageAdapter.emitter.emit(\"signOut\");\n\n // Clean up storage and URL\n sessionStorage.removeItem(LOGOUT_STATE);\n const cleanUrl = window.location.href.split(\"?\")[0];\n window.history.replaceState({}, document.title, cleanUrl);\n }\n });\n }, []);\n\n // Main sign-in logic\n const startSignIn = useCallback(async (): Promise<void> => {\n if (!authInitiator) return;\n\n // Create the promise and store its handlers\n const promise = new Promise<void>((resolve, reject) => {\n signInResolveRef.current = resolve;\n signInRejectRef.current = reject;\n });\n signInPromiseRef.current = promise;\n\n // Check if sign-in is already in progress using the ref, if so, return signIn promise\n if (isSigningInRef.current) {\n return promise;\n }\n\n // State machine for sign-in flow\n switch (authStatus) {\n case AuthStatus.AUTHENTICATED:\n return Promise.resolve();\n\n case AuthStatus.UNAUTHENTICATED:\n case AuthStatus.ERROR:\n break;\n\n case AuthStatus.AUTHENTICATING:\n // if we're already authenticating, return the existing promise\n return promise;\n\n default:\n return Promise.reject(\n new Error(`Invalid state for sign-in: ${authStatus}`),\n );\n }\n\n // Set signing in flag first\n isSigningInRef.current = true;\n\n // Clear any existing timeout\n if (timeoutRef.current !== null) {\n window.clearTimeout(timeoutRef.current);\n timeoutRef.current = null;\n }\n\n try {\n // Set authenticating status before any async operations\n setAuthStatus(AuthStatus.AUTHENTICATING);\n authStatusRef.current = AuthStatus.AUTHENTICATING;\n authInitiator.setDisplayMode(displayMode);\n\n // Set a timeout to reject the promise if authentication takes too long\n timeoutRef.current = window.setTimeout(() => {\n if (authStatusRef.current === AuthStatus.AUTHENTICATING) {\n rejectSignInPromise(new Error(\"Sign-in timeout\"));\n }\n }, SIGN_IN_TIMEOUT_MS);\n\n // Start the authentication process\n const useIframeRef = iframeRef?.current || null;\n\n await authInitiator.signIn(useIframeRef);\n } catch (error) {\n // Reset the signing in flag on error\n isSigningInRef.current = false;\n\n if (error instanceof PopupError) {\n // Fallback to redirect if popup fails\n setIframeIsVisible(false);\n authInitiator.cleanup();\n authInitiator.setDisplayMode(\"redirect\");\n try {\n // Call signIn again with redirect mode\n await authInitiator.signIn(iframeRef?.current || null);\n } catch (retryError) {\n console.error(\n \"[useSignIn] Redirect sign-in initiation error\",\n retryError,\n );\n rejectSignInPromise(\n retryError instanceof Error\n ? retryError\n : new Error(String(retryError)),\n );\n return promise;\n }\n } else {\n rejectSignInPromise(\n error instanceof Error ? error : new Error(String(error)),\n );\n return promise;\n }\n }\n\n return promise;\n }, [\n authInitiator,\n displayMode,\n iframeRef,\n setIframeIsVisible,\n authStatus,\n setAuthStatus,\n rejectSignInPromise,\n ]);\n\n // Public sign-in method\n const signIn = useCallback(async (): Promise<void> => {\n if (displayMode === \"iframe\") {\n setIframeIsVisible(true);\n }\n return startSignIn();\n }, [startSignIn, displayMode, setIframeIsVisible]);\n\n // Sign-out method\n const signOut = useCallback(async () => {\n const idToken = session?.idToken;\n if (!authInitiator) return;\n\n setAuthStatus(AuthStatus.SIGNING_OUT);\n if (displayMode === \"iframe\") {\n setIframeIsVisible(false);\n setLogoutIframeIsVisible(true);\n }\n\n try {\n await preSignOut?.();\n\n const useIframeRef = logoutIframeRef?.current || null;\n await authInitiator.signOut(idToken, useIframeRef).catch((error) => {\n setAuthStatus(AuthStatus.ERROR);\n console.error(\"signOut error\", {\n error,\n isPopupError: error instanceof PopupError,\n });\n\n if (error instanceof PopupError) {\n setLogoutIframeIsVisible(false);\n authInitiator.cleanup();\n authInitiator.setDisplayMode(\"redirect\");\n authInitiator.signOut(idToken, useIframeRef); // Retry sign out\n }\n });\n } catch (error) {\n console.error(\"Signout error:\", error);\n setAuthStatus(AuthStatus.ERROR);\n }\n }, [\n session?.idToken,\n authInitiator,\n displayMode,\n setLogoutIframeIsVisible,\n setIframeIsVisible,\n preSignOut,\n logoutIframeRef,\n setAuthStatus,\n ]);\n\n // Set up event listeners for authentication status\n useEffect(() => {\n // Update the ref with current auth status\n authStatusRef.current = authStatus;\n\n // Define handlers\n handlersRef.current = {\n handleSignInComplete: () => {\n if (authStatusRef.current === AuthStatus.AUTHENTICATING) {\n resolveSignInPromise();\n }\n },\n handleSignInError: (event: SignInErrorEvent) => {\n if (authStatusRef.current === AuthStatus.AUTHENTICATING) {\n const error = event.detail.error;\n rejectSignInPromise(\n error instanceof Error\n ? error\n : new Error(error.message || \"Sign-in failed\"),\n );\n }\n },\n };\n\n // Add listeners only when in authenticating state\n if (\n authStatus === AuthStatus.AUTHENTICATING &&\n handlersRef.current.handleSignInComplete &&\n handlersRef.current.handleSignInError\n ) {\n LocalStorageAdapter.emitter.on(\n \"civic-auth-signin-complete\",\n handlersRef.current.handleSignInComplete,\n );\n LocalStorageAdapter.emitter.on(\n \"civic-auth-signin-error\",\n handlersRef.current.handleSignInError,\n );\n } else if (\n authStatus !== AuthStatus.AUTHENTICATING &&\n timeoutRef.current !== null\n ) {\n // Clean up timeout when not in authenticating state\n window.clearTimeout(timeoutRef.current);\n timeoutRef.current = null;\n }\n\n // Cleanup listeners\n return () => {\n if (handlersRef.current.handleSignInComplete) {\n LocalStorageAdapter.emitter.off(\n \"civic-auth-signin-complete\",\n handlersRef.current.handleSignInComplete,\n );\n }\n if (handlersRef.current.handleSignInError) {\n LocalStorageAdapter.emitter.off(\n \"civic-auth-signin-error\",\n handlersRef.current.handleSignInError,\n );\n }\n };\n }, [authStatus, resolveSignInPromise, rejectSignInPromise]);\n\n // Effect to handle session updates and iframe aborts\n useEffect(() => {\n // If session becomes authenticated, update state and resolve pending promises\n if (\n session?.authenticated &&\n authStatusRef.current !== AuthStatus.AUTHENTICATED\n ) {\n setAuthStatus(AuthStatus.AUTHENTICATED);\n\n // If we have a pending sign-in promise, resolve it\n if (\n authStatusRef.current === AuthStatus.AUTHENTICATING &&\n signInResolveRef.current\n ) {\n resolveSignInPromise();\n }\n }\n\n // Handle iframe abortion\n if (displayMode === \"iframe\" && iframeAborted) {\n setIframeAborted(false);\n if (authStatusRef.current === AuthStatus.AUTHENTICATING) {\n rejectSignInPromise(\n new Error(\"Sign-in aborted by user\"),\n AuthStatus.UNAUTHENTICATED,\n );\n }\n }\n\n // Update unauthenticated state when session is absent\n if (\n !session?.authenticated &&\n ![AuthStatus.AUTHENTICATING, AuthStatus.SIGNING_OUT].includes(\n authStatusRef.current,\n )\n ) {\n if (authStatusRef.current !== AuthStatus.UNAUTHENTICATED) {\n setAuthStatus(AuthStatus.UNAUTHENTICATED);\n }\n }\n }, [\n displayMode,\n iframeAborted,\n session?.authenticated,\n setIframeAborted,\n resolveSignInPromise,\n rejectSignInPromise,\n setAuthStatus,\n ]);\n\n // Handle logout completion\n useEffect(() => {\n if (authStatus === AuthStatus.SIGNING_OUT && !session?.authenticated) {\n setAuthStatus(AuthStatus.UNAUTHENTICATED);\n postSignOut?.().then(() => {\n setLogoutIframeIsVisible(false);\n });\n }\n }, [\n session,\n postSignOut,\n setLogoutIframeIsVisible,\n authStatus,\n setAuthStatus,\n ]);\n\n return {\n signIn,\n signOut,\n startSignIn,\n authStatus,\n displayMode,\n };\n};\n\nexport { useSignIn };\n"]}
|
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
import type { AuthStatus, DisplayMode
|
|
2
|
-
type SignInResult = {
|
|
3
|
-
user: User | null;
|
|
4
|
-
error: Error | null;
|
|
5
|
-
};
|
|
1
|
+
import type { AuthStatus, DisplayMode } from "../../types.js";
|
|
6
2
|
export type AuthContextType = {
|
|
7
|
-
signIn: (displayMode?: DisplayMode) => Promise<
|
|
3
|
+
signIn: (displayMode?: DisplayMode) => Promise<void>;
|
|
8
4
|
isAuthenticated: boolean;
|
|
9
5
|
isLoading: boolean;
|
|
10
6
|
error: Error | null;
|
|
@@ -13,5 +9,4 @@ export type AuthContextType = {
|
|
|
13
9
|
displayMode: DisplayMode;
|
|
14
10
|
};
|
|
15
11
|
export declare const AuthContext: import("react").Context<AuthContextType | null>;
|
|
16
|
-
export {};
|
|
17
12
|
//# sourceMappingURL=AuthContext.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthContext.d.ts","sourceRoot":"","sources":["../../../src/shared/providers/AuthContext.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"AuthContext.d.ts","sourceRoot":"","sources":["../../../src/shared/providers/AuthContext.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE1D,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE,CAAC,WAAW,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,eAAe,EAAE,OAAO,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,UAAU,EAAE,UAAU,CAAC;IACvB,WAAW,EAAE,WAAW,CAAC;CAC1B,CAAC;AACF,eAAO,MAAM,WAAW,iDAA8C,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthContext.js","sourceRoot":"","sources":["../../../src/shared/providers/AuthContext.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;AACb,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"AuthContext.js","sourceRoot":"","sources":["../../../src/shared/providers/AuthContext.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;AACb,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAYtC,MAAM,CAAC,MAAM,WAAW,GAAG,aAAa,CAAyB,IAAI,CAAC,CAAC","sourcesContent":["\"use client\";\nimport { createContext } from \"react\";\nimport type { AuthStatus, DisplayMode } from \"@/types.js\";\n\nexport type AuthContextType = {\n signIn: (displayMode?: DisplayMode) => Promise<void>;\n isAuthenticated: boolean;\n isLoading: boolean;\n error: Error | null;\n signOut: () => Promise<void>;\n authStatus: AuthStatus;\n displayMode: DisplayMode;\n};\nexport const AuthContext = createContext<AuthContextType | null>(null);\n"]}
|
|
@@ -4,10 +4,6 @@ import type { AuthStatus, AuthStorage, DisplayMode, ForwardedTokens, User } from
|
|
|
4
4
|
import type { AuthContextType } from "../../shared/providers/AuthContext.js";
|
|
5
5
|
import type { JWTPayload } from "jose";
|
|
6
6
|
type UserContent = Record<string, unknown> & JWTPayload;
|
|
7
|
-
type SignInResult = {
|
|
8
|
-
user: User | null;
|
|
9
|
-
error: Error | null;
|
|
10
|
-
};
|
|
11
7
|
type UserContextType<T extends UserContent = UserContent> = {
|
|
12
8
|
user: User<T> | null;
|
|
13
9
|
} & {
|
|
@@ -22,7 +18,7 @@ declare const UserProvider: <T extends UserContent>({ children, storage, user: i
|
|
|
22
18
|
user: User<T> | null;
|
|
23
19
|
signOut: () => Promise<void>;
|
|
24
20
|
authStatus: AuthStatus;
|
|
25
|
-
signIn: (displayMode?: DisplayMode) => Promise<
|
|
21
|
+
signIn: (displayMode?: DisplayMode) => Promise<void>;
|
|
26
22
|
displayMode: DisplayMode;
|
|
27
23
|
}) => import("@emotion/react/jsx-runtime").JSX.Element;
|
|
28
24
|
export type { UserContextType };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UserProvider.d.ts","sourceRoot":"","sources":["../../../src/shared/providers/UserProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA0D,MAAM,OAAO,CAAC;AAC/E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,WAAW,EACX,eAAe,EACf,IAAI,EACL,MAAM,YAAY,CAAC;AAEpB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AAGzE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAEvC,KAAK,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"UserProvider.d.ts","sourceRoot":"","sources":["../../../src/shared/providers/UserProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA0D,MAAM,OAAO,CAAC;AAC/E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,WAAW,EACX,eAAe,EACf,IAAI,EACL,MAAM,YAAY,CAAC;AAEpB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AAGzE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAEvC,KAAK,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,UAAU,CAAC;AACxD,KAAK,eAAe,CAAC,CAAC,SAAS,WAAW,GAAG,WAAW,IAAI;IAC1D,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;CACtB,GAAG;IACF,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,eAAe,CAAC,EAAE,eAAe,CAAC;CACnC,GAAG,IAAI,CAAC,eAAe,EAAE,iBAAiB,CAAC,CAAC;AAE7C,QAAA,MAAM,WAAW,oDAA8C,CAAC;AAEhE,QAAA,MAAM,YAAY,GAAI,CAAC,SAAS,WAAW,qFAQxC;IACD,QAAQ,EAAE,SAAS,CAAC;IACpB,OAAO,EAAE,WAAW,CAAC;IACrB,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,UAAU,EAAE,UAAU,CAAC;IACvB,MAAM,EAAE,CAAC,WAAW,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,WAAW,EAAE,WAAW,CAAC;CAC1B,qDAmEA,CAAC;AAEF,YAAY,EAAE,eAAe,EAAE,CAAC;AAEhC,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UserProvider.js","sourceRoot":"","sources":["../../../src/shared/providers/UserProvider.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,KAAK,EAAE,EAAE,aAAa,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAS/E,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAE1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"UserProvider.js","sourceRoot":"","sources":["../../../src/shared/providers/UserProvider.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\n\nimport React, { createContext, useCallback, useEffect, useState } from \"react\";\nimport type { ReactNode } from \"react\";\nimport type {\n AuthStatus,\n AuthStorage,\n DisplayMode,\n ForwardedTokens,\n User,\n} from \"@/types.js\";\nimport { useSession } from \"@/shared/hooks/useSession.js\";\nimport type { AuthContextType } from \"@/shared/providers/AuthContext.js\";\nimport { GenericUserSession } from \"@/shared/lib/UserSession.js\";\nimport { useToken } from \"../hooks/useToken.js\";\nimport type { JWTPayload } from \"jose\";\n\ntype UserContent = Record<string, unknown> & JWTPayload;\ntype UserContextType<T extends UserContent = UserContent> = {\n user: User<T> | null;\n} & {\n accessToken?: string | null;\n idToken?: string | null;\n forwardedTokens?: ForwardedTokens;\n} & Omit<AuthContextType, \"isAuthenticated\">;\n\nconst UserContext = createContext<UserContextType | null>(null);\n\nconst UserProvider = <T extends UserContent>({\n children,\n storage,\n user: inputUser,\n signOut,\n authStatus,\n signIn,\n displayMode,\n}: {\n children: ReactNode;\n storage: AuthStorage;\n user: User<T> | null;\n signOut: () => Promise<void>;\n authStatus: AuthStatus;\n signIn: (displayMode?: DisplayMode) => Promise<void>;\n displayMode: DisplayMode;\n}) => {\n const {\n data: session,\n error: authError,\n isLoading: authLoading,\n } = useSession();\n const tokens = useToken();\n const [userLoading, setUserLoading] = useState<boolean>(false);\n const [userError, setUserError] = useState<Error | null>(null);\n const [user, setUser] = useState<User<T> | null>(inputUser);\n\n const fetchUser = useCallback(async (): Promise<User<T> | null> => {\n if (!session?.idToken) return null;\n const userSession = new GenericUserSession<T>(storage);\n return userSession.get();\n }, [session?.idToken, storage]);\n\n useEffect(() => {\n if (session?.idToken) {\n setUserLoading(true);\n fetchUser()\n .then((user) => {\n setUserLoading(false);\n setUser((prevUser) => {\n // we only want to update the user if it's set - if a user is passed in, don't assume it is wrong here\n // it could be just the fetchUser returned null for some other reason.\n // TODO consider cleaning this up in general to avoid needing context here.\n return user ?? prevUser;\n });\n })\n .catch((error) => {\n setUserLoading(false);\n setUserError(error);\n });\n } else {\n setUser(null);\n }\n }, [fetchUser, session?.idToken]);\n\n const isLoading = authLoading || userLoading;\n const error = authError ?? userError;\n\n // While we are passing a user as a prop _and_ storing it in state,\n // there is the case where the user is not set in the state yet\n // (setState is called but the rerender has not yet happened), but\n // is passed as a prop. In this case, we want to use the prop value.\n // A better solution is to avoid having multiple layers of context.\n // If the user is passed in, we just use that.\n // We should not split user state management across multiple contexts\n const userValue = user ?? inputUser;\n\n return (\n <UserContext.Provider\n value={{\n ...tokens,\n user: userValue,\n isLoading,\n error,\n signIn,\n signOut,\n authStatus,\n displayMode: displayMode || \"iframe\",\n }}\n >\n {children}\n </UserContext.Provider>\n );\n};\n\nexport type { UserContextType };\n\nexport { UserProvider, UserContext };\n"]}
|
package/dist/shared/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "@civic/auth:0.7.0
|
|
1
|
+
export declare const VERSION = "@civic/auth:0.7.0";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/shared/version.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,OAAO,
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/shared/version.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,OAAO,sBAAsB,CAAC"}
|
package/dist/shared/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/shared/version.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAE/C,MAAM,CAAC,MAAM,OAAO,GAAG,
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/shared/version.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAE/C,MAAM,CAAC,MAAM,OAAO,GAAG,mBAAmB,CAAC","sourcesContent":["// This is an auto-generated file. Do not edit.\n\nexport const VERSION = \"@civic/auth:0.7.0\";\n"]}
|