@civic/auth 0.8.2 → 0.8.3-beta.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 (132) hide show
  1. package/README.md +6 -0
  2. package/dist/lib/oauth.d.ts +4 -2
  3. package/dist/lib/oauth.d.ts.map +1 -1
  4. package/dist/lib/oauth.js +4 -2
  5. package/dist/lib/oauth.js.map +1 -1
  6. package/dist/nextjs/NextClientAuthenticationRefresher.d.ts +1 -1
  7. package/dist/nextjs/NextClientAuthenticationRefresher.d.ts.map +1 -1
  8. package/dist/nextjs/NextClientAuthenticationRefresher.js.map +1 -1
  9. package/dist/nextjs/NextServerAuthenticationRefresherImpl.d.ts +1 -1
  10. package/dist/nextjs/NextServerAuthenticationRefresherImpl.d.ts.map +1 -1
  11. package/dist/nextjs/NextServerAuthenticationRefresherImpl.js +3 -0
  12. package/dist/nextjs/NextServerAuthenticationRefresherImpl.js.map +1 -1
  13. package/dist/nextjs/routeHandler.d.ts.map +1 -1
  14. package/dist/nextjs/routeHandler.js +2 -1
  15. package/dist/nextjs/routeHandler.js.map +1 -1
  16. package/dist/reactjs/core/GlobalAuthManager.d.ts +15 -0
  17. package/dist/reactjs/core/GlobalAuthManager.d.ts.map +1 -1
  18. package/dist/reactjs/core/GlobalAuthManager.js +26 -1
  19. package/dist/reactjs/core/GlobalAuthManager.js.map +1 -1
  20. package/dist/reactjs/hooks/useUser.d.ts +3 -0
  21. package/dist/reactjs/hooks/useUser.d.ts.map +1 -1
  22. package/dist/reactjs/hooks/useUser.js +32 -0
  23. package/dist/reactjs/hooks/useUser.js.map +1 -1
  24. package/dist/reactjs/providers/CivicAuthContext.d.ts +4 -0
  25. package/dist/reactjs/providers/CivicAuthContext.d.ts.map +1 -1
  26. package/dist/reactjs/providers/CivicAuthContext.js +22 -13
  27. package/dist/reactjs/providers/CivicAuthContext.js.map +1 -1
  28. package/dist/reactjs/providers/CivicAuthProvider.d.ts +1 -0
  29. package/dist/reactjs/providers/CivicAuthProvider.d.ts.map +1 -1
  30. package/dist/reactjs/providers/CivicAuthProvider.js +3 -1
  31. package/dist/reactjs/providers/CivicAuthProvider.js.map +1 -1
  32. package/dist/server/config.d.ts +47 -0
  33. package/dist/server/config.d.ts.map +1 -1
  34. package/dist/server/config.js.map +1 -1
  35. package/dist/server/index.d.ts +8 -2
  36. package/dist/server/index.d.ts.map +1 -1
  37. package/dist/server/index.js +5 -1
  38. package/dist/server/index.js.map +1 -1
  39. package/dist/server/login.d.ts +9 -0
  40. package/dist/server/login.d.ts.map +1 -1
  41. package/dist/server/login.js +4 -2
  42. package/dist/server/login.js.map +1 -1
  43. package/dist/server/refresh.d.ts +1 -1
  44. package/dist/server/refresh.d.ts.map +1 -1
  45. package/dist/server/refresh.js.map +1 -1
  46. package/dist/server/session.d.ts +60 -2
  47. package/dist/server/session.d.ts.map +1 -1
  48. package/dist/server/session.js +216 -5
  49. package/dist/server/session.js.map +1 -1
  50. package/dist/server/types/express.d.ts +97 -0
  51. package/dist/server/types/express.d.ts.map +1 -0
  52. package/dist/server/types/express.js +2 -0
  53. package/dist/server/types/express.js.map +1 -0
  54. package/dist/services/AuthenticationService.d.ts +6 -0
  55. package/dist/services/AuthenticationService.d.ts.map +1 -1
  56. package/dist/services/AuthenticationService.js +48 -6
  57. package/dist/services/AuthenticationService.js.map +1 -1
  58. package/dist/services/types.d.ts +1 -1
  59. package/dist/services/types.d.ts.map +1 -1
  60. package/dist/services/types.js.map +1 -1
  61. package/dist/shared/components/CivicAuthIframe.d.ts +1 -0
  62. package/dist/shared/components/CivicAuthIframe.d.ts.map +1 -1
  63. package/dist/shared/components/CivicAuthIframe.js +4 -4
  64. package/dist/shared/components/CivicAuthIframe.js.map +1 -1
  65. package/dist/shared/components/CivicAuthIframeContainer.d.ts +2 -1
  66. package/dist/shared/components/CivicAuthIframeContainer.d.ts.map +1 -1
  67. package/dist/shared/components/CivicAuthIframeContainer.js +10 -3
  68. package/dist/shared/components/CivicAuthIframeContainer.js.map +1 -1
  69. package/dist/shared/hooks/useSignIn.d.ts.map +1 -1
  70. package/dist/shared/hooks/useSignIn.js +2 -1
  71. package/dist/shared/hooks/useSignIn.js.map +1 -1
  72. package/dist/shared/lib/AuthenticationRefresherImpl.d.ts +2 -2
  73. package/dist/shared/lib/AuthenticationRefresherImpl.d.ts.map +1 -1
  74. package/dist/shared/lib/AuthenticationRefresherImpl.js +3 -0
  75. package/dist/shared/lib/AuthenticationRefresherImpl.js.map +1 -1
  76. package/dist/shared/lib/GenericAuthenticationRefresher.d.ts +2 -2
  77. package/dist/shared/lib/GenericAuthenticationRefresher.d.ts.map +1 -1
  78. package/dist/shared/lib/GenericAuthenticationRefresher.js.map +1 -1
  79. package/dist/shared/lib/iframeUtils.d.ts +1 -0
  80. package/dist/shared/lib/iframeUtils.d.ts.map +1 -1
  81. package/dist/shared/lib/iframeUtils.js +3 -0
  82. package/dist/shared/lib/iframeUtils.js.map +1 -1
  83. package/dist/shared/lib/util.d.ts +7 -0
  84. package/dist/shared/lib/util.d.ts.map +1 -1
  85. package/dist/shared/lib/util.js +12 -0
  86. package/dist/shared/lib/util.js.map +1 -1
  87. package/dist/shared/version.d.ts +1 -1
  88. package/dist/shared/version.d.ts.map +1 -1
  89. package/dist/shared/version.js +1 -1
  90. package/dist/shared/version.js.map +1 -1
  91. package/dist/vanillajs/auth/BackendAuthenticationRefresher.d.ts +41 -0
  92. package/dist/vanillajs/auth/BackendAuthenticationRefresher.d.ts.map +1 -0
  93. package/dist/vanillajs/auth/BackendAuthenticationRefresher.js +125 -0
  94. package/dist/vanillajs/auth/BackendAuthenticationRefresher.js.map +1 -0
  95. package/dist/vanillajs/auth/CivicAuth.d.ts +66 -0
  96. package/dist/vanillajs/auth/CivicAuth.d.ts.map +1 -1
  97. package/dist/vanillajs/auth/CivicAuth.js +296 -10
  98. package/dist/vanillajs/auth/CivicAuth.js.map +1 -1
  99. package/dist/vanillajs/auth/SessionManager.d.ts +31 -3
  100. package/dist/vanillajs/auth/SessionManager.d.ts.map +1 -1
  101. package/dist/vanillajs/auth/SessionManager.js +253 -22
  102. package/dist/vanillajs/auth/SessionManager.js.map +1 -1
  103. package/dist/vanillajs/auth/TokenRefresher.d.ts.map +1 -1
  104. package/dist/vanillajs/auth/TokenRefresher.js +31 -18
  105. package/dist/vanillajs/auth/TokenRefresher.js.map +1 -1
  106. package/dist/vanillajs/auth/config/ConfigProcessor.d.ts.map +1 -1
  107. package/dist/vanillajs/auth/config/ConfigProcessor.js +14 -8
  108. package/dist/vanillajs/auth/config/ConfigProcessor.js.map +1 -1
  109. package/dist/vanillajs/auth/handlers/IframeAuthHandler.d.ts +34 -0
  110. package/dist/vanillajs/auth/handlers/IframeAuthHandler.d.ts.map +1 -1
  111. package/dist/vanillajs/auth/handlers/IframeAuthHandler.js +139 -0
  112. package/dist/vanillajs/auth/handlers/IframeAuthHandler.js.map +1 -1
  113. package/dist/vanillajs/auth/handlers/MessageHandler.d.ts +21 -0
  114. package/dist/vanillajs/auth/handlers/MessageHandler.d.ts.map +1 -1
  115. package/dist/vanillajs/auth/handlers/MessageHandler.js +52 -2
  116. package/dist/vanillajs/auth/handlers/MessageHandler.js.map +1 -1
  117. package/dist/vanillajs/auth/types/AuthTypes.d.ts +17 -0
  118. package/dist/vanillajs/auth/types/AuthTypes.d.ts.map +1 -1
  119. package/dist/vanillajs/auth/types/AuthTypes.js +1 -0
  120. package/dist/vanillajs/auth/types/AuthTypes.js.map +1 -1
  121. package/dist/vanillajs/iframe/IframeManager.d.ts +36 -0
  122. package/dist/vanillajs/iframe/IframeManager.d.ts.map +1 -1
  123. package/dist/vanillajs/iframe/IframeManager.js +205 -18
  124. package/dist/vanillajs/iframe/IframeManager.js.map +1 -1
  125. package/dist/vanillajs/index.d.ts +2 -0
  126. package/dist/vanillajs/index.d.ts.map +1 -1
  127. package/dist/vanillajs/index.js +4 -0
  128. package/dist/vanillajs/index.js.map +1 -1
  129. package/dist/vanillajs/ui/LoadingComponents.d.ts.map +1 -1
  130. package/dist/vanillajs/ui/LoadingComponents.js +1 -1
  131. package/dist/vanillajs/ui/LoadingComponents.js.map +1 -1
  132. package/package.json +7 -2
package/README.md CHANGED
@@ -11,6 +11,7 @@
11
11
  - [Getting User Information on the Frontend](#getting-user-information-on-the-frontend)
12
12
  - [Advanced Configuration](#advanced-configuration)
13
13
  - [Display Mode](#display-mode)
14
+ - [Browser-Specific Support](#browser-specific-support)
14
15
  - [API](#api)
15
16
  - [User Context](#user-context)
16
17
  - [User](#user)
@@ -30,6 +31,7 @@
30
31
  - [Getting User Information on the Backend](#getting-user-information-on-the-backend)
31
32
  - [Advanced Configuration](#advanced-configuration-1)
32
33
  - [Server Integration](#server-integration)
34
+ - [Client Secret Support](#client-secret-support)
33
35
  - [Using the CivicAuth Interface](#using-the-civicauth-interface)
34
36
  - [Quick Start](#quick-start-2)
35
37
  - [Framework Examples](#framework-examples)
@@ -181,6 +183,10 @@ The display mode indicates where the Civic login UI will be displayed. The foll
181
183
  * `redirect`: the UI redirects the current URL to a Civic login screen, then redirects back to your site when login is complete
182
184
  * `new_tab`: the UI opens in a new tab or popup window (depending on browser preferences), and after login is complete, the tab or popup closes to return the user to your site
183
185
 
186
+ ### Browser-Specific Support
187
+
188
+ The Civic Auth SDK includes automatic browser detection to handle browser-specific limitations. Some browsers like Safari don't support creation of passkeys in 'iframe' mode. In cases like these we auto-initiate the 'redirect' flow so that your users have a seamless UX. The user sees a loader in place of the iframe, then the page redirects to show the login interface directly.
189
+
184
190
  ## API
185
191
 
186
192
  ### User Context
@@ -8,12 +8,13 @@ declare const getOauthEndpoints: (oauthServer: string) => Promise<Endpoints>;
8
8
  */
9
9
  type GenerateStateInput = {
10
10
  displayMode?: DisplayMode;
11
+ iframeDisplayMode?: "modal" | "embedded";
11
12
  serverTokenExchange?: boolean;
12
13
  loginSuccessUrl?: string;
13
14
  framework?: FrameworkType;
14
15
  sdkVersion?: string;
15
16
  };
16
- declare const generateState: ({ displayMode, serverTokenExchange, loginSuccessUrl, framework, sdkVersion, }: GenerateStateInput) => string;
17
+ declare const generateState: ({ displayMode, iframeDisplayMode, serverTokenExchange, loginSuccessUrl, framework, sdkVersion, }: GenerateStateInput) => string;
17
18
  /**
18
19
  * parses the state string from the OAuth2 flow, decoding the display mode too
19
20
  * @param state
@@ -23,5 +24,6 @@ declare const generateState: ({ displayMode, serverTokenExchange, loginSuccessUr
23
24
  declare const displayModeFromState: (state: string, sessionDisplayMode: DisplayMode | undefined) => DisplayMode | undefined;
24
25
  declare const serverTokenExchangeFromState: (state: string) => boolean | undefined;
25
26
  declare const loginSuccessUrlFromState: (state: string | null) => string | undefined;
26
- export { serverTokenExchangeFromState, loginSuccessUrlFromState, getIssuerVariations, getOauthEndpoints, displayModeFromState, generateState, };
27
+ declare const iframeDisplayModeFromState: (state: string) => "modal" | "embedded" | undefined;
28
+ export { serverTokenExchangeFromState, loginSuccessUrlFromState, getIssuerVariations, getOauthEndpoints, displayModeFromState, iframeDisplayModeFromState, generateState, };
27
29
  //# sourceMappingURL=oauth.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../../src/lib/oauth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,SAAS,EAET,aAAa,EACd,MAAM,YAAY,CAAC;AAGpB,QAAA,MAAM,mBAAmB,WAAY,MAAM,KAAG,MAAM,EAQnD,CAAC;AAMF,QAAA,MAAM,iBAAiB,gBAAuB,MAAM,KAAG,OAAO,CAAC,SAAS,CAmBvE,CAAC;AAEF;;;;GAIG;AACH,KAAK,kBAAkB,GAAG;IACxB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AACF,QAAA,MAAM,aAAa,kFAMhB,kBAAkB,KAAG,MAUvB,CAAC;AAEF;;;;;GAKG;AACH,QAAA,MAAM,oBAAoB,UACjB,MAAM,sBACO,WAAW,GAAG,SAAS,KAC1C,WAAW,GAAG,SAQhB,CAAC;AAqBF,QAAA,MAAM,4BAA4B,UAAW,MAAM,KAAG,OAAO,GAAG,SACvB,CAAC;AAE1C,QAAA,MAAM,wBAAwB,UAAW,MAAM,GAAG,IAAI,KAAG,MAAM,GAAG,SACT,CAAC;AAE1D,OAAO,EACL,4BAA4B,EAC5B,wBAAwB,EACxB,mBAAmB,EACnB,iBAAiB,EACjB,oBAAoB,EACpB,aAAa,GACd,CAAC"}
1
+ {"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../../src/lib/oauth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,SAAS,EAET,aAAa,EACd,MAAM,YAAY,CAAC;AAGpB,QAAA,MAAM,mBAAmB,WAAY,MAAM,KAAG,MAAM,EAQnD,CAAC;AAMF,QAAA,MAAM,iBAAiB,gBAAuB,MAAM,KAAG,OAAO,CAAC,SAAS,CAmBvE,CAAC;AAEF;;;;GAIG;AACH,KAAK,kBAAkB,GAAG;IACxB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,iBAAiB,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IACzC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AACF,QAAA,MAAM,aAAa,qGAOhB,kBAAkB,KAAG,MAWvB,CAAC;AAEF;;;;;GAKG;AACH,QAAA,MAAM,oBAAoB,UACjB,MAAM,sBACO,WAAW,GAAG,SAAS,KAC1C,WAAW,GAAG,SAQhB,CAAC;AAsBF,QAAA,MAAM,4BAA4B,UAAW,MAAM,KAAG,OAAO,GAAG,SACvB,CAAC;AAE1C,QAAA,MAAM,wBAAwB,UAAW,MAAM,GAAG,IAAI,KAAG,MAAM,GAAG,SACT,CAAC;AAE1D,QAAA,MAAM,0BAA0B,UACvB,MAAM,KACZ,OAAO,GAAG,UAAU,GAAG,SAAkD,CAAC;AAE7E,OAAO,EACL,4BAA4B,EAC5B,wBAAwB,EACxB,mBAAmB,EACnB,iBAAiB,EACjB,oBAAoB,EACpB,0BAA0B,EAC1B,aAAa,GACd,CAAC"}
package/dist/lib/oauth.js CHANGED
@@ -24,10 +24,11 @@ const getOauthEndpoints = async (oauthServer) => {
24
24
  cache[oauthServer] = endpoints;
25
25
  return endpoints;
26
26
  };
27
- const generateState = ({ displayMode, serverTokenExchange, loginSuccessUrl, framework, sdkVersion, }) => {
27
+ const generateState = ({ displayMode, iframeDisplayMode, serverTokenExchange, loginSuccessUrl, framework, sdkVersion, }) => {
28
28
  const jsonString = JSON.stringify({
29
29
  uuid: uuid(),
30
30
  ...(displayMode ? { displayMode } : {}),
31
+ ...(iframeDisplayMode ? { iframeDisplayMode } : {}),
31
32
  ...(serverTokenExchange ? { serverTokenExchange } : {}),
32
33
  ...(loginSuccessUrl ? { loginSuccessUrl } : {}),
33
34
  ...(framework ? { framework } : {}),
@@ -63,5 +64,6 @@ const decodeState = (state) => {
63
64
  };
64
65
  const serverTokenExchangeFromState = (state) => decodeState(state)?.serverTokenExchange;
65
66
  const loginSuccessUrlFromState = (state) => state ? decodeState(state)?.loginSuccessUrl : undefined;
66
- export { serverTokenExchangeFromState, loginSuccessUrlFromState, getIssuerVariations, getOauthEndpoints, displayModeFromState, generateState, };
67
+ const iframeDisplayModeFromState = (state) => decodeState(state)?.iframeDisplayMode;
68
+ export { serverTokenExchangeFromState, loginSuccessUrlFromState, getIssuerVariations, getOauthEndpoints, displayModeFromState, iframeDisplayModeFromState, generateState, };
67
69
  //# sourceMappingURL=oauth.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"oauth.js","sourceRoot":"","sources":["../../src/lib/oauth.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n DisplayMode,\n Endpoints,\n OpenIdConfiguration,\n FrameworkType,\n} from \"@/types.js\";\nimport { v4 as uuid } from \"uuid\";\n\nconst getIssuerVariations = (issuer: string): string[] => {\n const issuerWithoutSlash = issuer.endsWith(\"/\")\n ? issuer.slice(0, issuer.length - 1)\n : issuer;\n\n const issuerWithSlash = `${issuerWithoutSlash}/`;\n\n return [issuerWithoutSlash, issuerWithSlash];\n};\n\nconst addSlashIfNeeded = (url: string): string =>\n url.endsWith(\"/\") ? url : `${url}/`;\n\nconst cache: { [key: string]: Endpoints } = {};\nconst getOauthEndpoints = async (oauthServer: string): Promise<Endpoints> => {\n if (cache[oauthServer]) {\n return cache[oauthServer];\n }\n const openIdConfigResponse = await fetch(\n `${addSlashIfNeeded(oauthServer)}.well-known/openid-configuration`,\n );\n const openIdConfig =\n (await openIdConfigResponse.json()) as OpenIdConfiguration;\n const endpoints: Endpoints = {\n jwks: openIdConfig.jwks_uri,\n auth: openIdConfig.authorization_endpoint,\n token: openIdConfig.token_endpoint,\n userinfo: openIdConfig.userinfo_endpoint,\n endsession: openIdConfig.end_session_endpoint,\n };\n\n cache[oauthServer] = endpoints;\n return endpoints;\n};\n\n/**\n * creates a state string for the OAuth2 flow, encoding the display mode too for future use\n * @param {DisplayMode} displayMode\n * @returns {string}\n */\ntype GenerateStateInput = {\n displayMode?: DisplayMode;\n serverTokenExchange?: boolean;\n loginSuccessUrl?: string;\n framework?: FrameworkType;\n sdkVersion?: string;\n};\nconst generateState = ({\n displayMode,\n serverTokenExchange,\n loginSuccessUrl,\n framework,\n sdkVersion,\n}: GenerateStateInput): string => {\n const jsonString = JSON.stringify({\n uuid: uuid(),\n ...(displayMode ? { displayMode } : {}),\n ...(serverTokenExchange ? { serverTokenExchange } : {}),\n ...(loginSuccessUrl ? { loginSuccessUrl } : {}),\n ...(framework ? { framework } : {}),\n ...(sdkVersion ? { sdkVersion } : {}),\n });\n return btoa(jsonString);\n};\n\n/**\n * parses the state string from the OAuth2 flow, decoding the display mode too\n * @param state\n * @param sessionDisplayMode\n * @returns { uuid: string, displayMode: DisplayMode }\n */\nconst displayModeFromState = (\n state: string,\n sessionDisplayMode: DisplayMode | undefined,\n): DisplayMode | undefined => {\n try {\n const jsonString = atob(state);\n return JSON.parse(jsonString).displayMode;\n } catch (e) {\n console.error(\"Failed to parse displayMode from state:\", state, e);\n return sessionDisplayMode;\n }\n};\n\nconst decodeState = (\n state: string,\n):\n | {\n serverTokenExchange?: boolean;\n loginSuccessUrl?: string;\n framework?: FrameworkType;\n sdkVersion?: string;\n }\n | undefined => {\n try {\n const jsonString = atob(state);\n return JSON.parse(jsonString);\n } catch {\n console.error(\"Failed to parse state string to json:\", state);\n return undefined;\n }\n};\n\nconst serverTokenExchangeFromState = (state: string): boolean | undefined =>\n decodeState(state)?.serverTokenExchange;\n\nconst loginSuccessUrlFromState = (state: string | null): string | undefined =>\n state ? decodeState(state)?.loginSuccessUrl : undefined;\n\nexport {\n serverTokenExchangeFromState,\n loginSuccessUrlFromState,\n getIssuerVariations,\n getOauthEndpoints,\n displayModeFromState,\n generateState,\n};\n"]}
1
+ {"version":3,"file":"oauth.js","sourceRoot":"","sources":["../../src/lib/oauth.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n DisplayMode,\n Endpoints,\n OpenIdConfiguration,\n FrameworkType,\n} from \"@/types.js\";\nimport { v4 as uuid } from \"uuid\";\n\nconst getIssuerVariations = (issuer: string): string[] => {\n const issuerWithoutSlash = issuer.endsWith(\"/\")\n ? issuer.slice(0, issuer.length - 1)\n : issuer;\n\n const issuerWithSlash = `${issuerWithoutSlash}/`;\n\n return [issuerWithoutSlash, issuerWithSlash];\n};\n\nconst addSlashIfNeeded = (url: string): string =>\n url.endsWith(\"/\") ? url : `${url}/`;\n\nconst cache: { [key: string]: Endpoints } = {};\nconst getOauthEndpoints = async (oauthServer: string): Promise<Endpoints> => {\n if (cache[oauthServer]) {\n return cache[oauthServer];\n }\n const openIdConfigResponse = await fetch(\n `${addSlashIfNeeded(oauthServer)}.well-known/openid-configuration`,\n );\n const openIdConfig =\n (await openIdConfigResponse.json()) as OpenIdConfiguration;\n const endpoints: Endpoints = {\n jwks: openIdConfig.jwks_uri,\n auth: openIdConfig.authorization_endpoint,\n token: openIdConfig.token_endpoint,\n userinfo: openIdConfig.userinfo_endpoint,\n endsession: openIdConfig.end_session_endpoint,\n };\n\n cache[oauthServer] = endpoints;\n return endpoints;\n};\n\n/**\n * creates a state string for the OAuth2 flow, encoding the display mode too for future use\n * @param {DisplayMode} displayMode\n * @returns {string}\n */\ntype GenerateStateInput = {\n displayMode?: DisplayMode;\n iframeDisplayMode?: \"modal\" | \"embedded\";\n serverTokenExchange?: boolean;\n loginSuccessUrl?: string;\n framework?: FrameworkType;\n sdkVersion?: string;\n};\nconst generateState = ({\n displayMode,\n iframeDisplayMode,\n serverTokenExchange,\n loginSuccessUrl,\n framework,\n sdkVersion,\n}: GenerateStateInput): string => {\n const jsonString = JSON.stringify({\n uuid: uuid(),\n ...(displayMode ? { displayMode } : {}),\n ...(iframeDisplayMode ? { iframeDisplayMode } : {}),\n ...(serverTokenExchange ? { serverTokenExchange } : {}),\n ...(loginSuccessUrl ? { loginSuccessUrl } : {}),\n ...(framework ? { framework } : {}),\n ...(sdkVersion ? { sdkVersion } : {}),\n });\n return btoa(jsonString);\n};\n\n/**\n * parses the state string from the OAuth2 flow, decoding the display mode too\n * @param state\n * @param sessionDisplayMode\n * @returns { uuid: string, displayMode: DisplayMode }\n */\nconst displayModeFromState = (\n state: string,\n sessionDisplayMode: DisplayMode | undefined,\n): DisplayMode | undefined => {\n try {\n const jsonString = atob(state);\n return JSON.parse(jsonString).displayMode;\n } catch (e) {\n console.error(\"Failed to parse displayMode from state:\", state, e);\n return sessionDisplayMode;\n }\n};\n\nconst decodeState = (\n state: string,\n):\n | {\n serverTokenExchange?: boolean;\n loginSuccessUrl?: string;\n framework?: FrameworkType;\n sdkVersion?: string;\n iframeDisplayMode?: \"modal\" | \"embedded\";\n }\n | undefined => {\n try {\n const jsonString = atob(state);\n return JSON.parse(jsonString);\n } catch {\n console.error(\"Failed to parse state string to json:\", state);\n return undefined;\n }\n};\n\nconst serverTokenExchangeFromState = (state: string): boolean | undefined =>\n decodeState(state)?.serverTokenExchange;\n\nconst loginSuccessUrlFromState = (state: string | null): string | undefined =>\n state ? decodeState(state)?.loginSuccessUrl : undefined;\n\nconst iframeDisplayModeFromState = (\n state: string,\n): \"modal\" | \"embedded\" | undefined => decodeState(state)?.iframeDisplayMode;\n\nexport {\n serverTokenExchangeFromState,\n loginSuccessUrlFromState,\n getIssuerVariations,\n getOauthEndpoints,\n displayModeFromState,\n iframeDisplayModeFromState,\n generateState,\n};\n"]}
@@ -3,6 +3,6 @@ import type { AuthStorage, OIDCTokenResponseBody } from "../types.js";
3
3
  import { BrowserAuthenticationRefresher } from "../shared/lib/BrowserAuthenticationRefresher.js";
4
4
  export declare class NextClientAuthenticationRefresher extends BrowserAuthenticationRefresher {
5
5
  static build(authConfig: AuthConfig, storage: AuthStorage, onError: (error: Error) => Promise<void>): Promise<NextClientAuthenticationRefresher>;
6
- refreshAccessToken(): Promise<OIDCTokenResponseBody>;
6
+ refreshAccessToken(): Promise<OIDCTokenResponseBody | null>;
7
7
  }
8
8
  //# sourceMappingURL=NextClientAuthenticationRefresher.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"NextClientAuthenticationRefresher.d.ts","sourceRoot":"","sources":["../../src/nextjs/NextClientAuthenticationRefresher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACrE,OAAO,EAAE,8BAA8B,EAAE,MAAM,gDAAgD,CAAC;AAEhG,qBAAa,iCAAkC,SAAQ,8BAA8B;WAC7D,KAAK,CACzB,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,IAAI,CAAC,GACvC,OAAO,CAAC,iCAAiC,CAAC;IAS9B,kBAAkB,IAAI,OAAO,CAAC,qBAAqB,CAAC;CAkBpE"}
1
+ {"version":3,"file":"NextClientAuthenticationRefresher.d.ts","sourceRoot":"","sources":["../../src/nextjs/NextClientAuthenticationRefresher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACrE,OAAO,EAAE,8BAA8B,EAAE,MAAM,gDAAgD,CAAC;AAEhG,qBAAa,iCAAkC,SAAQ,8BAA8B;WAC7D,KAAK,CACzB,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,IAAI,CAAC,GACvC,OAAO,CAAC,iCAAiC,CAAC;IAS9B,kBAAkB,IAAI,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC;CAkB3E"}
@@ -1 +1 @@
1
- {"version":3,"file":"NextClientAuthenticationRefresher.js","sourceRoot":"","sources":["../../src/nextjs/NextClientAuthenticationRefresher.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,8BAA8B,EAAE,MAAM,gDAAgD,CAAC;AAEhG,MAAM,OAAO,iCAAkC,SAAQ,8BAA8B;IACnF,MAAM,CAAU,KAAK,CAAC,KAAK,CACzB,UAAsB,EACtB,OAAoB,EACpB,OAAwC;QAExC,MAAM,SAAS,GAAG,IAAI,iCAAiC,CACrD,UAAU,EACV,OAAO,EACP,OAAO,CACR,CAAC;QACF,OAAO,SAAS,CAAC;IACnB,CAAC;IAEQ,KAAK,CAAC,kBAAkB;QAC/B,IAAI,CAAC,IAAI,CAAC,UAAU;YAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAClE,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU;YAC7B,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAE9C,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;YACpD,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;YAC9B,OAAO,IAAI,CAAC,MAA+B,CAAC;QAC9C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CACX,iFAAiF,EACjF,KAAK,CACN,CAAC;YACF,IAAI,CAAC,OAAO,CAAC,KAAc,CAAC,CAAC;YAC7B,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;CACF","sourcesContent":["import type { AuthConfig } from \"@/server/config.js\";\nimport type { AuthStorage, OIDCTokenResponseBody } from \"@/types.js\";\nimport { BrowserAuthenticationRefresher } from \"@/shared/lib/BrowserAuthenticationRefresher.js\";\n\nexport class NextClientAuthenticationRefresher extends BrowserAuthenticationRefresher {\n static override async build(\n authConfig: AuthConfig,\n storage: AuthStorage,\n onError: (error: Error) => Promise<void>,\n ): Promise<NextClientAuthenticationRefresher> {\n const refresher = new NextClientAuthenticationRefresher(\n authConfig,\n storage,\n onError,\n );\n return refresher;\n }\n\n override async refreshAccessToken(): Promise<OIDCTokenResponseBody> {\n if (!this.authConfig) throw new Error(\"No auth config available\");\n if (!this.authConfig.refreshUrl)\n throw new Error(\"No refresh URL available\");\n\n try {\n const res = await fetch(this.authConfig.refreshUrl);\n const json = await res.json();\n return json.tokens as OIDCTokenResponseBody;\n } catch (error) {\n console.error(\n \"NextClientAuthenticationRefresher refreshAccessToken: Failed to refresh tokens:\",\n error,\n );\n this.onError(error as Error);\n throw error;\n }\n }\n}\n"]}
1
+ {"version":3,"file":"NextClientAuthenticationRefresher.js","sourceRoot":"","sources":["../../src/nextjs/NextClientAuthenticationRefresher.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,8BAA8B,EAAE,MAAM,gDAAgD,CAAC;AAEhG,MAAM,OAAO,iCAAkC,SAAQ,8BAA8B;IACnF,MAAM,CAAU,KAAK,CAAC,KAAK,CACzB,UAAsB,EACtB,OAAoB,EACpB,OAAwC;QAExC,MAAM,SAAS,GAAG,IAAI,iCAAiC,CACrD,UAAU,EACV,OAAO,EACP,OAAO,CACR,CAAC;QACF,OAAO,SAAS,CAAC;IACnB,CAAC;IAEQ,KAAK,CAAC,kBAAkB;QAC/B,IAAI,CAAC,IAAI,CAAC,UAAU;YAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAClE,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU;YAC7B,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAE9C,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;YACpD,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;YAC9B,OAAO,IAAI,CAAC,MAA+B,CAAC;QAC9C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CACX,iFAAiF,EACjF,KAAK,CACN,CAAC;YACF,IAAI,CAAC,OAAO,CAAC,KAAc,CAAC,CAAC;YAC7B,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;CACF","sourcesContent":["import type { AuthConfig } from \"@/server/config.js\";\nimport type { AuthStorage, OIDCTokenResponseBody } from \"@/types.js\";\nimport { BrowserAuthenticationRefresher } from \"@/shared/lib/BrowserAuthenticationRefresher.js\";\n\nexport class NextClientAuthenticationRefresher extends BrowserAuthenticationRefresher {\n static override async build(\n authConfig: AuthConfig,\n storage: AuthStorage,\n onError: (error: Error) => Promise<void>,\n ): Promise<NextClientAuthenticationRefresher> {\n const refresher = new NextClientAuthenticationRefresher(\n authConfig,\n storage,\n onError,\n );\n return refresher;\n }\n\n override async refreshAccessToken(): Promise<OIDCTokenResponseBody | null> {\n if (!this.authConfig) throw new Error(\"No auth config available\");\n if (!this.authConfig.refreshUrl)\n throw new Error(\"No refresh URL available\");\n\n try {\n const res = await fetch(this.authConfig.refreshUrl);\n const json = await res.json();\n return json.tokens as OIDCTokenResponseBody;\n } catch (error) {\n console.error(\n \"NextClientAuthenticationRefresher refreshAccessToken: Failed to refresh tokens:\",\n error,\n );\n this.onError(error as Error);\n throw error;\n }\n }\n}\n"]}
@@ -6,7 +6,7 @@ export declare class NextServerAuthenticationRefresherImpl extends Authenticatio
6
6
  endpointOverrides?: Partial<Endpoints> | undefined;
7
7
  storage: CookieStorage | undefined;
8
8
  constructor(authConfig: AuthConfig, storage: CookieStorage, onError: (error: Error) => Promise<void>, endpointOverrides?: Partial<Endpoints> | undefined);
9
- storeTokens(tokenResponseBody: OIDCTokenResponseBody): Promise<void>;
9
+ storeTokens(tokenResponseBody: OIDCTokenResponseBody | null): Promise<void>;
10
10
  static build(authConfig: AuthConfig, storage: CookieStorage, onError: (error: Error) => Promise<void>, endpointOverrides?: Partial<Endpoints>): Promise<NextServerAuthenticationRefresherImpl>;
11
11
  }
12
12
  //# sourceMappingURL=NextServerAuthenticationRefresherImpl.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"NextServerAuthenticationRefresherImpl.d.ts","sourceRoot":"","sources":["../../src/nextjs/NextServerAuthenticationRefresherImpl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,MAAM,6CAA6C,CAAC;AAC1F,OAAO,KAAK,EAAE,SAAS,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACnE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD,qBAAa,qCAAsC,SAAQ,2BAA2B;IAMzE,iBAAiB,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC;IALxC,OAAO,EAAE,aAAa,GAAG,SAAS,CAAC;gBAE1C,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,IAAI,CAAC,EAC/B,iBAAiB,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,YAAA;IAMlC,WAAW,CACxB,iBAAiB,EAAE,qBAAqB,GACvC,OAAO,CAAC,IAAI,CAAC;WAKM,KAAK,CACzB,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,IAAI,CAAC,EACxC,iBAAiB,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,GACrC,OAAO,CAAC,qCAAqC,CAAC;CAWlD"}
1
+ {"version":3,"file":"NextServerAuthenticationRefresherImpl.d.ts","sourceRoot":"","sources":["../../src/nextjs/NextServerAuthenticationRefresherImpl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,MAAM,6CAA6C,CAAC;AAC1F,OAAO,KAAK,EAAE,SAAS,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACnE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD,qBAAa,qCAAsC,SAAQ,2BAA2B;IAMzE,iBAAiB,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC;IALxC,OAAO,EAAE,aAAa,GAAG,SAAS,CAAC;gBAE1C,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,IAAI,CAAC,EAC/B,iBAAiB,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,YAAA;IAMlC,WAAW,CACxB,iBAAiB,EAAE,qBAAqB,GAAG,IAAI,GAC9C,OAAO,CAAC,IAAI,CAAC;WAQM,KAAK,CACzB,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,IAAI,CAAC,EACxC,iBAAiB,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,GACrC,OAAO,CAAC,qCAAqC,CAAC;CAWlD"}
@@ -11,6 +11,9 @@ export class NextServerAuthenticationRefresherImpl extends AuthenticationRefresh
11
11
  async storeTokens(tokenResponseBody) {
12
12
  if (!this.storage)
13
13
  throw new Error("No storage available");
14
+ // For null tokenResponseBody, we skip storage since tokens might be managed elsewhere (e.g., HTTP-only cookies)
15
+ if (!tokenResponseBody)
16
+ return;
14
17
  await storeServerTokens(this.storage, tokenResponseBody);
15
18
  }
16
19
  static async build(authConfig, storage, onError, endpointOverrides) {
@@ -1 +1 @@
1
- {"version":3,"file":"NextServerAuthenticationRefresherImpl.js","sourceRoot":"","sources":["../../src/nextjs/NextServerAuthenticationRefresherImpl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,MAAM,6CAA6C,CAAC;AAG1F,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAGzD,MAAM,OAAO,qCAAsC,SAAQ,2BAA2B;IAMzE;IALF,OAAO,CAA4B;IAC5C,YACE,UAAsB,EACtB,OAAsB,EACtB,OAAwC,EAC/B,iBAAsC;QAE/C,KAAK,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,iBAAiB,CAAC,CAAC;QAF9C,sBAAiB,GAAjB,iBAAiB,CAAqB;QAG/C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAEQ,KAAK,CAAC,WAAW,CACxB,iBAAwC;QAExC,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;QAC3D,MAAM,iBAAiB,CAAC,IAAI,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC;IAC3D,CAAC;IAED,MAAM,CAAU,KAAK,CAAC,KAAK,CACzB,UAAsB,EACtB,OAAsB,EACtB,OAAwC,EACxC,iBAAsC;QAEtC,MAAM,SAAS,GAAG,IAAI,qCAAqC,CACzD,UAAU,EACV,OAAO,EACP,OAAO,EACP,iBAAiB,CAClB,CAAC;QACF,MAAM,SAAS,CAAC,IAAI,EAAE,CAAC;QAEvB,OAAO,SAAS,CAAC;IACnB,CAAC;CACF","sourcesContent":["import { AuthenticationRefresherImpl } from \"@/shared/lib/AuthenticationRefresherImpl.js\";\nimport type { Endpoints, OIDCTokenResponseBody } from \"@/types.js\";\nimport type { AuthConfig } from \"@/server/config.js\";\nimport { storeServerTokens } from \"@/shared/lib/util.js\";\nimport type { CookieStorage } from \"@/server/index.js\";\n\nexport class NextServerAuthenticationRefresherImpl extends AuthenticationRefresherImpl {\n override storage: CookieStorage | undefined;\n constructor(\n authConfig: AuthConfig,\n storage: CookieStorage,\n onError: (error: Error) => Promise<void>,\n override endpointOverrides?: Partial<Endpoints>,\n ) {\n super(authConfig, storage, onError, endpointOverrides);\n this.storage = storage;\n }\n\n override async storeTokens(\n tokenResponseBody: OIDCTokenResponseBody,\n ): Promise<void> {\n if (!this.storage) throw new Error(\"No storage available\");\n await storeServerTokens(this.storage, tokenResponseBody);\n }\n\n static override async build(\n authConfig: AuthConfig,\n storage: CookieStorage,\n onError: (error: Error) => Promise<void>,\n endpointOverrides?: Partial<Endpoints>,\n ): Promise<NextServerAuthenticationRefresherImpl> {\n const refresher = new NextServerAuthenticationRefresherImpl(\n authConfig,\n storage,\n onError,\n endpointOverrides,\n );\n await refresher.init();\n\n return refresher;\n }\n}\n"]}
1
+ {"version":3,"file":"NextServerAuthenticationRefresherImpl.js","sourceRoot":"","sources":["../../src/nextjs/NextServerAuthenticationRefresherImpl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,MAAM,6CAA6C,CAAC;AAG1F,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAGzD,MAAM,OAAO,qCAAsC,SAAQ,2BAA2B;IAMzE;IALF,OAAO,CAA4B;IAC5C,YACE,UAAsB,EACtB,OAAsB,EACtB,OAAwC,EAC/B,iBAAsC;QAE/C,KAAK,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,iBAAiB,CAAC,CAAC;QAF9C,sBAAiB,GAAjB,iBAAiB,CAAqB;QAG/C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAEQ,KAAK,CAAC,WAAW,CACxB,iBAA+C;QAE/C,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;QAC3D,gHAAgH;QAChH,IAAI,CAAC,iBAAiB;YAAE,OAAO;QAE/B,MAAM,iBAAiB,CAAC,IAAI,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC;IAC3D,CAAC;IAED,MAAM,CAAU,KAAK,CAAC,KAAK,CACzB,UAAsB,EACtB,OAAsB,EACtB,OAAwC,EACxC,iBAAsC;QAEtC,MAAM,SAAS,GAAG,IAAI,qCAAqC,CACzD,UAAU,EACV,OAAO,EACP,OAAO,EACP,iBAAiB,CAClB,CAAC;QACF,MAAM,SAAS,CAAC,IAAI,EAAE,CAAC;QAEvB,OAAO,SAAS,CAAC;IACnB,CAAC;CACF","sourcesContent":["import { AuthenticationRefresherImpl } from \"@/shared/lib/AuthenticationRefresherImpl.js\";\nimport type { Endpoints, OIDCTokenResponseBody } from \"@/types.js\";\nimport type { AuthConfig } from \"@/server/config.js\";\nimport { storeServerTokens } from \"@/shared/lib/util.js\";\nimport type { CookieStorage } from \"@/server/index.js\";\n\nexport class NextServerAuthenticationRefresherImpl extends AuthenticationRefresherImpl {\n override storage: CookieStorage | undefined;\n constructor(\n authConfig: AuthConfig,\n storage: CookieStorage,\n onError: (error: Error) => Promise<void>,\n override endpointOverrides?: Partial<Endpoints>,\n ) {\n super(authConfig, storage, onError, endpointOverrides);\n this.storage = storage;\n }\n\n override async storeTokens(\n tokenResponseBody: OIDCTokenResponseBody | null,\n ): Promise<void> {\n if (!this.storage) throw new Error(\"No storage available\");\n // For null tokenResponseBody, we skip storage since tokens might be managed elsewhere (e.g., HTTP-only cookies)\n if (!tokenResponseBody) return;\n\n await storeServerTokens(this.storage, tokenResponseBody);\n }\n\n static override async build(\n authConfig: AuthConfig,\n storage: CookieStorage,\n onError: (error: Error) => Promise<void>,\n endpointOverrides?: Partial<Endpoints>,\n ): Promise<NextServerAuthenticationRefresherImpl> {\n const refresher = new NextServerAuthenticationRefresherImpl(\n authConfig,\n storage,\n onError,\n endpointOverrides,\n );\n await refresher.init();\n\n return refresher;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"routeHandler.d.ts","sourceRoot":"","sources":["../../src/nextjs/routeHandler.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,UAAU,EAA0B,MAAM,oBAAoB,CAAC;AAW7E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAqa9C,wBAAsB,YAAY,CAChC,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,YAAY,CAAC,CAyCvB;AAwDD,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,YAAY,CAAC,CAwBvB;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,OAAO,iCAEF,WAAW,KAAG,OAAO,CAAC,YAAY,CAkCjD,CAAC"}
1
+ {"version":3,"file":"routeHandler.d.ts","sourceRoot":"","sources":["../../src/nextjs/routeHandler.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,UAAU,EAA0B,MAAM,oBAAoB,CAAC;AAW7E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAsa9C,wBAAsB,YAAY,CAChC,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,YAAY,CAAC,CAyCvB;AAwDD,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,YAAY,CAAC,CAwBvB;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,OAAO,iCAEF,WAAW,KAAG,OAAO,CAAC,YAAY,CAkCjD,CAAC"}
@@ -132,7 +132,8 @@ async function handleRefresh(request, config) {
132
132
  if (targetUrl) {
133
133
  return NextResponse.redirect(targetUrl);
134
134
  }
135
- return NextResponse.json({ status: "success", tokens });
135
+ // For backend flows, tokens might be null since they're managed in HTTP-only cookies
136
+ return NextResponse.json({ status: "success", tokens: tokens || null });
136
137
  }
137
138
  catch (error) {
138
139
  logger.error("handleRefresh: Token refresh failed, clearing tokens:", error);
@@ -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 // 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 logger.debug(\n \"handleLogoutComplete: sameDomainCallback=true, returning JSON response with redirect URL\",\n { postLogoutRedirectUrl },\n );\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 logger.debug(\n \"handleLogoutComplete: iframe mode, rendering HTML with logout success text\",\n { postLogoutRedirectUrl },\n );\n return response;\n }\n\n logger.debug(\"handleLogoutComplete: redirecting to postLogoutRedirectUrl\", {\n postLogoutRedirectUrl,\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 logger.debug(\n \"handleLogoutCallback can access cookies: clearing auth cookies\",\n );\n await clearAuthCookies();\n return handleLogoutComplete({ request, resolvedConfigs });\n }\n\n logger.debug(\n \"handleLogoutCallback cannot access cookies: generating HTML response with callback\",\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 // For backend flows, tokens might be null since they're managed in HTTP-only cookies\n return NextResponse.json({ status: \"success\", tokens: tokens || null });\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 logger.debug(\n \"handleLogoutComplete: sameDomainCallback=true, returning JSON response with redirect URL\",\n { postLogoutRedirectUrl },\n );\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 logger.debug(\n \"handleLogoutComplete: iframe mode, rendering HTML with logout success text\",\n { postLogoutRedirectUrl },\n );\n return response;\n }\n\n logger.debug(\"handleLogoutComplete: redirecting to postLogoutRedirectUrl\", {\n postLogoutRedirectUrl,\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 logger.debug(\n \"handleLogoutCallback can access cookies: clearing auth cookies\",\n );\n await clearAuthCookies();\n return handleLogoutComplete({ request, resolvedConfigs });\n }\n\n logger.debug(\n \"handleLogoutCallback cannot access cookies: generating HTML response with callback\",\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"]}
@@ -44,6 +44,7 @@ export interface GlobalAuthConfig {
44
44
  onSignIn?: (error?: Error) => void;
45
45
  onSignOut?: () => void;
46
46
  logging?: LoggingConfig;
47
+ preloadIframe?: boolean;
47
48
  /** Framework being used (for analytics) - internal use only */
48
49
  framework?: FrameworkType;
49
50
  }
@@ -55,6 +56,7 @@ export interface GlobalAuthState {
55
56
  authStatus: AuthStatus;
56
57
  error: Error | null;
57
58
  displayMode?: DisplayMode;
59
+ isPreloaded?: boolean;
58
60
  }
59
61
  type StateListener = (state: GlobalAuthState) => void;
60
62
  /**
@@ -99,6 +101,19 @@ declare class GlobalAuthManager {
99
101
  * Sign out
100
102
  */
101
103
  signOut(): Promise<void>;
104
+ /**
105
+ * Check if authentication is preloaded and ready for instant sign-in
106
+ * @returns True if an iframe is preloaded and ready
107
+ */
108
+ isAuthenticationPreloaded(): boolean;
109
+ /**
110
+ * Enable or disable iframe preloading
111
+ */
112
+ setPreloadEnabled(enabled: boolean): void;
113
+ /**
114
+ * Check if iframe preloading is enabled
115
+ */
116
+ getPreloadEnabled(): boolean;
102
117
  /**
103
118
  * Check if config is the same (for idempotent initialization)
104
119
  */
@@ -1 +1 @@
1
- {"version":3,"file":"GlobalAuthManager.d.ts","sourceRoot":"","sources":["../../../src/reactjs/core/GlobalAuthManager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAOH,OAAO,KAAK,EACV,IAAI,EACJ,OAAO,EAER,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AAOzE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE;QACP,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,UAAU,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,KAAK,IAAI,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,+DAA+D;IAC/D,SAAS,CAAC,EAAE,aAAa,CAAC;CAC3B;AAED,MAAM,MAAM,UAAU,GAClB,eAAe,GACf,iBAAiB,GACjB,gBAAgB,GAChB,OAAO,GACP,aAAa,CAAC;AAElB,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAClB,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,UAAU,CAAC;IACvB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED,KAAK,aAAa,GAAG,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;AAEtD;;;GAGG;AACH,cAAM,iBAAiB;IACrB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAkC;IACzD,OAAO,CAAC,IAAI,CAA0B;IACtC,OAAO,CAAC,MAAM,CAAqC;IACnD,OAAO,CAAC,MAAM,CAAiC;IAC/C,OAAO,CAAC,SAAS,CAA4B;IAC7C,OAAO,CAAC,SAAS,CAGV;IACP,OAAO,CAAC,qBAAqB,CAA8B;IAE3D,OAAO,CAAC,KAAK,CAOX;IAEF,OAAO;IAIP,MAAM,CAAC,WAAW,IAAI,iBAAiB;IAOvC;;;OAGG;IACG,UAAU,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAwBzD;;OAEG;YACW,aAAa;IA2E3B;;OAEG;IACH,SAAS,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,IAAI;IAK9C;;OAEG;IACH,QAAQ,IAAI,eAAe;IAI3B;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC;QAAE,IAAI,EAAE,IAAI,CAAA;KAAE,CAAC;IAiBvC;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAa9B;;OAEG;IACH,OAAO,CAAC,YAAY;IAUpB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAwD3B;;OAEG;YACW,qBAAqB;IAiBnC;;OAEG;IACH,OAAO,CAAC,QAAQ;IAKhB;;OAEG;YACW,OAAO;CAStB;AAED,OAAO,EAAE,iBAAiB,EAAE,CAAC"}
1
+ {"version":3,"file":"GlobalAuthManager.d.ts","sourceRoot":"","sources":["../../../src/reactjs/core/GlobalAuthManager.ts"],"names":[],"mappings":"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"}
@@ -104,6 +104,7 @@ class GlobalAuthManager {
104
104
  iframeDisplayMode: config.iframeMode || "modal",
105
105
  nonce: config.nonce,
106
106
  authProcessTimeout: config.authProcessTimeout || 120000,
107
+ preloadIframe: config.preloadIframe,
107
108
  events: this.events,
108
109
  logging: {
109
110
  enabled: true,
@@ -128,6 +129,7 @@ class GlobalAuthManager {
128
129
  }
129
130
  else {
130
131
  this.setState({ authStatus: "unauthenticated" });
132
+ // Note: Preloading is now handled automatically by CivicAuth based on config.preloadIframe
131
133
  }
132
134
  this.setState({
133
135
  isLoading: false,
@@ -191,6 +193,28 @@ class GlobalAuthManager {
191
193
  authStatus: "unauthenticated",
192
194
  });
193
195
  }
196
+ /**
197
+ * Check if authentication is preloaded and ready for instant sign-in
198
+ * @returns True if an iframe is preloaded and ready
199
+ */
200
+ isAuthenticationPreloaded() {
201
+ return this.auth?.isAuthenticationPreloaded() ?? false;
202
+ }
203
+ /**
204
+ * Enable or disable iframe preloading
205
+ */
206
+ setPreloadEnabled(enabled) {
207
+ if (!this.auth) {
208
+ throw new Error("Auth not initialized");
209
+ }
210
+ this.auth.setPreloadEnabled(enabled);
211
+ }
212
+ /**
213
+ * Check if iframe preloading is enabled
214
+ */
215
+ getPreloadEnabled() {
216
+ return this.auth?.getPreloadEnabled() ?? true;
217
+ }
194
218
  /**
195
219
  * Check if config is the same (for idempotent initialization)
196
220
  */
@@ -200,7 +224,8 @@ class GlobalAuthManager {
200
224
  return (this.config.clientId === newConfig.clientId &&
201
225
  this.config.config?.oauthServer === newConfig.config?.oauthServer &&
202
226
  this.config.displayMode === newConfig.displayMode &&
203
- this.config.nonce === newConfig.nonce);
227
+ this.config.nonce === newConfig.nonce &&
228
+ this.config.preloadIframe === newConfig.preloadIframe);
204
229
  }
205
230
  /**
206
231
  * Setup event listeners for auth state changes
@@ -1 +1 @@
1
- {"version":3,"file":"GlobalAuthManager.js","sourceRoot":"","sources":["../../../src/reactjs/core/GlobalAuthManager.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * GlobalAuthManager - Singleton Authentication State Manager\n *\n * This module provides a global singleton that manages authentication state across a React application\n * without requiring React Context providers or prop drilling. It acts as a centralized authentication\n * manager that wraps the CivicAuth vanilla JavaScript library and provides a React-friendly interface.\n *\n * Key Features:\n * - Singleton pattern ensures single auth instance across the entire app\n * - Eliminates need for React Context providers and reduces bundle size\n * - Manages authentication state (user, session, loading, errors)\n * - Handles sign-in/sign-out flows with event-driven updates\n * - Provides idempotent initialization (safe to call multiple times)\n * - Supports multiple React hooks subscribing to the same auth state\n * - Automatic session refresh and user data synchronization\n *\n * Usage:\n * - Initialize once in your app with authentication configuration\n * - Use React hooks (useCivicAuth, useAuth, etc.) to access auth state\n * - The manager handles all underlying CivicAuth SDK interactions\n * - State updates are automatically propagated to all subscribed components\n *\n * This design pattern is particularly useful for:\n * - Large applications with many components needing auth state\n * - Avoiding provider wrapper hell in React component trees\n * - Ensuring consistent auth state across disconnected component hierarchies\n * - Server-side rendering scenarios where providers might be problematic\n */\n\nimport {\n CivicAuth,\n AuthenticationEvents,\n AuthEvent,\n} from \"../../vanillajs/index.js\";\nimport type {\n User,\n Session,\n CivicAuthClientConfig,\n} from \"../../vanillajs/index.js\";\nimport type { DisplayMode, FrameworkType } from \"../../types.js\";\nimport type { LoggingConfig } from \"@/vanillajs/auth/types/AuthTypes.js\";\n\n// Event payload interfaces\ninterface SignInErrorEvent {\n detail: string;\n}\n\nexport interface GlobalAuthConfig {\n clientId: string;\n redirectUrl?: string;\n config?: {\n oauthServer?: string;\n };\n displayMode?: DisplayMode;\n iframeMode?: \"modal\" | \"embedded\";\n nonce?: string;\n logoutRedirectUrl?: string;\n scopes?: string[];\n authProcessTimeout?: number;\n onSignIn?: (error?: Error) => void;\n onSignOut?: () => void;\n logging?: LoggingConfig;\n /** Framework being used (for analytics) - internal use only */\n framework?: FrameworkType;\n}\n\nexport type AuthStatus =\n | \"authenticated\"\n | \"unauthenticated\"\n | \"authenticating\"\n | \"error\"\n | \"signing_out\";\n\nexport interface GlobalAuthState {\n user: User | null;\n session: Session | null;\n isLoading: boolean;\n authStatus: AuthStatus;\n error: Error | null;\n displayMode?: DisplayMode;\n}\n\ntype StateListener = (state: GlobalAuthState) => void;\n\n/**\n * Global singleton that manages CivicAuth instance for React hooks\n * Eliminates the need for React providers\n */\nclass GlobalAuthManager {\n private static instance: GlobalAuthManager | null = null;\n private auth: CivicAuth | null = null;\n private events: AuthenticationEvents | null = null;\n private config: GlobalAuthConfig | null = null;\n private listeners = new Set<StateListener>();\n private callbacks: {\n onSignIn?: (error?: Error) => void;\n onSignOut?: () => void;\n } = {};\n private initializationPromise: Promise<void> | null = null;\n\n private state: GlobalAuthState = {\n user: null,\n session: null,\n isLoading: false,\n authStatus: \"unauthenticated\",\n error: null,\n displayMode: undefined,\n };\n\n private constructor() {\n // Private constructor for singleton\n }\n\n static getInstance(): GlobalAuthManager {\n if (!GlobalAuthManager.instance) {\n GlobalAuthManager.instance = new GlobalAuthManager();\n }\n return GlobalAuthManager.instance;\n }\n\n /**\n * Initialize auth with config (idempotent)\n * Returns the same promise for concurrent calls with same config\n */\n async initialize(config: GlobalAuthConfig): Promise<void> {\n // If we have a promise and same config, return existing promise\n if (\n this.initializationPromise &&\n this.config &&\n this.isSameConfig(config)\n ) {\n return this.initializationPromise;\n }\n\n // If different config, reset everything\n if (this.config && !this.isSameConfig(config)) {\n this.initializationPromise = null;\n await this.cleanup();\n }\n\n // Create new initialization promise if needed\n if (!this.initializationPromise) {\n this.initializationPromise = this._doInitialize(config);\n }\n\n return this.initializationPromise;\n }\n\n /**\n * Private method that does the actual initialization work\n */\n private async _doInitialize(config: GlobalAuthConfig): Promise<void> {\n this.config = config;\n this.callbacks = {\n onSignIn: config.onSignIn,\n onSignOut: config.onSignOut,\n };\n this.setState({ isLoading: true, error: null });\n\n try {\n this.events = new AuthenticationEvents();\n this.setupEventListeners();\n\n const authConfig: CivicAuthClientConfig = {\n clientId: config.clientId,\n oauthServerBaseUrl: config.config?.oauthServer,\n scopes: config.scopes || [\n \"openid\",\n \"profile\",\n \"email\",\n \"offline_access\",\n ],\n displayMode: config.displayMode || \"iframe\",\n iframeDisplayMode: config.iframeMode || \"modal\",\n nonce: config.nonce,\n authProcessTimeout: config.authProcessTimeout || 120000,\n events: this.events,\n logging: {\n enabled: true,\n level: \"debug\" as const,\n },\n framework: config.framework,\n };\n\n // Only add redirectUrl if provided\n if (config.redirectUrl) {\n authConfig.redirectUrl = config.redirectUrl;\n }\n\n // Only add logoutRedirectUrl if provided\n if (config.logoutRedirectUrl) {\n authConfig.logoutRedirectUrl = config.logoutRedirectUrl;\n }\n\n this.auth = await CivicAuth.create(authConfig);\n\n // Check initial auth state\n const isAuthenticated = await this.auth.isAuthenticated();\n if (isAuthenticated) {\n await this.refreshUserAndSession();\n this.setState({ authStatus: \"authenticated\" });\n } else {\n this.setState({ authStatus: \"unauthenticated\" });\n }\n\n this.setState({\n isLoading: false,\n displayMode: config.displayMode,\n });\n } catch (error) {\n // Reset promise on error so it can be retried\n this.initializationPromise = null;\n\n const authError =\n error instanceof Error\n ? error\n : new Error(\"Auth initialization failed\");\n this.setState({\n error: authError,\n authStatus: \"error\",\n isLoading: false,\n });\n throw authError;\n }\n }\n\n /**\n * Subscribe to state changes\n */\n subscribe(listener: StateListener): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n /**\n * Get current state\n */\n getState(): GlobalAuthState {\n return { ...this.state };\n }\n\n /**\n * Sign in\n */\n async signIn(): Promise<{ user: User }> {\n if (!this.auth) {\n throw new Error(\"Auth not initialized\");\n }\n\n const { user } = await this.auth.startAuthentication();\n await this.refreshUserAndSession();\n\n // Ensure we have a user to return\n if (!user) {\n throw new Error(\"Authentication succeeded but no user was returned\");\n }\n\n // Return the user object\n return { user };\n }\n\n /**\n * Sign out\n */\n async signOut(): Promise<void> {\n if (!this.auth) {\n throw new Error(\"Auth not initialized\");\n }\n\n await this.auth.logout();\n this.setState({\n user: null,\n session: null,\n authStatus: \"unauthenticated\",\n });\n }\n\n /**\n * Check if config is the same (for idempotent initialization)\n */\n private isSameConfig(newConfig: GlobalAuthConfig): boolean {\n if (!this.config) return false;\n return (\n this.config.clientId === newConfig.clientId &&\n this.config.config?.oauthServer === newConfig.config?.oauthServer &&\n this.config.displayMode === newConfig.displayMode &&\n this.config.nonce === newConfig.nonce\n );\n }\n\n /**\n * Setup event listeners for auth state changes\n */\n private setupEventListeners(): void {\n if (!this.events) return;\n\n this.events.on(AuthEvent.SIGN_IN_STARTED, () => {\n this.setState({\n isLoading: true,\n authStatus: \"authenticating\",\n error: null,\n });\n });\n\n this.events.on(AuthEvent.SIGN_IN_COMPLETE, () => {\n this.setState({\n isLoading: false,\n authStatus: \"authenticated\",\n error: null,\n });\n this.refreshUserAndSession();\n this.callbacks.onSignIn?.();\n });\n\n this.events.on(AuthEvent.SIGN_IN_ERROR, (event?: SignInErrorEvent) => {\n const errorDetail = event?.detail || \"Authentication failed\";\n const authError = new Error(errorDetail);\n this.setState({\n isLoading: false,\n authStatus: \"error\",\n error: authError,\n });\n this.callbacks.onSignIn?.(authError);\n });\n\n this.events.on(AuthEvent.SIGN_OUT_STARTED, () => {\n this.setState({\n isLoading: true,\n authStatus: \"signing_out\",\n error: null,\n });\n });\n\n this.events.on(AuthEvent.SIGN_OUT_COMPLETE, () => {\n this.setState({\n isLoading: false,\n authStatus: \"unauthenticated\",\n user: null,\n session: null,\n error: null,\n });\n this.callbacks.onSignOut?.();\n });\n\n this.events.on(AuthEvent.USER_SESSION_CHANGED, () => {\n this.refreshUserAndSession();\n });\n }\n\n /**\n * Refresh user and session data\n */\n private async refreshUserAndSession(): Promise<void> {\n if (!this.auth) return;\n\n try {\n const [session, user] = await Promise.all([\n this.auth.getCurrentSession(),\n this.auth.getCurrentUser(),\n ]);\n\n this.setState({ session, user });\n } catch (error) {\n const sessionError =\n error instanceof Error ? error : new Error(\"Failed to get session\");\n this.setState({ error: sessionError });\n }\n }\n\n /**\n * Update state and notify listeners\n */\n private setState(updates: Partial<GlobalAuthState>): void {\n this.state = { ...this.state, ...updates };\n this.listeners.forEach((listener) => listener(this.state));\n }\n\n /**\n * Cleanup auth instance\n */\n private async cleanup(): Promise<void> {\n if (this.auth) {\n await this.auth.destroy();\n this.auth = null;\n }\n this.events = null;\n this.config = null;\n this.initializationPromise = null; // Reset promise for clean re-initialization\n }\n}\n\nexport { GlobalAuthManager };\n"]}
1
+ {"version":3,"file":"GlobalAuthManager.js","sourceRoot":"","sources":["../../../src/reactjs/core/GlobalAuthManager.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * GlobalAuthManager - Singleton Authentication State Manager\n *\n * This module provides a global singleton that manages authentication state across a React application\n * without requiring React Context providers or prop drilling. It acts as a centralized authentication\n * manager that wraps the CivicAuth vanilla JavaScript library and provides a React-friendly interface.\n *\n * Key Features:\n * - Singleton pattern ensures single auth instance across the entire app\n * - Eliminates need for React Context providers and reduces bundle size\n * - Manages authentication state (user, session, loading, errors)\n * - Handles sign-in/sign-out flows with event-driven updates\n * - Provides idempotent initialization (safe to call multiple times)\n * - Supports multiple React hooks subscribing to the same auth state\n * - Automatic session refresh and user data synchronization\n *\n * Usage:\n * - Initialize once in your app with authentication configuration\n * - Use React hooks (useCivicAuth, useAuth, etc.) to access auth state\n * - The manager handles all underlying CivicAuth SDK interactions\n * - State updates are automatically propagated to all subscribed components\n *\n * This design pattern is particularly useful for:\n * - Large applications with many components needing auth state\n * - Avoiding provider wrapper hell in React component trees\n * - Ensuring consistent auth state across disconnected component hierarchies\n * - Server-side rendering scenarios where providers might be problematic\n */\n\nimport {\n CivicAuth,\n AuthenticationEvents,\n AuthEvent,\n} from \"../../vanillajs/index.js\";\nimport type {\n User,\n Session,\n CivicAuthClientConfig,\n} from \"../../vanillajs/index.js\";\nimport type { DisplayMode, FrameworkType } from \"../../types.js\";\nimport type { LoggingConfig } from \"@/vanillajs/auth/types/AuthTypes.js\";\n\n// Event payload interfaces\ninterface SignInErrorEvent {\n detail: string;\n}\n\nexport interface GlobalAuthConfig {\n clientId: string;\n redirectUrl?: string;\n config?: {\n oauthServer?: string;\n };\n displayMode?: DisplayMode;\n iframeMode?: \"modal\" | \"embedded\";\n nonce?: string;\n logoutRedirectUrl?: string;\n scopes?: string[];\n authProcessTimeout?: number;\n onSignIn?: (error?: Error) => void;\n onSignOut?: () => void;\n logging?: LoggingConfig;\n preloadIframe?: boolean;\n /** Framework being used (for analytics) - internal use only */\n framework?: FrameworkType;\n}\n\nexport type AuthStatus =\n | \"authenticated\"\n | \"unauthenticated\"\n | \"authenticating\"\n | \"error\"\n | \"signing_out\";\n\nexport interface GlobalAuthState {\n user: User | null;\n session: Session | null;\n isLoading: boolean;\n authStatus: AuthStatus;\n error: Error | null;\n displayMode?: DisplayMode;\n isPreloaded?: boolean;\n}\n\ntype StateListener = (state: GlobalAuthState) => void;\n\n/**\n * Global singleton that manages CivicAuth instance for React hooks\n * Eliminates the need for React providers\n */\nclass GlobalAuthManager {\n private static instance: GlobalAuthManager | null = null;\n private auth: CivicAuth | null = null;\n private events: AuthenticationEvents | null = null;\n private config: GlobalAuthConfig | null = null;\n private listeners = new Set<StateListener>();\n private callbacks: {\n onSignIn?: (error?: Error) => void;\n onSignOut?: () => void;\n } = {};\n private initializationPromise: Promise<void> | null = null;\n\n private state: GlobalAuthState = {\n user: null,\n session: null,\n isLoading: false,\n authStatus: \"unauthenticated\",\n error: null,\n displayMode: undefined,\n };\n\n private constructor() {\n // Private constructor for singleton\n }\n\n static getInstance(): GlobalAuthManager {\n if (!GlobalAuthManager.instance) {\n GlobalAuthManager.instance = new GlobalAuthManager();\n }\n return GlobalAuthManager.instance;\n }\n\n /**\n * Initialize auth with config (idempotent)\n * Returns the same promise for concurrent calls with same config\n */\n async initialize(config: GlobalAuthConfig): Promise<void> {\n // If we have a promise and same config, return existing promise\n if (\n this.initializationPromise &&\n this.config &&\n this.isSameConfig(config)\n ) {\n return this.initializationPromise;\n }\n\n // If different config, reset everything\n if (this.config && !this.isSameConfig(config)) {\n this.initializationPromise = null;\n await this.cleanup();\n }\n\n // Create new initialization promise if needed\n if (!this.initializationPromise) {\n this.initializationPromise = this._doInitialize(config);\n }\n\n return this.initializationPromise;\n }\n\n /**\n * Private method that does the actual initialization work\n */\n private async _doInitialize(config: GlobalAuthConfig): Promise<void> {\n this.config = config;\n this.callbacks = {\n onSignIn: config.onSignIn,\n onSignOut: config.onSignOut,\n };\n this.setState({ isLoading: true, error: null });\n\n try {\n this.events = new AuthenticationEvents();\n this.setupEventListeners();\n\n const authConfig: CivicAuthClientConfig = {\n clientId: config.clientId,\n oauthServerBaseUrl: config.config?.oauthServer,\n scopes: config.scopes || [\n \"openid\",\n \"profile\",\n \"email\",\n \"offline_access\",\n ],\n displayMode: config.displayMode || \"iframe\",\n iframeDisplayMode: config.iframeMode || \"modal\",\n nonce: config.nonce,\n authProcessTimeout: config.authProcessTimeout || 120000,\n preloadIframe: config.preloadIframe,\n events: this.events,\n logging: {\n enabled: true,\n level: \"debug\" as const,\n },\n framework: config.framework,\n };\n\n // Only add redirectUrl if provided\n if (config.redirectUrl) {\n authConfig.redirectUrl = config.redirectUrl;\n }\n\n // Only add logoutRedirectUrl if provided\n if (config.logoutRedirectUrl) {\n authConfig.logoutRedirectUrl = config.logoutRedirectUrl;\n }\n\n this.auth = await CivicAuth.create(authConfig);\n\n // Check initial auth state\n const isAuthenticated = await this.auth.isAuthenticated();\n if (isAuthenticated) {\n await this.refreshUserAndSession();\n this.setState({ authStatus: \"authenticated\" });\n } else {\n this.setState({ authStatus: \"unauthenticated\" });\n\n // Note: Preloading is now handled automatically by CivicAuth based on config.preloadIframe\n }\n\n this.setState({\n isLoading: false,\n displayMode: config.displayMode,\n });\n } catch (error) {\n // Reset promise on error so it can be retried\n this.initializationPromise = null;\n\n const authError =\n error instanceof Error\n ? error\n : new Error(\"Auth initialization failed\");\n this.setState({\n error: authError,\n authStatus: \"error\",\n isLoading: false,\n });\n throw authError;\n }\n }\n\n /**\n * Subscribe to state changes\n */\n subscribe(listener: StateListener): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n /**\n * Get current state\n */\n getState(): GlobalAuthState {\n return { ...this.state };\n }\n\n /**\n * Sign in\n */\n async signIn(): Promise<{ user: User }> {\n if (!this.auth) {\n throw new Error(\"Auth not initialized\");\n }\n\n const { user } = await this.auth.startAuthentication();\n await this.refreshUserAndSession();\n\n // Ensure we have a user to return\n if (!user) {\n throw new Error(\"Authentication succeeded but no user was returned\");\n }\n\n // Return the user object\n return { user };\n }\n\n /**\n * Sign out\n */\n async signOut(): Promise<void> {\n if (!this.auth) {\n throw new Error(\"Auth not initialized\");\n }\n\n await this.auth.logout();\n this.setState({\n user: null,\n session: null,\n authStatus: \"unauthenticated\",\n });\n }\n\n /**\n * Check if authentication is preloaded and ready for instant sign-in\n * @returns True if an iframe is preloaded and ready\n */\n isAuthenticationPreloaded(): boolean {\n return this.auth?.isAuthenticationPreloaded() ?? false;\n }\n\n /**\n * Enable or disable iframe preloading\n */\n setPreloadEnabled(enabled: boolean): void {\n if (!this.auth) {\n throw new Error(\"Auth not initialized\");\n }\n this.auth.setPreloadEnabled(enabled);\n }\n\n /**\n * Check if iframe preloading is enabled\n */\n getPreloadEnabled(): boolean {\n return this.auth?.getPreloadEnabled() ?? true;\n }\n\n /**\n * Check if config is the same (for idempotent initialization)\n */\n private isSameConfig(newConfig: GlobalAuthConfig): boolean {\n if (!this.config) return false;\n return (\n this.config.clientId === newConfig.clientId &&\n this.config.config?.oauthServer === newConfig.config?.oauthServer &&\n this.config.displayMode === newConfig.displayMode &&\n this.config.nonce === newConfig.nonce &&\n this.config.preloadIframe === newConfig.preloadIframe\n );\n }\n\n /**\n * Setup event listeners for auth state changes\n */\n private setupEventListeners(): void {\n if (!this.events) return;\n\n this.events.on(AuthEvent.SIGN_IN_STARTED, () => {\n this.setState({\n isLoading: true,\n authStatus: \"authenticating\",\n error: null,\n });\n });\n\n this.events.on(AuthEvent.SIGN_IN_COMPLETE, () => {\n this.setState({\n isLoading: false,\n authStatus: \"authenticated\",\n error: null,\n });\n this.refreshUserAndSession();\n this.callbacks.onSignIn?.();\n });\n\n this.events.on(AuthEvent.SIGN_IN_ERROR, (event?: SignInErrorEvent) => {\n const errorDetail = event?.detail || \"Authentication failed\";\n const authError = new Error(errorDetail);\n this.setState({\n isLoading: false,\n authStatus: \"error\",\n error: authError,\n });\n this.callbacks.onSignIn?.(authError);\n });\n\n this.events.on(AuthEvent.SIGN_OUT_STARTED, () => {\n this.setState({\n isLoading: true,\n authStatus: \"signing_out\",\n error: null,\n });\n });\n\n this.events.on(AuthEvent.SIGN_OUT_COMPLETE, () => {\n this.setState({\n isLoading: false,\n authStatus: \"unauthenticated\",\n user: null,\n session: null,\n error: null,\n });\n this.callbacks.onSignOut?.();\n });\n\n this.events.on(AuthEvent.USER_SESSION_CHANGED, () => {\n this.refreshUserAndSession();\n });\n }\n\n /**\n * Refresh user and session data\n */\n private async refreshUserAndSession(): Promise<void> {\n if (!this.auth) return;\n\n try {\n const [session, user] = await Promise.all([\n this.auth.getCurrentSession(),\n this.auth.getCurrentUser(),\n ]);\n\n this.setState({ session, user });\n } catch (error) {\n const sessionError =\n error instanceof Error ? error : new Error(\"Failed to get session\");\n this.setState({ error: sessionError });\n }\n }\n\n /**\n * Update state and notify listeners\n */\n private setState(updates: Partial<GlobalAuthState>): void {\n this.state = { ...this.state, ...updates };\n this.listeners.forEach((listener) => listener(this.state));\n }\n\n /**\n * Cleanup auth instance\n */\n private async cleanup(): Promise<void> {\n if (this.auth) {\n await this.auth.destroy();\n this.auth = null;\n }\n this.events = null;\n this.config = null;\n this.initializationPromise = null; // Reset promise for clean re-initialization\n }\n}\n\nexport { GlobalAuthManager };\n"]}