@civic/auth 0.10.0-beta.6 → 0.10.0-beta.8

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 (83) hide show
  1. package/CHANGELOG.md +3 -0
  2. package/README.md +1 -0
  3. package/dist/browser/storage.d.ts +1 -0
  4. package/dist/browser/storage.d.ts.map +1 -1
  5. package/dist/browser/storage.js +3 -0
  6. package/dist/browser/storage.js.map +1 -1
  7. package/dist/lib/logger.d.ts +1 -0
  8. package/dist/lib/logger.d.ts.map +1 -1
  9. package/dist/lib/logger.js +1 -0
  10. package/dist/lib/logger.js.map +1 -1
  11. package/dist/nextjs/hooks/useInitialAuthConfig.d.ts.map +1 -1
  12. package/dist/nextjs/hooks/useInitialAuthConfig.js +10 -0
  13. package/dist/nextjs/hooks/useInitialAuthConfig.js.map +1 -1
  14. package/dist/nextjs/middleware.d.ts +2 -1
  15. package/dist/nextjs/middleware.d.ts.map +1 -1
  16. package/dist/nextjs/middleware.js +33 -51
  17. package/dist/nextjs/middleware.js.map +1 -1
  18. package/dist/nextjs/routeHandler.d.ts +3 -0
  19. package/dist/nextjs/routeHandler.d.ts.map +1 -1
  20. package/dist/nextjs/routeHandler.js +7 -1
  21. package/dist/nextjs/routeHandler.js.map +1 -1
  22. package/dist/nextjs/utils.d.ts +16 -1
  23. package/dist/nextjs/utils.d.ts.map +1 -1
  24. package/dist/nextjs/utils.js +78 -10
  25. package/dist/nextjs/utils.js.map +1 -1
  26. package/dist/reactjs/core/GlobalAuthManager.d.ts +6 -2
  27. package/dist/reactjs/core/GlobalAuthManager.d.ts.map +1 -1
  28. package/dist/reactjs/core/GlobalAuthManager.js +26 -7
  29. package/dist/reactjs/core/GlobalAuthManager.js.map +1 -1
  30. package/dist/reactjs/hooks/useUser.d.ts.map +1 -1
  31. package/dist/reactjs/hooks/useUser.js +79 -127
  32. package/dist/reactjs/hooks/useUser.js.map +1 -1
  33. package/dist/server/ServerAuthenticationResolver.d.ts +3 -2
  34. package/dist/server/ServerAuthenticationResolver.d.ts.map +1 -1
  35. package/dist/server/ServerAuthenticationResolver.js +23 -6
  36. package/dist/server/ServerAuthenticationResolver.js.map +1 -1
  37. package/dist/server/index.d.ts +1 -0
  38. package/dist/server/index.d.ts.map +1 -1
  39. package/dist/server/index.js.map +1 -1
  40. package/dist/server/login.d.ts +2 -1
  41. package/dist/server/login.d.ts.map +1 -1
  42. package/dist/server/login.js.map +1 -1
  43. package/dist/server/session.d.ts +4 -3
  44. package/dist/server/session.d.ts.map +1 -1
  45. package/dist/server/session.js.map +1 -1
  46. package/dist/server/users.d.ts +4 -3
  47. package/dist/server/users.d.ts.map +1 -1
  48. package/dist/server/users.js.map +1 -1
  49. package/dist/services/types.d.ts +1 -1
  50. package/dist/services/types.d.ts.map +1 -1
  51. package/dist/services/types.js.map +1 -1
  52. package/dist/shared/lib/BrowserAuthenticationRefresher.d.ts.map +1 -1
  53. package/dist/shared/lib/BrowserAuthenticationRefresher.js +6 -6
  54. package/dist/shared/lib/BrowserAuthenticationRefresher.js.map +1 -1
  55. package/dist/shared/lib/UserSession.d.ts +4 -3
  56. package/dist/shared/lib/UserSession.d.ts.map +1 -1
  57. package/dist/shared/lib/UserSession.js +4 -0
  58. package/dist/shared/lib/UserSession.js.map +1 -1
  59. package/dist/shared/lib/session.d.ts +2 -1
  60. package/dist/shared/lib/session.d.ts.map +1 -1
  61. package/dist/shared/lib/session.js +11 -2
  62. package/dist/shared/lib/session.js.map +1 -1
  63. package/dist/shared/lib/util.d.ts +2 -2
  64. package/dist/shared/lib/util.d.ts.map +1 -1
  65. package/dist/shared/lib/util.js +4 -4
  66. package/dist/shared/lib/util.js.map +1 -1
  67. package/dist/shared/version.d.ts +1 -1
  68. package/dist/shared/version.js +1 -1
  69. package/dist/shared/version.js.map +1 -1
  70. package/dist/types.d.ts +4 -0
  71. package/dist/types.d.ts.map +1 -1
  72. package/dist/types.js.map +1 -1
  73. package/dist/vanillajs/auth/BackendAuthenticationRefresher.d.ts +4 -3
  74. package/dist/vanillajs/auth/BackendAuthenticationRefresher.d.ts.map +1 -1
  75. package/dist/vanillajs/auth/BackendAuthenticationRefresher.js +34 -21
  76. package/dist/vanillajs/auth/BackendAuthenticationRefresher.js.map +1 -1
  77. package/dist/vanillajs/auth/SessionManager.d.ts.map +1 -1
  78. package/dist/vanillajs/auth/SessionManager.js +13 -14
  79. package/dist/vanillajs/auth/SessionManager.js.map +1 -1
  80. package/dist/vanillajs/auth/TokenRefresher.d.ts.map +1 -1
  81. package/dist/vanillajs/auth/TokenRefresher.js +3 -3
  82. package/dist/vanillajs/auth/TokenRefresher.js.map +1 -1
  83. package/package.json +1 -1
@@ -2,6 +2,8 @@ import type { AuthConfig, AuthConfigWithDefaults } from "../nextjs/config.js";
2
2
  import type { NextRequest } from "next/server.js";
3
3
  import { NextResponse } from "next/server.js";
4
4
  import type { SessionData } from "../types.js";
5
+ import { type CookieConfig, type KeySetter } from "../shared/lib/types.js";
6
+ import { CookieStorage } from "../server/index.js";
5
7
  export declare const resolveCallbackUrl: (config: AuthConfigWithDefaults, baseUrl?: string) => string;
6
8
  export declare function sanitizeBasePath(path: string): string;
7
9
  /**
@@ -21,6 +23,18 @@ export declare const createRefreshResponse: (request: NextRequest, authConfig: A
21
23
  * Checks if the current path is a system URL that should skip auth
22
24
  */
23
25
  export declare const shouldSkipAuthForSystemUrls: (pathname: string, authConfig: AuthConfigWithDefaults, method: string) => boolean;
26
+ /**
27
+ * CookieStorage implementation for NextJS middleware context that works with NextRequest
28
+ */
29
+ export declare class NextjsMiddlewareCookieStorage extends CookieStorage {
30
+ config: Partial<Record<KeySetter, CookieConfig>>;
31
+ private request;
32
+ private response;
33
+ constructor(config: Partial<Record<KeySetter, CookieConfig>> | undefined, request: NextRequest, response: NextResponse);
34
+ get(key: string): Promise<string | null>;
35
+ set(key: string, value: string, cookieConfigOverride: CookieConfig): Promise<void>;
36
+ delete(key: string): Promise<void>;
37
+ }
24
38
  /**
25
39
  * Handles authentication logic specifically for the login URL
26
40
  * Provides logging for login URL access patterns
@@ -30,10 +44,11 @@ export declare const handleLoginUrl: (pathname: string, session: SessionData, au
30
44
  * Checks if the current path should skip auth based on include/exclude patterns
31
45
  */
32
46
  export declare const shouldSkipAuthForRoutePatterns: (pathname: string, authConfig: AuthConfigWithDefaults) => boolean;
47
+ export declare const copyCivicCookies: (sourceResponse: NextResponse, targetResponse: NextResponse) => void;
33
48
  /**
34
49
  * Handles final authentication logic for unauthenticated users on protected routes
35
50
  */
36
- export declare const handleUnauthenticatedUser: (session: SessionData, request: NextRequest, authConfig: AuthConfigWithDefaults) => NextResponse | undefined;
51
+ export declare const handleUnauthenticatedUser: (session: SessionData, request: NextRequest, response: NextResponse, storage: NextjsMiddlewareCookieStorage, authConfig: AuthConfigWithDefaults) => Promise<NextResponse | undefined>;
37
52
  /**
38
53
  * Prepends the basePath onto a given URL if it's not already there. Works for both relative and absolute URLs.
39
54
  * @param url
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/nextjs/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC7E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAM9C,eAAO,MAAM,kBAAkB,WACrB,sBAAsB,YACpB,MAAM,KACf,MAGF,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQrD;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE,MAAM,GAChB,MAAM,CAoBR;AA+BD;;GAEG;AACH,eAAO,MAAM,oBAAoB,YAAa,WAAW,KAAG,OAE3D,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,qBAAqB,YACvB,WAAW,cACR,sBAAsB,KACjC,YAAY,GAAG,IAqBjB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,2BAA2B,aAC5B,MAAM,cACJ,sBAAsB,UAC1B,MAAM,KACb,OAkBF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,cAAc,aACf,MAAM,WACP,WAAW,cACR,sBAAsB,KACjC,IAWF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,8BAA8B,aAC/B,MAAM,cACJ,sBAAsB,KACjC,OAiBF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,yBAAyB,YAC3B,WAAW,WACX,WAAW,cACR,sBAAsB,KACjC,YAAY,GAAG,SAuCjB,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,eAAe,QAAS,MAAM,YAAY,MAAM,WAiB5D,CAAC;AAEF,eAAO,MAAM,oBAAoB,WACvB,UAAU,aACP,MAAM,KAChB,YACuE,CAAC"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/nextjs/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC7E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAG9C,OAAO,EAIL,KAAK,YAAY,EACjB,KAAK,SAAS,EACf,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAIlD,eAAO,MAAM,kBAAkB,WACrB,sBAAsB,YACpB,MAAM,KACf,MAGF,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQrD;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE,MAAM,GAChB,MAAM,CAoBR;AA+BD;;GAEG;AACH,eAAO,MAAM,oBAAoB,YAAa,WAAW,KAAG,OAE3D,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,qBAAqB,YACvB,WAAW,cACR,sBAAsB,KACjC,YAAY,GAAG,IAqBjB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,2BAA2B,aAC5B,MAAM,cACJ,sBAAsB,UAC1B,MAAM,KACb,OAkBF,CAAC;AAEF;;GAEG;AACH,qBAAa,6BAA8B,SAAQ,aAAa;IAErD,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IACvD,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,QAAQ;gBAFT,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC,YAAK,EACpD,OAAO,EAAE,WAAW,EACpB,QAAQ,EAAE,YAAY;IAQ1B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAIxC,GAAG,CACP,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,oBAAoB,EAAE,YAAY,GACjC,OAAO,CAAC,IAAI,CAAC;IAkBV,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAczC;AAED;;;GAGG;AACH,eAAO,MAAM,cAAc,aACf,MAAM,WACP,WAAW,cACR,sBAAsB,KACjC,IAWF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,8BAA8B,aAC/B,MAAM,cACJ,sBAAsB,KACjC,OAiBF,CAAC;AAEF,eAAO,MAAM,gBAAgB,mBACX,YAAY,kBACZ,YAAY,SAoB7B,CAAC;AACF;;GAEG;AACH,eAAO,MAAM,yBAAyB,YAC3B,WAAW,WACX,WAAW,YACV,YAAY,WACb,6BAA6B,cAC1B,sBAAsB,KACjC,OAAO,CAAC,YAAY,GAAG,SAAS,CA8BlC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,eAAe,QAAS,MAAM,YAAY,MAAM,WAiB5D,CAAC;AAEF,eAAO,MAAM,oBAAoB,WACvB,UAAU,aACP,MAAM,KAChB,YACuE,CAAC"}
@@ -1,6 +1,9 @@
1
1
  import { NextResponse } from "next/server.js";
2
2
  import { loggers } from "../lib/logger.js";
3
3
  import picomatch from "picomatch";
4
+ import { CodeVerifier, OAuthTokenTypes, UserStorage, } from "../shared/lib/types.js";
5
+ import { clearTokens, getCookieConfiguration } from "../shared/lib/util.js";
6
+ import { CookieStorage } from "../server/index.js";
4
7
  const logger = loggers.nextjs.middleware;
5
8
  export const resolveCallbackUrl = (config, baseUrl) => {
6
9
  const callbackUrl = new URL(config?.callbackUrl, baseUrl).toString();
@@ -96,6 +99,55 @@ export const shouldSkipAuthForSystemUrls = (pathname, authConfig, method) => {
96
99
  }
97
100
  return isSystemUrl;
98
101
  };
102
+ /**
103
+ * CookieStorage implementation for NextJS middleware context that works with NextRequest
104
+ */
105
+ export class NextjsMiddlewareCookieStorage extends CookieStorage {
106
+ config;
107
+ request;
108
+ response;
109
+ constructor(config = {}, request, response) {
110
+ super({
111
+ secure: true,
112
+ httpOnly: true,
113
+ });
114
+ this.config = config;
115
+ this.request = request;
116
+ this.response = response;
117
+ }
118
+ async get(key) {
119
+ return this.request.cookies.get(key)?.value || null;
120
+ }
121
+ async set(key, value, cookieConfigOverride) {
122
+ const cookieSettings = this.config?.[key] || {
123
+ ...this.settings,
124
+ };
125
+ const dynamicConfig = getCookieConfiguration(this.request);
126
+ const useCookieSettings = {
127
+ ...cookieSettings,
128
+ ...cookieConfigOverride,
129
+ // Apply dynamic configuration for secure and sameSite
130
+ secure: dynamicConfig.secure,
131
+ sameSite: dynamicConfig.sameSite,
132
+ };
133
+ // Respect the httpOnly setting from configuration instead of hardcoding it
134
+ this.response.cookies.set(key, value, useCookieSettings);
135
+ }
136
+ async delete(key) {
137
+ // Get cookie configuration for this key to respect the path setting
138
+ const cookieSettings = this.config?.[key] || {};
139
+ // If we have a path configured, use it when deleting the cookie
140
+ if (cookieSettings.path) {
141
+ this.response.cookies.set(key, "", {
142
+ expires: new Date(0), // Expire in the past
143
+ path: cookieSettings.path,
144
+ });
145
+ }
146
+ else {
147
+ this.response.cookies.delete(key);
148
+ }
149
+ }
150
+ }
99
151
  /**
100
152
  * Handles authentication logic specifically for the login URL
101
153
  * Provides logging for login URL access patterns
@@ -128,17 +180,32 @@ export const shouldSkipAuthForRoutePatterns = (pathname, authConfig) => {
128
180
  }
129
181
  return false;
130
182
  };
183
+ export const copyCivicCookies = (sourceResponse, targetResponse) => {
184
+ const civicCookieNames = [
185
+ ...Object.values(OAuthTokenTypes),
186
+ ...Object.values(UserStorage),
187
+ ...Object.values(CodeVerifier),
188
+ ];
189
+ logger.debug("Copying Civic cookies:", {
190
+ src: sourceResponse.url,
191
+ target: targetResponse.url,
192
+ });
193
+ sourceResponse?.cookies
194
+ .getAll()
195
+ .filter((cookie) => civicCookieNames.includes(cookie.name))
196
+ .forEach((cookie) => {
197
+ logger.debug("Setting middlewareResponse cookie:", cookie);
198
+ targetResponse.cookies.set(cookie);
199
+ });
200
+ };
131
201
  /**
132
202
  * Handles final authentication logic for unauthenticated users on protected routes
133
203
  */
134
- export const handleUnauthenticatedUser = (session, request, authConfig) => {
135
- const targetUrl = getOriginUrl(request, authConfig) + request.nextUrl.pathname;
136
- // Clear expired/invalid tokens if they exist without refresh token
137
- if (session.accessToken || session.idToken) {
138
- const clearBadTokensUrl = new URL(authConfig.logoutCallbackUrl, getOriginUrl(request, authConfig));
139
- clearBadTokensUrl.searchParams.set("targetUrl", targetUrl);
140
- logger.debug(`→ Invalid tokens found without refresh - clearing via "${clearBadTokensUrl}"`);
141
- return redirectWithBasePath(authConfig, clearBadTokensUrl.toString());
204
+ export const handleUnauthenticatedUser = async (session, request, response, storage, authConfig) => {
205
+ // Clear expired/invalid tokens if they exist
206
+ if (session.accessToken || session.idToken || session.refreshToken) {
207
+ logger.debug(`→ Clearing expired/invalid tokens`);
208
+ await clearTokens(storage);
142
209
  }
143
210
  // Final fallback: redirect to login unless we're already there.
144
211
  const loginUrl = new URL(authConfig.loginUrl, getOriginUrl(request, authConfig));
@@ -149,9 +216,10 @@ export const handleUnauthenticatedUser = (session, request, authConfig) => {
149
216
  // The loginUrl from getOriginUrl already includes the basePath, but request.nextUrl.pathname does not. So we strip it off to enable comparison.
150
217
  if (request.nextUrl.pathname !== loginPathWithoutBasePath) {
151
218
  logger.debug(`→ No valid tokens found - redirecting to login "${redirectUrl}"`);
152
- return redirectWithBasePath(authConfig, redirectUrl);
219
+ const redirectedResponse = redirectWithBasePath(authConfig, redirectUrl);
220
+ return redirectedResponse;
153
221
  }
154
- return undefined;
222
+ return response;
155
223
  };
156
224
  /**
157
225
  * Prepends the basePath onto a given URL if it's not already there. Works for both relative and absolute URLs.
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/nextjs/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AuthConfig, AuthConfigWithDefaults } from \"@/nextjs/config.js\";\nimport type { NextRequest } from \"next/server.js\";\nimport { NextResponse } from \"next/server.js\";\nimport type { SessionData } from \"@/types.js\";\nimport { loggers } from \"@/lib/logger.js\";\nimport picomatch from \"picomatch\";\n\nconst logger = loggers.nextjs.middleware;\n\nexport const resolveCallbackUrl = (\n config: AuthConfigWithDefaults,\n baseUrl?: string,\n): string => {\n const callbackUrl = new URL(config?.callbackUrl, baseUrl).toString();\n return callbackUrl.toString();\n};\n\nexport function sanitizeBasePath(path: string): string {\n if (!path || path === \"/\") return \"\";\n\n // Ensure it starts with a slash\n const withLeadingSlash = path.startsWith(\"/\") ? path : `/${path}`;\n\n // Remove all trailing slashes (not just one)\n return withLeadingSlash.replace(/\\/+$/, \"\");\n}\n\n/**\n * Removes the basePath prefix from a pathname, properly handling edge cases\n * This is the inverse operation of adding basePath to a URL\n */\nexport function removeBasePathFromPath(\n pathname: string,\n basePath?: string,\n): string {\n if (!basePath || basePath === \"\" || basePath === \"/\") {\n return pathname;\n }\n\n // Sanitize the basePath to ensure consistent format\n const sanitizedBasePath = sanitizeBasePath(basePath);\n\n // Check if pathname starts with the basePath followed by a slash or end of string\n // This prevents partial matches like \"/app\" matching \"/application\"\n if (pathname === sanitizedBasePath) {\n // Exact match - return root\n return \"/\";\n } else if (pathname.startsWith(sanitizedBasePath + \"/\")) {\n // basePath followed by slash - remove basePath but keep the slash\n return pathname.slice(sanitizedBasePath.length);\n }\n\n // If basePath doesn't match as a complete path segment, return pathname as-is\n return pathname;\n}\n\nconst getOriginUrl = (\n request: NextRequest,\n authConfig: AuthConfigWithDefaults,\n): string => {\n // Use configured baseUrl if provided (for reverse proxy scenarios)\n if (authConfig.baseUrl) {\n return authConfig.baseUrl;\n }\n\n // Fallback to nextUrl.origin (includes port automatically)\n return request.nextUrl.origin;\n};\n\n// Matches globs:\n// Examples:\n// /user\n// /user/*\n// /user/**/info\nconst matchGlob = (pathname: string, globPattern: string) => {\n const matches = picomatch(globPattern);\n return matches(pathname);\n};\n\nconst matchesGlobs = (pathname: string, patterns: string[]) =>\n patterns.some((pattern) => {\n if (!pattern) return false;\n return matchGlob(pathname, pattern);\n });\n\n/**\n * Determines if we should attempt token refresh based on session state\n */\nexport const shouldAttemptRefresh = (session: SessionData): boolean => {\n return !session.authenticated && !!session.refreshToken;\n};\n\n/**\n * Creates a redirect response to the refresh endpoint\n */\nexport const createRefreshResponse = (\n request: NextRequest,\n authConfig: AuthConfigWithDefaults,\n): NextResponse | null => {\n const targetUrl = prependBasePath(\n getOriginUrl(request, authConfig) + request.nextUrl.pathname,\n authConfig.basePath || \"\",\n );\n\n // Check if we're already in a redirect flow\n if (request.nextUrl.searchParams.has(\"targetUrl\")) {\n return null;\n }\n\n // Create refresh redirect\n const refreshUrl = new URL(\n authConfig.refreshUrl,\n getOriginUrl(request, authConfig),\n );\n refreshUrl.searchParams.set(\"targetUrl\", targetUrl);\n\n logger.debug(\"→ Refresh token found - redirecting to refresh endpoint\");\n\n return redirectWithBasePath(authConfig, refreshUrl.toString());\n};\n\n/**\n * Checks if the current path is a system URL that should skip auth\n */\nexport const shouldSkipAuthForSystemUrls = (\n pathname: string,\n authConfig: AuthConfigWithDefaults,\n method: string,\n): boolean => {\n const systemUrls = [\n authConfig.callbackUrl,\n authConfig.challengeUrl,\n authConfig.logoutCallbackUrl,\n authConfig.logoutUrl,\n ];\n\n const isSystemUrl = systemUrls.includes(pathname) && method === \"GET\";\n\n if (isSystemUrl) {\n logger.debug(\n \"→ Skipping auth check - this a URL defined in authConfig\",\n pathname,\n );\n }\n\n return isSystemUrl;\n};\n\n/**\n * Handles authentication logic specifically for the login URL\n * Provides logging for login URL access patterns\n */\nexport const handleLoginUrl = (\n pathname: string,\n session: SessionData,\n authConfig: AuthConfigWithDefaults,\n): void => {\n if (pathname !== authConfig.loginUrl) {\n return;\n }\n\n // We are on the login URL - log the access pattern\n if (session.authenticated) {\n logger.debug(`→ Authenticated user accessing login page`);\n } else {\n logger.debug(`→ Unauthenticated user accessing login page`);\n }\n};\n\n/**\n * Checks if the current path should skip auth based on include/exclude patterns\n */\nexport const shouldSkipAuthForRoutePatterns = (\n pathname: string,\n authConfig: AuthConfigWithDefaults,\n): boolean => {\n // Check include patterns\n if (!matchesGlobs(pathname, authConfig.include)) {\n logger.debug(\n \"→ Skipping auth check - path not in include patterns\",\n pathname,\n );\n return true;\n }\n\n // Check exclude patterns\n if (matchesGlobs(pathname, authConfig.exclude)) {\n logger.debug(\"→ Skipping auth check - path in exclude patterns\", pathname);\n return true;\n }\n\n return false;\n};\n\n/**\n * Handles final authentication logic for unauthenticated users on protected routes\n */\nexport const handleUnauthenticatedUser = (\n session: SessionData,\n request: NextRequest,\n authConfig: AuthConfigWithDefaults,\n): NextResponse | undefined => {\n const targetUrl =\n getOriginUrl(request, authConfig) + request.nextUrl.pathname;\n\n // Clear expired/invalid tokens if they exist without refresh token\n if (session.accessToken || session.idToken) {\n const clearBadTokensUrl = new URL(\n authConfig.logoutCallbackUrl,\n getOriginUrl(request, authConfig),\n );\n clearBadTokensUrl.searchParams.set(\"targetUrl\", targetUrl);\n logger.debug(\n `→ Invalid tokens found without refresh - clearing via \"${clearBadTokensUrl}\"`,\n );\n return redirectWithBasePath(authConfig, clearBadTokensUrl.toString());\n }\n\n // Final fallback: redirect to login unless we're already there.\n const loginUrl = new URL(\n authConfig.loginUrl,\n getOriginUrl(request, authConfig),\n );\n const redirectUrl = `${loginUrl.toString()}`;\n const loginPathWithoutBasePath = removeBasePathFromPath(\n loginUrl.pathname,\n authConfig.basePath,\n );\n\n // If we're already at the login URL, the middleware will just return undefined.\n // This is to prevent an infinite redirect loop if middleware is applied to the login route itself.\n // The loginUrl from getOriginUrl already includes the basePath, but request.nextUrl.pathname does not. So we strip it off to enable comparison.\n if (request.nextUrl.pathname !== loginPathWithoutBasePath) {\n logger.debug(\n `→ No valid tokens found - redirecting to login \"${redirectUrl}\"`,\n );\n return redirectWithBasePath(authConfig, redirectUrl);\n }\n\n return undefined;\n};\n\n/**\n * Prepends the basePath onto a given URL if it's not already there. Works for both relative and absolute URLs.\n * @param url\n * @param basePath\n * @returns\n */\nexport const prependBasePath = (url: string, basePath: string) => {\n basePath = \"/\" + basePath.replace(/^\\/|\\/$/g, \"\"); // normalize basePath\n\n const isAbsolute = /^https?:\\/\\//.test(url);\n\n if (isAbsolute) {\n const u = new URL(url);\n if (!u.pathname.startsWith(basePath)) {\n u.pathname =\n basePath + (u.pathname.startsWith(\"/\") ? \"\" : \"/\") + u.pathname;\n }\n return u.toString();\n }\n\n return url.startsWith(basePath)\n ? url\n : basePath + (url.startsWith(\"/\") ? \"\" : \"/\") + url;\n};\n\nexport const redirectWithBasePath = (\n config: AuthConfig,\n targetUrl: string,\n): NextResponse =>\n NextResponse.redirect(prependBasePath(targetUrl, config.basePath || \"\"));\n"]}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/nextjs/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AuthConfig, AuthConfigWithDefaults } from \"@/nextjs/config.js\";\nimport type { NextRequest } from \"next/server.js\";\nimport { NextResponse } from \"next/server.js\";\nimport type { SessionData } from \"@/types.js\";\nimport { loggers } from \"@/lib/logger.js\";\nimport picomatch from \"picomatch\";\nimport {\n CodeVerifier,\n OAuthTokenTypes,\n UserStorage,\n type CookieConfig,\n type KeySetter,\n} from \"@/shared/lib/types.js\";\nimport { clearTokens, getCookieConfiguration } from \"@/shared/lib/util.js\";\nimport { CookieStorage } from \"@/server/index.js\";\n\nconst logger = loggers.nextjs.middleware;\n\nexport const resolveCallbackUrl = (\n config: AuthConfigWithDefaults,\n baseUrl?: string,\n): string => {\n const callbackUrl = new URL(config?.callbackUrl, baseUrl).toString();\n return callbackUrl.toString();\n};\n\nexport function sanitizeBasePath(path: string): string {\n if (!path || path === \"/\") return \"\";\n\n // Ensure it starts with a slash\n const withLeadingSlash = path.startsWith(\"/\") ? path : `/${path}`;\n\n // Remove all trailing slashes (not just one)\n return withLeadingSlash.replace(/\\/+$/, \"\");\n}\n\n/**\n * Removes the basePath prefix from a pathname, properly handling edge cases\n * This is the inverse operation of adding basePath to a URL\n */\nexport function removeBasePathFromPath(\n pathname: string,\n basePath?: string,\n): string {\n if (!basePath || basePath === \"\" || basePath === \"/\") {\n return pathname;\n }\n\n // Sanitize the basePath to ensure consistent format\n const sanitizedBasePath = sanitizeBasePath(basePath);\n\n // Check if pathname starts with the basePath followed by a slash or end of string\n // This prevents partial matches like \"/app\" matching \"/application\"\n if (pathname === sanitizedBasePath) {\n // Exact match - return root\n return \"/\";\n } else if (pathname.startsWith(sanitizedBasePath + \"/\")) {\n // basePath followed by slash - remove basePath but keep the slash\n return pathname.slice(sanitizedBasePath.length);\n }\n\n // If basePath doesn't match as a complete path segment, return pathname as-is\n return pathname;\n}\n\nconst getOriginUrl = (\n request: NextRequest,\n authConfig: AuthConfigWithDefaults,\n): string => {\n // Use configured baseUrl if provided (for reverse proxy scenarios)\n if (authConfig.baseUrl) {\n return authConfig.baseUrl;\n }\n\n // Fallback to nextUrl.origin (includes port automatically)\n return request.nextUrl.origin;\n};\n\n// Matches globs:\n// Examples:\n// /user\n// /user/*\n// /user/**/info\nconst matchGlob = (pathname: string, globPattern: string) => {\n const matches = picomatch(globPattern);\n return matches(pathname);\n};\n\nconst matchesGlobs = (pathname: string, patterns: string[]) =>\n patterns.some((pattern) => {\n if (!pattern) return false;\n return matchGlob(pathname, pattern);\n });\n\n/**\n * Determines if we should attempt token refresh based on session state\n */\nexport const shouldAttemptRefresh = (session: SessionData): boolean => {\n return !session.authenticated && !!session.refreshToken;\n};\n\n/**\n * Creates a redirect response to the refresh endpoint\n */\nexport const createRefreshResponse = (\n request: NextRequest,\n authConfig: AuthConfigWithDefaults,\n): NextResponse | null => {\n const targetUrl = prependBasePath(\n getOriginUrl(request, authConfig) + request.nextUrl.pathname,\n authConfig.basePath || \"\",\n );\n\n // Check if we're already in a redirect flow\n if (request.nextUrl.searchParams.has(\"targetUrl\")) {\n return null;\n }\n\n // Create refresh redirect\n const refreshUrl = new URL(\n authConfig.refreshUrl,\n getOriginUrl(request, authConfig),\n );\n refreshUrl.searchParams.set(\"targetUrl\", targetUrl);\n\n logger.debug(\"→ Refresh token found - redirecting to refresh endpoint\");\n\n return redirectWithBasePath(authConfig, refreshUrl.toString());\n};\n\n/**\n * Checks if the current path is a system URL that should skip auth\n */\nexport const shouldSkipAuthForSystemUrls = (\n pathname: string,\n authConfig: AuthConfigWithDefaults,\n method: string,\n): boolean => {\n const systemUrls = [\n authConfig.callbackUrl,\n authConfig.challengeUrl,\n authConfig.logoutCallbackUrl,\n authConfig.logoutUrl,\n ];\n\n const isSystemUrl = systemUrls.includes(pathname) && method === \"GET\";\n\n if (isSystemUrl) {\n logger.debug(\n \"→ Skipping auth check - this a URL defined in authConfig\",\n pathname,\n );\n }\n\n return isSystemUrl;\n};\n\n/**\n * CookieStorage implementation for NextJS middleware context that works with NextRequest\n */\nexport class NextjsMiddlewareCookieStorage extends CookieStorage {\n constructor(\n public config: Partial<Record<KeySetter, CookieConfig>> = {},\n private request: NextRequest,\n private response: NextResponse,\n ) {\n super({\n secure: true,\n httpOnly: true,\n });\n }\n\n async get(key: string): Promise<string | null> {\n return this.request.cookies.get(key)?.value || null;\n }\n\n async set(\n key: string,\n value: string,\n cookieConfigOverride: CookieConfig,\n ): Promise<void> {\n const cookieSettings = this.config?.[key as KeySetter] || {\n ...this.settings,\n };\n const dynamicConfig = getCookieConfiguration(this.request);\n\n const useCookieSettings = {\n ...cookieSettings,\n ...cookieConfigOverride,\n // Apply dynamic configuration for secure and sameSite\n secure: dynamicConfig.secure,\n sameSite: dynamicConfig.sameSite,\n };\n\n // Respect the httpOnly setting from configuration instead of hardcoding it\n this.response.cookies.set(key, value, useCookieSettings);\n }\n\n async delete(key: string): Promise<void> {\n // Get cookie configuration for this key to respect the path setting\n const cookieSettings = this.config?.[key as KeySetter] || {};\n\n // If we have a path configured, use it when deleting the cookie\n if (cookieSettings.path) {\n this.response.cookies.set(key, \"\", {\n expires: new Date(0), // Expire in the past\n path: cookieSettings.path,\n });\n } else {\n this.response.cookies.delete(key);\n }\n }\n}\n\n/**\n * Handles authentication logic specifically for the login URL\n * Provides logging for login URL access patterns\n */\nexport const handleLoginUrl = (\n pathname: string,\n session: SessionData,\n authConfig: AuthConfigWithDefaults,\n): void => {\n if (pathname !== authConfig.loginUrl) {\n return;\n }\n\n // We are on the login URL - log the access pattern\n if (session.authenticated) {\n logger.debug(`→ Authenticated user accessing login page`);\n } else {\n logger.debug(`→ Unauthenticated user accessing login page`);\n }\n};\n\n/**\n * Checks if the current path should skip auth based on include/exclude patterns\n */\nexport const shouldSkipAuthForRoutePatterns = (\n pathname: string,\n authConfig: AuthConfigWithDefaults,\n): boolean => {\n // Check include patterns\n if (!matchesGlobs(pathname, authConfig.include)) {\n logger.debug(\n \"→ Skipping auth check - path not in include patterns\",\n pathname,\n );\n return true;\n }\n\n // Check exclude patterns\n if (matchesGlobs(pathname, authConfig.exclude)) {\n logger.debug(\"→ Skipping auth check - path in exclude patterns\", pathname);\n return true;\n }\n\n return false;\n};\n\nexport const copyCivicCookies = (\n sourceResponse: NextResponse,\n targetResponse: NextResponse,\n) => {\n const civicCookieNames = [\n ...Object.values(OAuthTokenTypes),\n ...Object.values(UserStorage),\n ...Object.values(CodeVerifier),\n ];\n logger.debug(\"Copying Civic cookies:\", {\n src: sourceResponse.url,\n target: targetResponse.url,\n });\n sourceResponse?.cookies\n .getAll()\n .filter((cookie) =>\n civicCookieNames.includes(cookie.name as OAuthTokenTypes),\n )\n .forEach((cookie) => {\n logger.debug(\"Setting middlewareResponse cookie:\", cookie);\n targetResponse.cookies.set(cookie);\n });\n};\n/**\n * Handles final authentication logic for unauthenticated users on protected routes\n */\nexport const handleUnauthenticatedUser = async (\n session: SessionData,\n request: NextRequest,\n response: NextResponse,\n storage: NextjsMiddlewareCookieStorage,\n authConfig: AuthConfigWithDefaults,\n): Promise<NextResponse | undefined> => {\n // Clear expired/invalid tokens if they exist\n if (session.accessToken || session.idToken || session.refreshToken) {\n logger.debug(`→ Clearing expired/invalid tokens`);\n await clearTokens(storage);\n }\n\n // Final fallback: redirect to login unless we're already there.\n const loginUrl = new URL(\n authConfig.loginUrl,\n getOriginUrl(request, authConfig),\n );\n const redirectUrl = `${loginUrl.toString()}`;\n const loginPathWithoutBasePath = removeBasePathFromPath(\n loginUrl.pathname,\n authConfig.basePath,\n );\n\n // If we're already at the login URL, the middleware will just return undefined.\n // This is to prevent an infinite redirect loop if middleware is applied to the login route itself.\n // The loginUrl from getOriginUrl already includes the basePath, but request.nextUrl.pathname does not. So we strip it off to enable comparison.\n if (request.nextUrl.pathname !== loginPathWithoutBasePath) {\n logger.debug(\n `→ No valid tokens found - redirecting to login \"${redirectUrl}\"`,\n );\n const redirectedResponse = redirectWithBasePath(authConfig, redirectUrl);\n return redirectedResponse;\n }\n\n return response;\n};\n\n/**\n * Prepends the basePath onto a given URL if it's not already there. Works for both relative and absolute URLs.\n * @param url\n * @param basePath\n * @returns\n */\nexport const prependBasePath = (url: string, basePath: string) => {\n basePath = \"/\" + basePath.replace(/^\\/|\\/$/g, \"\"); // normalize basePath\n\n const isAbsolute = /^https?:\\/\\//.test(url);\n\n if (isAbsolute) {\n const u = new URL(url);\n if (!u.pathname.startsWith(basePath)) {\n u.pathname =\n basePath + (u.pathname.startsWith(\"/\") ? \"\" : \"/\") + u.pathname;\n }\n return u.toString();\n }\n\n return url.startsWith(basePath)\n ? url\n : basePath + (url.startsWith(\"/\") ? \"\" : \"/\") + url;\n};\n\nexport const redirectWithBasePath = (\n config: AuthConfig,\n targetUrl: string,\n): NextResponse =>\n NextResponse.redirect(prependBasePath(targetUrl, config.basePath || \"\"));\n"]}
@@ -27,7 +27,7 @@
27
27
  * - Server-side rendering scenarios where providers might be problematic
28
28
  */
29
29
  import type { User, Session } from "../../vanillajs/index.js";
30
- import type { FrameworkType } from "../../types.js";
30
+ import type { AuthStorage, FrameworkType } from "../../types.js";
31
31
  import type { VanillaJSDisplayMode } from "../../vanillajs/auth/types/AuthTypes.js";
32
32
  import type { LoggingConfig } from "../../vanillajs/auth/types/AuthTypes.js";
33
33
  import type { BackendEndpoints } from "../../server/config.js";
@@ -44,6 +44,7 @@ export interface GlobalAuthConfig {
44
44
  logoutRedirectUrl?: string;
45
45
  scopes?: string[];
46
46
  authProcessTimeout?: number;
47
+ onRefresh?: (error?: Error) => void;
47
48
  onSignIn?: (error?: Error) => void;
48
49
  onSignOut?: () => void;
49
50
  onUrlChange?: (url: string, source?: string) => void;
@@ -55,6 +56,8 @@ export interface GlobalAuthConfig {
55
56
  backendEndpoints?: BackendEndpoints;
56
57
  targetContainerElement?: HTMLElement | string;
57
58
  loginSuccessUrl?: string;
59
+ storage?: AuthStorage;
60
+ initialUser?: User | null;
58
61
  }
59
62
  export type AuthStatus = "authenticated" | "unauthenticated" | "authenticating" | "error" | "signing_out";
60
63
  export interface GlobalAuthState {
@@ -87,6 +90,7 @@ declare class GlobalAuthManager {
87
90
  * Returns the same promise for concurrent calls with same config
88
91
  */
89
92
  initialize(config: GlobalAuthConfig): Promise<void>;
93
+ private defaultOnUrlChange;
90
94
  /**
91
95
  * Private method that does the actual initialization work
92
96
  */
@@ -154,7 +158,7 @@ declare class GlobalAuthManager {
154
158
  /**
155
159
  * Refresh user and session data
156
160
  */
157
- private refreshUserAndSession;
161
+ private updateUserAndSession;
158
162
  /**
159
163
  * Update state and notify listeners
160
164
  */
@@ -1 +1 @@
1
- {"version":3,"file":"GlobalAuthManager.d.ts","sourceRoot":"","sources":["../../../src/reactjs/core/GlobalAuthManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"GlobalAuthManager.d.ts","sourceRoot":"","sources":["../../../src/reactjs/core/GlobalAuthManager.ts"],"names":[],"mappings":"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"}
@@ -79,6 +79,10 @@ class GlobalAuthManager {
79
79
  }
80
80
  return this.initializationPromise;
81
81
  }
82
+ defaultOnUrlChange(url, source) {
83
+ console.log("onUrlChange triggering window redirect", { url, source });
84
+ window.location.href = url;
85
+ }
82
86
  /**
83
87
  * Private method that does the actual initialization work
84
88
  */
@@ -87,9 +91,16 @@ class GlobalAuthManager {
87
91
  this.callbacks = {
88
92
  onSignIn: config.onSignIn,
89
93
  onSignOut: config.onSignOut,
90
- onUrlChange: config.onUrlChange,
94
+ onUrlChange: config.onUrlChange || this.defaultOnUrlChange,
95
+ onRefresh: config.onRefresh,
91
96
  };
92
- this.setState({ isLoading: true, error: null });
97
+ this.setState({
98
+ isLoading: true,
99
+ error: null,
100
+ ...(this.config.initialUser
101
+ ? { user: this.config.initialUser, authStatus: "authenticated" }
102
+ : {}), // Set initial user if provided
103
+ });
93
104
  try {
94
105
  this.events = new AuthenticationEvents();
95
106
  this.setupEventListeners();
@@ -142,7 +153,7 @@ class GlobalAuthManager {
142
153
  // Check initial auth state
143
154
  const isAuthenticated = await this.auth.isAuthenticated();
144
155
  if (isAuthenticated) {
145
- await this.refreshUserAndSession();
156
+ await this.updateUserAndSession();
146
157
  this.setState({ authStatus: "authenticated" });
147
158
  }
148
159
  else {
@@ -206,7 +217,7 @@ class GlobalAuthManager {
206
217
  return { user: authResult.user };
207
218
  }
208
219
  // Fallback: try to refresh user and session data
209
- await this.refreshUserAndSession();
220
+ await this.updateUserAndSession();
210
221
  // Check the current state for the user after refresh
211
222
  const currentState = this.getState();
212
223
  if (!currentState.user) {
@@ -315,13 +326,21 @@ class GlobalAuthManager {
315
326
  error: null,
316
327
  });
317
328
  });
329
+ this.events.on(AuthEvent.TOKEN_REFRESH_COMPLETE, () => {
330
+ this.setState({
331
+ isLoading: false,
332
+ authStatus: "authenticated",
333
+ });
334
+ this.updateUserAndSession();
335
+ this.callbacks.onRefresh?.();
336
+ });
318
337
  this.events.on(AuthEvent.SIGN_IN_COMPLETE, () => {
319
338
  this.setState({
320
339
  isLoading: false,
321
340
  authStatus: "authenticated",
322
341
  error: null,
323
342
  });
324
- this.refreshUserAndSession();
343
+ this.updateUserAndSession();
325
344
  this.callbacks.onSignIn?.();
326
345
  });
327
346
  this.events.on(AuthEvent.SIGN_IN_ERROR, (event) => {
@@ -352,7 +371,7 @@ class GlobalAuthManager {
352
371
  this.callbacks.onSignOut?.();
353
372
  });
354
373
  this.events.on(AuthEvent.USER_SESSION_CHANGED, () => {
355
- this.refreshUserAndSession();
374
+ this.updateUserAndSession();
356
375
  });
357
376
  this.events.on(AuthEvent.URL_CHANGE, (event) => {
358
377
  this.setState({
@@ -368,7 +387,7 @@ class GlobalAuthManager {
368
387
  /**
369
388
  * Refresh user and session data
370
389
  */
371
- async refreshUserAndSession() {
390
+ async updateUserAndSession() {
372
391
  if (!this.auth)
373
392
  return;
374
393
  try {
@@ -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 { FrameworkType } from \"../../types.js\";\nimport type { VanillaJSDisplayMode } from \"../../vanillajs/auth/types/AuthTypes.js\";\nimport type { LoggingConfig } from \"@/vanillajs/auth/types/AuthTypes.js\";\nimport { DEFAULT_AUTH_PROCESS_TIMEOUT } from \"../../vanillajs/auth/types/AuthTypes.js\";\nimport type { BackendEndpoints } from \"@/server/config.js\";\n\n// Event payload interfaces\ninterface SignInErrorEvent {\n detail: string;\n}\n\nexport interface GlobalAuthConfig {\n clientId?: string;\n redirectUrl?: string;\n loginUrl?: string;\n config?: {\n oauthServer?: string;\n };\n displayMode?: VanillaJSDisplayMode;\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 onUrlChange?: (url: string, source?: string) => void;\n logging?: LoggingConfig;\n preloadIframe?: boolean;\n autoRedirect?: boolean;\n /** Framework being used (for analytics) - internal use only */\n framework?: FrameworkType;\n backendEndpoints?: BackendEndpoints;\n targetContainerElement?: HTMLElement | string;\n loginSuccessUrl?: string;\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?: VanillaJSDisplayMode;\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 onUrlChange?: (url: string, source?: string) => 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 onUrlChange: config.onUrlChange,\n };\n this.setState({ isLoading: true, error: null });\n\n try {\n this.events = new AuthenticationEvents();\n this.setupEventListeners();\n\n // Build base config common to both branches\n const baseConfig = {\n ...config,\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:\n config.authProcessTimeout || DEFAULT_AUTH_PROCESS_TIMEOUT,\n preloadIframe: config.preloadIframe,\n autoRedirect: config.autoRedirect,\n events: this.events,\n framework: config.framework,\n };\n\n // Build auth config based on discriminated union requirements\n const authConfig: CivicAuthClientConfig = config.loginUrl\n ? {\n // Backend integration mode: loginUrl required, clientId optional\n ...baseConfig,\n loginUrl: config.loginUrl,\n clientId: config.clientId,\n }\n : {\n // Standard OAuth mode: clientId required, loginUrl optional\n ...baseConfig,\n clientId: config.clientId!,\n loginUrl: config.loginUrl,\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 // Only add loginSuccessUrl if provided\n if (config.loginSuccessUrl) {\n authConfig.loginSuccessUrl = config.loginSuccessUrl;\n }\n\n this.auth = await CivicAuth.create(authConfig);\n\n // Check initial auth state\n const isAuthenticated = await this.auth.isAuthenticated();\n\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 * Get current configuration\n * Returns the current config or null if not initialized\n */\n getConfig(): GlobalAuthConfig | null {\n return this.config ? { ...this.config } : null;\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 authResult = await this.auth.startAuthentication();\n\n // If authentication returned a user, use it directly\n if (authResult.user) {\n this.setState({\n user: authResult.user,\n authStatus: \"authenticated\",\n error: null,\n });\n return { user: authResult.user };\n }\n\n // Fallback: try to refresh user and session data\n await this.refreshUserAndSession();\n\n // Check the current state for the user after refresh\n const currentState = this.getState();\n\n if (!currentState.user) {\n throw new Error(\"Authentication succeeded but no user was returned\");\n }\n\n // Return the user object from current state\n return { user: currentState.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 * Reloads embedded authentication interface\n *\n * This method is specifically designed for embedded mode scenarios where the iframe\n * needs to be recreated after navigation or DOM changes. It delegates to the\n * underlying CivicAuth instance's reloadEmbedded method.\n *\n * @returns Promise that resolves when the embedded iframe is created\n * @throws {Error} If not in embedded mode or if auth is not initialized\n */\n async reloadEmbedded(): Promise<void> {\n if (!this.auth) {\n throw new Error(\"Auth not initialized. Call initialize() first.\");\n }\n\n return this.auth.reloadEmbedded();\n }\n\n /**\n * Reset authentication state when detected from back-forward cache (bfcache)\n * This fixes issues where sign-in button becomes unclickable after back navigation\n */\n resetOnBfcache(): void {\n if (!this.auth) return;\n\n // Reset internal CivicAuth state first\n this.auth.resetOnBfcache();\n\n // Reset auth state to unauthenticated to allow new sign-in attempts\n this.setState({\n authStatus: \"unauthenticated\",\n isLoading: false,\n error: null,\n user: null,\n session: null,\n });\n\n // Ensure iframe preloading state is refreshed if needed\n if (this.getPreloadEnabled()) {\n this.auth.setPreloadEnabled(true);\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 this.config.preloadIframe === newConfig.preloadIframe &&\n this.config.autoRedirect === newConfig.autoRedirect\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 this.events.on(\n AuthEvent.URL_CHANGE,\n (event?: { detail?: string; url?: string; source?: string }) => {\n this.setState({\n authStatus: \"authenticating\", // Keep as authenticating since we're redirecting\n error: null,\n });\n // Call custom URL change handler if provided\n if (event?.url && this.callbacks.onUrlChange) {\n this.callbacks.onUrlChange(event.url, event.source);\n }\n },\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 { AuthStorage, FrameworkType } from \"../../types.js\";\nimport type { VanillaJSDisplayMode } from \"../../vanillajs/auth/types/AuthTypes.js\";\nimport type { LoggingConfig } from \"@/vanillajs/auth/types/AuthTypes.js\";\nimport { DEFAULT_AUTH_PROCESS_TIMEOUT } from \"../../vanillajs/auth/types/AuthTypes.js\";\nimport type { BackendEndpoints } from \"@/server/config.js\";\n\n// Event payload interfaces\ninterface SignInErrorEvent {\n detail: string;\n}\n\nexport interface GlobalAuthConfig {\n clientId?: string;\n redirectUrl?: string;\n loginUrl?: string;\n config?: {\n oauthServer?: string;\n };\n displayMode?: VanillaJSDisplayMode;\n iframeMode?: \"modal\" | \"embedded\";\n nonce?: string;\n logoutRedirectUrl?: string;\n scopes?: string[];\n authProcessTimeout?: number;\n onRefresh?: (error?: Error) => void;\n onSignIn?: (error?: Error) => void;\n onSignOut?: () => void;\n onUrlChange?: (url: string, source?: string) => void;\n logging?: LoggingConfig;\n preloadIframe?: boolean;\n autoRedirect?: boolean;\n /** Framework being used (for analytics) - internal use only */\n framework?: FrameworkType;\n backendEndpoints?: BackendEndpoints;\n targetContainerElement?: HTMLElement | string;\n loginSuccessUrl?: string;\n storage?: AuthStorage;\n initialUser?: User | null;\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?: VanillaJSDisplayMode;\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 onUrlChange?: (url: string, source?: string) => void;\n onRefresh?: (error?: Error) => 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 private defaultOnUrlChange(url: string, source?: string) {\n console.log(\"onUrlChange triggering window redirect\", { url, source });\n window.location.href = url;\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 onUrlChange: config.onUrlChange || this.defaultOnUrlChange,\n onRefresh: config.onRefresh,\n };\n this.setState({\n isLoading: true,\n error: null,\n ...(this.config.initialUser\n ? { user: this.config.initialUser, authStatus: \"authenticated\" }\n : {}), // Set initial user if provided\n });\n\n try {\n this.events = new AuthenticationEvents();\n this.setupEventListeners();\n\n // Build base config common to both branches\n const baseConfig = {\n ...config,\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:\n config.authProcessTimeout || DEFAULT_AUTH_PROCESS_TIMEOUT,\n preloadIframe: config.preloadIframe,\n autoRedirect: config.autoRedirect,\n events: this.events,\n framework: config.framework,\n };\n\n // Build auth config based on discriminated union requirements\n const authConfig: CivicAuthClientConfig = config.loginUrl\n ? {\n // Backend integration mode: loginUrl required, clientId optional\n ...baseConfig,\n loginUrl: config.loginUrl,\n clientId: config.clientId,\n }\n : {\n // Standard OAuth mode: clientId required, loginUrl optional\n ...baseConfig,\n clientId: config.clientId!,\n loginUrl: config.loginUrl,\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 // Only add loginSuccessUrl if provided\n if (config.loginSuccessUrl) {\n authConfig.loginSuccessUrl = config.loginSuccessUrl;\n }\n\n this.auth = await CivicAuth.create(authConfig);\n\n // Check initial auth state\n const isAuthenticated = await this.auth.isAuthenticated();\n\n if (isAuthenticated) {\n await this.updateUserAndSession();\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 * Get current configuration\n * Returns the current config or null if not initialized\n */\n getConfig(): GlobalAuthConfig | null {\n return this.config ? { ...this.config } : null;\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 authResult = await this.auth.startAuthentication();\n\n // If authentication returned a user, use it directly\n if (authResult.user) {\n this.setState({\n user: authResult.user,\n authStatus: \"authenticated\",\n error: null,\n });\n return { user: authResult.user };\n }\n\n // Fallback: try to refresh user and session data\n await this.updateUserAndSession();\n\n // Check the current state for the user after refresh\n const currentState = this.getState();\n\n if (!currentState.user) {\n throw new Error(\"Authentication succeeded but no user was returned\");\n }\n\n // Return the user object from current state\n return { user: currentState.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 * Reloads embedded authentication interface\n *\n * This method is specifically designed for embedded mode scenarios where the iframe\n * needs to be recreated after navigation or DOM changes. It delegates to the\n * underlying CivicAuth instance's reloadEmbedded method.\n *\n * @returns Promise that resolves when the embedded iframe is created\n * @throws {Error} If not in embedded mode or if auth is not initialized\n */\n async reloadEmbedded(): Promise<void> {\n if (!this.auth) {\n throw new Error(\"Auth not initialized. Call initialize() first.\");\n }\n\n return this.auth.reloadEmbedded();\n }\n\n /**\n * Reset authentication state when detected from back-forward cache (bfcache)\n * This fixes issues where sign-in button becomes unclickable after back navigation\n */\n resetOnBfcache(): void {\n if (!this.auth) return;\n\n // Reset internal CivicAuth state first\n this.auth.resetOnBfcache();\n\n // Reset auth state to unauthenticated to allow new sign-in attempts\n this.setState({\n authStatus: \"unauthenticated\",\n isLoading: false,\n error: null,\n user: null,\n session: null,\n });\n\n // Ensure iframe preloading state is refreshed if needed\n if (this.getPreloadEnabled()) {\n this.auth.setPreloadEnabled(true);\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 this.config.preloadIframe === newConfig.preloadIframe &&\n this.config.autoRedirect === newConfig.autoRedirect\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.TOKEN_REFRESH_COMPLETE, () => {\n this.setState({\n isLoading: false,\n authStatus: \"authenticated\",\n });\n this.updateUserAndSession();\n this.callbacks.onRefresh?.();\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.updateUserAndSession();\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.updateUserAndSession();\n });\n\n this.events.on(\n AuthEvent.URL_CHANGE,\n (event?: { detail?: string; url?: string; source?: string }) => {\n this.setState({\n authStatus: \"authenticating\", // Keep as authenticating since we're redirecting\n error: null,\n });\n // Call custom URL change handler if provided\n if (event?.url && this.callbacks.onUrlChange) {\n this.callbacks.onUrlChange(event.url, event.source);\n }\n },\n );\n }\n\n /**\n * Refresh user and session data\n */\n private async updateUserAndSession(): 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 +1 @@
1
- {"version":3,"file":"useUser.d.ts","sourceRoot":"","sources":["../../../src/reactjs/hooks/useUser.ts"],"names":[],"mappings":"AA0CA,OAAO,KAAK,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAEL,KAAK,gBAAgB,EAEtB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AACpF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAQjD,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,oBAAoB,CAAC;IACnC,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,sBAAsB,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;IAC9C,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,KAAK,IAAI,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CACtD;AAED,MAAM,WAAW,eAAe,CAC9B,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC;IAEzD,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,UAAU,CAAC;IACvB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,YAAY,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAA;KAAE,CAAC,CAAC;IAC9D,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAElD,yBAAyB,EAAE,MAAM,OAAO,CAAC;IACzC,iBAAiB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC9C,iBAAiB,EAAE,MAAM,OAAO,CAAC;IACjC,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED,QAAA,MAAM,OAAO,GAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,mCACvC,gBAAgB,KACxB,eAAe,CAAC,CAAC,CA0SnB,CAAC;AAEF,OAAO,EAAE,OAAO,EAAE,CAAC"}
1
+ {"version":3,"file":"useUser.d.ts","sourceRoot":"","sources":["../../../src/reactjs/hooks/useUser.ts"],"names":[],"mappings":"AAyCA,OAAO,KAAK,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAEL,KAAK,gBAAgB,EAEtB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AACpF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAYjD,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,oBAAoB,CAAC;IACnC,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,sBAAsB,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;IAC9C,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,KAAK,IAAI,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CACtD;AAED,MAAM,WAAW,eAAe,CAC9B,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC;IAEzD,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,UAAU,CAAC;IACvB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,YAAY,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAA;KAAE,CAAC,CAAC;IAC9D,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAElD,yBAAyB,EAAE,MAAM,OAAO,CAAC;IACzC,iBAAiB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC9C,iBAAiB,EAAE,MAAM,OAAO,CAAC;IACjC,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED,QAAA,MAAM,OAAO,GAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,mCACvC,gBAAgB,KACxB,eAAe,CAAC,CAAC,CAuOnB,CAAC;AAEF,OAAO,EAAE,OAAO,EAAE,CAAC"}