@civic/auth 0.6.1-beta.3 → 0.6.1

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.
Files changed (94) hide show
  1. package/CHANGELOG.md +3 -0
  2. package/README.md +7 -0
  3. package/dist/nextjs/config.d.ts.map +1 -1
  4. package/dist/nextjs/config.js +1 -5
  5. package/dist/nextjs/config.js.map +1 -1
  6. package/dist/nextjs/hooks/useUserCookie.d.ts.map +1 -1
  7. package/dist/nextjs/hooks/useUserCookie.js.map +1 -1
  8. package/dist/nextjs/middleware.d.ts.map +1 -1
  9. package/dist/nextjs/middleware.js +51 -18
  10. package/dist/nextjs/middleware.js.map +1 -1
  11. package/dist/nextjs/providers/NextAuthProvider.d.ts.map +1 -1
  12. package/dist/nextjs/providers/NextAuthProvider.js +0 -1
  13. package/dist/nextjs/providers/NextAuthProvider.js.map +1 -1
  14. package/dist/nextjs/routeHandler.d.ts.map +1 -1
  15. package/dist/nextjs/routeHandler.js +8 -0
  16. package/dist/nextjs/routeHandler.js.map +1 -1
  17. package/dist/shared/hooks/useSignIn.d.ts +4 -9
  18. package/dist/shared/hooks/useSignIn.d.ts.map +1 -1
  19. package/dist/shared/hooks/useSignIn.js +42 -75
  20. package/dist/shared/hooks/useSignIn.js.map +1 -1
  21. package/dist/shared/providers/AuthContext.d.ts +2 -7
  22. package/dist/shared/providers/AuthContext.d.ts.map +1 -1
  23. package/dist/shared/providers/AuthContext.js.map +1 -1
  24. package/dist/shared/providers/UserProvider.d.ts +1 -5
  25. package/dist/shared/providers/UserProvider.d.ts.map +1 -1
  26. package/dist/shared/providers/UserProvider.js.map +1 -1
  27. package/dist/shared/version.d.ts +1 -1
  28. package/dist/shared/version.d.ts.map +1 -1
  29. package/dist/shared/version.js +1 -1
  30. package/dist/shared/version.js.map +1 -1
  31. package/dist/vanillajs/auth/AuthenticationEvents.d.ts.map +1 -1
  32. package/dist/vanillajs/auth/AuthenticationEvents.js +2 -2
  33. package/dist/vanillajs/auth/AuthenticationEvents.js.map +1 -1
  34. package/dist/vanillajs/auth/CivicAuth.d.ts +107 -68
  35. package/dist/vanillajs/auth/CivicAuth.d.ts.map +1 -1
  36. package/dist/vanillajs/auth/CivicAuth.js +412 -389
  37. package/dist/vanillajs/auth/CivicAuth.js.map +1 -1
  38. package/dist/vanillajs/auth/{handlers/OAuthCallbackHandler.d.ts → OAuthCallbackHandler.d.ts} +2 -2
  39. package/dist/vanillajs/auth/OAuthCallbackHandler.d.ts.map +1 -0
  40. package/dist/vanillajs/auth/OAuthCallbackHandler.js +143 -0
  41. package/dist/vanillajs/auth/OAuthCallbackHandler.js.map +1 -0
  42. package/dist/vanillajs/auth/SessionManager.d.ts.map +1 -1
  43. package/dist/vanillajs/auth/SessionManager.js +2 -2
  44. package/dist/vanillajs/auth/SessionManager.js.map +1 -1
  45. package/dist/vanillajs/auth/TokenRefresher.d.ts.map +1 -1
  46. package/dist/vanillajs/auth/TokenRefresher.js +2 -2
  47. package/dist/vanillajs/auth/TokenRefresher.js.map +1 -1
  48. package/dist/vanillajs/iframe/IframeManager.d.ts +0 -33
  49. package/dist/vanillajs/iframe/IframeManager.d.ts.map +1 -1
  50. package/dist/vanillajs/iframe/IframeManager.js +36 -163
  51. package/dist/vanillajs/iframe/IframeManager.js.map +1 -1
  52. package/dist/vanillajs/index.d.ts +2 -2
  53. package/dist/vanillajs/index.d.ts.map +1 -1
  54. package/dist/vanillajs/index.js +2 -2
  55. package/dist/vanillajs/index.js.map +1 -1
  56. package/dist/vanillajs/services/ApiService.d.ts.map +1 -1
  57. package/dist/vanillajs/services/ApiService.js +2 -2
  58. package/dist/vanillajs/services/ApiService.js.map +1 -1
  59. package/dist/vanillajs/types/index.d.ts +10 -15
  60. package/dist/vanillajs/types/index.d.ts.map +1 -1
  61. package/dist/vanillajs/types/index.js +10 -15
  62. package/dist/vanillajs/types/index.js.map +1 -1
  63. package/dist/vanillajs/utils/auth-utils.d.ts +1 -2
  64. package/dist/vanillajs/utils/auth-utils.d.ts.map +1 -1
  65. package/dist/vanillajs/utils/auth-utils.js +3 -6
  66. package/dist/vanillajs/utils/auth-utils.js.map +1 -1
  67. package/dist/vanillajs/utils/logger.d.ts +15 -16
  68. package/dist/vanillajs/utils/logger.d.ts.map +1 -1
  69. package/dist/vanillajs/utils/logger.js +19 -35
  70. package/dist/vanillajs/utils/logger.js.map +1 -1
  71. package/package.json +1 -6
  72. package/dist/vanillajs/auth/config/ConfigProcessor.d.ts +0 -6
  73. package/dist/vanillajs/auth/config/ConfigProcessor.d.ts.map +0 -1
  74. package/dist/vanillajs/auth/config/ConfigProcessor.js +0 -59
  75. package/dist/vanillajs/auth/config/ConfigProcessor.js.map +0 -1
  76. package/dist/vanillajs/auth/handlers/IframeAuthHandler.d.ts +0 -40
  77. package/dist/vanillajs/auth/handlers/IframeAuthHandler.d.ts.map +0 -1
  78. package/dist/vanillajs/auth/handlers/IframeAuthHandler.js +0 -388
  79. package/dist/vanillajs/auth/handlers/IframeAuthHandler.js.map +0 -1
  80. package/dist/vanillajs/auth/handlers/MessageHandler.d.ts +0 -170
  81. package/dist/vanillajs/auth/handlers/MessageHandler.d.ts.map +0 -1
  82. package/dist/vanillajs/auth/handlers/MessageHandler.js +0 -367
  83. package/dist/vanillajs/auth/handlers/MessageHandler.js.map +0 -1
  84. package/dist/vanillajs/auth/handlers/OAuthCallbackHandler.d.ts.map +0 -1
  85. package/dist/vanillajs/auth/handlers/OAuthCallbackHandler.js +0 -301
  86. package/dist/vanillajs/auth/handlers/OAuthCallbackHandler.js.map +0 -1
  87. package/dist/vanillajs/auth/handlers/PopupHandler.d.ts +0 -108
  88. package/dist/vanillajs/auth/handlers/PopupHandler.d.ts.map +0 -1
  89. package/dist/vanillajs/auth/handlers/PopupHandler.js +0 -333
  90. package/dist/vanillajs/auth/handlers/PopupHandler.js.map +0 -1
  91. package/dist/vanillajs/auth/types/AuthTypes.d.ts +0 -128
  92. package/dist/vanillajs/auth/types/AuthTypes.d.ts.map +0 -1
  93. package/dist/vanillajs/auth/types/AuthTypes.js +0 -40
  94. package/dist/vanillajs/auth/types/AuthTypes.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"routeHandler.js","sourceRoot":"","sources":["../../src/nextjs/routeHandler.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n LOGOUT_SUCCESS_TEXT,\n TOKEN_EXCHANGE_SUCCESS_TEXT,\n TOKEN_EXCHANGE_TRIGGER_TEXT,\n} from \"@/constants.js\";\nimport { loggers } from \"@/lib/logger.js\";\nimport {\n displayModeFromState,\n loginSuccessUrlFromState,\n serverTokenExchangeFromState,\n} from \"@/lib/oauth.js\";\nimport type { AuthConfig, AuthConfigWithDefaults } from \"@/nextjs/config.js\";\nimport { resolveAuthConfig } from \"@/nextjs/config.js\";\nimport { clearAuthCookies, NextjsCookieStorage } from \"@/nextjs/cookies.js\";\nimport { getUser } from \"@/nextjs/index.js\";\nimport { resolveCallbackUrl } from \"@/nextjs/utils.js\";\nimport { resolveOAuthAccessCode } from \"@/server/login.js\";\nimport { GenericPublicClientPKCEProducer } from \"@/services/PKCE.js\";\nimport { CodeVerifier, OAuthTokenTypes } from \"@/shared/lib/types.js\";\nimport { GenericUserSession } from \"@/shared/lib/UserSession.js\";\nimport { clearTokens, generateOauthLogoutUrl } from \"@/shared/lib/util.js\";\nimport { revalidatePath } from \"next/cache.js\";\nimport type { NextRequest } from \"next/server.js\";\nimport { NextResponse } from \"next/server.js\";\nimport { NextServerAuthenticationRefresherImpl } from \"./NextServerAuthenticationRefresherImpl.js\";\n\nconst logger = loggers.nextjs.handlers.auth;\n\nclass AuthError extends Error {\n constructor(\n message: string,\n public readonly status: number = 401,\n ) {\n super(message);\n this.name = \"AuthError\";\n }\n}\n\nconst tryUriDecode = (value: string): string | null => {\n try {\n return decodeURIComponent(value);\n } catch (e) {\n logger.error(\"Error decoding URI component:\", e);\n return value;\n }\n};\n\nconst getDecodedQueryParam = (\n request: NextRequest,\n paramName: string,\n): string | null => {\n const queryParam = request.nextUrl.searchParams.get(paramName);\n if (queryParam) {\n return tryUriDecode(queryParam);\n }\n return null;\n};\n\nconst getCookieOrQueryParam = (\n request: NextRequest,\n cookieName: string,\n queryName: string,\n): string | null => {\n // First check the cookie as it might have the full path with base directory\n const cookieValue = request.cookies.get(cookieName)?.value;\n if (cookieValue) {\n return tryUriDecode(cookieValue);\n }\n\n // Fallback to query parameter\n return getDecodedQueryParam(request, queryName);\n};\n\nconst getAppUrl = (request: NextRequest): string | null =>\n getCookieOrQueryParam(request, CodeVerifier.APP_URL, \"appUrl\");\n\n// The loginSuccessUrl can either be decoded from the state parameter, or passed as a cookie or query parameter\nconst getLoginSuccessUrl = (\n request: NextRequest,\n baseUrl?: string | null,\n): string | null => {\n const loginSuccessUrl =\n loginSuccessUrlFromState(request.nextUrl.searchParams.get(\"state\")) ||\n getDecodedQueryParam(request, \"loginSuccessUrl\");\n if (!loginSuccessUrl) {\n return null;\n }\n return baseUrl ? new URL(loginSuccessUrl, baseUrl).href : loginSuccessUrl;\n};\n\nconst getIdToken = async (config: AuthConfig): Promise<string | null> => {\n const cookieStorage = new NextjsCookieStorage(config.cookies?.tokens ?? {});\n return cookieStorage.get(OAuthTokenTypes.ID_TOKEN);\n};\n\n/**\n * create a code verifier and challenge for PKCE\n * saving the verifier in a cookie for later use\n * @returns {Promise<NextResponse>}\n */\nasync function handleChallenge(\n request: NextRequest,\n config: AuthConfig,\n): Promise<NextResponse> {\n const cookieStorage = new NextjsCookieStorage(config.cookies?.tokens ?? {});\n const pkceProducer = new GenericPublicClientPKCEProducer(cookieStorage);\n\n const challenge = await pkceProducer.getCodeChallenge();\n const appUrl = request.nextUrl.searchParams.get(\"appUrl\");\n if (appUrl) {\n await cookieStorage.set(CodeVerifier.APP_URL, appUrl);\n }\n\n return NextResponse.json({ status: \"success\", challenge });\n}\n\nconst getCookieStorageWithUserOverrides = (config: AuthConfig) => {\n const resolvedConfigs = resolveAuthConfig(config);\n return new NextjsCookieStorage({\n ...resolvedConfigs.cookies.tokens,\n user: resolvedConfigs.cookies.user,\n });\n};\nasync function performTokenExchangeAndSetCookies(\n config: AuthConfig,\n code: string,\n state: string,\n appUrl: string,\n) {\n const resolvedConfigs = resolveAuthConfig(config);\n // TODO This is messy, better would be to fix the config.cookies type to always be <name: settings>\n // rather than nesting the tokens-related ones *and* code-verifier inside \"tokens\"\n // (despite code-verifier not relating directly to tokens)\n const cookieStorage = getCookieStorageWithUserOverrides(config);\n\n const callbackUrl = resolveCallbackUrl(resolvedConfigs, appUrl);\n try {\n await resolveOAuthAccessCode(code, state, cookieStorage, {\n ...resolvedConfigs,\n redirectUrl: callbackUrl,\n });\n } catch (error) {\n logger.error(\"Token exchange failed:\", error);\n throw new AuthError(\"Failed to authenticate user\", 401);\n }\n\n const user = await getUser();\n if (!user) {\n throw new AuthError(\"Failed to get user info\", 401);\n }\n const userSession = new GenericUserSession(cookieStorage);\n await userSession.set(user);\n}\nasync function handleRefresh(\n request: NextRequest,\n config: AuthConfig,\n): Promise<NextResponse> {\n const resolvedConfigs = resolveAuthConfig(config);\n const cookieStorage = getCookieStorageWithUserOverrides(config);\n const userSession = new GenericUserSession(cookieStorage);\n try {\n const onError = (error: Error) => {\n logger.error(\"handleRefresh: Token refresh failed:\", error);\n throw new AuthError(\"Failed to refresh tokens\", 500);\n };\n const refresher = await NextServerAuthenticationRefresherImpl.build(\n {\n clientId: resolvedConfigs.clientId,\n oauthServer: resolvedConfigs.oauthServer,\n redirectUrl: resolvedConfigs.callbackUrl,\n refreshUrl: resolvedConfigs.refreshUrl,\n },\n cookieStorage,\n onError,\n );\n\n const tokens = await refresher.refreshAccessToken();\n const user = await getUser();\n if (!user) {\n throw new AuthError(\"Failed to get user info\", 401);\n }\n await userSession.set(user);\n const targetUrl = request.nextUrl.searchParams.get(\"targetUrl\");\n if (targetUrl) {\n return NextResponse.redirect(targetUrl);\n }\n return NextResponse.json({ status: \"success\", tokens });\n } catch (error) {\n logger.error(\n \"handleRefresh: Token refresh failed, clearing tokens:\",\n error,\n );\n await clearTokens(cookieStorage);\n await userSession.clear();\n const targetUrl = request.nextUrl.searchParams.get(\"targetUrl\");\n if (targetUrl) {\n logger.warn(\"redirecting to targetUrl\", targetUrl);\n return NextResponse.redirect(targetUrl);\n }\n return NextResponse.json({ status: \"failed\" });\n }\n}\n\nconst generateHtmlResponseWithCallback = (\n request: NextRequest,\n callbackUrl: string,\n loginSuccessUrl?: string,\n) => {\n // we need to replace the URL with resolved config in case the server is hosted\n // behind a reverse proxy or load balancer\n const requestUrl = new URL(request.url);\n const fetchUrl = `${callbackUrl}?${requestUrl.searchParams.toString()}&sameDomainCallback=true`;\n const loginSuccessSegment = loginSuccessUrl\n ? `&loginSuccessUrl=${encodeURIComponent(loginSuccessUrl)}`\n : \"\";\n const html = `<html lang=\"en\">\n <body>\n <span style=\"display:none\">\n <script>\n window.onload = function () {\n // Get the complete URL including origin and path\n // This ensures we capture any base path like /directory\n const appUrl = window.location.href.substring(\n 0,\n window.location.href.indexOf(\"/api/auth\")\n );\n fetch('${fetchUrl}&appUrl=' + encodeURIComponent(appUrl) + '${loginSuccessSegment}').then((response) => {\n response.json().then((jsonResponse) => {\n // For login: Redirect back to the callback route, so Case 2 in handleTokenExchangeComplete will be triggered\n // For logout: Redirect to the postLogoutRedirectUrl\n if(jsonResponse.redirectUrl) {\n window.location.href = jsonResponse.redirectUrl;\n }\n });\n });\n };\n </script>\n </span>\n </body>\n</html>\n`;\n const response = new NextResponse(html);\n response.headers.set(\"Content-Type\", \"text/html; charset=utf-8\");\n return response;\n};\n\ntype TokkenExchangeCompletInput = {\n request: NextRequest;\n config: AuthConfig;\n loginSuccessUrl?: string | null;\n appUrl?: string | null;\n state: string;\n};\n\nconst handleTokenExchangeComplete = async (\n params: TokkenExchangeCompletInput,\n) => {\n const { request, config, appUrl, loginSuccessUrl, state } = params;\n // Case 1: We are being called via fetch to facilitate access to the cookies. Return success json. The iframe has javascript that will reload this route so Case 2 below will be triggered.\n if (isCalledFromBrowserFetch(request)) {\n logger.debug(\n \"CASE 1: sameDomainCallback=true, returning JSON response with redirect URL\",\n { appUrl, loginSuccessUrl, callbackUrl: config.callbackUrl },\n );\n\n const currentUrl = new URL(request.url);\n // When the client-side JS redirects back here, we don't want to hit this branch again because we can't return JSON from a redirect.\n // So we strip off the sameDomainCallback parameter from the URL.\n const newSearchParams = new URLSearchParams(currentUrl.search);\n newSearchParams.delete(\"sameDomainCallback\");\n\n // We strip off the origin so reverse proxies don't break the redirect.\n const redirectUrl = `${currentUrl.pathname}?${newSearchParams.toString()}${currentUrl.hash}`;\n return NextResponse.json({\n status: \"success\",\n // This makes the iframe redirect back to this route, so Case 2 below will be triggered.\n\n redirectUrl,\n });\n }\n\n // Case 2: We are already authenticated and in iframe mode.\n // Case 2a: We have a custom loginSuccessUrl, so we have to trigger a top-level redirect to it. We do this by rendering a page with the TOKEN_EXCHANGE_SUCCESS_TEXT, which is then picked up by the iframe container.\n // Case 2b: We don't have a custom loginSuccessUrl, so we just redirect to the appUrl. If we don't do this, Cypress tests will fail in the 'no custom loginSuccessUrl' case, because in Cypress an iframe redirect is converted to a top-level redirect,\n // which means the iframe container no longer exists and so can't action the redirect.\n const user = await getUser();\n if (!!user && displayModeFromState(state, \"iframe\") === \"iframe\") {\n if (loginSuccessUrl) {\n logger.debug(\n \"CASE 2a: iframe mode with loginSuccessUrl configured. Returning TOKEN_EXCHANGE_SUCCESS_TEXT to trigger redirect to loginSuccessUrl if any\",\n { loginSuccessUrl },\n );\n const response = new NextResponse(\n `<html lang=\"en\"><span style=\"display:none\">${TOKEN_EXCHANGE_SUCCESS_TEXT}</span></html>`,\n );\n response.headers.set(\"Content-Type\", \"text/html; charset=utf-8\");\n return response;\n } else {\n logger.debug(\n \"CASE 2b: iframe mode with no loginSuccessUrl configured. Doing a normal redirect without relying on the iframe container to redirect.\",\n );\n return NextResponse.redirect(`${appUrl}`);\n }\n }\n\n // CASE 3: We're not in iframe mode. We can just do a stright http redirect to the final destination, which is either the loginSuccessUrl if specified, or the appUrl.\n logger.debug(\"CASE 3: non-iframe mode, redirecting to loginSuccessUrl\");\n return NextResponse.redirect(`${loginSuccessUrl || appUrl}`);\n};\n\nasync function handleCallback(\n request: NextRequest,\n config: AuthConfig,\n): Promise<NextResponse> {\n const resolvedConfigs = resolveAuthConfig(config);\n const code = request.nextUrl.searchParams.get(\"code\");\n const state = request.nextUrl.searchParams.get(\"state\");\n\n if (!code || !state) throw new AuthError(\"Bad parameters\", 400);\n\n // appUrl is passed from the client to the server in the query string\n // this is necessary because the server does not have access to the client's window.location.origin\n // and can not accurately determine the appUrl (specially if the app is behind a reverse proxy)\n const appUrl = getAppUrl(request);\n\n // If the integrator has specified a loginSuccessUrl, we'll send the user there after the login completes (including token exchange)\n // We pass in the basePath from config to use as the baseUrl, because we might not have access to the app_url cookie at this point if this was a third-party redirect.\n const loginSuccessUrl = getLoginSuccessUrl(request, appUrl);\n\n const tokenExchangeCompleteParams = {\n request,\n config,\n appUrl,\n state,\n loginSuccessUrl,\n };\n\n const user = await getUser();\n if (user) {\n // User already authenticated.\n return handleTokenExchangeComplete(tokenExchangeCompleteParams);\n }\n\n // User not authenticated yet.\n\n // If we have a code_verifier cookie and the appUrl, we can do a token exchange.\n // Otherwise, just render an empty page.\n // The initial redirect back from the auth server does not send cookies, because the redirect is from a 3rd-party domain.\n // The client will make an additional call to this route with cookies included, at which point we do the token exchange.\n const codeVerifier = request.cookies.get(CodeVerifier.COOKIE_NAME);\n\n if (!codeVerifier || !appUrl) {\n logger.debug(\"handleCallback no code_verifier found\", {\n state,\n serverTokenExchange: serverTokenExchangeFromState(`${state}`),\n });\n let response = new NextResponse(\n `<html lang=\"en\"><body><span style=\"display:none\">${TOKEN_EXCHANGE_TRIGGER_TEXT}</span></body></html>`,\n );\n\n // in server-side token exchange mode we need to launch a page that will trigger the token exchange\n // from the same domain, allowing it access to the code_verifier cookie\n // we only need to do this in redirect mode, as the iframe already triggers a client-side token exchange\n // if no code-verifier cookie is found\n if (state && serverTokenExchangeFromState(state)) {\n logger.debug(\n \"handleCallback serverTokenExchangeFromState, launching redirect page...\",\n {\n requestUrl: request.url,\n configCallbackUrl: resolvedConfigs.callbackUrl,\n },\n );\n // generate a page that will callback to the same domain, allowing access\n // to the code_verifier cookie and passing the appUrl.\n response = generateHtmlResponseWithCallback(\n request,\n resolvedConfigs.callbackUrl,\n loginSuccessUrl || undefined,\n );\n }\n logger.debug(\n `handleCallback no code_verifier found, returning ${TOKEN_EXCHANGE_TRIGGER_TEXT}`,\n );\n return response;\n }\n\n await performTokenExchangeAndSetCookies(resolvedConfigs, code, state, appUrl);\n return handleTokenExchangeComplete(tokenExchangeCompleteParams);\n}\n\n/**\n * If redirectPath is an absolute path, return it as-is.\n * Otherwise for relative paths, append it to the current domain.\n * @param redirectPath\n * @param currentBasePath\n * @returns\n */\nconst getAbsoluteRedirectPath = (\n redirectPath: string,\n currentBasePath: string,\n) => new URL(redirectPath, currentBasePath).href;\n\nconst getPostLogoutRedirectUrl = (\n request: NextRequest,\n config: AuthConfig,\n): string => {\n const { loginUrl } = resolveAuthConfig(config);\n const redirectTarget = loginUrl ?? \"/\";\n\n // if the optional loginUrl is provided and it is an absolute URL,\n // use it as the redirect target\n const isAbsoluteRedirect = /^(https?:\\/\\/|www\\.).+/i.test(redirectTarget);\n if (isAbsoluteRedirect) {\n return redirectTarget;\n }\n\n // if loginUrl is not defined, the appUrl is passed from the client to the server\n // in the query string or cookies. This is necessary because the server does not\n // have access to the client's window.location and can not accurately determine\n // the appUrl (specially if the app is behind a reverse proxy).\n const appUrl = getAppUrl(request);\n if (appUrl) return getAbsoluteRedirectPath(redirectTarget, appUrl);\n\n // If we can't determine the post-logout redirect URL, fallback to the app root as it's the most likely location of the login page.\n return request.nextUrl.origin;\n};\n\nconst revalidateUrlPath = async (url: string) => {\n try {\n const path = new URL(url).pathname;\n revalidatePath(path);\n } catch (error) {\n logger.warn(\"Failed to revalidate path after logout:\", error);\n }\n};\n\nexport async function handleLogout(\n request: NextRequest,\n config: AuthConfig,\n): Promise<NextResponse> {\n const resolvedConfigs = resolveAuthConfig(config);\n\n // Ensure we have the proper app URL including any base path\n const appBaseUrl = getAppUrl(request) || request.url;\n\n // Construct the post-logout URL with the base path included\n const postLogoutUrl = new URL(resolvedConfigs.logoutCallbackUrl, appBaseUrl);\n\n // read the id_token from the cookies\n const idToken = await getIdToken(resolvedConfigs);\n\n // read the state from the query parameters\n const state = request.nextUrl.searchParams.get(\"state\");\n\n if (!state || !idToken) {\n logger.error(\"handleLogout: missing state or idToken\", { state, idToken });\n await clearAuthCookies();\n // if token or state is missing, the logout call to the server will fail,\n // (token has potentially expired already) so go straight to the postLogoutUrl\n // so the user can be signed out.\n return NextResponse.redirect(\n `${postLogoutUrl}${state ? \"?state=\" + state : \"\"}`,\n );\n }\n\n const displayMode = displayModeFromState(state, \"iframe\");\n if (displayMode === \"iframe\") {\n // clear auth cookies immediately before calling the logout endpoint to give faster UX\n await clearAuthCookies();\n await revalidateUrlPath(request.url);\n }\n\n const logoutUrl = await generateOauthLogoutUrl({\n clientId: resolvedConfigs.clientId,\n idToken,\n state,\n redirectUrl: postLogoutUrl.href,\n oauthServer: resolvedConfigs.oauthServer,\n });\n return NextResponse.redirect(`${logoutUrl.href}`);\n}\n\nconst isCalledFromBrowserFetch = (request: NextRequest) =>\n request.url.includes(\"sameDomainCallback=true\");\n\n/**\n * Called after the cookies have been cleared.\n */\ntype LogoutCompleteInputs = {\n request: NextRequest;\n resolvedConfigs: AuthConfigWithDefaults;\n};\nconst handleLogoutComplete = async (params: LogoutCompleteInputs) => {\n const { request, resolvedConfigs } = params;\n const state = request.nextUrl.searchParams.get(\"state\");\n const postLogoutRedirectUrl = getPostLogoutRedirectUrl(\n request,\n resolvedConfigs,\n );\n\n // If this is a FETCH call, we can only return json. Trying to redirect or return HTML will fail.\n if (isCalledFromBrowserFetch(request)) {\n // The client-side JS will do a window.location.href redirect to postLogoutRedirectUrl when this request returns success.\n return NextResponse.json({\n status: \"success\",\n redirectUrl: postLogoutRedirectUrl,\n });\n }\n\n // If this is a redirect inside an iframe and the user is indeed logged out, render some text that makes the parent redirect to the postLogoutRedirectUrl.\n const user = await getUser();\n if (!user && !!state && displayModeFromState(state, \"iframe\") === \"iframe\") {\n // User is logged out while in an iframe redirect (not a FETCH call).\n // Render some text to make the CivicLogoutIframeContainer redirect to the postLogoutRedirectUrl.\n const response = new NextResponse(\n `<html lang=\"en\"><span style=\"display:none\">${LOGOUT_SUCCESS_TEXT}<a href=\"${[postLogoutRedirectUrl]}\" rel=\"civic-auth-post-logout-redirect-url\"></a></span></html>`,\n );\n response.headers.set(\"Content-Type\", \"text/html; charset=utf-8\");\n return response;\n }\n\n revalidateUrlPath(postLogoutRedirectUrl);\n return NextResponse.redirect(postLogoutRedirectUrl);\n};\n\nexport async function handleLogoutCallback(\n request: NextRequest,\n config: AuthConfig,\n): Promise<NextResponse> {\n const resolvedConfigs = resolveAuthConfig(config);\n const canAccessCookies = !!(await getIdToken(resolvedConfigs));\n\n // If we have access to cookies, clear them.\n if (canAccessCookies) {\n await clearAuthCookies();\n return handleLogoutComplete({ request, resolvedConfigs });\n }\n\n // If we don't have access to cookies, render some javascript to the client that will:\n // 1. make a same-domain fetch call back to this endpoint and receive a '{status: \"success\"}' back.\n // 2. On status: success, set the window.location.href to the post-logout redirect URL (usually the appUrl).\n return generateHtmlResponseWithCallback(\n request,\n // The client-side JS will make a fetch call back to this URL.\n resolvedConfigs.logoutCallbackUrl,\n );\n}\n\n/**\n * Creates an authentication handler for Next.js API routes\n *\n * Usage:\n * ```ts\n * // app/api/auth/[...civicauth]/route.ts\n * import { handler } from '@civic/auth/nextjs'\n * export const GET = handler({\n * // optional config overrides\n * })\n * ```\n */\nexport const handler =\n (authConfig = {}) =>\n async (request: NextRequest): Promise<NextResponse> => {\n const config = resolveAuthConfig(authConfig);\n\n try {\n const pathname = request.nextUrl.pathname;\n const pathSegments = pathname.split(\"/\");\n const lastSegment = pathSegments[pathSegments.length - 1];\n\n switch (lastSegment) {\n case \"challenge\":\n return await handleChallenge(request, config);\n case \"callback\":\n return await handleCallback(request, config);\n case \"refresh\":\n return await handleRefresh(request, config);\n case \"logout\":\n return await handleLogout(request, config);\n case \"logoutcallback\":\n return await handleLogoutCallback(request, config);\n default:\n throw new AuthError(`Invalid auth route: ${pathname}`, 404);\n }\n } catch (error) {\n logger.error(\"Auth handler error:\", error);\n\n const status = error instanceof AuthError ? error.status : 500;\n const message =\n error instanceof Error ? error.message : \"Authentication failed\";\n\n const response = NextResponse.json({ error: message }, { status });\n\n await clearAuthCookies();\n return response;\n }\n };\n"]}
1
+ {"version":3,"file":"routeHandler.js","sourceRoot":"","sources":["../../src/nextjs/routeHandler.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n LOGOUT_SUCCESS_TEXT,\n TOKEN_EXCHANGE_SUCCESS_TEXT,\n TOKEN_EXCHANGE_TRIGGER_TEXT,\n} from \"@/constants.js\";\nimport { loggers } from \"@/lib/logger.js\";\nimport {\n displayModeFromState,\n loginSuccessUrlFromState,\n serverTokenExchangeFromState,\n} from \"@/lib/oauth.js\";\nimport type { AuthConfig, AuthConfigWithDefaults } from \"@/nextjs/config.js\";\nimport { resolveAuthConfig } from \"@/nextjs/config.js\";\nimport { clearAuthCookies, NextjsCookieStorage } from \"@/nextjs/cookies.js\";\nimport { getUser } from \"@/nextjs/index.js\";\nimport { resolveCallbackUrl } from \"@/nextjs/utils.js\";\nimport { resolveOAuthAccessCode } from \"@/server/login.js\";\nimport { GenericPublicClientPKCEProducer } from \"@/services/PKCE.js\";\nimport { CodeVerifier, OAuthTokenTypes } from \"@/shared/lib/types.js\";\nimport { GenericUserSession } from \"@/shared/lib/UserSession.js\";\nimport { clearTokens, generateOauthLogoutUrl } from \"@/shared/lib/util.js\";\nimport { revalidatePath } from \"next/cache.js\";\nimport type { NextRequest } from \"next/server.js\";\nimport { NextResponse } from \"next/server.js\";\nimport { NextServerAuthenticationRefresherImpl } from \"./NextServerAuthenticationRefresherImpl.js\";\n\nconst logger = loggers.nextjs.handlers.auth;\n\nclass AuthError extends Error {\n constructor(\n message: string,\n public readonly status: number = 401,\n ) {\n super(message);\n this.name = \"AuthError\";\n }\n}\n\nconst tryUriDecode = (value: string): string | null => {\n try {\n return decodeURIComponent(value);\n } catch (e) {\n logger.error(\"Error decoding URI component:\", e);\n return value;\n }\n};\n\nconst getDecodedQueryParam = (\n request: NextRequest,\n paramName: string,\n): string | null => {\n const queryParam = request.nextUrl.searchParams.get(paramName);\n if (queryParam) {\n return tryUriDecode(queryParam);\n }\n return null;\n};\n\nconst getCookieOrQueryParam = (\n request: NextRequest,\n cookieName: string,\n queryName: string,\n): string | null => {\n // First check the cookie as it might have the full path with base directory\n const cookieValue = request.cookies.get(cookieName)?.value;\n if (cookieValue) {\n return tryUriDecode(cookieValue);\n }\n\n // Fallback to query parameter\n return getDecodedQueryParam(request, queryName);\n};\n\nconst getAppUrl = (request: NextRequest): string | null =>\n getCookieOrQueryParam(request, CodeVerifier.APP_URL, \"appUrl\");\n\n// The loginSuccessUrl can either be decoded from the state parameter, or passed as a cookie or query parameter\nconst getLoginSuccessUrl = (\n request: NextRequest,\n baseUrl?: string | null,\n): string | null => {\n const loginSuccessUrl =\n loginSuccessUrlFromState(request.nextUrl.searchParams.get(\"state\")) ||\n getDecodedQueryParam(request, \"loginSuccessUrl\");\n if (!loginSuccessUrl) {\n return null;\n }\n return baseUrl ? new URL(loginSuccessUrl, baseUrl).href : loginSuccessUrl;\n};\n\nconst getIdToken = async (config: AuthConfig): Promise<string | null> => {\n const cookieStorage = new NextjsCookieStorage(config.cookies?.tokens ?? {});\n return cookieStorage.get(OAuthTokenTypes.ID_TOKEN);\n};\n\n/**\n * create a code verifier and challenge for PKCE\n * saving the verifier in a cookie for later use\n * @returns {Promise<NextResponse>}\n */\nasync function handleChallenge(\n request: NextRequest,\n config: AuthConfig,\n): Promise<NextResponse> {\n const cookieStorage = new NextjsCookieStorage(config.cookies?.tokens ?? {});\n const pkceProducer = new GenericPublicClientPKCEProducer(cookieStorage);\n\n const challenge = await pkceProducer.getCodeChallenge();\n const appUrl = request.nextUrl.searchParams.get(\"appUrl\");\n if (appUrl) {\n await cookieStorage.set(CodeVerifier.APP_URL, appUrl);\n }\n\n return NextResponse.json({ status: \"success\", challenge });\n}\n\nconst getCookieStorageWithUserOverrides = (config: AuthConfig) => {\n const resolvedConfigs = resolveAuthConfig(config);\n return new NextjsCookieStorage({\n ...resolvedConfigs.cookies.tokens,\n user: resolvedConfigs.cookies.user,\n });\n};\nasync function performTokenExchangeAndSetCookies(\n config: AuthConfig,\n code: string,\n state: string,\n appUrl: string,\n) {\n const resolvedConfigs = resolveAuthConfig(config);\n // TODO This is messy, better would be to fix the config.cookies type to always be <name: settings>\n // rather than nesting the tokens-related ones *and* code-verifier inside \"tokens\"\n // (despite code-verifier not relating directly to tokens)\n const cookieStorage = getCookieStorageWithUserOverrides(config);\n\n const callbackUrl = resolveCallbackUrl(resolvedConfigs, appUrl);\n try {\n await resolveOAuthAccessCode(code, state, cookieStorage, {\n ...resolvedConfigs,\n redirectUrl: callbackUrl,\n });\n } catch (error) {\n logger.error(\"Token exchange failed:\", error);\n throw new AuthError(\"Failed to authenticate user\", 401);\n }\n\n const user = await getUser();\n if (!user) {\n throw new AuthError(\"Failed to get user info\", 401);\n }\n const userSession = new GenericUserSession(cookieStorage);\n await userSession.set(user);\n}\nasync function handleRefresh(\n request: NextRequest,\n config: AuthConfig,\n): Promise<NextResponse> {\n const resolvedConfigs = resolveAuthConfig(config);\n const cookieStorage = getCookieStorageWithUserOverrides(config);\n const userSession = new GenericUserSession(cookieStorage);\n try {\n const onError = (error: Error) => {\n logger.error(\"handleRefresh: Token refresh failed:\", error);\n throw new AuthError(\"Failed to refresh tokens\", 500);\n };\n const refresher = await NextServerAuthenticationRefresherImpl.build(\n {\n clientId: resolvedConfigs.clientId,\n oauthServer: resolvedConfigs.oauthServer,\n redirectUrl: resolvedConfigs.callbackUrl,\n refreshUrl: resolvedConfigs.refreshUrl,\n },\n cookieStorage,\n onError,\n );\n\n const tokens = await refresher.refreshAccessToken();\n const user = await getUser();\n if (!user) {\n throw new AuthError(\"Failed to get user info\", 401);\n }\n await userSession.set(user);\n const targetUrl = request.nextUrl.searchParams.get(\"targetUrl\");\n if (targetUrl) {\n return NextResponse.redirect(targetUrl);\n }\n return NextResponse.json({ status: \"success\", tokens });\n } catch (error) {\n logger.error(\n \"handleRefresh: Token refresh failed, clearing tokens:\",\n error,\n );\n await clearTokens(cookieStorage);\n await userSession.clear();\n const targetUrl = request.nextUrl.searchParams.get(\"targetUrl\");\n if (targetUrl) {\n logger.warn(\"redirecting to targetUrl\", targetUrl);\n return NextResponse.redirect(targetUrl);\n }\n return NextResponse.json({ status: \"failed\" });\n }\n}\n\nconst generateHtmlResponseWithCallback = (\n request: NextRequest,\n callbackUrl: string,\n loginSuccessUrl?: string,\n) => {\n // we need to replace the URL with resolved config in case the server is hosted\n // behind a reverse proxy or load balancer\n const requestUrl = new URL(request.url);\n const fetchUrl = `${callbackUrl}?${requestUrl.searchParams.toString()}&sameDomainCallback=true`;\n const loginSuccessSegment = loginSuccessUrl\n ? `&loginSuccessUrl=${encodeURIComponent(loginSuccessUrl)}`\n : \"\";\n const html = `<html lang=\"en\">\n <body>\n <span style=\"display:none\">\n <script>\n window.onload = function () {\n // Get the complete URL including origin and path\n // This ensures we capture any base path like /directory\n const appUrl = window.location.href.substring(\n 0,\n window.location.href.indexOf(\"/api/auth\")\n );\n fetch('${fetchUrl}&appUrl=' + encodeURIComponent(appUrl) + '${loginSuccessSegment}').then((response) => {\n response.json().then((jsonResponse) => {\n // For login: Redirect back to the callback route, so Case 2 in handleTokenExchangeComplete will be triggered\n // For logout: Redirect to the postLogoutRedirectUrl\n if(jsonResponse.redirectUrl) {\n window.location.href = jsonResponse.redirectUrl;\n }\n });\n });\n };\n </script>\n </span>\n </body>\n</html>\n`;\n const response = new NextResponse(html);\n response.headers.set(\"Content-Type\", \"text/html; charset=utf-8\");\n return response;\n};\n\ntype TokkenExchangeCompletInput = {\n request: NextRequest;\n config: AuthConfig;\n loginSuccessUrl?: string | null;\n appUrl?: string | null;\n state: string;\n};\n\nconst handleTokenExchangeComplete = async (\n params: TokkenExchangeCompletInput,\n) => {\n const { request, config, appUrl, loginSuccessUrl, state } = params;\n // Case 1: We are being called via fetch to facilitate access to the cookies. Return success json. The iframe has javascript that will reload this route so Case 2 below will be triggered.\n if (isCalledFromBrowserFetch(request)) {\n logger.debug(\n \"CASE 1: sameDomainCallback=true, returning JSON response with redirect URL\",\n { appUrl, loginSuccessUrl, callbackUrl: config.callbackUrl },\n );\n\n const currentUrl = new URL(request.url);\n // When the client-side JS redirects back here, we don't want to hit this branch again because we can't return JSON from a redirect.\n // So we strip off the sameDomainCallback parameter from the URL.\n const newSearchParams = new URLSearchParams(currentUrl.search);\n newSearchParams.delete(\"sameDomainCallback\");\n\n // We strip off the origin so reverse proxies don't break the redirect.\n const redirectUrl = `${currentUrl.pathname}?${newSearchParams.toString()}${currentUrl.hash}`;\n return NextResponse.json({\n status: \"success\",\n // This makes the iframe redirect back to this route, so Case 2 below will be triggered.\n\n redirectUrl,\n });\n }\n\n // Case 2: We are already authenticated and in iframe mode.\n // Case 2a: We have a custom loginSuccessUrl, so we have to trigger a top-level redirect to it. We do this by rendering a page with the TOKEN_EXCHANGE_SUCCESS_TEXT, which is then picked up by the iframe container.\n // Case 2b: We don't have a custom loginSuccessUrl, so we just redirect to the appUrl. If we don't do this, Cypress tests will fail in the 'no custom loginSuccessUrl' case, because in Cypress an iframe redirect is converted to a top-level redirect,\n // which means the iframe container no longer exists and so can't action the redirect.\n const user = await getUser();\n if (!!user && displayModeFromState(state, \"iframe\") === \"iframe\") {\n if (loginSuccessUrl) {\n logger.debug(\n \"CASE 2a: iframe mode with loginSuccessUrl configured. Returning TOKEN_EXCHANGE_SUCCESS_TEXT to trigger redirect to loginSuccessUrl if any\",\n { loginSuccessUrl },\n );\n const response = new NextResponse(\n `<html lang=\"en\"><span style=\"display:none\">${TOKEN_EXCHANGE_SUCCESS_TEXT}</span></html>`,\n );\n response.headers.set(\"Content-Type\", \"text/html; charset=utf-8\");\n return response;\n } else {\n logger.debug(\n \"CASE 2b: iframe mode with no loginSuccessUrl configured. Doing a normal redirect without relying on the iframe container to redirect.\",\n );\n return NextResponse.redirect(`${appUrl}`);\n }\n }\n\n // CASE 3: We're not in iframe mode. We can just do a stright http redirect to the final destination, which is either the loginSuccessUrl if specified, or the appUrl.\n logger.debug(\"CASE 3: non-iframe mode, redirecting to loginSuccessUrl\");\n return NextResponse.redirect(`${loginSuccessUrl || appUrl}`);\n};\n\nasync function handleCallback(\n request: NextRequest,\n config: AuthConfig,\n): Promise<NextResponse> {\n const resolvedConfigs = resolveAuthConfig(config);\n const code = request.nextUrl.searchParams.get(\"code\");\n const state = request.nextUrl.searchParams.get(\"state\");\n\n if (!code || !state) throw new AuthError(\"Bad parameters\", 400);\n\n // appUrl is passed from the client to the server in the query string\n // this is necessary because the server does not have access to the client's window.location.origin\n // and can not accurately determine the appUrl (specially if the app is behind a reverse proxy)\n const appUrl = getAppUrl(request);\n\n // If the integrator has specified a loginSuccessUrl, we'll send the user there after the login completes (including token exchange)\n // We pass in the basePath from config to use as the baseUrl, because we might not have access to the app_url cookie at this point if this was a third-party redirect.\n const loginSuccessUrl = getLoginSuccessUrl(request, appUrl);\n\n const tokenExchangeCompleteParams = {\n request,\n config,\n appUrl,\n state,\n loginSuccessUrl,\n };\n\n const user = await getUser();\n if (user) {\n // User already authenticated.\n return handleTokenExchangeComplete(tokenExchangeCompleteParams);\n }\n\n // User not authenticated yet.\n\n // If we have a code_verifier cookie and the appUrl, we can do a token exchange.\n // Otherwise, just render an empty page.\n // The initial redirect back from the auth server does not send cookies, because the redirect is from a 3rd-party domain.\n // The client will make an additional call to this route with cookies included, at which point we do the token exchange.\n const codeVerifier = request.cookies.get(CodeVerifier.COOKIE_NAME);\n\n if (!codeVerifier || !appUrl) {\n logger.debug(\"handleCallback no code_verifier found\", {\n state,\n serverTokenExchange: serverTokenExchangeFromState(`${state}`),\n });\n let response = new NextResponse(\n `<html lang=\"en\"><body><span style=\"display:none\">${TOKEN_EXCHANGE_TRIGGER_TEXT}</span></body></html>`,\n );\n\n // in server-side token exchange mode we need to launch a page that will trigger the token exchange\n // from the same domain, allowing it access to the code_verifier cookie\n // we only need to do this in redirect mode, as the iframe already triggers a client-side token exchange\n // if no code-verifier cookie is found\n if (state && serverTokenExchangeFromState(state)) {\n logger.debug(\n \"handleCallback serverTokenExchangeFromState, launching redirect page...\",\n {\n requestUrl: request.url,\n configCallbackUrl: resolvedConfigs.callbackUrl,\n },\n );\n // generate a page that will callback to the same domain, allowing access\n // to the code_verifier cookie and passing the appUrl.\n response = generateHtmlResponseWithCallback(\n request,\n resolvedConfigs.callbackUrl,\n loginSuccessUrl || undefined,\n );\n }\n logger.debug(\n `handleCallback no code_verifier found, returning ${TOKEN_EXCHANGE_TRIGGER_TEXT}`,\n );\n return response;\n }\n\n await performTokenExchangeAndSetCookies(resolvedConfigs, code, state, appUrl);\n return handleTokenExchangeComplete(tokenExchangeCompleteParams);\n}\n\n/**\n * If redirectPath is an absolute path, return it as-is.\n * Otherwise for relative paths, append it to the current domain.\n * @param redirectPath\n * @param currentBasePath\n * @returns\n */\nconst getAbsoluteRedirectPath = (\n redirectPath: string,\n currentBasePath: string,\n) => new URL(redirectPath, currentBasePath).href;\n\nconst getPostLogoutRedirectUrl = (\n request: NextRequest,\n config: AuthConfig,\n): string => {\n const { loginUrl } = resolveAuthConfig(config);\n // if we have a target URL in the request, it's come from civic middleware\n // and we should use it as the redirect target.\n const targetUrl = request.nextUrl.searchParams.get(\"targetUrl\");\n if (targetUrl) {\n // If a targetUrl is provided, use it as the redirect target.\n // This is useful for redirecting to a specific page after logout.\n return targetUrl;\n }\n const redirectTarget = loginUrl ?? \"/\";\n\n // if the optional loginUrl is provided and it is an absolute URL,\n // use it as the redirect target\n const isAbsoluteRedirect = /^(https?:\\/\\/|www\\.).+/i.test(redirectTarget);\n if (isAbsoluteRedirect) {\n return redirectTarget;\n }\n\n // if loginUrl is not defined, the appUrl is passed from the client to the server\n // in the query string or cookies. This is necessary because the server does not\n // have access to the client's window.location and can not accurately determine\n // the appUrl (specially if the app is behind a reverse proxy).\n const appUrl = getAppUrl(request);\n if (appUrl) return getAbsoluteRedirectPath(redirectTarget, appUrl);\n\n // If we can't determine the post-logout redirect URL, fallback to the app root as it's the most likely location of the login page.\n return request.nextUrl.origin;\n};\n\nconst revalidateUrlPath = async (url: string) => {\n try {\n const path = new URL(url).pathname;\n revalidatePath(path);\n } catch (error) {\n logger.warn(\"Failed to revalidate path after logout:\", error);\n }\n};\n\nexport async function handleLogout(\n request: NextRequest,\n config: AuthConfig,\n): Promise<NextResponse> {\n const resolvedConfigs = resolveAuthConfig(config);\n\n // Ensure we have the proper app URL including any base path\n const appBaseUrl = getAppUrl(request) || request.url;\n\n // Construct the post-logout URL with the base path included\n const postLogoutUrl = new URL(resolvedConfigs.logoutCallbackUrl, appBaseUrl);\n\n // read the id_token from the cookies\n const idToken = await getIdToken(resolvedConfigs);\n\n // read the state from the query parameters\n const state = request.nextUrl.searchParams.get(\"state\");\n\n if (!state || !idToken) {\n logger.error(\"handleLogout: missing state or idToken\", { state, idToken });\n await clearAuthCookies();\n // if token or state is missing, the logout call to the server will fail,\n // (token has potentially expired already) so go straight to the postLogoutUrl\n // so the user can be signed out.\n return NextResponse.redirect(\n `${postLogoutUrl}${state ? \"?state=\" + state : \"\"}`,\n );\n }\n\n const displayMode = displayModeFromState(state, \"iframe\");\n if (displayMode === \"iframe\") {\n // clear auth cookies immediately before calling the logout endpoint to give faster UX\n await clearAuthCookies();\n await revalidateUrlPath(request.url);\n }\n\n const logoutUrl = await generateOauthLogoutUrl({\n clientId: resolvedConfigs.clientId,\n idToken,\n state,\n redirectUrl: postLogoutUrl.href,\n oauthServer: resolvedConfigs.oauthServer,\n });\n return NextResponse.redirect(`${logoutUrl.href}`);\n}\n\nconst isCalledFromBrowserFetch = (request: NextRequest) =>\n request.url.includes(\"sameDomainCallback=true\");\n\n/**\n * Called after the cookies have been cleared.\n */\ntype LogoutCompleteInputs = {\n request: NextRequest;\n resolvedConfigs: AuthConfigWithDefaults;\n};\nconst handleLogoutComplete = async (params: LogoutCompleteInputs) => {\n const { request, resolvedConfigs } = params;\n const state = request.nextUrl.searchParams.get(\"state\");\n const postLogoutRedirectUrl = getPostLogoutRedirectUrl(\n request,\n resolvedConfigs,\n );\n\n // If this is a FETCH call, we can only return json. Trying to redirect or return HTML will fail.\n if (isCalledFromBrowserFetch(request)) {\n // The client-side JS will do a window.location.href redirect to postLogoutRedirectUrl when this request returns success.\n return NextResponse.json({\n status: \"success\",\n redirectUrl: postLogoutRedirectUrl,\n });\n }\n\n // If this is a redirect inside an iframe and the user is indeed logged out, render some text that makes the parent redirect to the postLogoutRedirectUrl.\n const user = await getUser();\n if (!user && !!state && displayModeFromState(state, \"iframe\") === \"iframe\") {\n // User is logged out while in an iframe redirect (not a FETCH call).\n // Render some text to make the CivicLogoutIframeContainer redirect to the postLogoutRedirectUrl.\n const response = new NextResponse(\n `<html lang=\"en\"><span style=\"display:none\">${LOGOUT_SUCCESS_TEXT}<a href=\"${[postLogoutRedirectUrl]}\" rel=\"civic-auth-post-logout-redirect-url\"></a></span></html>`,\n );\n response.headers.set(\"Content-Type\", \"text/html; charset=utf-8\");\n return response;\n }\n\n revalidateUrlPath(postLogoutRedirectUrl);\n return NextResponse.redirect(postLogoutRedirectUrl);\n};\n\nexport async function handleLogoutCallback(\n request: NextRequest,\n config: AuthConfig,\n): Promise<NextResponse> {\n const resolvedConfigs = resolveAuthConfig(config);\n const canAccessCookies = !!(await getIdToken(resolvedConfigs));\n\n // If we have access to cookies, clear them.\n if (canAccessCookies) {\n await clearAuthCookies();\n return handleLogoutComplete({ request, resolvedConfigs });\n }\n\n // If we don't have access to cookies, render some javascript to the client that will:\n // 1. make a same-domain fetch call back to this endpoint and receive a '{status: \"success\"}' back.\n // 2. On status: success, set the window.location.href to the post-logout redirect URL (usually the appUrl).\n return generateHtmlResponseWithCallback(\n request,\n // The client-side JS will make a fetch call back to this URL.\n resolvedConfigs.logoutCallbackUrl,\n );\n}\n\n/**\n * Creates an authentication handler for Next.js API routes\n *\n * Usage:\n * ```ts\n * // app/api/auth/[...civicauth]/route.ts\n * import { handler } from '@civic/auth/nextjs'\n * export const GET = handler({\n * // optional config overrides\n * })\n * ```\n */\nexport const handler =\n (authConfig = {}) =>\n async (request: NextRequest): Promise<NextResponse> => {\n const config = resolveAuthConfig(authConfig);\n\n try {\n const pathname = request.nextUrl.pathname;\n const pathSegments = pathname.split(\"/\");\n const lastSegment = pathSegments[pathSegments.length - 1];\n\n switch (lastSegment) {\n case \"challenge\":\n return await handleChallenge(request, config);\n case \"callback\":\n return await handleCallback(request, config);\n case \"refresh\":\n return await handleRefresh(request, config);\n case \"logout\":\n return await handleLogout(request, config);\n case \"logoutcallback\":\n return await handleLogoutCallback(request, config);\n default:\n throw new AuthError(`Invalid auth route: ${pathname}`, 404);\n }\n } catch (error) {\n logger.error(\"Auth handler error:\", error);\n\n const status = error instanceof AuthError ? error.status : 500;\n const message =\n error instanceof Error ? error.message : \"Authentication failed\";\n\n const response = NextResponse.json({ error: message }, { status });\n\n await clearAuthCookies();\n return response;\n }\n };\n"]}
@@ -1,23 +1,18 @@
1
- import { AuthStatus, type AuthStorage, type DisplayMode, type User } from "../../types.js";
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, storage, }?: SignInProps) => {
18
- signIn: () => Promise<SignInResult>;
12
+ declare const useSignIn: ({ pkceConsumer, preSignOut, postSignOut, displayMode }?: SignInProps) => {
13
+ signIn: () => Promise<void>;
19
14
  signOut: () => Promise<void>;
20
- startSignIn: () => Promise<SignInResult>;
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,EAChB,KAAK,WAAW,EAEhB,KAAK,IAAI,EACV,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAc,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AASpE,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;IACzB,OAAO,CAAC,EAAE,WAAW,CAAC;CACvB,CAAC;AAYF,KAAK,YAAY,GAAG;IAClB,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAClB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;CACrB,CAAC;AAIF;;GAEG;AACH,QAAA,MAAM,SAAS,sEAOV,WAAW;kBA6RuB,OAAO,CAAC,YAAY,CAAC;;uBA3HhB,OAAO,CAAC,YAAY,CAAC;;;CA2ThE,CAAC;AAEF,OAAO,EAAE,SAAS,EAAE,CAAC"}
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, storage, } = {
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 success
41
- const resolveSignInPromiseWithSuccess = useCallback(async () => {
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
- // Get user data from storage
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, storage]);
64
- // Helper to resolve sign-in promise with error
65
- const resolveSignInPromiseWithError = useCallback((error, newStatus = AuthStatus.ERROR) => {
66
- if (signInResolveRef.current) {
67
- // Always resolve, but with error set and user as null
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
- user: null,
134
- error: new Error("Authentication initiator not available"),
135
- };
136
- // Check if sign-in is already in progress using the ref, if so, return existing promise
137
- if (isSigningInRef.current && signInPromiseRef.current) {
138
- return signInPromiseRef.current;
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 - check early states before creating promise
135
+ // State machine for sign-in flow
141
136
  switch (authStatus) {
142
- case AuthStatus.AUTHENTICATED: {
143
- // Get current user if already authenticated
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
- // Create the promise and store its handlers ONLY if we're starting a new sign-in
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 resolve the promise with error if authentication takes too long
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
- resolveSignInPromiseWithError(new Error("Sign-in timeout"));
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
- resolveSignInPromiseWithError(retryError instanceof Error
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
- resolveSignInPromiseWithError(error instanceof Error ? error : new Error(String(error)));
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
- resolveSignInPromiseWithError,
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
- resolveSignInPromiseWithSuccess();
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
- resolveSignInPromiseWithError(error instanceof Error
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
- resolveSignInPromiseWithSuccess();
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
- resolveSignInPromiseWithError(new Error("Sign-in aborted by user"), AuthStatus.UNAUTHENTICATED);
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
- resolveSignInPromiseWithSuccess,
361
- resolveSignInPromiseWithError,
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":"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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 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, User } from "../../types.js";
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<SignInResult>;
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,IAAI,EAAE,MAAM,YAAY,CAAC;AAEhE,KAAK,YAAY,GAAG;IAClB,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAClB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE,CAAC,WAAW,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;IAC7D,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
+ {"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;AAiBtC,MAAM,CAAC,MAAM,WAAW,GAAG,aAAa,CAAyB,IAAI,CAAC,CAAC","sourcesContent":["\"use client\";\nimport { createContext } from \"react\";\nimport type { AuthStatus, DisplayMode, User } from \"@/types.js\";\n\ntype SignInResult = {\n user: User | null;\n error: Error | null;\n};\n\nexport type AuthContextType = {\n signIn: (displayMode?: DisplayMode) => Promise<SignInResult>;\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"]}
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"]}