@civic/auth 0.10.0-beta.8 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/dist/lib/logger.d.ts +1 -0
  3. package/dist/lib/logger.d.ts.map +1 -1
  4. package/dist/lib/logger.js +1 -0
  5. package/dist/lib/logger.js.map +1 -1
  6. package/dist/nextjs/config.d.ts +29 -0
  7. package/dist/nextjs/config.d.ts.map +1 -1
  8. package/dist/nextjs/config.js +53 -24
  9. package/dist/nextjs/config.js.map +1 -1
  10. package/dist/nextjs/cookies.d.ts.map +1 -1
  11. package/dist/nextjs/cookies.js +16 -1
  12. package/dist/nextjs/cookies.js.map +1 -1
  13. package/dist/nextjs/hooks/useInitialAuthConfig.d.ts.map +1 -1
  14. package/dist/nextjs/hooks/useInitialAuthConfig.js +27 -15
  15. package/dist/nextjs/hooks/useInitialAuthConfig.js.map +1 -1
  16. package/dist/nextjs/middleware.d.ts.map +1 -1
  17. package/dist/nextjs/middleware.js +17 -6
  18. package/dist/nextjs/middleware.js.map +1 -1
  19. package/dist/nextjs/providers/NextAuthProviderClient.js +1 -1
  20. package/dist/nextjs/providers/NextAuthProviderClient.js.map +1 -1
  21. package/dist/nextjs/routeHandler.d.ts.map +1 -1
  22. package/dist/nextjs/routeHandler.js +0 -11
  23. package/dist/nextjs/routeHandler.js.map +1 -1
  24. package/dist/nextjs/utils.d.ts +3 -7
  25. package/dist/nextjs/utils.d.ts.map +1 -1
  26. package/dist/nextjs/utils.js +34 -25
  27. package/dist/nextjs/utils.js.map +1 -1
  28. package/dist/reactjs/core/GlobalAuthManager.d.ts.map +1 -1
  29. package/dist/reactjs/core/GlobalAuthManager.js +1 -1
  30. package/dist/reactjs/core/GlobalAuthManager.js.map +1 -1
  31. package/dist/shared/hooks/index.d.ts +0 -1
  32. package/dist/shared/hooks/index.d.ts.map +1 -1
  33. package/dist/shared/hooks/index.js +0 -1
  34. package/dist/shared/hooks/index.js.map +1 -1
  35. package/dist/shared/lib/BrowserAuthenticationRefresher.d.ts.map +1 -1
  36. package/dist/shared/lib/BrowserAuthenticationRefresher.js +8 -0
  37. package/dist/shared/lib/BrowserAuthenticationRefresher.js.map +1 -1
  38. package/dist/shared/lib/GenericAuthenticationRefresher.d.ts +1 -0
  39. package/dist/shared/lib/GenericAuthenticationRefresher.d.ts.map +1 -1
  40. package/dist/shared/lib/GenericAuthenticationRefresher.js +2 -0
  41. package/dist/shared/lib/GenericAuthenticationRefresher.js.map +1 -1
  42. package/dist/shared/lib/cookieUtils.d.ts +6 -0
  43. package/dist/shared/lib/cookieUtils.d.ts.map +1 -0
  44. package/dist/shared/lib/cookieUtils.js +21 -0
  45. package/dist/shared/lib/cookieUtils.js.map +1 -0
  46. package/dist/shared/version.d.ts +1 -1
  47. package/dist/shared/version.d.ts.map +1 -1
  48. package/dist/shared/version.js +1 -1
  49. package/dist/shared/version.js.map +1 -1
  50. package/dist/vanillajs/auth/BackendAuthenticationRefresher.d.ts.map +1 -1
  51. package/dist/vanillajs/auth/BackendAuthenticationRefresher.js +10 -2
  52. package/dist/vanillajs/auth/BackendAuthenticationRefresher.js.map +1 -1
  53. package/dist/vanillajs/auth/SessionManager.d.ts.map +1 -1
  54. package/dist/vanillajs/auth/SessionManager.js +10 -2
  55. package/dist/vanillajs/auth/SessionManager.js.map +1 -1
  56. package/dist/vanillajs/auth/TokenRefresher.d.ts +3 -0
  57. package/dist/vanillajs/auth/TokenRefresher.d.ts.map +1 -1
  58. package/dist/vanillajs/auth/TokenRefresher.js +24 -1
  59. package/dist/vanillajs/auth/TokenRefresher.js.map +1 -1
  60. package/package.json +1 -1
  61. package/dist/nextjs/hooks/useRefresh.d.ts +0 -5
  62. package/dist/nextjs/hooks/useRefresh.d.ts.map +0 -1
  63. package/dist/nextjs/hooks/useRefresh.js +0 -57
  64. package/dist/nextjs/hooks/useRefresh.js.map +0 -1
  65. package/dist/shared/hooks/useRefresh.d.ts +0 -6
  66. package/dist/shared/hooks/useRefresh.d.ts.map +0 -1
  67. package/dist/shared/hooks/useRefresh.js +0 -47
  68. package/dist/shared/hooks/useRefresh.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -7,6 +7,8 @@
7
7
  - Refactor NextJS middleware to use direct session rehydration and setting of response cookies rather than redirect
8
8
  - Add POST method documentation to routeHandler
9
9
  - Fix auto-redirect behaviour in browsers that don't support popups (like safari)
10
+ - Fix cookie retrieval logic at different basePaths
11
+ - Various fixes to refresh and session hydration, so that refresh works in various scenarios with and without middleware, on backends and SPA's.
10
12
 
11
13
  # 0.9.5
12
14
 
@@ -13,6 +13,7 @@ export declare const loggers: {
13
13
  readonly auth: Logger;
14
14
  };
15
15
  readonly actions: Logger;
16
+ readonly hooks: Logger;
16
17
  };
17
18
  readonly react: {
18
19
  readonly components: Logger;
@@ -1 +1 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/lib/logger.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,MAAM;IACrB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IACjD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAChD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAChD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;CAClD;AAsCD,eAAO,MAAM,YAAY,cAAe,MAAM,KAAG,MACrB,CAAC;AAG7B,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;CA4BV,CAAC"}
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/lib/logger.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,MAAM;IACrB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IACjD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAChD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAChD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;CAClD;AAsCD,eAAO,MAAM,YAAY,cAAe,MAAM,KAAG,MACrB,CAAC;AAG7B,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;CA6BV,CAAC"}
@@ -40,6 +40,7 @@ export const loggers = {
40
40
  auth: createLogger("api:handlers:auth"),
41
41
  },
42
42
  actions: createLogger("api:actions"),
43
+ hooks: createLogger("next:hooks"),
43
44
  },
44
45
  // React specific loggers
45
46
  react: {
@@ -1 +1 @@
1
- {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/lib/logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,YAAY,GAAG,aAAa,CAAC;AASnC,MAAM,WAAW;IACP,WAAW,CAAiB;IAC5B,UAAU,CAAiB;IAC3B,UAAU,CAAiB;IAC3B,WAAW,CAAiB;IAEpC,YAAY,SAAiB;QAC3B,+CAA+C;QAC/C,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,GAAG,YAAY,IAAI,SAAS,QAAQ,CAAC,CAAC;QAC/D,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,GAAG,YAAY,IAAI,SAAS,OAAO,CAAC,CAAC;QAC7D,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,GAAG,YAAY,IAAI,SAAS,OAAO,CAAC,CAAC;QAC7D,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,GAAG,YAAY,IAAI,SAAS,QAAQ,CAAC,CAAC;QAE/D,IAAI,CAAC,WAAW,CAAC,KAAK,GAAG,GAAG,CAAC;QAC7B,IAAI,CAAC,UAAU,CAAC,KAAK,GAAG,GAAG,CAAC;QAC5B,IAAI,CAAC,UAAU,CAAC,KAAK,GAAG,GAAG,CAAC;QAC5B,IAAI,CAAC,WAAW,CAAC,KAAK,GAAG,GAAG,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,GAAG,IAAe;QACvC,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IACrC,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,GAAG,IAAe;QACtC,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IACpC,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,GAAG,IAAe;QACtC,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IACpC,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,GAAG,IAAe;QACvC,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IACrC,CAAC;CACF;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,SAAiB,EAAU,EAAE,CACxD,IAAI,WAAW,CAAC,SAAS,CAAC,CAAC;AAE7B,4DAA4D;AAC5D,MAAM,CAAC,MAAM,OAAO,GAAG;IACrB,2BAA2B;IAC3B,MAAM,EAAE;QACN,MAAM,EAAE,YAAY,CAAC,YAAY,CAAC;QAClC,UAAU,EAAE,YAAY,CAAC,gBAAgB,CAAC;QAC1C,QAAQ,EAAE;YACR,IAAI,EAAE,YAAY,CAAC,mBAAmB,CAAC;SACxC;QACD,OAAO,EAAE,YAAY,CAAC,aAAa,CAAC;KACrC;IACD,yBAAyB;IACzB,KAAK,EAAE;QACL,UAAU,EAAE,YAAY,CAAC,kBAAkB,CAAC;QAC5C,KAAK,EAAE,YAAY,CAAC,aAAa,CAAC;QAClC,OAAO,EAAE,YAAY,CAAC,eAAe,CAAC;KACvC;IACD,gCAAgC;IAChC,WAAW,EAAE;QACX,MAAM,EAAE,YAAY,CAAC,qBAAqB,CAAC;QAC3C,QAAQ,EAAE;YACR,IAAI,EAAE,YAAY,CAAC,4BAA4B,CAAC;SACjD;KACF;IACD,2BAA2B;IAC3B,QAAQ,EAAE;QACR,UAAU,EAAE,YAAY,CAAC,kBAAkB,CAAC;QAC5C,OAAO,EAAE,YAAY,CAAC,eAAe,CAAC;KACvC;CACO,CAAC","sourcesContent":["import debug from \"debug\";\n\nconst PACKAGE_NAME = \"@civic/auth\";\n\nexport interface Logger {\n debug(message: string, ...args: unknown[]): void;\n info(message: string, ...args: unknown[]): void;\n warn(message: string, ...args: unknown[]): void;\n error(message: string, ...args: unknown[]): void;\n}\n\nclass DebugLogger implements Logger {\n private debugLogger: debug.Debugger;\n private infoLogger: debug.Debugger;\n private warnLogger: debug.Debugger;\n private errorLogger: debug.Debugger;\n\n constructor(namespace: string) {\n // Format: @org/package:library:component:level\n this.debugLogger = debug(`${PACKAGE_NAME}:${namespace}:debug`);\n this.infoLogger = debug(`${PACKAGE_NAME}:${namespace}:info`);\n this.warnLogger = debug(`${PACKAGE_NAME}:${namespace}:warn`);\n this.errorLogger = debug(`${PACKAGE_NAME}:${namespace}:error`);\n\n this.debugLogger.color = \"4\";\n this.infoLogger.color = \"2\";\n this.warnLogger.color = \"3\";\n this.errorLogger.color = \"1\";\n }\n\n debug(message: string, ...args: unknown[]): void {\n this.debugLogger(message, ...args);\n }\n\n info(message: string, ...args: unknown[]): void {\n this.infoLogger(message, ...args);\n }\n\n warn(message: string, ...args: unknown[]): void {\n this.warnLogger(message, ...args);\n }\n\n error(message: string, ...args: unknown[]): void {\n this.errorLogger(message, ...args);\n }\n}\n\nexport const createLogger = (namespace: string): Logger =>\n new DebugLogger(namespace);\n\n// Pre-configured loggers for different parts of the package\nexport const loggers = {\n // Next.js specific loggers\n nextjs: {\n routes: createLogger(\"api:routes\"),\n middleware: createLogger(\"api:middleware\"),\n handlers: {\n auth: createLogger(\"api:handlers:auth\"),\n },\n actions: createLogger(\"api:actions\"),\n },\n // React specific loggers\n react: {\n components: createLogger(\"react:components\"),\n hooks: createLogger(\"react:hooks\"),\n context: createLogger(\"react:context\"),\n },\n // React Router specific loggers\n reactRouter: {\n routes: createLogger(\"react-router:routes\"),\n handlers: {\n auth: createLogger(\"react-router:handlers:auth\"),\n },\n },\n // Shared utilities loggers\n services: {\n validation: createLogger(\"utils:validation\"),\n network: createLogger(\"utils:network\"),\n },\n} as const;\n"]}
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/lib/logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,YAAY,GAAG,aAAa,CAAC;AASnC,MAAM,WAAW;IACP,WAAW,CAAiB;IAC5B,UAAU,CAAiB;IAC3B,UAAU,CAAiB;IAC3B,WAAW,CAAiB;IAEpC,YAAY,SAAiB;QAC3B,+CAA+C;QAC/C,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,GAAG,YAAY,IAAI,SAAS,QAAQ,CAAC,CAAC;QAC/D,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,GAAG,YAAY,IAAI,SAAS,OAAO,CAAC,CAAC;QAC7D,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,GAAG,YAAY,IAAI,SAAS,OAAO,CAAC,CAAC;QAC7D,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,GAAG,YAAY,IAAI,SAAS,QAAQ,CAAC,CAAC;QAE/D,IAAI,CAAC,WAAW,CAAC,KAAK,GAAG,GAAG,CAAC;QAC7B,IAAI,CAAC,UAAU,CAAC,KAAK,GAAG,GAAG,CAAC;QAC5B,IAAI,CAAC,UAAU,CAAC,KAAK,GAAG,GAAG,CAAC;QAC5B,IAAI,CAAC,WAAW,CAAC,KAAK,GAAG,GAAG,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,GAAG,IAAe;QACvC,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IACrC,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,GAAG,IAAe;QACtC,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IACpC,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,GAAG,IAAe;QACtC,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IACpC,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,GAAG,IAAe;QACvC,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IACrC,CAAC;CACF;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,SAAiB,EAAU,EAAE,CACxD,IAAI,WAAW,CAAC,SAAS,CAAC,CAAC;AAE7B,4DAA4D;AAC5D,MAAM,CAAC,MAAM,OAAO,GAAG;IACrB,2BAA2B;IAC3B,MAAM,EAAE;QACN,MAAM,EAAE,YAAY,CAAC,YAAY,CAAC;QAClC,UAAU,EAAE,YAAY,CAAC,gBAAgB,CAAC;QAC1C,QAAQ,EAAE;YACR,IAAI,EAAE,YAAY,CAAC,mBAAmB,CAAC;SACxC;QACD,OAAO,EAAE,YAAY,CAAC,aAAa,CAAC;QACpC,KAAK,EAAE,YAAY,CAAC,YAAY,CAAC;KAClC;IACD,yBAAyB;IACzB,KAAK,EAAE;QACL,UAAU,EAAE,YAAY,CAAC,kBAAkB,CAAC;QAC5C,KAAK,EAAE,YAAY,CAAC,aAAa,CAAC;QAClC,OAAO,EAAE,YAAY,CAAC,eAAe,CAAC;KACvC;IACD,gCAAgC;IAChC,WAAW,EAAE;QACX,MAAM,EAAE,YAAY,CAAC,qBAAqB,CAAC;QAC3C,QAAQ,EAAE;YACR,IAAI,EAAE,YAAY,CAAC,4BAA4B,CAAC;SACjD;KACF;IACD,2BAA2B;IAC3B,QAAQ,EAAE;QACR,UAAU,EAAE,YAAY,CAAC,kBAAkB,CAAC;QAC5C,OAAO,EAAE,YAAY,CAAC,eAAe,CAAC;KACvC;CACO,CAAC","sourcesContent":["import debug from \"debug\";\n\nconst PACKAGE_NAME = \"@civic/auth\";\n\nexport interface Logger {\n debug(message: string, ...args: unknown[]): void;\n info(message: string, ...args: unknown[]): void;\n warn(message: string, ...args: unknown[]): void;\n error(message: string, ...args: unknown[]): void;\n}\n\nclass DebugLogger implements Logger {\n private debugLogger: debug.Debugger;\n private infoLogger: debug.Debugger;\n private warnLogger: debug.Debugger;\n private errorLogger: debug.Debugger;\n\n constructor(namespace: string) {\n // Format: @org/package:library:component:level\n this.debugLogger = debug(`${PACKAGE_NAME}:${namespace}:debug`);\n this.infoLogger = debug(`${PACKAGE_NAME}:${namespace}:info`);\n this.warnLogger = debug(`${PACKAGE_NAME}:${namespace}:warn`);\n this.errorLogger = debug(`${PACKAGE_NAME}:${namespace}:error`);\n\n this.debugLogger.color = \"4\";\n this.infoLogger.color = \"2\";\n this.warnLogger.color = \"3\";\n this.errorLogger.color = \"1\";\n }\n\n debug(message: string, ...args: unknown[]): void {\n this.debugLogger(message, ...args);\n }\n\n info(message: string, ...args: unknown[]): void {\n this.infoLogger(message, ...args);\n }\n\n warn(message: string, ...args: unknown[]): void {\n this.warnLogger(message, ...args);\n }\n\n error(message: string, ...args: unknown[]): void {\n this.errorLogger(message, ...args);\n }\n}\n\nexport const createLogger = (namespace: string): Logger =>\n new DebugLogger(namespace);\n\n// Pre-configured loggers for different parts of the package\nexport const loggers = {\n // Next.js specific loggers\n nextjs: {\n routes: createLogger(\"api:routes\"),\n middleware: createLogger(\"api:middleware\"),\n handlers: {\n auth: createLogger(\"api:handlers:auth\"),\n },\n actions: createLogger(\"api:actions\"),\n hooks: createLogger(\"next:hooks\"),\n },\n // React specific loggers\n react: {\n components: createLogger(\"react:components\"),\n hooks: createLogger(\"react:hooks\"),\n context: createLogger(\"react:context\"),\n },\n // React Router specific loggers\n reactRouter: {\n routes: createLogger(\"react-router:routes\"),\n handlers: {\n auth: createLogger(\"react-router:handlers:auth\"),\n },\n },\n // Shared utilities loggers\n services: {\n validation: createLogger(\"utils:validation\"),\n network: createLogger(\"utils:network\"),\n },\n} as const;\n"]}
@@ -2,6 +2,32 @@ import type { NextConfig } from "next";
2
2
  import { type CookieConfig, type TokensCookieConfig } from "../shared/lib/types.js";
3
3
  import { type CookiesConfigObject } from "../shared/lib/cookieConfig.js";
4
4
  export type { CookiesConfigObject };
5
+ export declare const systemUrlsConfig: {
6
+ callbackUrl: {
7
+ defaultPath: string;
8
+ applyBasePath: boolean;
9
+ };
10
+ challengeUrl: {
11
+ defaultPath: string;
12
+ applyBasePath: boolean;
13
+ };
14
+ refreshUrl: {
15
+ defaultPath: string;
16
+ applyBasePath: boolean;
17
+ };
18
+ logoutUrl: {
19
+ defaultPath: string;
20
+ applyBasePath: boolean;
21
+ };
22
+ loginInitUrl: {
23
+ defaultPath: string;
24
+ applyBasePath: boolean;
25
+ };
26
+ userUrl: {
27
+ defaultPath: string;
28
+ applyBasePath: boolean;
29
+ };
30
+ };
5
31
  /**
6
32
  * Configuration values for Civic Auth.
7
33
  * Only clientId is required, all others are optional.
@@ -14,6 +40,7 @@ export type AuthConfigWithDefaults = {
14
40
  logoutUrl: string;
15
41
  challengeUrl: string;
16
42
  refreshUrl: string;
43
+ userUrl: string;
17
44
  loginSuccessUrl?: string;
18
45
  loginUrl: string;
19
46
  logoutCallbackUrl: string;
@@ -42,6 +69,7 @@ export type OptionalAuthConfig = Partial<AuthConfigWithDefaults | {
42
69
  logoutCallbackUrl?: string;
43
70
  challengeUrl?: string;
44
71
  refreshUrl?: string;
72
+ userUrl?: string;
45
73
  include?: string[];
46
74
  exclude?: string[];
47
75
  basePath?: string;
@@ -133,6 +161,7 @@ export declare const createCivicAuthPlugin: (authConfig: AuthConfig) => (nextCon
133
161
  _civic_auth_logout_url: string;
134
162
  _civic_auth_logout_callback_url: string;
135
163
  _civic_auth_refresh_url: string;
164
+ _civic_auth_user_url: string;
136
165
  _civic_auth_includes: string;
137
166
  _civic_auth_excludes: string;
138
167
  _civic_auth_cookie_config: string;
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/nextjs/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/nextjs/config.ts"],"names":[],"mappings":"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"}
@@ -6,17 +6,39 @@ import { merge } from "ts-deepmerge";
6
6
  import { sanitizeBasePath } from "./utils.js";
7
7
  import { createNextJSCookieConfig, } from "../shared/lib/cookieConfig.js";
8
8
  const logger = loggers.nextjs.handlers.auth;
9
+ export const systemUrlsConfig = {
10
+ callbackUrl: { defaultPath: "/api/auth/callback", applyBasePath: true },
11
+ challengeUrl: { defaultPath: "/api/auth/challenge", applyBasePath: true },
12
+ refreshUrl: { defaultPath: "/api/auth/refresh", applyBasePath: true },
13
+ logoutUrl: { defaultPath: "/api/auth/logout", applyBasePath: true },
14
+ loginInitUrl: { defaultPath: "/api/auth/login", applyBasePath: true },
15
+ userUrl: { defaultPath: "/api/auth/user", applyBasePath: true },
16
+ };
17
+ const URL_CONFIG = {
18
+ ...systemUrlsConfig,
19
+ logoutCallbackUrl: {
20
+ defaultPath: "",
21
+ applyBasePath: true,
22
+ useBasePathOnly: true,
23
+ },
24
+ loginUrl: {
25
+ defaultPath: "",
26
+ applyBasePath: true,
27
+ useBasePathOnly: true,
28
+ checkEmpty: true,
29
+ },
30
+ };
9
31
  /**
10
32
  * Default configuration values that will be used if not overridden
11
33
  */
12
34
  export const defaultAuthConfig = {
13
35
  oauthServer: DEFAULT_AUTH_SERVER,
14
36
  // Internal API routes
15
- callbackUrl: "/api/auth/callback",
16
- loginInitUrl: "/api/auth/login",
17
- logoutUrl: "/api/auth/logout",
18
- challengeUrl: "/api/auth/challenge",
19
- refreshUrl: "/api/auth/refresh",
37
+ // deconstruct systemUrls to set the keys and default values
38
+ ...Object.fromEntries(Object.entries(systemUrlsConfig).map(([key, value]) => [
39
+ key,
40
+ value.defaultPath,
41
+ ])),
20
42
  // User-facing routes
21
43
  loginSuccessUrl: undefined, // By default, the user is sent to the redirect_url
22
44
  loginUrl: "/",
@@ -63,6 +85,7 @@ export const resolveAuthConfig = (config = {}) => {
63
85
  logoutUrl: process.env._civic_auth_logout_url,
64
86
  logoutCallbackUrl: process.env._civic_auth_logout_callback_url,
65
87
  refreshUrl: process.env._civic_auth_refresh_url,
88
+ userUrl: process.env._civic_auth_user_url,
66
89
  include: process.env._civic_auth_includes?.split(","),
67
90
  exclude: process.env._civic_auth_excludes?.split(","),
68
91
  cookies: hasExplicitCookies
@@ -101,6 +124,28 @@ export const resolveAuthConfig = (config = {}) => {
101
124
  }
102
125
  return mergedConfig;
103
126
  };
127
+ /**
128
+ * Applies basePath to URLs based on URL_CONFIG rules
129
+ */
130
+ function applyBasePathToUrls(authConfig, basePath) {
131
+ const defaultUrlsWithBasePath = {};
132
+ if (!basePath)
133
+ return defaultUrlsWithBasePath;
134
+ Object.entries(URL_CONFIG).forEach(([key, config]) => {
135
+ // Skip if explicitly set in authConfig
136
+ const currentValue = authConfig[key];
137
+ if (currentValue !== undefined &&
138
+ !(config.checkEmpty && currentValue === "")) {
139
+ return;
140
+ }
141
+ // Apply basePath based on config rules
142
+ const urlValue = config.useBasePathOnly
143
+ ? basePath
144
+ : `${basePath}${config.defaultPath}`;
145
+ defaultUrlsWithBasePath[key] = urlValue;
146
+ });
147
+ return defaultUrlsWithBasePath;
148
+ }
104
149
  /**
105
150
  * Creates a Next.js plugin that handles auth configuration.
106
151
  *
@@ -144,25 +189,8 @@ export const createCivicAuthPlugin = (authConfig) => {
144
189
  logger.debug("createCivicAuthPlugin nextConfig", JSON.stringify(nextConfig, null, 2));
145
190
  // Extract basePath from Next.js config
146
191
  const basePath = sanitizeBasePath(nextConfig?.basePath || "");
147
- // Create a copy of default URLs with basePath added
148
- const defaultUrlsWithBasePath = {};
149
- // Only apply to URLs that aren't explicitly set in authConfig
150
- if (basePath) {
151
- if (!authConfig.callbackUrl)
152
- defaultUrlsWithBasePath.callbackUrl = `${basePath}/api/auth/callback`;
153
- if (!authConfig.challengeUrl)
154
- defaultUrlsWithBasePath.challengeUrl = `${basePath}/api/auth/challenge`;
155
- if (!authConfig.refreshUrl)
156
- defaultUrlsWithBasePath.refreshUrl = `${basePath}/api/auth/refresh`;
157
- if (!authConfig.logoutUrl)
158
- defaultUrlsWithBasePath.logoutUrl = `${basePath}/api/auth/logout`;
159
- if (!authConfig.loginInitUrl)
160
- defaultUrlsWithBasePath.loginInitUrl = `${basePath}/api/auth/login`;
161
- if (!authConfig.logoutCallbackUrl)
162
- defaultUrlsWithBasePath.logoutCallbackUrl = `${basePath}`;
163
- if (!authConfig.loginUrl && authConfig.loginUrl !== "")
164
- defaultUrlsWithBasePath.loginUrl = basePath;
165
- }
192
+ // Apply basePath to URLs using the configuration mapping
193
+ const defaultUrlsWithBasePath = applyBasePathToUrls(authConfig, basePath);
166
194
  // Create final config with basePath and possibly modified URLs
167
195
  const resolvedConfig = resolveAuthConfig({
168
196
  ...defaultUrlsWithBasePath,
@@ -184,6 +212,7 @@ export const createCivicAuthPlugin = (authConfig) => {
184
212
  _civic_auth_logout_url: resolvedConfig.logoutUrl,
185
213
  _civic_auth_logout_callback_url: resolvedConfig.logoutCallbackUrl,
186
214
  _civic_auth_refresh_url: resolvedConfig.refreshUrl,
215
+ _civic_auth_user_url: resolvedConfig.userUrl,
187
216
  _civic_auth_includes: resolvedConfig.include.join(","),
188
217
  _civic_auth_excludes: resolvedConfig.exclude.join(","),
189
218
  _civic_auth_cookie_config: JSON.stringify(resolvedConfig.cookies),
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/nextjs/config.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable turbo/no-undeclared-env-vars */\nimport type { NextConfig } from \"next\";\nimport { loggers } from \"@/lib/logger.js\";\nimport { withoutUndefined } from \"@/utils.js\";\nimport {\n type CookieConfig,\n type TokensCookieConfig,\n} from \"@/shared/lib/types.js\";\nimport { DEFAULT_AUTH_SERVER } from \"@/constants.js\";\nimport { merge } from \"ts-deepmerge\";\nimport { sanitizeBasePath } from \"./utils.js\";\nimport {\n createNextJSCookieConfig,\n type CookiesConfigObject,\n} from \"@/shared/lib/cookieConfig.js\";\n\n// Re-export the shared type for public API\nexport type { CookiesConfigObject };\n\nconst logger = loggers.nextjs.handlers.auth;\n\n/**\n * Configuration values for Civic Auth.\n * Only clientId is required, all others are optional.\n */\nexport type AuthConfigWithDefaults = {\n clientId: string;\n oauthServer: string;\n // Internal API routes\n callbackUrl: string; // where Civic's internal OAuth callback is hosted\n loginInitUrl: string; // Internal auth route for initiating login flow (e.g., /api/auth/login)\n logoutUrl: string;\n challengeUrl: string;\n refreshUrl: string;\n // User-facing routes\n loginSuccessUrl?: string; // where the user should be sent after the entire login completes, including the token exchange\n // The path the user will be sent to if they access a resource that needs\n // them to be logged in. If there is a dedicated login page, it can be set here.\n // Note: This is NOT for internal auth routes - see loginInitUrl for that.\n loginUrl: string;\n logoutCallbackUrl: string;\n include: string[];\n exclude: string[];\n cookies: CookiesConfigObject;\n basePath?: string;\n baseUrl?: string; // Public domain for apps behind reverse proxies (e.g., \"https://myapp.com\")\n autoRedirect: boolean;\n targetContainerElement?: HTMLElement | string;\n};\n\n/**\n * All possible config values for Civic Auth\n */\nexport type OptionalAuthConfig = Partial<\n | AuthConfigWithDefaults\n | {\n cookies?: {\n tokens?: Partial<TokensCookieConfig>;\n user?: CookieConfig;\n };\n }\n> & {\n // Ensure TypeScript understands these properties are available\n // This doesn't change the public API, just helps TypeScript internally\n callbackUrl?: string; // where Civic's internal OAuth callback is hosted\n loginSuccessUrl?: string; // where the user should be sent after the entire login completes, including the token exchange\n loginUrl?: string;\n loginInitUrl?: string;\n logoutUrl?: string;\n logoutCallbackUrl?: string;\n challengeUrl?: string;\n refreshUrl?: string;\n include?: string[];\n exclude?: string[];\n basePath?: string;\n baseUrl?: string;\n oauthServer?: string;\n autoRedirect?: boolean;\n targetContainerElement?: HTMLElement | string;\n};\n\n/**\n * Configuration values for Civic Auth.\n * Only clientId is required, all others are optional.\n */\nexport type AuthConfig = OptionalAuthConfig & {\n clientId: string;\n exclude?: string[];\n};\n\n/**\n * Default configuration values that will be used if not overridden\n */\nexport const defaultAuthConfig: Omit<AuthConfigWithDefaults, \"clientId\"> = {\n oauthServer: DEFAULT_AUTH_SERVER,\n // Internal API routes\n callbackUrl: \"/api/auth/callback\",\n loginInitUrl: \"/api/auth/login\",\n logoutUrl: \"/api/auth/logout\",\n challengeUrl: \"/api/auth/challenge\",\n refreshUrl: \"/api/auth/refresh\",\n // User-facing routes\n loginSuccessUrl: undefined, // By default, the user is sent to the redirect_url\n loginUrl: \"/\",\n logoutCallbackUrl: \"/\",\n include: [\"/**\"],\n exclude: [\"/api/auth/**\"],\n basePath: \"\",\n baseUrl: undefined, // No default - will use request.nextUrl.origin when undefined\n autoRedirect: true, // Default to current behavior\n cookies: createNextJSCookieConfig(),\n};\n\n/**\n * Resolves the authentication configuration by combining:\n * 1. Default values\n * 2. Environment variables (set internally by the plugin)\n * 3. Explicitly passed configuration\n *\n * Config will be merged deeply, with arrays not merged, so that the\n * default include list (for example) [\"/*\"] will not be added\n *\n * Note: Developers should not set _civic_auth_* environment variables directly.\n * Instead, pass configuration to the createCivicAuthPlugin in next.config.js:\n *\n * @example\n * ```js\n * // next.config.js\n * export default createCivicAuthPlugin({\n * callbackUrl: '/custom/callback',\n * })\n * ```\n */\nexport const resolveAuthConfig = (\n config: Partial<AuthConfig> = {},\n): AuthConfigWithDefaults => {\n // Read configuration that was set by the plugin via environment variables\n // Don't load environment cookies if explicit cookies are provided\n const hasExplicitCookies = config.cookies;\n\n const configFromEnv = withoutUndefined({\n clientId: process.env._civic_auth_client_id,\n oauthServer: process.env._civic_oauth_server,\n callbackUrl: process.env._civic_auth_callback_url,\n loginSuccessUrl: process.env._civic_auth_login_success_url,\n challengeUrl: process.env._civic_auth_challenge_url,\n loginUrl: process.env._civic_auth_login_url,\n loginInitUrl: process.env._civic_auth_login_init_url,\n logoutUrl: process.env._civic_auth_logout_url,\n logoutCallbackUrl: process.env._civic_auth_logout_callback_url,\n refreshUrl: process.env._civic_auth_refresh_url,\n include: process.env._civic_auth_includes?.split(\",\"),\n exclude: process.env._civic_auth_excludes?.split(\",\"),\n cookies: hasExplicitCookies\n ? undefined\n : process.env._civic_auth_cookie_config\n ? JSON.parse(process.env._civic_auth_cookie_config)\n : undefined,\n basePath: process.env._civic_auth_base_path || \"\",\n baseUrl: process.env._civic_auth_base_url,\n autoRedirect:\n process.env._civic_auth_auto_redirect === \"false\" ? false : undefined,\n targetContainerElement: process.env._civic_auth_target_container_element,\n }) as AuthConfig;\n\n // Ensure \"/api/auth/**\" is always excluded\n const finalExclude = new Set([\n ...defaultAuthConfig.exclude,\n ...(configFromEnv.exclude || []),\n ...(config.exclude ?? []),\n ]);\n\n // Store explicit cookies config before merge to preserve it\n const explicitCookies = config.cookies;\n\n // Perform a deep merge of the configurations\n const mergedConfig = merge.withOptions(\n { mergeArrays: false },\n defaultAuthConfig,\n configFromEnv,\n config,\n );\n\n // Override the exclude list with the ensured list\n mergedConfig.exclude = Array.from(finalExclude);\n\n // Update cookie configuration with basePath if it wasn't explicitly provided\n // Only auto-configure if no explicit cookies are provided anywhere\n if (!config.cookies && !configFromEnv.cookies && mergedConfig.basePath) {\n mergedConfig.cookies = createNextJSCookieConfig(mergedConfig.basePath);\n }\n\n // Merge explicit cookies with merged config to preserve both explicit settings and defaults\n if (explicitCookies && mergedConfig.cookies) {\n mergedConfig.cookies = merge.withOptions(\n { mergeArrays: false },\n mergedConfig.cookies,\n explicitCookies,\n );\n }\n\n if (mergedConfig.clientId === undefined) {\n throw new Error(\"Civic Auth client ID is required\");\n }\n\n return mergedConfig as AuthConfigWithDefaults & { clientId: string };\n};\n\n/**\n * Creates a Next.js plugin that handles auth configuration.\n *\n * This is the main configuration point for the auth system.\n * Do not set _civic_auth_* environment variables directly - instead,\n * pass your configuration here.\n *\n * The only required field is clientId.\n *\n * Notes:\n * - If you provide explicit URLs, they will be used exactly as provided.\n * - Default URLs will automatically include the basePath from your Next.js config.\n *\n * @example\n * ```js\n * // next.config.js\n * export default createCivicAuthPlugin({\n * clientId: 'my-client-id',\n * });\n * ```\n *\n * @example\n * ```js\n * // next.config.js\n * export default createCivicAuthPlugin({\n * clientId: 'my-client-id',\n * callbackUrl: '/custom/callback',\n * loginUrl: '/custom/login',\n * logoutUrl: '/custom/logout',\n * logoutCallbackUrl: '/custom/logoutcallback',\n * include: ['/protected/*'],\n * exclude: ['/public/*']\n * })\n * ```\n *\n * The plugin sets internal environment variables that are used by\n * the auth system. These variables should not be set manually.\n */\nexport const createCivicAuthPlugin = (authConfig: AuthConfig) => {\n return (nextConfig?: NextConfig) => {\n logger.debug(\n \"createCivicAuthPlugin nextConfig\",\n JSON.stringify(nextConfig, null, 2),\n );\n\n // Extract basePath from Next.js config\n const basePath = sanitizeBasePath(nextConfig?.basePath || \"\");\n\n // Create a copy of default URLs with basePath added\n const defaultUrlsWithBasePath: Partial<AuthConfig> = {};\n\n // Only apply to URLs that aren't explicitly set in authConfig\n if (basePath) {\n if (!authConfig.callbackUrl)\n defaultUrlsWithBasePath.callbackUrl = `${basePath}/api/auth/callback`;\n if (!authConfig.challengeUrl)\n defaultUrlsWithBasePath.challengeUrl = `${basePath}/api/auth/challenge`;\n if (!authConfig.refreshUrl)\n defaultUrlsWithBasePath.refreshUrl = `${basePath}/api/auth/refresh`;\n if (!authConfig.logoutUrl)\n defaultUrlsWithBasePath.logoutUrl = `${basePath}/api/auth/logout`;\n if (!authConfig.loginInitUrl)\n defaultUrlsWithBasePath.loginInitUrl = `${basePath}/api/auth/login`;\n if (!authConfig.logoutCallbackUrl)\n defaultUrlsWithBasePath.logoutCallbackUrl = `${basePath}`;\n if (!authConfig.loginUrl && authConfig.loginUrl !== \"\")\n defaultUrlsWithBasePath.loginUrl = basePath;\n }\n\n // Create final config with basePath and possibly modified URLs\n const resolvedConfig = resolveAuthConfig({\n ...defaultUrlsWithBasePath,\n ...authConfig,\n basePath,\n });\n\n return {\n ...nextConfig,\n env: {\n ...nextConfig?.env,\n // Internal environment variables - do not set these manually\n _civic_auth_client_id: resolvedConfig.clientId,\n _civic_oauth_server: resolvedConfig.oauthServer,\n _civic_auth_callback_url: resolvedConfig.callbackUrl,\n _civic_auth_login_success_url: resolvedConfig.loginSuccessUrl,\n _civic_auth_challenge_url: resolvedConfig.challengeUrl,\n _civic_auth_login_url: resolvedConfig.loginUrl,\n _civic_auth_login_init_url: resolvedConfig.loginInitUrl,\n _civic_auth_logout_url: resolvedConfig.logoutUrl,\n _civic_auth_logout_callback_url: resolvedConfig.logoutCallbackUrl,\n _civic_auth_refresh_url: resolvedConfig.refreshUrl,\n _civic_auth_includes: resolvedConfig.include.join(\",\"),\n _civic_auth_excludes: resolvedConfig.exclude.join(\",\"),\n _civic_auth_cookie_config: JSON.stringify(resolvedConfig.cookies),\n _civic_auth_base_path: resolvedConfig.basePath,\n _civic_auth_base_url: resolvedConfig.baseUrl,\n _civic_auth_auto_redirect: resolvedConfig.autoRedirect.toString(),\n },\n };\n };\n};\n"]}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/nextjs/config.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable turbo/no-undeclared-env-vars */\nimport type { NextConfig } from \"next\";\nimport { loggers } from \"@/lib/logger.js\";\nimport { withoutUndefined } from \"@/utils.js\";\nimport {\n type CookieConfig,\n type TokensCookieConfig,\n} from \"@/shared/lib/types.js\";\nimport { DEFAULT_AUTH_SERVER } from \"@/constants.js\";\nimport { merge } from \"ts-deepmerge\";\nimport { sanitizeBasePath } from \"./utils.js\";\nimport {\n createNextJSCookieConfig,\n type CookiesConfigObject,\n} from \"@/shared/lib/cookieConfig.js\";\n\n// Re-export the shared type for public API\nexport type { CookiesConfigObject };\n\nconst logger = loggers.nextjs.handlers.auth;\n\n/**\n * URL configuration mapping for applying basePath\n */\ntype UrlConfigEntry = {\n defaultPath: string;\n applyBasePath: boolean;\n useBasePathOnly?: boolean;\n checkEmpty?: boolean;\n};\n\nexport const systemUrlsConfig = {\n callbackUrl: { defaultPath: \"/api/auth/callback\", applyBasePath: true },\n challengeUrl: { defaultPath: \"/api/auth/challenge\", applyBasePath: true },\n refreshUrl: { defaultPath: \"/api/auth/refresh\", applyBasePath: true },\n logoutUrl: { defaultPath: \"/api/auth/logout\", applyBasePath: true },\n loginInitUrl: { defaultPath: \"/api/auth/login\", applyBasePath: true },\n userUrl: { defaultPath: \"/api/auth/user\", applyBasePath: true },\n};\nconst URL_CONFIG: Record<string, UrlConfigEntry> = {\n ...systemUrlsConfig,\n logoutCallbackUrl: {\n defaultPath: \"\",\n applyBasePath: true,\n useBasePathOnly: true,\n },\n loginUrl: {\n defaultPath: \"\",\n applyBasePath: true,\n useBasePathOnly: true,\n checkEmpty: true,\n },\n};\n\n/**\n * Configuration values for Civic Auth.\n * Only clientId is required, all others are optional.\n */\nexport type AuthConfigWithDefaults = {\n clientId: string;\n oauthServer: string;\n // Internal API routes\n callbackUrl: string; // where Civic's internal OAuth callback is hosted\n loginInitUrl: string; // Internal auth route for initiating login flow (e.g., /api/auth/login)\n logoutUrl: string;\n challengeUrl: string;\n refreshUrl: string;\n userUrl: string;\n // User-facing routes\n loginSuccessUrl?: string; // where the user should be sent after the entire login completes, including the token exchange\n // The path the user will be sent to if they access a resource that needs\n // them to be logged in. If there is a dedicated login page, it can be set here.\n // Note: This is NOT for internal auth routes - see loginInitUrl for that.\n loginUrl: string;\n logoutCallbackUrl: string;\n include: string[];\n exclude: string[];\n cookies: CookiesConfigObject;\n basePath?: string;\n baseUrl?: string; // Public domain for apps behind reverse proxies (e.g., \"https://myapp.com\")\n autoRedirect: boolean;\n targetContainerElement?: HTMLElement | string;\n};\n\n/**\n * All possible config values for Civic Auth\n */\nexport type OptionalAuthConfig = Partial<\n | AuthConfigWithDefaults\n | {\n cookies?: {\n tokens?: Partial<TokensCookieConfig>;\n user?: CookieConfig;\n };\n }\n> & {\n // Ensure TypeScript understands these properties are available\n // This doesn't change the public API, just helps TypeScript internally\n callbackUrl?: string; // where Civic's internal OAuth callback is hosted\n loginSuccessUrl?: string; // where the user should be sent after the entire login completes, including the token exchange\n loginUrl?: string;\n loginInitUrl?: string;\n logoutUrl?: string;\n logoutCallbackUrl?: string;\n challengeUrl?: string;\n refreshUrl?: string;\n userUrl?: string;\n include?: string[];\n exclude?: string[];\n basePath?: string;\n baseUrl?: string;\n oauthServer?: string;\n autoRedirect?: boolean;\n targetContainerElement?: HTMLElement | string;\n};\n\n/**\n * Configuration values for Civic Auth.\n * Only clientId is required, all others are optional.\n */\nexport type AuthConfig = OptionalAuthConfig & {\n clientId: string;\n exclude?: string[];\n};\n\n/**\n * Default configuration values that will be used if not overridden\n */\nexport const defaultAuthConfig: Omit<AuthConfigWithDefaults, \"clientId\"> = {\n oauthServer: DEFAULT_AUTH_SERVER,\n // Internal API routes\n // deconstruct systemUrls to set the keys and default values\n ...(Object.fromEntries(\n Object.entries(systemUrlsConfig).map(([key, value]) => [\n key,\n value.defaultPath,\n ]),\n ) as {\n [key in keyof typeof systemUrlsConfig]: string;\n }),\n // User-facing routes\n loginSuccessUrl: undefined, // By default, the user is sent to the redirect_url\n loginUrl: \"/\",\n logoutCallbackUrl: \"/\",\n include: [\"/**\"],\n exclude: [\"/api/auth/**\"],\n basePath: \"\",\n baseUrl: undefined, // No default - will use request.nextUrl.origin when undefined\n autoRedirect: true, // Default to current behavior\n cookies: createNextJSCookieConfig(),\n};\n\n/**\n * Resolves the authentication configuration by combining:\n * 1. Default values\n * 2. Environment variables (set internally by the plugin)\n * 3. Explicitly passed configuration\n *\n * Config will be merged deeply, with arrays not merged, so that the\n * default include list (for example) [\"/*\"] will not be added\n *\n * Note: Developers should not set _civic_auth_* environment variables directly.\n * Instead, pass configuration to the createCivicAuthPlugin in next.config.js:\n *\n * @example\n * ```js\n * // next.config.js\n * export default createCivicAuthPlugin({\n * callbackUrl: '/custom/callback',\n * })\n * ```\n */\nexport const resolveAuthConfig = (\n config: Partial<AuthConfig> = {},\n): AuthConfigWithDefaults => {\n // Read configuration that was set by the plugin via environment variables\n // Don't load environment cookies if explicit cookies are provided\n const hasExplicitCookies = config.cookies;\n\n const configFromEnv = withoutUndefined({\n clientId: process.env._civic_auth_client_id,\n oauthServer: process.env._civic_oauth_server,\n callbackUrl: process.env._civic_auth_callback_url,\n loginSuccessUrl: process.env._civic_auth_login_success_url,\n challengeUrl: process.env._civic_auth_challenge_url,\n loginUrl: process.env._civic_auth_login_url,\n loginInitUrl: process.env._civic_auth_login_init_url,\n logoutUrl: process.env._civic_auth_logout_url,\n logoutCallbackUrl: process.env._civic_auth_logout_callback_url,\n refreshUrl: process.env._civic_auth_refresh_url,\n userUrl: process.env._civic_auth_user_url,\n include: process.env._civic_auth_includes?.split(\",\"),\n exclude: process.env._civic_auth_excludes?.split(\",\"),\n cookies: hasExplicitCookies\n ? undefined\n : process.env._civic_auth_cookie_config\n ? JSON.parse(process.env._civic_auth_cookie_config)\n : undefined,\n basePath: process.env._civic_auth_base_path || \"\",\n baseUrl: process.env._civic_auth_base_url,\n autoRedirect:\n process.env._civic_auth_auto_redirect === \"false\" ? false : undefined,\n targetContainerElement: process.env._civic_auth_target_container_element,\n }) as AuthConfig;\n\n // Ensure \"/api/auth/**\" is always excluded\n const finalExclude = new Set([\n ...defaultAuthConfig.exclude,\n ...(configFromEnv.exclude || []),\n ...(config.exclude ?? []),\n ]);\n\n // Store explicit cookies config before merge to preserve it\n const explicitCookies = config.cookies;\n\n // Perform a deep merge of the configurations\n const mergedConfig = merge.withOptions(\n { mergeArrays: false },\n defaultAuthConfig,\n configFromEnv,\n config,\n );\n\n // Override the exclude list with the ensured list\n mergedConfig.exclude = Array.from(finalExclude);\n\n // Update cookie configuration with basePath if it wasn't explicitly provided\n // Only auto-configure if no explicit cookies are provided anywhere\n if (!config.cookies && !configFromEnv.cookies && mergedConfig.basePath) {\n mergedConfig.cookies = createNextJSCookieConfig(mergedConfig.basePath);\n }\n\n // Merge explicit cookies with merged config to preserve both explicit settings and defaults\n if (explicitCookies && mergedConfig.cookies) {\n mergedConfig.cookies = merge.withOptions(\n { mergeArrays: false },\n mergedConfig.cookies,\n explicitCookies,\n );\n }\n\n if (mergedConfig.clientId === undefined) {\n throw new Error(\"Civic Auth client ID is required\");\n }\n\n return mergedConfig as AuthConfigWithDefaults & { clientId: string };\n};\n\n/**\n * Applies basePath to URLs based on URL_CONFIG rules\n */\nfunction applyBasePathToUrls(\n authConfig: AuthConfig,\n basePath: string,\n): Partial<AuthConfig> {\n const defaultUrlsWithBasePath: Record<string, string> = {};\n\n if (!basePath) return defaultUrlsWithBasePath;\n\n Object.entries(URL_CONFIG).forEach(([key, config]) => {\n // Skip if explicitly set in authConfig\n const currentValue = authConfig[key as keyof AuthConfig];\n if (\n currentValue !== undefined &&\n !(config.checkEmpty && currentValue === \"\")\n ) {\n return;\n }\n\n // Apply basePath based on config rules\n const urlValue = config.useBasePathOnly\n ? basePath\n : `${basePath}${config.defaultPath}`;\n\n defaultUrlsWithBasePath[key] = urlValue;\n });\n\n return defaultUrlsWithBasePath as Partial<AuthConfig>;\n}\n\n/**\n * Creates a Next.js plugin that handles auth configuration.\n *\n * This is the main configuration point for the auth system.\n * Do not set _civic_auth_* environment variables directly - instead,\n * pass your configuration here.\n *\n * The only required field is clientId.\n *\n * Notes:\n * - If you provide explicit URLs, they will be used exactly as provided.\n * - Default URLs will automatically include the basePath from your Next.js config.\n *\n * @example\n * ```js\n * // next.config.js\n * export default createCivicAuthPlugin({\n * clientId: 'my-client-id',\n * });\n * ```\n *\n * @example\n * ```js\n * // next.config.js\n * export default createCivicAuthPlugin({\n * clientId: 'my-client-id',\n * callbackUrl: '/custom/callback',\n * loginUrl: '/custom/login',\n * logoutUrl: '/custom/logout',\n * logoutCallbackUrl: '/custom/logoutcallback',\n * include: ['/protected/*'],\n * exclude: ['/public/*']\n * })\n * ```\n *\n * The plugin sets internal environment variables that are used by\n * the auth system. These variables should not be set manually.\n */\nexport const createCivicAuthPlugin = (authConfig: AuthConfig) => {\n return (nextConfig?: NextConfig) => {\n logger.debug(\n \"createCivicAuthPlugin nextConfig\",\n JSON.stringify(nextConfig, null, 2),\n );\n\n // Extract basePath from Next.js config\n const basePath = sanitizeBasePath(nextConfig?.basePath || \"\");\n\n // Apply basePath to URLs using the configuration mapping\n const defaultUrlsWithBasePath = applyBasePathToUrls(authConfig, basePath);\n\n // Create final config with basePath and possibly modified URLs\n const resolvedConfig = resolveAuthConfig({\n ...defaultUrlsWithBasePath,\n ...authConfig,\n basePath,\n });\n\n return {\n ...nextConfig,\n env: {\n ...nextConfig?.env,\n // Internal environment variables - do not set these manually\n _civic_auth_client_id: resolvedConfig.clientId,\n _civic_oauth_server: resolvedConfig.oauthServer,\n _civic_auth_callback_url: resolvedConfig.callbackUrl,\n _civic_auth_login_success_url: resolvedConfig.loginSuccessUrl,\n _civic_auth_challenge_url: resolvedConfig.challengeUrl,\n _civic_auth_login_url: resolvedConfig.loginUrl,\n _civic_auth_login_init_url: resolvedConfig.loginInitUrl,\n _civic_auth_logout_url: resolvedConfig.logoutUrl,\n _civic_auth_logout_callback_url: resolvedConfig.logoutCallbackUrl,\n _civic_auth_refresh_url: resolvedConfig.refreshUrl,\n _civic_auth_user_url: resolvedConfig.userUrl,\n _civic_auth_includes: resolvedConfig.include.join(\",\"),\n _civic_auth_excludes: resolvedConfig.exclude.join(\",\"),\n _civic_auth_cookie_config: JSON.stringify(resolvedConfig.cookies),\n _civic_auth_base_path: resolvedConfig.basePath,\n _civic_auth_base_url: resolvedConfig.baseUrl,\n _civic_auth_auto_redirect: resolvedConfig.autoRedirect.toString(),\n },\n };\n };\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"cookies.d.ts","sourceRoot":"","sources":["../../src/nextjs/cookies.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAe,KAAK,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAGxD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAqCjE;;GAEG;AACH,QAAA,MAAM,gBAAgB,YAAmB,OAAO,CAAC,sBAAsB,CAAC,kBAOvE,CAAC;AAEF,cAAM,mBAAoB,SAAQ,aAAa;IAC1B,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;gBAAhD,MAAM,GAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,CAAM;IAOlE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAKxC,GAAG,CACP,GAAG,EAAE,SAAS,EACd,KAAK,EAAE,MAAM,EACb,oBAAoB,GAAE,OAAO,CAAC,YAAY,CAAM,GAC/C,OAAO,CAAC,IAAI,CAAC;IAsBV,MAAM,CAAC,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;CAgB5C;AAED,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,CAAC"}
1
+ {"version":3,"file":"cookies.d.ts","sourceRoot":"","sources":["../../src/nextjs/cookies.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAe,KAAK,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAGxD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAqCjE;;GAEG;AACH,QAAA,MAAM,gBAAgB,YAAmB,OAAO,CAAC,sBAAsB,CAAC,kBAOvE,CAAC;AAEF,cAAM,mBAAoB,SAAQ,aAAa;IAC1B,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;gBAAhD,MAAM,GAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,CAAM;IAOlE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAqBxC,GAAG,CACP,GAAG,EAAE,SAAS,EACd,KAAK,EAAE,MAAM,EACb,oBAAoB,GAAE,OAAO,CAAC,YAAY,CAAM,GAC/C,OAAO,CAAC,IAAI,CAAC;IAsBV,MAAM,CAAC,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;CAgB5C;AAED,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { cookies, headers } from "next/headers.js";
2
+ import { extractCookieFromRawHeader } from "../shared/lib/cookieUtils.js";
2
3
  import { UserStorage } from "../shared/lib/types.js";
3
4
  import { CookieStorage } from "../shared/lib/storage.js";
4
5
  import * as session from "../shared/lib/session.js";
@@ -56,7 +57,21 @@ class NextjsCookieStorage extends CookieStorage {
56
57
  }
57
58
  async get(key) {
58
59
  const cookieStore = await cookies();
59
- return cookieStore.get(key)?.value || null;
60
+ const cookieSettings = this.config?.[key] || {};
61
+ const configuredPath = cookieSettings.path;
62
+ // If we have a non-root basePath, use raw header parsing to get the first cookie
63
+ // which should be from the most specific path, avoiding duplicate cookie conflicts
64
+ if (configuredPath && configuredPath !== "/") {
65
+ const headerStore = await headers();
66
+ const cookieHeader = headerStore.get("cookie");
67
+ const rawValue = extractCookieFromRawHeader(cookieHeader, key);
68
+ if (rawValue) {
69
+ return rawValue;
70
+ }
71
+ }
72
+ // Fallback to standard Next.js cookie store
73
+ const cookieValue = cookieStore.get(key);
74
+ return cookieValue?.value || null;
60
75
  }
61
76
  async set(key, value, cookieConfigOverride = {}) {
62
77
  const cookieStore = await cookies();
@@ -1 +1 @@
1
- {"version":3,"file":"cookies.js","sourceRoot":"","sources":["../../src/nextjs/cookies.ts"],"names":[],"mappings":"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","sourcesContent":["import { cookies, headers } from \"next/headers.js\";\n\nimport type { KeySetter } from \"@/shared/lib/types.js\";\nimport { UserStorage, type CookieConfig } from \"@/shared/lib/types.js\";\nimport { CookieStorage } from \"@/shared/lib/storage.js\";\nimport * as session from \"@/shared/lib/session.js\";\nimport { getCookieConfiguration } from \"@/shared/lib/util.js\";\nimport type { AuthConfigWithDefaults } from \"@/nextjs/config.js\";\n\n/**\n * Create a mock Request object from Next.js headers for cookie configuration\n */\nconst createRequestFromHeaders = async (): Promise<Request | undefined> => {\n try {\n const headerStore = await headers();\n const host = headerStore.get(\"host\");\n const userAgent = headerStore.get(\"user-agent\");\n const protocol =\n headerStore.get(\"x-forwarded-proto\") ||\n headerStore.get(\"x-forwarded-protocol\") ||\n (process.env.NODE_ENV === \"production\" ? \"https\" : \"http\");\n\n if (!host) return undefined;\n\n const url = `${protocol}://${host}/`;\n\n // Create a minimal Request object with the headers we need\n const request = new Request(url, {\n headers: {\n \"user-agent\": userAgent || \"\",\n \"x-forwarded-proto\": headerStore.get(\"x-forwarded-proto\") || \"\",\n \"x-forwarded-protocol\": headerStore.get(\"x-forwarded-protocol\") || \"\",\n forwarded: headerStore.get(\"forwarded\") || \"\",\n },\n });\n\n return request;\n } catch (error) {\n console.error(\"Error creating request from headers\", error);\n // Headers might not be available in all contexts\n return undefined;\n }\n};\n\n/**\n * Clears all authentication cookies on server. Note, this can only be called by the server\n */\nconst clearAuthCookies = async (config?: Partial<AuthConfigWithDefaults>) => {\n // Use resolved config cookies if available, otherwise use default\n const cookieStorage = new NextjsCookieStorage({\n ...config?.cookies?.tokens,\n [UserStorage.USER]: config?.cookies?.user,\n });\n await session.clearAuthCookies(cookieStorage);\n};\n\nclass NextjsCookieStorage extends CookieStorage {\n constructor(public config: Partial<Record<KeySetter, CookieConfig>> = {}) {\n super({\n secure: true,\n httpOnly: true,\n });\n }\n\n async get(key: string): Promise<string | null> {\n const cookieStore = await cookies();\n return cookieStore.get(key)?.value || null;\n }\n\n async set(\n key: KeySetter,\n value: string,\n cookieConfigOverride: Partial<CookieConfig> = {},\n ): Promise<void> {\n const cookieStore = await cookies();\n const cookieSettings = this.config?.[key as KeySetter] || {\n ...this.settings,\n };\n\n // Get dynamic cookie configuration based on environment and browser\n const request = await createRequestFromHeaders();\n const dynamicConfig = getCookieConfiguration(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 await cookieStore.set(key, value, useCookieSettings);\n }\n\n async delete(key: KeySetter): Promise<void> {\n const cookieStore = await cookies();\n\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 cookieStore.set(key, \"\", {\n expires: new Date(0), // Expire in the past\n path: cookieSettings.path,\n });\n } else {\n cookieStore.delete(key);\n }\n }\n}\n\nexport { clearAuthCookies, NextjsCookieStorage };\n"]}
1
+ {"version":3,"file":"cookies.js","sourceRoot":"","sources":["../../src/nextjs/cookies.ts"],"names":[],"mappings":"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","sourcesContent":["import { cookies, headers } from \"next/headers.js\";\nimport { extractCookieFromRawHeader } from \"@/shared/lib/cookieUtils.js\";\n\nimport type { KeySetter } from \"@/shared/lib/types.js\";\nimport { UserStorage, type CookieConfig } from \"@/shared/lib/types.js\";\nimport { CookieStorage } from \"@/shared/lib/storage.js\";\nimport * as session from \"@/shared/lib/session.js\";\nimport { getCookieConfiguration } from \"@/shared/lib/util.js\";\nimport type { AuthConfigWithDefaults } from \"@/nextjs/config.js\";\n\n/**\n * Create a mock Request object from Next.js headers for cookie configuration\n */\nconst createRequestFromHeaders = async (): Promise<Request | undefined> => {\n try {\n const headerStore = await headers();\n const host = headerStore.get(\"host\");\n const userAgent = headerStore.get(\"user-agent\");\n const protocol =\n headerStore.get(\"x-forwarded-proto\") ||\n headerStore.get(\"x-forwarded-protocol\") ||\n (process.env.NODE_ENV === \"production\" ? \"https\" : \"http\");\n\n if (!host) return undefined;\n\n const url = `${protocol}://${host}/`;\n\n // Create a minimal Request object with the headers we need\n const request = new Request(url, {\n headers: {\n \"user-agent\": userAgent || \"\",\n \"x-forwarded-proto\": headerStore.get(\"x-forwarded-proto\") || \"\",\n \"x-forwarded-protocol\": headerStore.get(\"x-forwarded-protocol\") || \"\",\n forwarded: headerStore.get(\"forwarded\") || \"\",\n },\n });\n\n return request;\n } catch (error) {\n console.error(\"Error creating request from headers\", error);\n // Headers might not be available in all contexts\n return undefined;\n }\n};\n\n/**\n * Clears all authentication cookies on server. Note, this can only be called by the server\n */\nconst clearAuthCookies = async (config?: Partial<AuthConfigWithDefaults>) => {\n // Use resolved config cookies if available, otherwise use default\n const cookieStorage = new NextjsCookieStorage({\n ...config?.cookies?.tokens,\n [UserStorage.USER]: config?.cookies?.user,\n });\n await session.clearAuthCookies(cookieStorage);\n};\n\nclass NextjsCookieStorage extends CookieStorage {\n constructor(public config: Partial<Record<KeySetter, CookieConfig>> = {}) {\n super({\n secure: true,\n httpOnly: true,\n });\n }\n\n async get(key: string): Promise<string | null> {\n const cookieStore = await cookies();\n const cookieSettings = this.config?.[key as KeySetter] || {};\n const configuredPath = cookieSettings.path;\n\n // If we have a non-root basePath, use raw header parsing to get the first cookie\n // which should be from the most specific path, avoiding duplicate cookie conflicts\n if (configuredPath && configuredPath !== \"/\") {\n const headerStore = await headers();\n const cookieHeader = headerStore.get(\"cookie\");\n const rawValue = extractCookieFromRawHeader(cookieHeader, key);\n if (rawValue) {\n return rawValue;\n }\n }\n\n // Fallback to standard Next.js cookie store\n const cookieValue = cookieStore.get(key);\n return cookieValue?.value || null;\n }\n\n async set(\n key: KeySetter,\n value: string,\n cookieConfigOverride: Partial<CookieConfig> = {},\n ): Promise<void> {\n const cookieStore = await cookies();\n const cookieSettings = this.config?.[key as KeySetter] || {\n ...this.settings,\n };\n\n // Get dynamic cookie configuration based on environment and browser\n const request = await createRequestFromHeaders();\n const dynamicConfig = getCookieConfiguration(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 await cookieStore.set(key, value, useCookieSettings);\n }\n\n async delete(key: KeySetter): Promise<void> {\n const cookieStore = await cookies();\n\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 cookieStore.set(key, \"\", {\n expires: new Date(0), // Expire in the past\n path: cookieSettings.path,\n });\n } else {\n cookieStore.delete(key);\n }\n }\n}\n\nexport { clearAuthCookies, NextjsCookieStorage };\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"useInitialAuthConfig.d.ts","sourceRoot":"","sources":["../../../src/nextjs/hooks/useInitialAuthConfig.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AAC5E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAChF,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAInD,MAAM,WAAW,2BAA2B;IAC1C,WAAW,CAAC,EAAE,oBAAoB,CAAC;IACnC,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,UAAU,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sBAAsB,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;IAC9C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CACtD;AAED,MAAM,WAAW,6BAA6B;IAC5C,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,MAAM,CAAC;CACjC;AAED;;;GAGG;AACH,eAAO,MAAM,oBAAoB,aACtB,2BAA2B,KACnC;IACD,aAAa,EAAE,gBAAgB,CAAC;IAChC,yBAAyB,EAAE,CACzB,SAAS,CAAC,EAAE,6BAA6B,KACtC,gBAAgB,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CA+HnB,CAAC"}
1
+ {"version":3,"file":"useInitialAuthConfig.d.ts","sourceRoot":"","sources":["../../../src/nextjs/hooks/useInitialAuthConfig.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AAC5E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAChF,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAKnD,MAAM,WAAW,2BAA2B;IAC1C,WAAW,CAAC,EAAE,oBAAoB,CAAC;IACnC,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,UAAU,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sBAAsB,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;IAC9C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CACtD;AAED,MAAM,WAAW,6BAA6B;IAC5C,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,MAAM,CAAC;CACjC;AAED;;;GAGG;AACH,eAAO,MAAM,oBAAoB,aACtB,2BAA2B,KACnC;IACD,aAAa,EAAE,gBAAgB,CAAC;IAChC,yBAAyB,EAAE,CACzB,SAAS,CAAC,EAAE,6BAA6B,KACtC,gBAAgB,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CAyInB,CAAC"}
@@ -3,11 +3,12 @@
3
3
  * Reusable across NextJS components that need to initialize GlobalAuthManager
4
4
  */
5
5
  "use client";
6
- import { useMemo } from "react";
6
+ import { useMemo, useState } from "react";
7
7
  import { useRouter, usePathname } from "next/navigation.js";
8
8
  import { resolveAuthConfig } from "../../nextjs/config.js";
9
9
  import { revalidateUserData } from "../../nextjs/actions.js";
10
10
  import { BrowserCookieStorage } from "../../shared/index.js";
11
+ import { loggers } from "../../lib/logger.js";
11
12
  /**
12
13
  * Hook that creates the initial auth configuration
13
14
  * Can be used standalone or merged with overrides
@@ -16,7 +17,10 @@ export const useInitialAuthConfig = (options = {}) => {
16
17
  const router = useRouter();
17
18
  const pathname = usePathname();
18
19
  const resolvedConfig = resolveAuthConfig(options);
19
- const { clientId, oauthServer, loginSuccessUrl, loginInitUrl, logoutUrl, refreshUrl, logoutCallbackUrl, callbackUrl, targetContainerElement, } = resolvedConfig;
20
+ // Force a re-render when the page gets re-rendered after sign-in/sign-out
21
+ // so that client-side hooks and event listeners are properly initialized
22
+ const [hasSignedOut, setHasSignedOut] = useState(false);
23
+ const { clientId, oauthServer, loginSuccessUrl, loginInitUrl, logoutUrl, refreshUrl, userUrl, logoutCallbackUrl, callbackUrl, targetContainerElement, } = resolvedConfig;
20
24
  const baseConfig = useMemo(() => {
21
25
  return {
22
26
  // we need this to retrieve client-available cookies for auto-refresh etc.
@@ -44,22 +48,27 @@ export const useInitialAuthConfig = (options = {}) => {
44
48
  enabled: false,
45
49
  },
46
50
  backendEndpoints: {
47
- user: "/api/auth/user",
51
+ user: userUrl,
48
52
  refresh: refreshUrl,
49
53
  logout: logoutUrl,
50
54
  },
55
+ onSignOut: async () => {
56
+ setHasSignedOut(true);
57
+ router.refresh();
58
+ },
51
59
  onRefresh: async (error) => {
52
60
  if (error) {
53
- console.error("onRefresh: Error refreshing", error);
54
- return;
61
+ loggers.nextjs.hooks.error("onRefresh: Error refreshing", error);
55
62
  }
63
+ setHasSignedOut(false);
56
64
  router.refresh();
57
65
  },
58
66
  onSignIn: async (error) => {
59
67
  if (error) {
60
- console.error("onSignIn: Error signing in", error);
68
+ loggers.nextjs.hooks.error("onSignIn: Error signing in", error);
61
69
  return;
62
70
  }
71
+ setHasSignedOut(false);
63
72
  try {
64
73
  // Trigger server-side revalidation to force NextAuthProvider to re-run
65
74
  await revalidateUserData(pathname);
@@ -75,25 +84,28 @@ export const useInitialAuthConfig = (options = {}) => {
75
84
  }
76
85
  },
77
86
  onUrlChange: options.onUrlChange,
78
- initialUser: options.serverUser || null,
87
+ initialUser: (!hasSignedOut && options.serverUser) || null,
88
+ // initialUser: options.serverUser || null,
79
89
  initialIdToken: null, // ID token is httpOnly and not accessible
80
90
  };
81
91
  }, [
82
92
  clientId,
83
- oauthServer,
84
- loginSuccessUrl,
85
93
  loginInitUrl,
94
+ callbackUrl,
95
+ oauthServer,
86
96
  logoutCallbackUrl,
87
- refreshUrl,
88
- logoutUrl,
89
- router,
90
- pathname,
97
+ loginSuccessUrl,
91
98
  targetContainerElement,
92
- callbackUrl,
93
99
  options.displayMode,
94
100
  options.iframeMode,
95
- options.serverUser,
96
101
  options.onUrlChange,
102
+ options.serverUser,
103
+ userUrl,
104
+ refreshUrl,
105
+ logoutUrl,
106
+ hasSignedOut,
107
+ router,
108
+ pathname,
97
109
  ]);
98
110
  const createConfigWithOverrides = useMemo(() => {
99
111
  return (overrides = {}) => {
@@ -1 +1 @@
1
- {"version":3,"file":"useInitialAuthConfig.js","sourceRoot":"","sources":["../../../src/nextjs/hooks/useInitialAuthConfig.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,YAAY,CAAC;AAEb,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAIvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAsBzD;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAClC,UAAuC,EAAE,EAOzC,EAAE;IACF,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,MAAM,cAAc,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAElD,MAAM,EACJ,QAAQ,EACR,WAAW,EACX,eAAe,EACf,YAAY,EACZ,SAAS,EACT,UAAU,EACV,iBAAiB,EACjB,WAAW,EACX,sBAAsB,GACvB,GAAG,cAAc,CAAC;IAEnB,MAAM,UAAU,GAAqB,OAAO,CAAC,GAAG,EAAE;QAChD,OAAO;YACL,0EAA0E;YAC1E,OAAO,EAAE,IAAI,oBAAoB,EAAE;YACnC,QAAQ,EAAE,QAAQ;YAClB,QAAQ,EACN,OAAO,MAAM,KAAK,WAAW;gBAC3B,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,YAAY;gBACvC,CAAC,CAAC,SAAS;YACf,WAAW,EACT,OAAO,MAAM,KAAK,WAAW;gBAC3B,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,WAAW;gBACtC,CAAC,CAAC,SAAS;YACf,MAAM,EAAE;gBACN,WAAW,EAAE,WAAW;gBACxB,kBAAkB,EAAE,WAAW;aAChC;YACD,iBAAiB,EAAE,iBAAiB;YACpC,eAAe,EAAE,eAAe;YAChC,sBAAsB,EAAE,sBAAsB;YAC9C,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,iBAAiB,EAAE,iBAAiB;YACpC,SAAS,EAAE,QAAQ;YACnB,OAAO,EAAE;gBACP,KAAK,EAAE,OAAO;gBACd,OAAO,EAAE,KAAK;aACf;YACD,gBAAgB,EAAE;gBAChB,IAAI,EAAE,gBAAgB;gBACtB,OAAO,EAAE,UAAU;gBACnB,MAAM,EAAE,SAAS;aAClB;YACD,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;gBACzB,IAAI,KAAK,EAAE,CAAC;oBACV,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAC;oBACpD,OAAO;gBACT,CAAC;gBACD,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,CAAC;YACD,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;gBACxB,IAAI,KAAK,EAAE,CAAC;oBACV,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAE,KAAK,CAAC,CAAC;oBACnD,OAAO;gBACT,CAAC;gBAED,IAAI,CAAC;oBACH,uEAAuE;oBACvE,MAAM,kBAAkB,CAAC,QAAQ,CAAC,CAAC;oBACnC,qBAAqB;oBACrB,IAAI,eAAe,IAAI,eAAe,KAAK,QAAQ,EAAE,CAAC;wBACpD,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;oBAC/B,CAAC;gBACH,CAAC;gBAAC,OAAO,eAAe,EAAE,CAAC;oBACzB,OAAO,CAAC,KAAK,CAAC,gCAAgC,EAAE,eAAe,CAAC,CAAC;oBACjE,sDAAsD;oBACtD,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnB,CAAC;YACH,CAAC;YACD,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,WAAW,EAAE,OAAO,CAAC,UAAU,IAAI,IAAI;YACvC,cAAc,EAAE,IAAI,EAAE,0CAA0C;SACjE,CAAC;IACJ,CAAC,EAAE;QACD,QAAQ;QACR,WAAW;QACX,eAAe;QACf,YAAY;QACZ,iBAAiB;QACjB,UAAU;QACV,SAAS;QACT,MAAM;QACN,QAAQ;QACR,sBAAsB;QACtB,WAAW;QACX,OAAO,CAAC,WAAW;QACnB,OAAO,CAAC,UAAU;QAClB,OAAO,CAAC,UAAU;QAClB,OAAO,CAAC,WAAW;KACpB,CAAC,CAAC;IAEH,MAAM,yBAAyB,GAAG,OAAO,CAAC,GAAG,EAAE;QAC7C,OAAO,CACL,YAA2C,EAAE,EAC3B,EAAE;YACpB,OAAO;gBACL,GAAG,UAAU;gBACb,6DAA6D;gBAC7D,GAAG,CAAC,SAAS,CAAC,WAAW,IAAI,EAAE,WAAW,EAAE,SAAS,CAAC,WAAW,EAAE,CAAC;gBACpE,GAAG,CAAC,SAAS,CAAC,UAAU,KAAK,SAAS,IAAI;oBACxC,UAAU,EAAE,SAAS,CAAC,UAAU;iBACjC,CAAC;gBACF,GAAG,CAAC,SAAS,CAAC,QAAQ,IAAI,EAAE,QAAQ,EAAE,SAAS,CAAC,QAAQ,EAAE,CAAC;gBAC3D,GAAG,CAAC,SAAS,CAAC,WAAW,IAAI,EAAE,WAAW,EAAE,SAAS,CAAC,WAAW,EAAE,CAAC;gBACpE,GAAG,CAAC,SAAS,CAAC,iBAAiB,IAAI;oBACjC,iBAAiB,EAAE,SAAS,CAAC,iBAAiB;iBAC/C,CAAC;gBACF,GAAG,CAAC,SAAS,CAAC,sBAAsB,IAAI;oBACtC,sBAAsB,EAAE,SAAS,CAAC,sBAAsB;iBACzD,CAAC;aACH,CAAC;QACJ,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;IAEjB,OAAO;QACL,aAAa,EAAE,UAAU;QACzB,yBAAyB;QACzB,SAAS;KACV,CAAC;AACJ,CAAC,CAAC","sourcesContent":["/**\n * Hook for creating the initial auth configuration\n * Reusable across NextJS components that need to initialize GlobalAuthManager\n */\n\"use client\";\n\nimport { useMemo } from \"react\";\nimport { useRouter, usePathname } from \"next/navigation.js\";\nimport { resolveAuthConfig } from \"@/nextjs/config.js\";\nimport type { GlobalAuthConfig } from \"@/reactjs/core/GlobalAuthManager.js\";\nimport type { VanillaJSDisplayMode } from \"@/vanillajs/auth/types/AuthTypes.js\";\nimport type { User, IframeMode } from \"@/types.js\";\nimport { revalidateUserData } from \"@/nextjs/actions.js\";\nimport { BrowserCookieStorage } from \"@/shared/index.js\";\n\nexport interface UseInitialAuthConfigOptions {\n displayMode?: VanillaJSDisplayMode;\n iframeMode?: IframeMode;\n serverUser?: User | null;\n nonce?: string;\n targetContainerElement?: HTMLElement | string;\n oauthServer?: string;\n loginSuccessUrl?: string;\n onUrlChange?: (url: string, source?: string) => void;\n}\n\nexport interface UseInitialAuthConfigOverrides {\n displayMode?: VanillaJSDisplayMode;\n iframeMode?: IframeMode;\n clientId?: string;\n redirectUrl?: string;\n logoutRedirectUrl?: string;\n targetContainerElement?: string;\n}\n\n/**\n * Hook that creates the initial auth configuration\n * Can be used standalone or merged with overrides\n */\nexport const useInitialAuthConfig = (\n options: UseInitialAuthConfigOptions = {},\n): {\n initialConfig: GlobalAuthConfig;\n createConfigWithOverrides: (\n overrides?: UseInitialAuthConfigOverrides,\n ) => GlobalAuthConfig;\n logoutUrl: string;\n} => {\n const router = useRouter();\n const pathname = usePathname();\n const resolvedConfig = resolveAuthConfig(options);\n\n const {\n clientId,\n oauthServer,\n loginSuccessUrl,\n loginInitUrl,\n logoutUrl,\n refreshUrl,\n logoutCallbackUrl,\n callbackUrl,\n targetContainerElement,\n } = resolvedConfig;\n\n const baseConfig: GlobalAuthConfig = useMemo(() => {\n return {\n // we need this to retrieve client-available cookies for auto-refresh etc.\n storage: new BrowserCookieStorage(),\n clientId: clientId,\n loginUrl:\n typeof window !== \"undefined\"\n ? window.location.origin + loginInitUrl\n : undefined,\n redirectUrl:\n typeof window !== \"undefined\"\n ? window.location.origin + callbackUrl\n : undefined,\n config: {\n oauthServer: oauthServer,\n oauthServerBaseUrl: oauthServer,\n },\n logoutRedirectUrl: logoutCallbackUrl,\n loginSuccessUrl: loginSuccessUrl,\n targetContainerElement: targetContainerElement,\n displayMode: options.displayMode,\n iframeMode: options.iframeMode,\n logoutCallbackUrl: logoutCallbackUrl,\n framework: \"nextjs\",\n logging: {\n level: \"debug\",\n enabled: false,\n },\n backendEndpoints: {\n user: \"/api/auth/user\",\n refresh: refreshUrl,\n logout: logoutUrl,\n },\n onRefresh: async (error) => {\n if (error) {\n console.error(\"onRefresh: Error refreshing\", error);\n return;\n }\n router.refresh();\n },\n onSignIn: async (error) => {\n if (error) {\n console.error(\"onSignIn: Error signing in\", error);\n return;\n }\n\n try {\n // Trigger server-side revalidation to force NextAuthProvider to re-run\n await revalidateUserData(pathname);\n // Navigate if needed\n if (loginSuccessUrl && loginSuccessUrl !== pathname) {\n router.push(loginSuccessUrl);\n }\n } catch (revalidateError) {\n console.error(\"onSignIn: Revalidation failed:\", revalidateError);\n // Fallback to router.refresh() if server action fails\n router.refresh();\n }\n },\n onUrlChange: options.onUrlChange,\n initialUser: options.serverUser || null,\n initialIdToken: null, // ID token is httpOnly and not accessible\n };\n }, [\n clientId,\n oauthServer,\n loginSuccessUrl,\n loginInitUrl,\n logoutCallbackUrl,\n refreshUrl,\n logoutUrl,\n router,\n pathname,\n targetContainerElement,\n callbackUrl,\n options.displayMode,\n options.iframeMode,\n options.serverUser,\n options.onUrlChange,\n ]);\n\n const createConfigWithOverrides = useMemo(() => {\n return (\n overrides: UseInitialAuthConfigOverrides = {},\n ): GlobalAuthConfig => {\n return {\n ...baseConfig,\n // Override specific properties while keeping the base config\n ...(overrides.displayMode && { displayMode: overrides.displayMode }),\n ...(overrides.iframeMode !== undefined && {\n iframeMode: overrides.iframeMode,\n }),\n ...(overrides.clientId && { clientId: overrides.clientId }),\n ...(overrides.redirectUrl && { redirectUrl: overrides.redirectUrl }),\n ...(overrides.logoutRedirectUrl && {\n logoutRedirectUrl: overrides.logoutRedirectUrl,\n }),\n ...(overrides.targetContainerElement && {\n targetContainerElement: overrides.targetContainerElement,\n }),\n };\n };\n }, [baseConfig]);\n\n return {\n initialConfig: baseConfig,\n createConfigWithOverrides,\n logoutUrl,\n };\n};\n"]}
1
+ {"version":3,"file":"useInitialAuthConfig.js","sourceRoot":"","sources":["../../../src/nextjs/hooks/useInitialAuthConfig.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,YAAY,CAAC;AAEb,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAIvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAsB1C;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAClC,UAAuC,EAAE,EAOzC,EAAE;IACF,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,MAAM,cAAc,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAClD,0EAA0E;IAC1E,yEAAyE;IACzE,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAU,KAAK,CAAC,CAAC;IACjE,MAAM,EACJ,QAAQ,EACR,WAAW,EACX,eAAe,EACf,YAAY,EACZ,SAAS,EACT,UAAU,EACV,OAAO,EACP,iBAAiB,EACjB,WAAW,EACX,sBAAsB,GACvB,GAAG,cAAc,CAAC;IAEnB,MAAM,UAAU,GAAqB,OAAO,CAAC,GAAG,EAAE;QAChD,OAAO;YACL,0EAA0E;YAC1E,OAAO,EAAE,IAAI,oBAAoB,EAAE;YACnC,QAAQ,EAAE,QAAQ;YAClB,QAAQ,EACN,OAAO,MAAM,KAAK,WAAW;gBAC3B,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,YAAY;gBACvC,CAAC,CAAC,SAAS;YACf,WAAW,EACT,OAAO,MAAM,KAAK,WAAW;gBAC3B,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,WAAW;gBACtC,CAAC,CAAC,SAAS;YACf,MAAM,EAAE;gBACN,WAAW,EAAE,WAAW;gBACxB,kBAAkB,EAAE,WAAW;aAChC;YACD,iBAAiB,EAAE,iBAAiB;YACpC,eAAe,EAAE,eAAe;YAChC,sBAAsB,EAAE,sBAAsB;YAC9C,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,iBAAiB,EAAE,iBAAiB;YACpC,SAAS,EAAE,QAAQ;YACnB,OAAO,EAAE;gBACP,KAAK,EAAE,OAAO;gBACd,OAAO,EAAE,KAAK;aACf;YACD,gBAAgB,EAAE;gBAChB,IAAI,EAAE,OAAO;gBACb,OAAO,EAAE,UAAU;gBACnB,MAAM,EAAE,SAAS;aAClB;YACD,SAAS,EAAE,KAAK,IAAI,EAAE;gBACpB,eAAe,CAAC,IAAI,CAAC,CAAC;gBACtB,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,CAAC;YACD,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;gBACzB,IAAI,KAAK,EAAE,CAAC;oBACV,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAC;gBACnE,CAAC;gBACD,eAAe,CAAC,KAAK,CAAC,CAAC;gBACvB,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,CAAC;YACD,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;gBACxB,IAAI,KAAK,EAAE,CAAC;oBACV,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,4BAA4B,EAAE,KAAK,CAAC,CAAC;oBAChE,OAAO;gBACT,CAAC;gBACD,eAAe,CAAC,KAAK,CAAC,CAAC;gBACvB,IAAI,CAAC;oBACH,uEAAuE;oBACvE,MAAM,kBAAkB,CAAC,QAAQ,CAAC,CAAC;oBACnC,qBAAqB;oBACrB,IAAI,eAAe,IAAI,eAAe,KAAK,QAAQ,EAAE,CAAC;wBACpD,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;oBAC/B,CAAC;gBACH,CAAC;gBAAC,OAAO,eAAe,EAAE,CAAC;oBACzB,OAAO,CAAC,KAAK,CAAC,gCAAgC,EAAE,eAAe,CAAC,CAAC;oBACjE,sDAAsD;oBACtD,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnB,CAAC;YACH,CAAC;YACD,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,WAAW,EAAE,CAAC,CAAC,YAAY,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,IAAI;YAC1D,2CAA2C;YAC3C,cAAc,EAAE,IAAI,EAAE,0CAA0C;SACjE,CAAC;IACJ,CAAC,EAAE;QACD,QAAQ;QACR,YAAY;QACZ,WAAW;QACX,WAAW;QACX,iBAAiB;QACjB,eAAe;QACf,sBAAsB;QACtB,OAAO,CAAC,WAAW;QACnB,OAAO,CAAC,UAAU;QAClB,OAAO,CAAC,WAAW;QACnB,OAAO,CAAC,UAAU;QAClB,OAAO;QACP,UAAU;QACV,SAAS;QACT,YAAY;QACZ,MAAM;QACN,QAAQ;KACT,CAAC,CAAC;IAEH,MAAM,yBAAyB,GAAG,OAAO,CAAC,GAAG,EAAE;QAC7C,OAAO,CACL,YAA2C,EAAE,EAC3B,EAAE;YACpB,OAAO;gBACL,GAAG,UAAU;gBACb,6DAA6D;gBAC7D,GAAG,CAAC,SAAS,CAAC,WAAW,IAAI,EAAE,WAAW,EAAE,SAAS,CAAC,WAAW,EAAE,CAAC;gBACpE,GAAG,CAAC,SAAS,CAAC,UAAU,KAAK,SAAS,IAAI;oBACxC,UAAU,EAAE,SAAS,CAAC,UAAU;iBACjC,CAAC;gBACF,GAAG,CAAC,SAAS,CAAC,QAAQ,IAAI,EAAE,QAAQ,EAAE,SAAS,CAAC,QAAQ,EAAE,CAAC;gBAC3D,GAAG,CAAC,SAAS,CAAC,WAAW,IAAI,EAAE,WAAW,EAAE,SAAS,CAAC,WAAW,EAAE,CAAC;gBACpE,GAAG,CAAC,SAAS,CAAC,iBAAiB,IAAI;oBACjC,iBAAiB,EAAE,SAAS,CAAC,iBAAiB;iBAC/C,CAAC;gBACF,GAAG,CAAC,SAAS,CAAC,sBAAsB,IAAI;oBACtC,sBAAsB,EAAE,SAAS,CAAC,sBAAsB;iBACzD,CAAC;aACH,CAAC;QACJ,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;IAEjB,OAAO;QACL,aAAa,EAAE,UAAU;QACzB,yBAAyB;QACzB,SAAS;KACV,CAAC;AACJ,CAAC,CAAC","sourcesContent":["/**\n * Hook for creating the initial auth configuration\n * Reusable across NextJS components that need to initialize GlobalAuthManager\n */\n\"use client\";\n\nimport { useMemo, useState } from \"react\";\nimport { useRouter, usePathname } from \"next/navigation.js\";\nimport { resolveAuthConfig } from \"@/nextjs/config.js\";\nimport type { GlobalAuthConfig } from \"@/reactjs/core/GlobalAuthManager.js\";\nimport type { VanillaJSDisplayMode } from \"@/vanillajs/auth/types/AuthTypes.js\";\nimport type { User, IframeMode } from \"@/types.js\";\nimport { revalidateUserData } from \"@/nextjs/actions.js\";\nimport { BrowserCookieStorage } from \"@/shared/index.js\";\nimport { loggers } from \"@/lib/logger.js\";\n\nexport interface UseInitialAuthConfigOptions {\n displayMode?: VanillaJSDisplayMode;\n iframeMode?: IframeMode;\n serverUser?: User | null;\n nonce?: string;\n targetContainerElement?: HTMLElement | string;\n oauthServer?: string;\n loginSuccessUrl?: string;\n onUrlChange?: (url: string, source?: string) => void;\n}\n\nexport interface UseInitialAuthConfigOverrides {\n displayMode?: VanillaJSDisplayMode;\n iframeMode?: IframeMode;\n clientId?: string;\n redirectUrl?: string;\n logoutRedirectUrl?: string;\n targetContainerElement?: string;\n}\n\n/**\n * Hook that creates the initial auth configuration\n * Can be used standalone or merged with overrides\n */\nexport const useInitialAuthConfig = (\n options: UseInitialAuthConfigOptions = {},\n): {\n initialConfig: GlobalAuthConfig;\n createConfigWithOverrides: (\n overrides?: UseInitialAuthConfigOverrides,\n ) => GlobalAuthConfig;\n logoutUrl: string;\n} => {\n const router = useRouter();\n const pathname = usePathname();\n const resolvedConfig = resolveAuthConfig(options);\n // Force a re-render when the page gets re-rendered after sign-in/sign-out\n // so that client-side hooks and event listeners are properly initialized\n const [hasSignedOut, setHasSignedOut] = useState<boolean>(false);\n const {\n clientId,\n oauthServer,\n loginSuccessUrl,\n loginInitUrl,\n logoutUrl,\n refreshUrl,\n userUrl,\n logoutCallbackUrl,\n callbackUrl,\n targetContainerElement,\n } = resolvedConfig;\n\n const baseConfig: GlobalAuthConfig = useMemo(() => {\n return {\n // we need this to retrieve client-available cookies for auto-refresh etc.\n storage: new BrowserCookieStorage(),\n clientId: clientId,\n loginUrl:\n typeof window !== \"undefined\"\n ? window.location.origin + loginInitUrl\n : undefined,\n redirectUrl:\n typeof window !== \"undefined\"\n ? window.location.origin + callbackUrl\n : undefined,\n config: {\n oauthServer: oauthServer,\n oauthServerBaseUrl: oauthServer,\n },\n logoutRedirectUrl: logoutCallbackUrl,\n loginSuccessUrl: loginSuccessUrl,\n targetContainerElement: targetContainerElement,\n displayMode: options.displayMode,\n iframeMode: options.iframeMode,\n logoutCallbackUrl: logoutCallbackUrl,\n framework: \"nextjs\",\n logging: {\n level: \"debug\",\n enabled: false,\n },\n backendEndpoints: {\n user: userUrl,\n refresh: refreshUrl,\n logout: logoutUrl,\n },\n onSignOut: async () => {\n setHasSignedOut(true);\n router.refresh();\n },\n onRefresh: async (error) => {\n if (error) {\n loggers.nextjs.hooks.error(\"onRefresh: Error refreshing\", error);\n }\n setHasSignedOut(false);\n router.refresh();\n },\n onSignIn: async (error) => {\n if (error) {\n loggers.nextjs.hooks.error(\"onSignIn: Error signing in\", error);\n return;\n }\n setHasSignedOut(false);\n try {\n // Trigger server-side revalidation to force NextAuthProvider to re-run\n await revalidateUserData(pathname);\n // Navigate if needed\n if (loginSuccessUrl && loginSuccessUrl !== pathname) {\n router.push(loginSuccessUrl);\n }\n } catch (revalidateError) {\n console.error(\"onSignIn: Revalidation failed:\", revalidateError);\n // Fallback to router.refresh() if server action fails\n router.refresh();\n }\n },\n onUrlChange: options.onUrlChange,\n initialUser: (!hasSignedOut && options.serverUser) || null,\n // initialUser: options.serverUser || null,\n initialIdToken: null, // ID token is httpOnly and not accessible\n };\n }, [\n clientId,\n loginInitUrl,\n callbackUrl,\n oauthServer,\n logoutCallbackUrl,\n loginSuccessUrl,\n targetContainerElement,\n options.displayMode,\n options.iframeMode,\n options.onUrlChange,\n options.serverUser,\n userUrl,\n refreshUrl,\n logoutUrl,\n hasSignedOut,\n router,\n pathname,\n ]);\n\n const createConfigWithOverrides = useMemo(() => {\n return (\n overrides: UseInitialAuthConfigOverrides = {},\n ): GlobalAuthConfig => {\n return {\n ...baseConfig,\n // Override specific properties while keeping the base config\n ...(overrides.displayMode && { displayMode: overrides.displayMode }),\n ...(overrides.iframeMode !== undefined && {\n iframeMode: overrides.iframeMode,\n }),\n ...(overrides.clientId && { clientId: overrides.clientId }),\n ...(overrides.redirectUrl && { redirectUrl: overrides.redirectUrl }),\n ...(overrides.logoutRedirectUrl && {\n logoutRedirectUrl: overrides.logoutRedirectUrl,\n }),\n ...(overrides.targetContainerElement && {\n targetContainerElement: overrides.targetContainerElement,\n }),\n };\n };\n }, [baseConfig]);\n\n return {\n initialConfig: baseConfig,\n createConfigWithOverrides,\n logoutUrl,\n };\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/nextjs/middleware.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,KAAK,EACV,sBAAsB,EACtB,kBAAkB,EACnB,MAAM,oBAAoB,CAAC;AAI5B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAS9C,OAAO,EAAE,6BAA6B,EAAE,MAAM,YAAY,CAAC;AAK3D,KAAK,UAAU,GAAG,CAChB,OAAO,EAAE,WAAW,KACjB,OAAO,CAAC,YAAY,CAAC,GAAG,YAAY,CAAC;AAE1C;;;;;;GAMG;AACH,eAAO,MAAM,2BAA2B,2BACd,sBAAsB,WACrC,6BAA6B,KACrC,OAAO,CAAC,WAAW,CAgBrB,CAAC;AAoFF;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,gBACZ,kBAAkB,eACf,WAAW,KAAG,OAAO,CAAC,YAAY,CAOjD,CAAC;AAEJ;;;;;;;GAOG;AAEH,wBAAgB,QAAQ,CACtB,UAAU,EAAE,UAAU,GACrB,CAAC,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC,YAAY,CAAC,CAEjD;AAKD;;;;;;;;;;GAUG;AACH,wBAAgB,IAAI,CAAC,UAAU,GAAE,kBAAuB,gBAExC,UAAU,KACrB,CAAC,CAAC,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC,CAuBrD"}
1
+ {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/nextjs/middleware.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,KAAK,EACV,sBAAsB,EACtB,kBAAkB,EACnB,MAAM,oBAAoB,CAAC;AAI5B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAS9C,OAAO,EAAE,6BAA6B,EAAE,MAAM,YAAY,CAAC;AAK3D,KAAK,UAAU,GAAG,CAChB,OAAO,EAAE,WAAW,KACjB,OAAO,CAAC,YAAY,CAAC,GAAG,YAAY,CAAC;AAE1C;;;;;;GAMG;AACH,eAAO,MAAM,2BAA2B,2BACd,sBAAsB,WACrC,6BAA6B,KACrC,OAAO,CAAC,WAAW,CAgBrB,CAAC;AA2FF;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,gBACZ,kBAAkB,eACf,WAAW,KAAG,OAAO,CAAC,YAAY,CAOjD,CAAC;AAEJ;;;;;;;GAOG;AAEH,wBAAgB,QAAQ,CACtB,UAAU,EAAE,UAAU,GACrB,CAAC,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC,YAAY,CAAC,CAEjD;AAKD;;;;;;;;;;GAUG;AACH,wBAAgB,IAAI,CAAC,UAAU,GAAE,kBAAuB,gBAExC,UAAU,KACrB,CAAC,CAAC,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC,CA2BrD"}
@@ -44,10 +44,21 @@ const applyAuth = async (authConfig, request) => {
44
44
  ...authConfigWithDefaults?.cookies?.tokens,
45
45
  [UserStorage.USER]: authConfigWithDefaults?.cookies?.user || {},
46
46
  };
47
+ logger.debug("Incoming request:", {
48
+ pathName: request.nextUrl.pathname,
49
+ method: request.method,
50
+ });
47
51
  const storage = new NextjsMiddlewareCookieStorage(cookieConfig, request, response);
52
+ // check if the incoming path is a system URL
53
+ const shouldSkipAuthForSystemUrlsCheck = shouldSkipAuthForSystemUrls(request.nextUrl.pathname, authConfigWithDefaults);
54
+ // Skip authentication for system URLs (callback, challenge, logout)
55
+ // we don't want to validate the session in this case as this would
56
+ // auto-hydrate and potential conflict with the logic of the api call
57
+ if (shouldSkipAuthForSystemUrlsCheck) {
58
+ return response;
59
+ }
48
60
  // Step 1: Understand the current authentication state
49
61
  const session = await validateAuthTokensIfPresent(authConfigWithDefaults, storage);
50
- const shouldSkipAuthForSystemUrlsCheck = shouldSkipAuthForSystemUrls(request.nextUrl.pathname, authConfigWithDefaults, request.method);
51
62
  const shouldSkipAuthForRoutePatternsCheck = shouldSkipAuthForRoutePatterns(request.nextUrl.pathname, authConfigWithDefaults);
52
63
  const pathNameIsLoginUrl = request.nextUrl.pathname === authConfigWithDefaults.loginUrl;
53
64
  logger.debug("Authentication state:", {
@@ -58,11 +69,7 @@ const applyAuth = async (authConfig, request) => {
58
69
  shouldSkipAuthForSystemUrls: shouldSkipAuthForSystemUrlsCheck,
59
70
  shouldSkipAuthForRoutePatterns: shouldSkipAuthForRoutePatternsCheck,
60
71
  });
61
- // Skip authentication for system URLs (callback, challenge, logout)
62
- if (shouldSkipAuthForSystemUrlsCheck) {
63
- return response;
64
- }
65
- // Handle login URL with special logic
72
+ // Step 2: Attempt token refresh if needed (the OAuth pipeline approach) // Handle login URL with special logic
66
73
  if (pathNameIsLoginUrl) {
67
74
  handleLoginUrl(request.nextUrl.pathname, session, authConfigWithDefaults);
68
75
  return response; // Always allow access to login URL
@@ -129,6 +136,10 @@ export function auth(authConfig = {}) {
129
136
  logger.debug("User is unauthenticated, redirecting to ", response.headers.get("location"));
130
137
  return response;
131
138
  }
139
+ // ensure requests get the cookies in case of redirects
140
+ if (response) {
141
+ copyCivicCookies(response, request);
142
+ }
132
143
  const middlewareResponse = await middleware(request);
133
144
  // we need to ensure that the civic cookies that were potentially
134
145
  // added by CivicAuth are set on the final response after all