@civic/auth 0.5.4 → 0.5.6-mcp-patch.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/constants.d.ts +2 -1
  3. package/dist/constants.d.ts.map +1 -1
  4. package/dist/constants.js +2 -1
  5. package/dist/constants.js.map +1 -1
  6. package/dist/lib/cookies.d.ts +7 -0
  7. package/dist/lib/cookies.d.ts.map +1 -0
  8. package/dist/lib/cookies.js +26 -0
  9. package/dist/lib/cookies.js.map +1 -0
  10. package/dist/lib/oauth.d.ts +8 -2
  11. package/dist/lib/oauth.d.ts.map +1 -1
  12. package/dist/lib/oauth.js +8 -10
  13. package/dist/lib/oauth.js.map +1 -1
  14. package/dist/nextjs/config.d.ts +3 -0
  15. package/dist/nextjs/config.d.ts.map +1 -1
  16. package/dist/nextjs/config.js +36 -4
  17. package/dist/nextjs/config.js.map +1 -1
  18. package/dist/nextjs/cookies.d.ts +6 -4
  19. package/dist/nextjs/cookies.d.ts.map +1 -1
  20. package/dist/nextjs/cookies.js +20 -12
  21. package/dist/nextjs/cookies.js.map +1 -1
  22. package/dist/nextjs/providers/NextAuthProvider.d.ts.map +1 -1
  23. package/dist/nextjs/providers/NextAuthProvider.js +2 -2
  24. package/dist/nextjs/providers/NextAuthProvider.js.map +1 -1
  25. package/dist/nextjs/routeHandler.d.ts.map +1 -1
  26. package/dist/nextjs/routeHandler.js +159 -104
  27. package/dist/nextjs/routeHandler.js.map +1 -1
  28. package/dist/reactjs/components/UserButton.d.ts.map +1 -1
  29. package/dist/reactjs/components/UserButton.js +1 -0
  30. package/dist/reactjs/components/UserButton.js.map +1 -1
  31. package/dist/services/AuthenticationService.d.ts +1 -0
  32. package/dist/services/AuthenticationService.d.ts.map +1 -1
  33. package/dist/services/AuthenticationService.js +5 -1
  34. package/dist/services/AuthenticationService.js.map +1 -1
  35. package/dist/shared/components/CivicAuthIframeContainer.d.ts.map +1 -1
  36. package/dist/shared/components/CivicAuthIframeContainer.js +5 -1
  37. package/dist/shared/components/CivicAuthIframeContainer.js.map +1 -1
  38. package/dist/shared/components/CivicAuthLogoutIframeContainer.d.ts.map +1 -1
  39. package/dist/shared/components/CivicAuthLogoutIframeContainer.js +31 -1
  40. package/dist/shared/components/CivicAuthLogoutIframeContainer.js.map +1 -1
  41. package/dist/shared/components/IFrameAndLoading.d.ts.map +1 -1
  42. package/dist/shared/components/IFrameAndLoading.js +11 -1
  43. package/dist/shared/components/IFrameAndLoading.js.map +1 -1
  44. package/dist/shared/hooks/useSignIn.d.ts.map +1 -1
  45. package/dist/shared/hooks/useSignIn.js +2 -1
  46. package/dist/shared/hooks/useSignIn.js.map +1 -1
  47. package/dist/shared/lib/types.d.ts +1 -0
  48. package/dist/shared/lib/types.d.ts.map +1 -1
  49. package/dist/shared/lib/types.js.map +1 -1
  50. package/dist/shared/providers/CivicAuthConfigContext.d.ts +2 -1
  51. package/dist/shared/providers/CivicAuthConfigContext.d.ts.map +1 -1
  52. package/dist/shared/providers/CivicAuthConfigContext.js +3 -1
  53. package/dist/shared/providers/CivicAuthConfigContext.js.map +1 -1
  54. package/dist/shared/version.d.ts +1 -1
  55. package/dist/shared/version.d.ts.map +1 -1
  56. package/dist/shared/version.js +1 -1
  57. package/dist/shared/version.js.map +1 -1
  58. package/package.json +19 -18
package/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ # 0.5.5 loginSuccessUrl property
2
+ - Add a new setting for loginSuccessUrl in NextJS, redirecting the user to a page of the customer's choice after login
3
+ - Fix bug where logout would hang in modes other than iframe.
4
+
1
5
  # 0.5.4 Sign In Promise Fix
2
6
 
3
7
  - Fix Sign In Promise Fix
@@ -4,6 +4,7 @@ declare const DEFAULT_OAUTH_GET_PARAMS: string[];
4
4
  declare const DEFAULT_EXPIRES_IN = 3600;
5
5
  declare const TOKEN_EXCHANGE_TRIGGER_TEXT = "sameDomainCodeExchangeRequired";
6
6
  declare const TOKEN_EXCHANGE_SUCCESS_TEXT = "serverSideTokenExchangeSuccess";
7
+ declare const LOGOUT_SUCCESS_TEXT = "serverSideLogoutSuccess";
7
8
  declare const DEFAULT_DISPLAY_MODE = "iframe";
8
9
  declare const JWT_PAYLOAD_KNOWN_CLAIM_KEYS: readonly ["iss", "aud", "sub", "iat", "exp"];
9
10
  declare const AUTOREFRESH_TIMEOUT_NAME = "civicAuthAutorefreshTimeout";
@@ -11,5 +12,5 @@ declare const REFRESH_IN_PROGRESS = "civicAuthRefreshInProgress";
11
12
  declare const LOGOUT_STATE = "logout_state";
12
13
  declare const DARK_BACKGROUND_COLOR = "rgb(30, 41, 59)";
13
14
  declare const LIGHT_BACKGROUND_COLOR = "white";
14
- export { DEFAULT_SCOPES, DEFAULT_OAUTH_GET_PARAMS, DEFAULT_DISPLAY_MODE, DEFAULT_AUTH_SERVER, DEFAULT_EXPIRES_IN, TOKEN_EXCHANGE_TRIGGER_TEXT, TOKEN_EXCHANGE_SUCCESS_TEXT, JWT_PAYLOAD_KNOWN_CLAIM_KEYS, AUTOREFRESH_TIMEOUT_NAME, REFRESH_IN_PROGRESS, DARK_BACKGROUND_COLOR, LIGHT_BACKGROUND_COLOR, LOGOUT_STATE, };
15
+ export { DEFAULT_SCOPES, DEFAULT_OAUTH_GET_PARAMS, DEFAULT_DISPLAY_MODE, DEFAULT_AUTH_SERVER, DEFAULT_EXPIRES_IN, TOKEN_EXCHANGE_TRIGGER_TEXT, TOKEN_EXCHANGE_SUCCESS_TEXT, LOGOUT_SUCCESS_TEXT, JWT_PAYLOAD_KNOWN_CLAIM_KEYS, AUTOREFRESH_TIMEOUT_NAME, REFRESH_IN_PROGRESS, DARK_BACKGROUND_COLOR, LIGHT_BACKGROUND_COLOR, LOGOUT_STATE, };
15
16
  //# sourceMappingURL=constants.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,cAAc,UAMnB,CAAC;AACF,QAAA,MAAM,mBAAmB,iCAAiC,CAAC;AAE3D,QAAA,MAAM,wBAAwB,UAA2B,CAAC;AAE1D,QAAA,MAAM,kBAAkB,OAAO,CAAC;AAIhC,QAAA,MAAM,2BAA2B,mCAAmC,CAAC;AAErE,QAAA,MAAM,2BAA2B,mCAAmC,CAAC;AAErE,QAAA,MAAM,oBAAoB,WAAW,CAAC;AACtC,QAAA,MAAM,4BAA4B,8CAMxB,CAAC;AAEX,QAAA,MAAM,wBAAwB,gCAAgC,CAAC;AAC/D,QAAA,MAAM,mBAAmB,+BAA+B,CAAC;AACzD,QAAA,MAAM,YAAY,iBAAiB,CAAC;AACpC,QAAA,MAAM,qBAAqB,oBAAoB,CAAC;AAChD,QAAA,MAAM,sBAAsB,UAAU,CAAC;AACvC,OAAO,EACL,cAAc,EACd,wBAAwB,EACxB,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,EAClB,2BAA2B,EAC3B,2BAA2B,EAC3B,4BAA4B,EAC5B,wBAAwB,EACxB,mBAAmB,EACnB,qBAAqB,EACrB,sBAAsB,EACtB,YAAY,GACb,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,cAAc,UAMnB,CAAC;AACF,QAAA,MAAM,mBAAmB,iCAAiC,CAAC;AAE3D,QAAA,MAAM,wBAAwB,UAA2B,CAAC;AAE1D,QAAA,MAAM,kBAAkB,OAAO,CAAC;AAIhC,QAAA,MAAM,2BAA2B,mCAAmC,CAAC;AAErE,QAAA,MAAM,2BAA2B,mCAAmC,CAAC;AAErE,QAAA,MAAM,mBAAmB,4BAA4B,CAAC;AAEtD,QAAA,MAAM,oBAAoB,WAAW,CAAC;AACtC,QAAA,MAAM,4BAA4B,8CAMxB,CAAC;AAEX,QAAA,MAAM,wBAAwB,gCAAgC,CAAC;AAC/D,QAAA,MAAM,mBAAmB,+BAA+B,CAAC;AACzD,QAAA,MAAM,YAAY,iBAAiB,CAAC;AACpC,QAAA,MAAM,qBAAqB,oBAAoB,CAAC;AAChD,QAAA,MAAM,sBAAsB,UAAU,CAAC;AACvC,OAAO,EACL,cAAc,EACd,wBAAwB,EACxB,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,EAClB,2BAA2B,EAC3B,2BAA2B,EAC3B,mBAAmB,EACnB,4BAA4B,EAC5B,wBAAwB,EACxB,mBAAmB,EACnB,qBAAqB,EACrB,sBAAsB,EACtB,YAAY,GACb,CAAC"}
package/dist/constants.js CHANGED
@@ -12,6 +12,7 @@ const DEFAULT_EXPIRES_IN = 3600; // 1 hour in seconds
12
12
  // for the iframe case where cookies are not sent along with the initial redirect.
13
13
  const TOKEN_EXCHANGE_TRIGGER_TEXT = "sameDomainCodeExchangeRequired";
14
14
  const TOKEN_EXCHANGE_SUCCESS_TEXT = "serverSideTokenExchangeSuccess";
15
+ const LOGOUT_SUCCESS_TEXT = "serverSideLogoutSuccess";
15
16
  const DEFAULT_DISPLAY_MODE = "iframe";
16
17
  const JWT_PAYLOAD_KNOWN_CLAIM_KEYS = [
17
18
  "iss",
@@ -25,5 +26,5 @@ const REFRESH_IN_PROGRESS = "civicAuthRefreshInProgress";
25
26
  const LOGOUT_STATE = "logout_state";
26
27
  const DARK_BACKGROUND_COLOR = "rgb(30, 41, 59)";
27
28
  const LIGHT_BACKGROUND_COLOR = "white";
28
- export { DEFAULT_SCOPES, DEFAULT_OAUTH_GET_PARAMS, DEFAULT_DISPLAY_MODE, DEFAULT_AUTH_SERVER, DEFAULT_EXPIRES_IN, TOKEN_EXCHANGE_TRIGGER_TEXT, TOKEN_EXCHANGE_SUCCESS_TEXT, JWT_PAYLOAD_KNOWN_CLAIM_KEYS, AUTOREFRESH_TIMEOUT_NAME, REFRESH_IN_PROGRESS, DARK_BACKGROUND_COLOR, LIGHT_BACKGROUND_COLOR, LOGOUT_STATE, };
29
+ export { DEFAULT_SCOPES, DEFAULT_OAUTH_GET_PARAMS, DEFAULT_DISPLAY_MODE, DEFAULT_AUTH_SERVER, DEFAULT_EXPIRES_IN, TOKEN_EXCHANGE_TRIGGER_TEXT, TOKEN_EXCHANGE_SUCCESS_TEXT, LOGOUT_SUCCESS_TEXT, JWT_PAYLOAD_KNOWN_CLAIM_KEYS, AUTOREFRESH_TIMEOUT_NAME, REFRESH_IN_PROGRESS, DARK_BACKGROUND_COLOR, LIGHT_BACKGROUND_COLOR, LOGOUT_STATE, };
29
30
  //# sourceMappingURL=constants.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,cAAc,GAAG;IACrB,QAAQ;IACR,SAAS;IACT,OAAO;IACP,iBAAiB;IACjB,gBAAgB;CACjB,CAAC;AACF,MAAM,mBAAmB,GAAG,8BAA8B,CAAC;AAE3D,MAAM,wBAAwB,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;AAE1D,MAAM,kBAAkB,GAAG,IAAI,CAAC,CAAC,oBAAoB;AAErD,uHAAuH;AACvH,kFAAkF;AAClF,MAAM,2BAA2B,GAAG,gCAAgC,CAAC;AAErE,MAAM,2BAA2B,GAAG,gCAAgC,CAAC;AAErE,MAAM,oBAAoB,GAAG,QAAQ,CAAC;AACtC,MAAM,4BAA4B,GAAG;IACnC,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;CACG,CAAC;AAEX,MAAM,wBAAwB,GAAG,6BAA6B,CAAC;AAC/D,MAAM,mBAAmB,GAAG,4BAA4B,CAAC;AACzD,MAAM,YAAY,GAAG,cAAc,CAAC;AACpC,MAAM,qBAAqB,GAAG,iBAAiB,CAAC;AAChD,MAAM,sBAAsB,GAAG,OAAO,CAAC;AACvC,OAAO,EACL,cAAc,EACd,wBAAwB,EACxB,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,EAClB,2BAA2B,EAC3B,2BAA2B,EAC3B,4BAA4B,EAC5B,wBAAwB,EACxB,mBAAmB,EACnB,qBAAqB,EACrB,sBAAsB,EACtB,YAAY,GACb,CAAC","sourcesContent":["const DEFAULT_SCOPES = [\n \"openid\",\n \"profile\",\n \"email\",\n \"forwardedTokens\",\n \"offline_access\",\n];\nconst DEFAULT_AUTH_SERVER = \"https://auth.civic.com/oauth\";\n\nconst DEFAULT_OAUTH_GET_PARAMS = [\"code\", \"state\", \"iss\"];\n\nconst DEFAULT_EXPIRES_IN = 3600; // 1 hour in seconds\n\n// The server's callback handler renders this text if it needs the front-end to make an additional token exchange call,\n// for the iframe case where cookies are not sent along with the initial redirect.\nconst TOKEN_EXCHANGE_TRIGGER_TEXT = \"sameDomainCodeExchangeRequired\";\n\nconst TOKEN_EXCHANGE_SUCCESS_TEXT = \"serverSideTokenExchangeSuccess\";\n\nconst DEFAULT_DISPLAY_MODE = \"iframe\";\nconst JWT_PAYLOAD_KNOWN_CLAIM_KEYS = [\n \"iss\",\n \"aud\",\n \"sub\",\n \"iat\",\n \"exp\",\n] as const;\n\nconst AUTOREFRESH_TIMEOUT_NAME = \"civicAuthAutorefreshTimeout\";\nconst REFRESH_IN_PROGRESS = \"civicAuthRefreshInProgress\";\nconst LOGOUT_STATE = \"logout_state\";\nconst DARK_BACKGROUND_COLOR = \"rgb(30, 41, 59)\";\nconst LIGHT_BACKGROUND_COLOR = \"white\";\nexport {\n DEFAULT_SCOPES,\n DEFAULT_OAUTH_GET_PARAMS,\n DEFAULT_DISPLAY_MODE,\n DEFAULT_AUTH_SERVER,\n DEFAULT_EXPIRES_IN,\n TOKEN_EXCHANGE_TRIGGER_TEXT,\n TOKEN_EXCHANGE_SUCCESS_TEXT,\n JWT_PAYLOAD_KNOWN_CLAIM_KEYS,\n AUTOREFRESH_TIMEOUT_NAME,\n REFRESH_IN_PROGRESS,\n DARK_BACKGROUND_COLOR,\n LIGHT_BACKGROUND_COLOR,\n LOGOUT_STATE,\n};\n"]}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,cAAc,GAAG;IACrB,QAAQ;IACR,SAAS;IACT,OAAO;IACP,iBAAiB;IACjB,gBAAgB;CACjB,CAAC;AACF,MAAM,mBAAmB,GAAG,8BAA8B,CAAC;AAE3D,MAAM,wBAAwB,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;AAE1D,MAAM,kBAAkB,GAAG,IAAI,CAAC,CAAC,oBAAoB;AAErD,uHAAuH;AACvH,kFAAkF;AAClF,MAAM,2BAA2B,GAAG,gCAAgC,CAAC;AAErE,MAAM,2BAA2B,GAAG,gCAAgC,CAAC;AAErE,MAAM,mBAAmB,GAAG,yBAAyB,CAAC;AAEtD,MAAM,oBAAoB,GAAG,QAAQ,CAAC;AACtC,MAAM,4BAA4B,GAAG;IACnC,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;CACG,CAAC;AAEX,MAAM,wBAAwB,GAAG,6BAA6B,CAAC;AAC/D,MAAM,mBAAmB,GAAG,4BAA4B,CAAC;AACzD,MAAM,YAAY,GAAG,cAAc,CAAC;AACpC,MAAM,qBAAqB,GAAG,iBAAiB,CAAC;AAChD,MAAM,sBAAsB,GAAG,OAAO,CAAC;AACvC,OAAO,EACL,cAAc,EACd,wBAAwB,EACxB,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,EAClB,2BAA2B,EAC3B,2BAA2B,EAC3B,mBAAmB,EACnB,4BAA4B,EAC5B,wBAAwB,EACxB,mBAAmB,EACnB,qBAAqB,EACrB,sBAAsB,EACtB,YAAY,GACb,CAAC","sourcesContent":["const DEFAULT_SCOPES = [\n \"openid\",\n \"profile\",\n \"email\",\n \"forwardedTokens\",\n \"offline_access\",\n];\nconst DEFAULT_AUTH_SERVER = \"https://auth.civic.com/oauth\";\n\nconst DEFAULT_OAUTH_GET_PARAMS = [\"code\", \"state\", \"iss\"];\n\nconst DEFAULT_EXPIRES_IN = 3600; // 1 hour in seconds\n\n// The server's callback handler renders this text if it needs the front-end to make an additional token exchange call,\n// for the iframe case where cookies are not sent along with the initial redirect.\nconst TOKEN_EXCHANGE_TRIGGER_TEXT = \"sameDomainCodeExchangeRequired\";\n\nconst TOKEN_EXCHANGE_SUCCESS_TEXT = \"serverSideTokenExchangeSuccess\";\n\nconst LOGOUT_SUCCESS_TEXT = \"serverSideLogoutSuccess\";\n\nconst DEFAULT_DISPLAY_MODE = \"iframe\";\nconst JWT_PAYLOAD_KNOWN_CLAIM_KEYS = [\n \"iss\",\n \"aud\",\n \"sub\",\n \"iat\",\n \"exp\",\n] as const;\n\nconst AUTOREFRESH_TIMEOUT_NAME = \"civicAuthAutorefreshTimeout\";\nconst REFRESH_IN_PROGRESS = \"civicAuthRefreshInProgress\";\nconst LOGOUT_STATE = \"logout_state\";\nconst DARK_BACKGROUND_COLOR = \"rgb(30, 41, 59)\";\nconst LIGHT_BACKGROUND_COLOR = \"white\";\nexport {\n DEFAULT_SCOPES,\n DEFAULT_OAUTH_GET_PARAMS,\n DEFAULT_DISPLAY_MODE,\n DEFAULT_AUTH_SERVER,\n DEFAULT_EXPIRES_IN,\n TOKEN_EXCHANGE_TRIGGER_TEXT,\n TOKEN_EXCHANGE_SUCCESS_TEXT,\n LOGOUT_SUCCESS_TEXT,\n JWT_PAYLOAD_KNOWN_CLAIM_KEYS,\n AUTOREFRESH_TIMEOUT_NAME,\n REFRESH_IN_PROGRESS,\n DARK_BACKGROUND_COLOR,\n LIGHT_BACKGROUND_COLOR,\n LOGOUT_STATE,\n};\n"]}
@@ -0,0 +1,7 @@
1
+ declare const getWindowCookieValue: (requests: {
2
+ key: string;
3
+ window: Window;
4
+ parseJson?: boolean;
5
+ }[]) => Record<string, string | Record<string, unknown>> | null;
6
+ export { getWindowCookieValue };
7
+ //# sourceMappingURL=cookies.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cookies.d.ts","sourceRoot":"","sources":["../../src/lib/cookies.ts"],"names":[],"mappings":"AACA,QAAA,MAAM,oBAAoB,aACd;IACR,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,EAAE,4DAqBJ,CAAC;AAEF,OAAO,EAAE,oBAAoB,EAAE,CAAC"}
@@ -0,0 +1,26 @@
1
+ // TODO REMOVE IN FAVOUR OF BrowserCookieStorage.get
2
+ const getWindowCookieValue = (requests) => {
3
+ const cookie = window.document.cookie;
4
+ if (!cookie)
5
+ return null;
6
+ const cookies = cookie.split(";");
7
+ const response = {};
8
+ for (const c of cookies) {
9
+ const [name, value] = c.trim().split("=");
10
+ const request = requests.find((r) => r.key === name);
11
+ if (value && request) {
12
+ try {
13
+ const decodeURIComponentValue = decodeURIComponent(value);
14
+ response[request.key] = request.parseJson
15
+ ? JSON.parse(decodeURIComponentValue)
16
+ : decodeURIComponentValue;
17
+ }
18
+ catch {
19
+ response[request.key] = value;
20
+ }
21
+ }
22
+ }
23
+ return response;
24
+ };
25
+ export { getWindowCookieValue };
26
+ //# sourceMappingURL=cookies.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cookies.js","sourceRoot":"","sources":["../../src/lib/cookies.ts"],"names":[],"mappings":"AAAA,oDAAoD;AACpD,MAAM,oBAAoB,GAAG,CAC3B,QAIG,EACH,EAAE;IACF,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;IACtC,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAClC,MAAM,QAAQ,GAAqD,EAAE,CAAC;IACtE,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC1C,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC;QACrD,IAAI,KAAK,IAAI,OAAO,EAAE,CAAC;YACrB,IAAI,CAAC;gBACH,MAAM,uBAAuB,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;gBAC1D,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,SAAS;oBACvC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,uBAAuB,CAAC;oBACrC,CAAC,CAAC,uBAAuB,CAAC;YAC9B,CAAC;YAAC,MAAM,CAAC;gBACP,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YAChC,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC,CAAC;AAEF,OAAO,EAAE,oBAAoB,EAAE,CAAC","sourcesContent":["// TODO REMOVE IN FAVOUR OF BrowserCookieStorage.get\nconst getWindowCookieValue = (\n requests: {\n key: string;\n window: Window;\n parseJson?: boolean;\n }[],\n) => {\n const cookie = window.document.cookie;\n if (!cookie) return null;\n const cookies = cookie.split(\";\");\n const response: Record<string, string | Record<string, unknown>> = {};\n for (const c of cookies) {\n const [name, value] = c.trim().split(\"=\");\n const request = requests.find((r) => r.key === name);\n if (value && request) {\n try {\n const decodeURIComponentValue = decodeURIComponent(value);\n response[request.key] = request.parseJson\n ? JSON.parse(decodeURIComponentValue)\n : decodeURIComponentValue;\n } catch {\n response[request.key] = value;\n }\n }\n }\n return response;\n};\n\nexport { getWindowCookieValue };\n"]}
@@ -6,7 +6,12 @@ declare const getOauthEndpoints: (oauthServer: string) => Promise<Endpoints>;
6
6
  * @param {DisplayMode} displayMode
7
7
  * @returns {string}
8
8
  */
9
- declare const generateState: (displayMode: DisplayMode, serverTokenExchange?: boolean) => string;
9
+ type GenerateStateInput = {
10
+ displayMode: DisplayMode;
11
+ serverTokenExchange?: boolean;
12
+ loginSuccessUrl?: string;
13
+ };
14
+ declare const generateState: ({ displayMode, serverTokenExchange, loginSuccessUrl, }: GenerateStateInput) => string;
10
15
  /**
11
16
  * parses the state string from the OAuth2 flow, decoding the display mode too
12
17
  * @param state
@@ -15,5 +20,6 @@ declare const generateState: (displayMode: DisplayMode, serverTokenExchange?: bo
15
20
  */
16
21
  declare const displayModeFromState: (state: string, sessionDisplayMode: DisplayMode | undefined) => DisplayMode | undefined;
17
22
  declare const serverTokenExchangeFromState: (state: string) => boolean | undefined;
18
- export { serverTokenExchangeFromState, getIssuerVariations, getOauthEndpoints, displayModeFromState, generateState, };
23
+ declare const loginSuccessUrlFromState: (state: string | null) => string | undefined;
24
+ export { serverTokenExchangeFromState, loginSuccessUrlFromState, getIssuerVariations, getOauthEndpoints, displayModeFromState, generateState, };
19
25
  //# sourceMappingURL=oauth.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../../src/lib/oauth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAuB,MAAM,YAAY,CAAC;AAG9E,QAAA,MAAM,mBAAmB,WAAY,MAAM,KAAG,MAAM,EAQnD,CAAC;AAMF,QAAA,MAAM,iBAAiB,gBAAuB,MAAM,KAAG,OAAO,CAAC,SAAS,CAmBvE,CAAC;AAEF;;;;GAIG;AACH,QAAA,MAAM,aAAa,gBACJ,WAAW,wBACF,OAAO,KAC5B,MAOF,CAAC;AAEF;;;;;GAKG;AACH,QAAA,MAAM,oBAAoB,UACjB,MAAM,sBACO,WAAW,GAAG,SAAS,KAC1C,WAAW,GAAG,SAQhB,CAAC;AAEF,QAAA,MAAM,4BAA4B,UAAW,MAAM,KAAG,OAAO,GAAG,SAQ/D,CAAC;AAEF,OAAO,EACL,4BAA4B,EAC5B,mBAAmB,EACnB,iBAAiB,EACjB,oBAAoB,EACpB,aAAa,GACd,CAAC"}
1
+ {"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../../src/lib/oauth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAuB,MAAM,YAAY,CAAC;AAG9E,QAAA,MAAM,mBAAmB,WAAY,MAAM,KAAG,MAAM,EAQnD,CAAC;AAMF,QAAA,MAAM,iBAAiB,gBAAuB,MAAM,KAAG,OAAO,CAAC,SAAS,CAmBvE,CAAC;AAEF;;;;GAIG;AACH,KAAK,kBAAkB,GAAG;IACxB,WAAW,EAAE,WAAW,CAAC;IACzB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AACF,QAAA,MAAM,aAAa,2DAIhB,kBAAkB,KAAG,MAQvB,CAAC;AAEF;;;;;GAKG;AACH,QAAA,MAAM,oBAAoB,UACjB,MAAM,sBACO,WAAW,GAAG,SAAS,KAC1C,WAAW,GAAG,SAQhB,CAAC;AAcF,QAAA,MAAM,4BAA4B,UAAW,MAAM,KAAG,OAAO,GAAG,SACvB,CAAC;AAC1C,QAAA,MAAM,wBAAwB,UAAW,MAAM,GAAG,IAAI,KAAG,MAAM,GAAG,SACT,CAAC;AAE1D,OAAO,EACL,4BAA4B,EAC5B,wBAAwB,EACxB,mBAAmB,EACnB,iBAAiB,EACjB,oBAAoB,EACpB,aAAa,GACd,CAAC"}
package/dist/lib/oauth.js CHANGED
@@ -24,16 +24,12 @@ const getOauthEndpoints = async (oauthServer) => {
24
24
  cache[oauthServer] = endpoints;
25
25
  return endpoints;
26
26
  };
27
- /**
28
- * creates a state string for the OAuth2 flow, encoding the display mode too for future use
29
- * @param {DisplayMode} displayMode
30
- * @returns {string}
31
- */
32
- const generateState = (displayMode, serverTokenExchange) => {
27
+ const generateState = ({ displayMode, serverTokenExchange, loginSuccessUrl, }) => {
33
28
  const jsonString = JSON.stringify({
34
29
  uuid: uuid(),
35
30
  displayMode,
36
31
  ...(serverTokenExchange ? { serverTokenExchange } : {}),
32
+ ...(loginSuccessUrl ? { loginSuccessUrl } : {}),
37
33
  });
38
34
  return btoa(jsonString);
39
35
  };
@@ -53,15 +49,17 @@ const displayModeFromState = (state, sessionDisplayMode) => {
53
49
  return sessionDisplayMode;
54
50
  }
55
51
  };
56
- const serverTokenExchangeFromState = (state) => {
52
+ const decodeState = (state) => {
57
53
  try {
58
54
  const jsonString = atob(state);
59
- return JSON.parse(jsonString).serverTokenExchange;
55
+ return JSON.parse(jsonString);
60
56
  }
61
57
  catch {
62
- console.error("Failed to parse serverTokenExchange from state:", state);
58
+ console.error("Failed to parse state string to json:", state);
63
59
  return undefined;
64
60
  }
65
61
  };
66
- export { serverTokenExchangeFromState, getIssuerVariations, getOauthEndpoints, displayModeFromState, generateState, };
62
+ const serverTokenExchangeFromState = (state) => decodeState(state)?.serverTokenExchange;
63
+ const loginSuccessUrlFromState = (state) => state ? decodeState(state)?.loginSuccessUrl : undefined;
64
+ export { serverTokenExchangeFromState, loginSuccessUrlFromState, getIssuerVariations, getOauthEndpoints, displayModeFromState, generateState, };
67
65
  //# sourceMappingURL=oauth.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"oauth.js","sourceRoot":"","sources":["../../src/lib/oauth.ts"],"names":[],"mappings":"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","sourcesContent":["import type { DisplayMode, Endpoints, OpenIdConfiguration } from \"@/types.js\";\nimport { v4 as uuid } from \"uuid\";\n\nconst getIssuerVariations = (issuer: string): string[] => {\n const issuerWithoutSlash = issuer.endsWith(\"/\")\n ? issuer.slice(0, issuer.length - 1)\n : issuer;\n\n const issuerWithSlash = `${issuerWithoutSlash}/`;\n\n return [issuerWithoutSlash, issuerWithSlash];\n};\n\nconst addSlashIfNeeded = (url: string): string =>\n url.endsWith(\"/\") ? url : `${url}/`;\n\nconst cache: { [key: string]: Endpoints } = {};\nconst getOauthEndpoints = async (oauthServer: string): Promise<Endpoints> => {\n if (cache[oauthServer]) {\n return cache[oauthServer];\n }\n const openIdConfigResponse = await fetch(\n `${addSlashIfNeeded(oauthServer)}.well-known/openid-configuration`,\n );\n const openIdConfig =\n (await openIdConfigResponse.json()) as OpenIdConfiguration;\n const endpoints: Endpoints = {\n jwks: openIdConfig.jwks_uri,\n auth: openIdConfig.authorization_endpoint,\n token: openIdConfig.token_endpoint,\n userinfo: openIdConfig.userinfo_endpoint,\n endsession: openIdConfig.end_session_endpoint,\n };\n\n cache[oauthServer] = endpoints;\n return endpoints;\n};\n\n/**\n * creates a state string for the OAuth2 flow, encoding the display mode too for future use\n * @param {DisplayMode} displayMode\n * @returns {string}\n */\nconst generateState = (\n displayMode: DisplayMode,\n serverTokenExchange?: boolean,\n): string => {\n const jsonString = JSON.stringify({\n uuid: uuid(),\n displayMode,\n ...(serverTokenExchange ? { serverTokenExchange } : {}),\n });\n return btoa(jsonString);\n};\n\n/**\n * parses the state string from the OAuth2 flow, decoding the display mode too\n * @param state\n * @param sessionDisplayMode\n * @returns { uuid: string, displayMode: DisplayMode }\n */\nconst displayModeFromState = (\n state: string,\n sessionDisplayMode: DisplayMode | undefined,\n): DisplayMode | undefined => {\n try {\n const jsonString = atob(state);\n return JSON.parse(jsonString).displayMode;\n } catch (e) {\n console.error(\"Failed to parse displayMode from state:\", state, e);\n return sessionDisplayMode;\n }\n};\n\nconst serverTokenExchangeFromState = (state: string): boolean | undefined => {\n try {\n const jsonString = atob(state);\n return JSON.parse(jsonString).serverTokenExchange;\n } catch {\n console.error(\"Failed to parse serverTokenExchange from state:\", state);\n return undefined;\n }\n};\n\nexport {\n serverTokenExchangeFromState,\n getIssuerVariations,\n getOauthEndpoints,\n displayModeFromState,\n generateState,\n};\n"]}
1
+ {"version":3,"file":"oauth.js","sourceRoot":"","sources":["../../src/lib/oauth.ts"],"names":[],"mappings":"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","sourcesContent":["import type { DisplayMode, Endpoints, OpenIdConfiguration } from \"@/types.js\";\nimport { v4 as uuid } from \"uuid\";\n\nconst getIssuerVariations = (issuer: string): string[] => {\n const issuerWithoutSlash = issuer.endsWith(\"/\")\n ? issuer.slice(0, issuer.length - 1)\n : issuer;\n\n const issuerWithSlash = `${issuerWithoutSlash}/`;\n\n return [issuerWithoutSlash, issuerWithSlash];\n};\n\nconst addSlashIfNeeded = (url: string): string =>\n url.endsWith(\"/\") ? url : `${url}/`;\n\nconst cache: { [key: string]: Endpoints } = {};\nconst getOauthEndpoints = async (oauthServer: string): Promise<Endpoints> => {\n if (cache[oauthServer]) {\n return cache[oauthServer];\n }\n const openIdConfigResponse = await fetch(\n `${addSlashIfNeeded(oauthServer)}.well-known/openid-configuration`,\n );\n const openIdConfig =\n (await openIdConfigResponse.json()) as OpenIdConfiguration;\n const endpoints: Endpoints = {\n jwks: openIdConfig.jwks_uri,\n auth: openIdConfig.authorization_endpoint,\n token: openIdConfig.token_endpoint,\n userinfo: openIdConfig.userinfo_endpoint,\n endsession: openIdConfig.end_session_endpoint,\n };\n\n cache[oauthServer] = endpoints;\n return endpoints;\n};\n\n/**\n * creates a state string for the OAuth2 flow, encoding the display mode too for future use\n * @param {DisplayMode} displayMode\n * @returns {string}\n */\ntype GenerateStateInput = {\n displayMode: DisplayMode;\n serverTokenExchange?: boolean;\n loginSuccessUrl?: string;\n};\nconst generateState = ({\n displayMode,\n serverTokenExchange,\n loginSuccessUrl,\n}: GenerateStateInput): string => {\n const jsonString = JSON.stringify({\n uuid: uuid(),\n displayMode,\n ...(serverTokenExchange ? { serverTokenExchange } : {}),\n ...(loginSuccessUrl ? { loginSuccessUrl } : {}),\n });\n return btoa(jsonString);\n};\n\n/**\n * parses the state string from the OAuth2 flow, decoding the display mode too\n * @param state\n * @param sessionDisplayMode\n * @returns { uuid: string, displayMode: DisplayMode }\n */\nconst displayModeFromState = (\n state: string,\n sessionDisplayMode: DisplayMode | undefined,\n): DisplayMode | undefined => {\n try {\n const jsonString = atob(state);\n return JSON.parse(jsonString).displayMode;\n } catch (e) {\n console.error(\"Failed to parse displayMode from state:\", state, e);\n return sessionDisplayMode;\n }\n};\n\nconst decodeState = (\n state: string,\n): { serverTokenExchange?: boolean; loginSuccessUrl?: string } | undefined => {\n try {\n const jsonString = atob(state);\n return JSON.parse(jsonString);\n } catch {\n console.error(\"Failed to parse state string to json:\", state);\n return undefined;\n }\n};\n\nconst serverTokenExchangeFromState = (state: string): boolean | undefined =>\n decodeState(state)?.serverTokenExchange;\nconst loginSuccessUrlFromState = (state: string | null): string | undefined =>\n state ? decodeState(state)?.loginSuccessUrl : undefined;\n\nexport {\n serverTokenExchangeFromState,\n loginSuccessUrlFromState,\n getIssuerVariations,\n getOauthEndpoints,\n displayModeFromState,\n generateState,\n};\n"]}
@@ -12,6 +12,7 @@ export type AuthConfigWithDefaults = {
12
12
  clientId: string;
13
13
  oauthServer: string;
14
14
  callbackUrl: string;
15
+ loginSuccessUrl?: string;
15
16
  loginUrl: string;
16
17
  logoutUrl: string;
17
18
  logoutCallbackUrl: string;
@@ -32,6 +33,7 @@ export type OptionalAuthConfig = Partial<AuthConfigWithDefaults | {
32
33
  };
33
34
  }> & {
34
35
  callbackUrl?: string;
36
+ loginSuccessUrl?: string;
35
37
  loginUrl?: string;
36
38
  logoutUrl?: string;
37
39
  logoutCallbackUrl?: string;
@@ -118,6 +120,7 @@ export declare const createCivicAuthPlugin: (authConfig: AuthConfig) => (nextCon
118
120
  _civic_auth_client_id: string;
119
121
  _civic_oauth_server: string;
120
122
  _civic_auth_callback_url: string;
123
+ _civic_auth_login_success_url: string | undefined;
121
124
  _civic_auth_challenge_url: string;
122
125
  _civic_auth_login_url: string;
123
126
  _civic_auth_logout_url: string;
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/nextjs/config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAGvC,OAAO,EAEL,KAAK,YAAY,EAEjB,KAAK,kBAAkB,EACxB,MAAM,uBAAuB,CAAC;AAO/B,MAAM,MAAM,mBAAmB,GAAG;IAChC,MAAM,EAAE,kBAAkB,CAAC;IAC3B,IAAI,EAAE,YAAY,CAAC;CACpB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,mBAAmB,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,OAAO,CACpC,sBAAsB,GACtB;IACE,OAAO,CAAC,EAAE;QACR,MAAM,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC;QACrC,IAAI,CAAC,EAAE,YAAY,CAAC;KACrB,CAAC;CACH,CACJ,GAAG;IAGF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG,kBAAkB,GAAG;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB,CAAC;AAKF;;GAEG;AACH,eAAO,MAAM,iBAAiB,EAAE,IAAI,CAAC,sBAAsB,EAAE,UAAU,CAgEtE,CAAC;AAEF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,iBAAiB,YACpB,OAAO,CAAC,UAAU,CAAC,KAC1B,sBAgDF,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,eAAO,MAAM,qBAAqB,eAAgB,UAAU,mBACrC,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAwDg/U,CAAC;6BAAsG,CAAC;;;sBAAke,CAAC;yBAA4H,CAAC;;;qBAA+H,CAAC;;;;;;;;;;;;;;;;;;iBAA8pE,CAAC;;;;;;;6BAAg6C,CAAC;sBAAoC,CAAC;;aAAoC,CAAC;;6BAA0D,CAAC;oBAA8B,CAAC;0BAAkE,CAAC;;qBAA2C,CAAC;mBAAiC,CAAC;;wBAA+C,CAAC;eAAmD,CAAC;iBAA4C,CAAC;2BAAyC,CAAC;;;;;;;;;yBAA4zC,CAAC;6BAAwC,CAAC;;;eAAkD,CAAC;mBAAuB,CAAC;;;;CADzzhB,CAAC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/nextjs/config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAGvC,OAAO,EAEL,KAAK,YAAY,EAEjB,KAAK,kBAAkB,EACxB,MAAM,uBAAuB,CAAC;AAO/B,MAAM,MAAM,mBAAmB,GAAG;IAChC,MAAM,EAAE,kBAAkB,CAAC;IAC3B,IAAI,EAAE,YAAY,CAAC;CACpB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,mBAAmB,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,OAAO,CACpC,sBAAsB,GACtB;IACE,OAAO,CAAC,EAAE;QACR,MAAM,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC;QACrC,IAAI,CAAC,EAAE,YAAY,CAAC;KACrB,CAAC;CACH,CACJ,GAAG;IAGF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG,kBAAkB,GAAG;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB,CAAC;AAKF;;GAEG;AACH,eAAO,MAAM,iBAAiB,EAAE,IAAI,CAAC,sBAAsB,EAAE,UAAU,CAiEtE,CAAC;AAEF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,iBAAiB,YACpB,OAAO,CAAC,UAAU,CAAC,KAC1B,sBAuFF,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,eAAO,MAAM,qBAAqB,eAAgB,UAAU,mBACrC,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAyDs+Q,CAAC;6BAAsG,CAAC;;;sBAAke,CAAC;yBAA4H,CAAC;;;qBAA+H,CAAC;;;;;;;;;;;;;;;;;;iBAA8pE,CAAC;;;;;;;6BAAg6C,CAAC;sBAAoC,CAAC;;aAAoC,CAAC;;6BAA0D,CAAC;oBAA8B,CAAC;0BAAkE,CAAC;;qBAA2C,CAAC;mBAAiC,CAAC;;wBAA+C,CAAC;eAAmD,CAAC;iBAA4C,CAAC;2BAAyC,CAAC;;;;;;;;;yBAA4zC,CAAC;6BAAwC,CAAC;;;eAAkD,CAAC;mBAAuB,CAAC;;;;CAD/yd,CAAC"}
@@ -13,6 +13,7 @@ const defaultCookiesMaxAge = 60 * 60; // 1 hour
13
13
  export const defaultAuthConfig = {
14
14
  oauthServer: DEFAULT_AUTH_SERVER,
15
15
  callbackUrl: "/api/auth/callback",
16
+ loginSuccessUrl: undefined, // By default, the user is sent to the redirect_url
16
17
  challengeUrl: "/api/auth/challenge",
17
18
  refreshUrl: "/api/auth/refresh",
18
19
  logoutUrl: "/api/auth/logout",
@@ -101,6 +102,7 @@ export const resolveAuthConfig = (config = {}) => {
101
102
  clientId: process.env._civic_auth_client_id,
102
103
  oauthServer: process.env._civic_oauth_server,
103
104
  callbackUrl: process.env._civic_auth_callback_url,
105
+ loginSuccessUrl: process.env._civic_auth_login_success_url,
104
106
  challengeUrl: process.env._civic_auth_challenge_url,
105
107
  loginUrl: process.env._civic_auth_login_url,
106
108
  logoutUrl: process.env._civic_auth_logout_url,
@@ -113,18 +115,47 @@ export const resolveAuthConfig = (config = {}) => {
113
115
  : undefined,
114
116
  basePath: process.env._civic_auth_base_path || "",
115
117
  });
116
- // Ensure "/api/auth/**" is always excluded
118
+ // Ensure "/api/auth/**" is always excluded, using the default exclude list
117
119
  const finalExclude = new Set([
118
120
  ...defaultAuthConfig.exclude,
119
121
  ...(configFromEnv.exclude || []),
120
122
  ...(config.exclude ?? []),
121
123
  ]);
122
- // Perform a deep merge of the configurations
124
+ // STEP 1: Perform an initial merge to incorporate all sources
123
125
  const mergedConfig = merge.withOptions({ mergeArrays: false }, defaultAuthConfig, configFromEnv, config);
124
- // Override the exclude list with the ensured list
126
+ // STEP 2: Determine the effective basePath from the merged configuration
127
+ const effectiveBasePath = mergedConfig.basePath || "";
128
+ // STEP 3: Apply basePath to cookie paths, respecting explicit user overrides
129
+ if (effectiveBasePath && mergedConfig.cookies) {
130
+ // Handle user cookie path
131
+ const userExplicitPath = config.cookies?.user?.path;
132
+ if (mergedConfig.cookies.user) {
133
+ if (userExplicitPath === undefined || userExplicitPath === "/") {
134
+ mergedConfig.cookies.user.path = effectiveBasePath;
135
+ }
136
+ // If userExplicitPath is defined and not '/', it was already set by the merge
137
+ }
138
+ // Handle token cookie paths
139
+ if (mergedConfig.cookies.tokens) {
140
+ Object.keys(mergedConfig.cookies.tokens).forEach((key) => {
141
+ const tokenKey = key;
142
+ const userExplicitTokenPath = config.cookies?.tokens?.[tokenKey]?.path;
143
+ if (userExplicitTokenPath === undefined ||
144
+ userExplicitTokenPath === "/") {
145
+ // Ensure the token itself exists in mergedConfig before assigning path
146
+ if (mergedConfig.cookies?.tokens?.[tokenKey]) {
147
+ mergedConfig.cookies.tokens[tokenKey].path = effectiveBasePath;
148
+ }
149
+ }
150
+ // If userExplicitTokenPath is defined and not '/', it was already set by the merge
151
+ });
152
+ }
153
+ }
154
+ // Apply the ensured exclude list
125
155
  mergedConfig.exclude = Array.from(finalExclude);
126
156
  logger.debug("Config from environment:", JSON.stringify(configFromEnv, null, 2));
127
- logger.debug("Resolved config:", JSON.stringify(mergedConfig, null, 2));
157
+ logger.debug("User config (input):", JSON.stringify(config, null, 2));
158
+ logger.debug("Resolved config (final):", JSON.stringify(mergedConfig, null, 2));
128
159
  if (mergedConfig.clientId === undefined) {
129
160
  throw new Error("Civic Auth client ID is required");
130
161
  }
@@ -204,6 +235,7 @@ export const createCivicAuthPlugin = (authConfig) => {
204
235
  _civic_auth_client_id: resolvedConfig.clientId,
205
236
  _civic_oauth_server: resolvedConfig.oauthServer,
206
237
  _civic_auth_callback_url: resolvedConfig.callbackUrl,
238
+ _civic_auth_login_success_url: resolvedConfig.loginSuccessUrl,
207
239
  _civic_auth_challenge_url: resolvedConfig.challengeUrl,
208
240
  _civic_auth_login_url: resolvedConfig.loginUrl,
209
241
  _civic_auth_logout_url: resolvedConfig.logoutUrl,
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/nextjs/config.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable turbo/no-undeclared-env-vars */\nimport type { NextConfig } from \"next\";\nimport { loggers } from \"@/lib/logger.js\";\nimport { withoutUndefined } from \"@/utils.js\";\nimport {\n CodeVerifier,\n type CookieConfig,\n OAuthTokenTypes,\n type TokensCookieConfig,\n} from \"@/shared/lib/types.js\";\nimport { DEFAULT_AUTH_SERVER } from \"@/constants.js\";\nimport { merge } from \"ts-deepmerge\";\nimport { sanitizeBasePath } from \"./utils.js\";\n\nconst logger = loggers.nextjs.handlers.auth;\n\nexport type CookiesConfigObject = {\n tokens: TokensCookieConfig;\n user: CookieConfig;\n};\n\n/**\n * Configuration values for Civic Auth.\n * Only clientId is required, all others are optional.\n */\nexport type AuthConfigWithDefaults = {\n clientId: string;\n oauthServer: string;\n callbackUrl: string;\n loginUrl: string;\n logoutUrl: string;\n logoutCallbackUrl: string;\n challengeUrl: string;\n refreshUrl: string;\n include: string[];\n exclude: string[];\n cookies: CookiesConfigObject;\n basePath?: string;\n};\n\n/**\n * All possible config values for Civic Auth\n */\nexport type OptionalAuthConfig = Partial<\n | AuthConfigWithDefaults\n | {\n cookies?: {\n tokens?: Partial<TokensCookieConfig>;\n user?: CookieConfig;\n };\n }\n> & {\n // Ensure TypeScript understands these properties are available\n // This doesn't change the public API, just helps TypeScript internally\n callbackUrl?: string;\n loginUrl?: string;\n logoutUrl?: string;\n logoutCallbackUrl?: string;\n challengeUrl?: string;\n refreshUrl?: string;\n include?: string[];\n exclude?: string[];\n basePath?: string;\n oauthServer?: string;\n};\n\n/**\n * Configuration values for Civic Auth.\n * Only clientId is required, all others are optional.\n */\nexport type AuthConfig = OptionalAuthConfig & {\n clientId: string;\n exclude?: string[];\n};\n\nconst defaultServerSecure = !(process.env.NODE_ENV === \"development\");\nconst defaultCookiesMaxAge = 60 * 60; // 1 hour\n\n/**\n * Default configuration values that will be used if not overridden\n */\nexport const defaultAuthConfig: Omit<AuthConfigWithDefaults, \"clientId\"> = {\n oauthServer: DEFAULT_AUTH_SERVER,\n callbackUrl: \"/api/auth/callback\",\n challengeUrl: \"/api/auth/challenge\",\n refreshUrl: \"/api/auth/refresh\",\n logoutUrl: \"/api/auth/logout\",\n logoutCallbackUrl: \"/api/auth/logoutcallback\",\n loginUrl: \"/\",\n include: [\"/**\"],\n exclude: [\"/api/auth/**\"],\n basePath: \"\",\n cookies: {\n tokens: {\n [OAuthTokenTypes.ID_TOKEN]: {\n secure: defaultServerSecure,\n httpOnly: true,\n sameSite: \"strict\",\n path: \"/\",\n maxAge: defaultCookiesMaxAge,\n },\n [OAuthTokenTypes.ACCESS_TOKEN]: {\n secure: defaultServerSecure,\n httpOnly: true,\n sameSite: \"strict\",\n path: \"/\",\n maxAge: defaultCookiesMaxAge,\n },\n [OAuthTokenTypes.REFRESH_TOKEN]: {\n secure: defaultServerSecure,\n httpOnly: true,\n sameSite: \"strict\",\n path: \"/\",\n maxAge: defaultCookiesMaxAge,\n },\n [OAuthTokenTypes.ACCESS_TOKEN_EXPIRES_AT]: {\n secure: defaultServerSecure,\n httpOnly: false, // we need this to be available client-side\n sameSite: \"strict\",\n path: \"/\",\n maxAge: defaultCookiesMaxAge,\n },\n [CodeVerifier.COOKIE_NAME]: {\n secure: defaultServerSecure,\n httpOnly: true,\n sameSite: \"strict\",\n path: \"/\",\n maxAge: defaultCookiesMaxAge,\n },\n [CodeVerifier.APP_URL]: {\n secure: defaultServerSecure,\n httpOnly: true,\n sameSite: \"strict\",\n path: \"/\",\n maxAge: defaultCookiesMaxAge,\n },\n },\n user: {\n secure: defaultServerSecure,\n httpOnly: false, // we need this to be available client-side\n sameSite: \"strict\",\n path: \"/\",\n maxAge: defaultCookiesMaxAge,\n },\n },\n};\n\n/**\n * Resolves the authentication configuration by combining:\n * 1. Default values\n * 2. Environment variables (set internally by the plugin)\n * 3. Explicitly passed configuration\n *\n * Config will be merged deeply, with arrays not merged, so that the\n * default include list (for example) [\"/*\"] will not be added\n *\n * Note: Developers should not set _civic_auth_* environment variables directly.\n * Instead, pass configuration to the createCivicAuthPlugin in next.config.js:\n *\n * @example\n * ```js\n * // next.config.js\n * export default createCivicAuthPlugin({\n * callbackUrl: '/custom/callback',\n * })\n * ```\n */\nexport const resolveAuthConfig = (\n config: Partial<AuthConfig> = {},\n): AuthConfigWithDefaults => {\n // Read configuration that was set by the plugin via environment variables\n const configFromEnv = withoutUndefined({\n clientId: process.env._civic_auth_client_id,\n oauthServer: process.env._civic_oauth_server,\n callbackUrl: process.env._civic_auth_callback_url,\n challengeUrl: process.env._civic_auth_challenge_url,\n loginUrl: process.env._civic_auth_login_url,\n logoutUrl: process.env._civic_auth_logout_url,\n logoutCallbackUrl: process.env._civic_auth_logout_callback_url,\n refreshUrl: process.env._civic_auth_refresh_url,\n include: process.env._civic_auth_includes?.split(\",\"),\n exclude: process.env._civic_auth_excludes?.split(\",\"),\n cookies: process.env._civic_auth_cookie_config\n ? JSON.parse(process.env._civic_auth_cookie_config)\n : undefined,\n basePath: process.env._civic_auth_base_path || \"\",\n }) as AuthConfig;\n\n // Ensure \"/api/auth/**\" is always excluded\n const finalExclude = new Set([\n ...defaultAuthConfig.exclude,\n ...(configFromEnv.exclude || []),\n ...(config.exclude ?? []),\n ]);\n\n // Perform a deep merge of the configurations\n const mergedConfig = merge.withOptions(\n { mergeArrays: false },\n defaultAuthConfig,\n configFromEnv,\n config,\n );\n\n // Override the exclude list with the ensured list\n mergedConfig.exclude = Array.from(finalExclude);\n\n logger.debug(\n \"Config from environment:\",\n JSON.stringify(configFromEnv, null, 2),\n );\n logger.debug(\"Resolved config:\", JSON.stringify(mergedConfig, null, 2));\n\n if (mergedConfig.clientId === undefined) {\n throw new Error(\"Civic Auth client ID is required\");\n }\n\n return mergedConfig as AuthConfigWithDefaults & { clientId: string };\n};\n\n/**\n * Creates a Next.js plugin that handles auth configuration.\n *\n * This is the main configuration point for the auth system.\n * Do not set _civic_auth_* environment variables directly - instead,\n * pass your configuration here.\n *\n * The only required field is clientId.\n *\n * Notes:\n * - If you provide explicit URLs, they will be used exactly as provided.\n * - Default URLs will automatically include the basePath from your Next.js config.\n *\n * @example\n * ```js\n * // next.config.js\n * export default createCivicAuthPlugin({\n * clientId: 'my-client-id',\n * });\n * ```\n *\n * @example\n * ```js\n * // next.config.js\n * export default createCivicAuthPlugin({\n * clientId: 'my-client-id',\n * callbackUrl: '/custom/callback',\n * loginUrl: '/custom/login',\n * logoutUrl: '/custom/logout',\n * logoutCallbackUrl: '/custom/logoutcallback',\n * include: ['/protected/*'],\n * exclude: ['/public/*']\n * })\n * ```\n *\n * The plugin sets internal environment variables that are used by\n * the auth system. These variables should not be set manually.\n */\nexport const createCivicAuthPlugin = (authConfig: AuthConfig) => {\n return (nextConfig?: NextConfig) => {\n logger.debug(\n \"createCivicAuthPlugin nextConfig\",\n JSON.stringify(nextConfig, null, 2),\n );\n\n // Extract basePath from Next.js config\n const basePath = sanitizeBasePath(nextConfig?.basePath || \"\");\n\n // Create a copy of default URLs with basePath added\n const defaultUrlsWithBasePath: Partial<AuthConfig> = {};\n\n // Only apply to URLs that aren't explicitly set in authConfig\n if (basePath) {\n if (!authConfig.callbackUrl)\n defaultUrlsWithBasePath.callbackUrl = `${basePath}/api/auth/callback`;\n if (!authConfig.challengeUrl)\n defaultUrlsWithBasePath.challengeUrl = `${basePath}/api/auth/challenge`;\n if (!authConfig.refreshUrl)\n defaultUrlsWithBasePath.refreshUrl = `${basePath}/api/auth/refresh`;\n if (!authConfig.logoutUrl)\n defaultUrlsWithBasePath.logoutUrl = `${basePath}/api/auth/logout`;\n if (!authConfig.logoutCallbackUrl)\n defaultUrlsWithBasePath.logoutCallbackUrl = `${basePath}/api/auth/logoutcallback`;\n if (!authConfig.loginUrl && authConfig.loginUrl !== \"\")\n defaultUrlsWithBasePath.loginUrl = basePath;\n }\n\n // Create final config with basePath and possibly modified URLs\n const resolvedConfig = resolveAuthConfig({\n ...defaultUrlsWithBasePath,\n ...authConfig,\n basePath,\n });\n\n return {\n ...nextConfig,\n env: {\n ...nextConfig?.env,\n // Internal environment variables - do not set these manually\n _civic_auth_client_id: resolvedConfig.clientId,\n _civic_oauth_server: resolvedConfig.oauthServer,\n _civic_auth_callback_url: resolvedConfig.callbackUrl,\n _civic_auth_challenge_url: resolvedConfig.challengeUrl,\n _civic_auth_login_url: resolvedConfig.loginUrl,\n _civic_auth_logout_url: resolvedConfig.logoutUrl,\n _civic_auth_logout_callback_url: resolvedConfig.logoutCallbackUrl,\n _civic_auth_refresh_url: resolvedConfig.refreshUrl,\n _civic_auth_includes: resolvedConfig.include.join(\",\"),\n _civic_auth_excludes: resolvedConfig.exclude.join(\",\"),\n _civic_auth_cookie_config: JSON.stringify(resolvedConfig.cookies),\n _civic_auth_base_path: resolvedConfig.basePath,\n },\n };\n };\n};\n"]}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/nextjs/config.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable turbo/no-undeclared-env-vars */\nimport type { NextConfig } from \"next\";\nimport { loggers } from \"@/lib/logger.js\";\nimport { withoutUndefined } from \"@/utils.js\";\nimport {\n CodeVerifier,\n type CookieConfig,\n OAuthTokenTypes,\n type TokensCookieConfig,\n} from \"@/shared/lib/types.js\";\nimport { DEFAULT_AUTH_SERVER } from \"@/constants.js\";\nimport { merge } from \"ts-deepmerge\";\nimport { sanitizeBasePath } from \"./utils.js\";\n\nconst logger = loggers.nextjs.handlers.auth;\n\nexport type CookiesConfigObject = {\n tokens: TokensCookieConfig;\n user: CookieConfig;\n};\n\n/**\n * Configuration values for Civic Auth.\n * Only clientId is required, all others are optional.\n */\nexport type AuthConfigWithDefaults = {\n clientId: string;\n oauthServer: string;\n callbackUrl: string; // where Civic's internal OAuth callback is hosted\n loginSuccessUrl?: string; // where the user should be sent after the entire login completes, including the token exchange\n loginUrl: string;\n logoutUrl: string;\n logoutCallbackUrl: string;\n challengeUrl: string;\n refreshUrl: string;\n include: string[];\n exclude: string[];\n cookies: CookiesConfigObject;\n basePath?: string;\n};\n\n/**\n * All possible config values for Civic Auth\n */\nexport type OptionalAuthConfig = Partial<\n | AuthConfigWithDefaults\n | {\n cookies?: {\n tokens?: Partial<TokensCookieConfig>;\n user?: CookieConfig;\n };\n }\n> & {\n // Ensure TypeScript understands these properties are available\n // This doesn't change the public API, just helps TypeScript internally\n callbackUrl?: string; // where Civic's internal OAuth callback is hosted\n loginSuccessUrl?: string; // where the user should be sent after the entire login completes, including the token exchange\n loginUrl?: string;\n logoutUrl?: string;\n logoutCallbackUrl?: string;\n challengeUrl?: string;\n refreshUrl?: string;\n include?: string[];\n exclude?: string[];\n basePath?: string;\n oauthServer?: string;\n};\n\n/**\n * Configuration values for Civic Auth.\n * Only clientId is required, all others are optional.\n */\nexport type AuthConfig = OptionalAuthConfig & {\n clientId: string;\n exclude?: string[];\n};\n\nconst defaultServerSecure = !(process.env.NODE_ENV === \"development\");\nconst defaultCookiesMaxAge = 60 * 60; // 1 hour\n\n/**\n * Default configuration values that will be used if not overridden\n */\nexport const defaultAuthConfig: Omit<AuthConfigWithDefaults, \"clientId\"> = {\n oauthServer: DEFAULT_AUTH_SERVER,\n callbackUrl: \"/api/auth/callback\",\n loginSuccessUrl: undefined, // By default, the user is sent to the redirect_url\n challengeUrl: \"/api/auth/challenge\",\n refreshUrl: \"/api/auth/refresh\",\n logoutUrl: \"/api/auth/logout\",\n logoutCallbackUrl: \"/api/auth/logoutcallback\",\n loginUrl: \"/\",\n include: [\"/**\"],\n exclude: [\"/api/auth/**\"],\n basePath: \"\",\n cookies: {\n tokens: {\n [OAuthTokenTypes.ID_TOKEN]: {\n secure: defaultServerSecure,\n httpOnly: true,\n sameSite: \"strict\",\n path: \"/\",\n maxAge: defaultCookiesMaxAge,\n },\n [OAuthTokenTypes.ACCESS_TOKEN]: {\n secure: defaultServerSecure,\n httpOnly: true,\n sameSite: \"strict\",\n path: \"/\",\n maxAge: defaultCookiesMaxAge,\n },\n [OAuthTokenTypes.REFRESH_TOKEN]: {\n secure: defaultServerSecure,\n httpOnly: true,\n sameSite: \"strict\",\n path: \"/\",\n maxAge: defaultCookiesMaxAge,\n },\n [OAuthTokenTypes.ACCESS_TOKEN_EXPIRES_AT]: {\n secure: defaultServerSecure,\n httpOnly: false, // we need this to be available client-side\n sameSite: \"strict\",\n path: \"/\",\n maxAge: defaultCookiesMaxAge,\n },\n [CodeVerifier.COOKIE_NAME]: {\n secure: defaultServerSecure,\n httpOnly: true,\n sameSite: \"strict\",\n path: \"/\",\n maxAge: defaultCookiesMaxAge,\n },\n [CodeVerifier.APP_URL]: {\n secure: defaultServerSecure,\n httpOnly: true,\n sameSite: \"strict\",\n path: \"/\",\n maxAge: defaultCookiesMaxAge,\n },\n },\n user: {\n secure: defaultServerSecure,\n httpOnly: false, // we need this to be available client-side\n sameSite: \"strict\",\n path: \"/\",\n maxAge: defaultCookiesMaxAge,\n },\n },\n};\n\n/**\n * Resolves the authentication configuration by combining:\n * 1. Default values\n * 2. Environment variables (set internally by the plugin)\n * 3. Explicitly passed configuration\n *\n * Config will be merged deeply, with arrays not merged, so that the\n * default include list (for example) [\"/*\"] will not be added\n *\n * Note: Developers should not set _civic_auth_* environment variables directly.\n * Instead, pass configuration to the createCivicAuthPlugin in next.config.js:\n *\n * @example\n * ```js\n * // next.config.js\n * export default createCivicAuthPlugin({\n * callbackUrl: '/custom/callback',\n * })\n * ```\n */\nexport const resolveAuthConfig = (\n config: Partial<AuthConfig> = {},\n): AuthConfigWithDefaults => {\n // Read configuration that was set by the plugin via environment variables\n const configFromEnv = withoutUndefined({\n clientId: process.env._civic_auth_client_id,\n oauthServer: process.env._civic_oauth_server,\n callbackUrl: process.env._civic_auth_callback_url,\n loginSuccessUrl: process.env._civic_auth_login_success_url,\n challengeUrl: process.env._civic_auth_challenge_url,\n loginUrl: process.env._civic_auth_login_url,\n logoutUrl: process.env._civic_auth_logout_url,\n logoutCallbackUrl: process.env._civic_auth_logout_callback_url,\n refreshUrl: process.env._civic_auth_refresh_url,\n include: process.env._civic_auth_includes?.split(\",\"),\n exclude: process.env._civic_auth_excludes?.split(\",\"),\n cookies: process.env._civic_auth_cookie_config\n ? JSON.parse(process.env._civic_auth_cookie_config)\n : undefined,\n basePath: process.env._civic_auth_base_path || \"\",\n }) as AuthConfig;\n\n // Ensure \"/api/auth/**\" is always excluded, using the default exclude list\n const finalExclude = new Set([\n ...defaultAuthConfig.exclude,\n ...(configFromEnv.exclude || []),\n ...(config.exclude ?? []),\n ]);\n\n // STEP 1: Perform an initial merge to incorporate all sources\n const mergedConfig = merge.withOptions(\n { mergeArrays: false },\n defaultAuthConfig,\n configFromEnv,\n config,\n );\n\n // STEP 2: Determine the effective basePath from the merged configuration\n const effectiveBasePath = mergedConfig.basePath || \"\";\n\n // STEP 3: Apply basePath to cookie paths, respecting explicit user overrides\n if (effectiveBasePath && mergedConfig.cookies) {\n // Handle user cookie path\n const userExplicitPath = config.cookies?.user?.path;\n if (mergedConfig.cookies.user) {\n if (userExplicitPath === undefined || userExplicitPath === \"/\") {\n mergedConfig.cookies.user.path = effectiveBasePath;\n }\n // If userExplicitPath is defined and not '/', it was already set by the merge\n }\n\n // Handle token cookie paths\n if (mergedConfig.cookies.tokens) {\n Object.keys(mergedConfig.cookies.tokens).forEach((key) => {\n const tokenKey = key as keyof TokensCookieConfig;\n const userExplicitTokenPath = config.cookies?.tokens?.[tokenKey]?.path;\n\n if (\n userExplicitTokenPath === undefined ||\n userExplicitTokenPath === \"/\"\n ) {\n // Ensure the token itself exists in mergedConfig before assigning path\n if (mergedConfig.cookies?.tokens?.[tokenKey]) {\n mergedConfig.cookies.tokens[tokenKey]!.path = effectiveBasePath;\n }\n }\n // If userExplicitTokenPath is defined and not '/', it was already set by the merge\n });\n }\n }\n\n // Apply the ensured exclude list\n mergedConfig.exclude = Array.from(finalExclude);\n\n logger.debug(\n \"Config from environment:\",\n JSON.stringify(configFromEnv, null, 2),\n );\n logger.debug(\"User config (input):\", JSON.stringify(config, null, 2));\n logger.debug(\n \"Resolved config (final):\",\n JSON.stringify(mergedConfig, null, 2),\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.logoutCallbackUrl)\n defaultUrlsWithBasePath.logoutCallbackUrl = `${basePath}/api/auth/logoutcallback`;\n if (!authConfig.loginUrl && authConfig.loginUrl !== \"\")\n defaultUrlsWithBasePath.loginUrl = basePath;\n }\n\n // Create final config with basePath and possibly modified URLs\n const resolvedConfig = resolveAuthConfig({\n ...defaultUrlsWithBasePath,\n ...authConfig,\n basePath,\n });\n\n return {\n ...nextConfig,\n env: {\n ...nextConfig?.env,\n // Internal environment variables - do not set these manually\n _civic_auth_client_id: resolvedConfig.clientId,\n _civic_oauth_server: resolvedConfig.oauthServer,\n _civic_auth_callback_url: resolvedConfig.callbackUrl,\n _civic_auth_login_success_url: resolvedConfig.loginSuccessUrl,\n _civic_auth_challenge_url: resolvedConfig.challengeUrl,\n _civic_auth_login_url: resolvedConfig.loginUrl,\n _civic_auth_logout_url: resolvedConfig.logoutUrl,\n _civic_auth_logout_callback_url: resolvedConfig.logoutCallbackUrl,\n _civic_auth_refresh_url: resolvedConfig.refreshUrl,\n _civic_auth_includes: resolvedConfig.include.join(\",\"),\n _civic_auth_excludes: resolvedConfig.exclude.join(\",\"),\n _civic_auth_cookie_config: JSON.stringify(resolvedConfig.cookies),\n _civic_auth_base_path: resolvedConfig.basePath,\n },\n };\n };\n};\n"]}
@@ -1,13 +1,15 @@
1
1
  import type { KeySetter } from "../shared/lib/types.js";
2
2
  import { type CookieConfig } from "../shared/lib/types.js";
3
- import { CookieStorage } from "../shared/lib/storage.js";
3
+ import { type CookiesConfigObject } from "./config.js";
4
+ import { CookieStorage, type CookieStorageSettings } from "../shared/lib/storage.js";
4
5
  /**
5
6
  * Clears all authentication cookies on server. Note, this can only be called by the server
6
7
  */
7
- declare const clearAuthCookies: () => Promise<void>;
8
+ declare const clearAuthCookies: (resolvedCookies?: CookiesConfigObject) => Promise<void>;
8
9
  declare class NextjsCookieStorage extends CookieStorage {
9
- config: Partial<Record<KeySetter, CookieConfig>>;
10
- constructor(config?: Partial<Record<KeySetter, CookieConfig>>);
10
+ config: Partial<Record<string, CookieConfig>>;
11
+ settings: CookieStorageSettings;
12
+ constructor(flatCookieConfig?: Partial<Record<string, CookieConfig>>);
11
13
  get(key: string): Promise<string | null>;
12
14
  set(key: KeySetter, value: string, cookieConfigOverride?: Partial<CookieConfig>): Promise<void>;
13
15
  delete(key: KeySetter): Promise<void>;
@@ -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;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAExD;;GAEG;AACH,QAAA,MAAM,gBAAgB,qBAGrB,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;IASV,MAAM,CAAC,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;CAI5C;AAED,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,CAAC"}
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;AAC1D,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EACL,aAAa,EACb,KAAK,qBAAqB,EAC3B,MAAM,yBAAyB,CAAC;AAGjC;;GAEG;AACH,QAAA,MAAM,gBAAgB,qBAA4B,mBAAmB,kBAapE,CAAC;AAEF,cAAM,mBAAoB,SAAQ,aAAa;IAE9B,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC;IAC9C,QAAQ,EAAE,qBAAqB,CAAC;gBAEnC,gBAAgB,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAI9D,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;IASV,MAAM,CAAC,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;CAO5C;AAED,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,CAAC"}
@@ -1,22 +1,28 @@
1
1
  import { cookies } from "next/headers.js";
2
2
  import {} from "../shared/lib/types.js";
3
- import { CookieStorage } from "../shared/lib/storage.js";
3
+ import {} from "./config.js";
4
+ import { CookieStorage, } from "../shared/lib/storage.js";
4
5
  import * as session from "../shared/lib/session.js";
5
6
  /**
6
7
  * Clears all authentication cookies on server. Note, this can only be called by the server
7
8
  */
8
- const clearAuthCookies = async () => {
9
- const cookieStorage = new NextjsCookieStorage(); // no cookie storage needed to simply clear it
9
+ const clearAuthCookies = async (resolvedCookies) => {
10
+ // Prepare a flat configuration, similar to what getCookieStorageWithUserOverrides does
11
+ let flatConfig = {};
12
+ if (resolvedCookies) {
13
+ if (resolvedCookies.tokens) {
14
+ flatConfig = { ...flatConfig, ...resolvedCookies.tokens };
15
+ }
16
+ if (resolvedCookies.user) {
17
+ flatConfig["user"] = resolvedCookies.user;
18
+ }
19
+ }
20
+ const cookieStorage = new NextjsCookieStorage(flatConfig);
10
21
  await session.clearAuthCookies(cookieStorage);
11
22
  };
12
23
  class NextjsCookieStorage extends CookieStorage {
13
- config;
14
- constructor(config = {}) {
15
- super({
16
- secure: true,
17
- httpOnly: true,
18
- });
19
- this.config = config;
24
+ constructor(flatCookieConfig) {
25
+ super(flatCookieConfig); // Assumes parent CookieStorage handles this flat config
20
26
  }
21
27
  async get(key) {
22
28
  const cookieStore = await cookies();
@@ -25,14 +31,16 @@ class NextjsCookieStorage extends CookieStorage {
25
31
  async set(key, value, cookieConfigOverride = {}) {
26
32
  const cookieStore = await cookies();
27
33
  const cookieSettings = this.config?.[key] || {
28
- ...this.settings,
34
+ ...(this.settings || {}),
29
35
  };
30
36
  const useCookieSettings = { ...cookieSettings, ...cookieConfigOverride };
31
37
  cookieStore.set(key, value, useCookieSettings);
32
38
  }
33
39
  async delete(key) {
34
40
  const cookieStore = await cookies();
35
- cookieStore.delete(key);
41
+ // Delete requires the path from config to match the path used for set
42
+ const path = this.config?.[key]?.path ?? this.settings?.path ?? "/";
43
+ cookieStore.delete({ name: key, path: path }); // Cast to any if delete options are strict
36
44
  }
37
45
  }
38
46
  export { clearAuthCookies, NextjsCookieStorage };
@@ -1 +1 @@
1
- {"version":3,"file":"cookies.js","sourceRoot":"","sources":["../../src/nextjs/cookies.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAG1C,OAAO,EAAqB,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,KAAK,OAAO,MAAM,yBAAyB,CAAC;AACnD;;GAEG;AACH,MAAM,gBAAgB,GAAG,KAAK,IAAI,EAAE;IAClC,MAAM,aAAa,GAAG,IAAI,mBAAmB,EAAE,CAAC,CAAC,8CAA8C;IAC/F,MAAM,OAAO,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC;AAChD,CAAC,CAAC;AAEF,MAAM,mBAAoB,SAAQ,aAAa;IAC1B;IAAnB,YAAmB,SAAmD,EAAE;QACtE,KAAK,CAAC;YACJ,MAAM,EAAE,IAAI;YACZ,QAAQ,EAAE,IAAI;SACf,CAAC,CAAC;QAJc,WAAM,GAAN,MAAM,CAA+C;IAKxE,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW;QACnB,MAAM,WAAW,GAAG,MAAM,OAAO,EAAE,CAAC;QACpC,OAAO,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,IAAI,IAAI,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,GAAG,CACP,GAAc,EACd,KAAa,EACb,uBAA8C,EAAE;QAEhD,MAAM,WAAW,GAAG,MAAM,OAAO,EAAE,CAAC;QACpC,MAAM,cAAc,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,GAAgB,CAAC,IAAI;YACxD,GAAG,IAAI,CAAC,QAAQ;SACjB,CAAC;QACF,MAAM,iBAAiB,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,oBAAoB,EAAE,CAAC;QACzE,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,iBAAiB,CAAC,CAAC;IACjD,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAc;QACzB,MAAM,WAAW,GAAG,MAAM,OAAO,EAAE,CAAC;QACpC,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;CACF;AAED,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,CAAC","sourcesContent":["import { cookies } from \"next/headers.js\";\n\nimport type { KeySetter } from \"@/shared/lib/types.js\";\nimport { type CookieConfig } from \"@/shared/lib/types.js\";\nimport { CookieStorage } from \"@/shared/lib/storage.js\";\nimport * as session from \"@/shared/lib/session.js\";\n/**\n * Clears all authentication cookies on server. Note, this can only be called by the server\n */\nconst clearAuthCookies = async () => {\n const cookieStorage = new NextjsCookieStorage(); // no cookie storage needed to simply clear it\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 const useCookieSettings = { ...cookieSettings, ...cookieConfigOverride };\n cookieStore.set(key, value, useCookieSettings);\n }\n\n async delete(key: KeySetter): Promise<void> {\n const cookieStore = await cookies();\n cookieStore.delete(key);\n }\n}\n\nexport { clearAuthCookies, NextjsCookieStorage };\n"]}
1
+ {"version":3,"file":"cookies.js","sourceRoot":"","sources":["../../src/nextjs/cookies.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAG1C,OAAO,EAAqB,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAA4B,MAAM,aAAa,CAAC;AACvD,OAAO,EACL,aAAa,GAEd,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,OAAO,MAAM,yBAAyB,CAAC;AAEnD;;GAEG;AACH,MAAM,gBAAgB,GAAG,KAAK,EAAE,eAAqC,EAAE,EAAE;IACvE,uFAAuF;IACvF,IAAI,UAAU,GAA0C,EAAE,CAAC;IAC3D,IAAI,eAAe,EAAE,CAAC;QACpB,IAAI,eAAe,CAAC,MAAM,EAAE,CAAC;YAC3B,UAAU,GAAG,EAAE,GAAG,UAAU,EAAE,GAAG,eAAe,CAAC,MAAM,EAAE,CAAC;QAC5D,CAAC;QACD,IAAI,eAAe,CAAC,IAAI,EAAE,CAAC;YACzB,UAAU,CAAC,MAAM,CAAC,GAAG,eAAe,CAAC,IAAI,CAAC;QAC5C,CAAC;IACH,CAAC;IACD,MAAM,aAAa,GAAG,IAAI,mBAAmB,CAAC,UAAU,CAAC,CAAC;IAC1D,MAAM,OAAO,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC;AAChD,CAAC,CAAC;AAEF,MAAM,mBAAoB,SAAQ,aAAa;IAK7C,YAAY,gBAAwD;QAClE,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,wDAAwD;IACnF,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW;QACnB,MAAM,WAAW,GAAG,MAAM,OAAO,EAAE,CAAC;QACpC,OAAO,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,IAAI,IAAI,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,GAAG,CACP,GAAc,EACd,KAAa,EACb,uBAA8C,EAAE;QAEhD,MAAM,WAAW,GAAG,MAAM,OAAO,EAAE,CAAC;QACpC,MAAM,cAAc,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,GAAa,CAAC,IAAI;YACrD,GAAG,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC;SACzB,CAAC;QACF,MAAM,iBAAiB,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,oBAAoB,EAAE,CAAC;QACzE,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,iBAAiB,CAAC,CAAC;IACjD,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAc;QACzB,MAAM,WAAW,GAAG,MAAM,OAAO,EAAE,CAAC;QACpC,sEAAsE;QACtE,MAAM,IAAI,GACR,IAAI,CAAC,MAAM,EAAE,CAAC,GAAa,CAAC,EAAE,IAAI,IAAI,IAAI,CAAC,QAAQ,EAAE,IAAI,IAAI,GAAG,CAAC;QACnE,WAAW,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,GAAa,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,2CAA2C;IACtG,CAAC;CACF;AAED,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,CAAC","sourcesContent":["import { cookies } from \"next/headers.js\";\n\nimport type { KeySetter } from \"@/shared/lib/types.js\";\nimport { type CookieConfig } from \"@/shared/lib/types.js\";\nimport { type CookiesConfigObject } from \"./config.js\";\nimport {\n CookieStorage,\n type CookieStorageSettings,\n} from \"@/shared/lib/storage.js\";\nimport * as session from \"@/shared/lib/session.js\";\n\n/**\n * Clears all authentication cookies on server. Note, this can only be called by the server\n */\nconst clearAuthCookies = async (resolvedCookies?: CookiesConfigObject) => {\n // Prepare a flat configuration, similar to what getCookieStorageWithUserOverrides does\n let flatConfig: Partial<Record<string, CookieConfig>> = {};\n if (resolvedCookies) {\n if (resolvedCookies.tokens) {\n flatConfig = { ...flatConfig, ...resolvedCookies.tokens };\n }\n if (resolvedCookies.user) {\n flatConfig[\"user\"] = resolvedCookies.user;\n }\n }\n const cookieStorage = new NextjsCookieStorage(flatConfig);\n await session.clearAuthCookies(cookieStorage);\n};\n\nclass NextjsCookieStorage extends CookieStorage {\n // Explicitly declare inherited properties for TypeScript\n declare public config: Partial<Record<string, CookieConfig>>;\n declare public settings: CookieStorageSettings;\n\n constructor(flatCookieConfig?: Partial<Record<string, CookieConfig>>) {\n super(flatCookieConfig); // Assumes parent CookieStorage handles this flat config\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 string] || {\n ...(this.settings || {}),\n };\n const useCookieSettings = { ...cookieSettings, ...cookieConfigOverride };\n cookieStore.set(key, value, useCookieSettings);\n }\n\n async delete(key: KeySetter): Promise<void> {\n const cookieStore = await cookies();\n // Delete requires the path from config to match the path used for set\n const path =\n this.config?.[key as string]?.path ?? this.settings?.path ?? \"/\";\n cookieStore.delete({ name: key as string, path: path }); // Cast to any if delete options are strict\n }\n}\n\nexport { clearAuthCookies, NextjsCookieStorage };\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"NextAuthProvider.d.ts","sourceRoot":"","sources":["../../../src/nextjs/providers/NextAuthProvider.tsx"],"names":[],"mappings":"AAWA,OAAO,EAEL,KAAK,sBAAsB,EAC5B,MAAM,oBAAoB,CAAC;AAe5B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAkBrE,KAAK,kCAAkC,GAAG,IAAI,CAC5C,iBAAiB,EACjB,UAAU,CACX,GAAG;IACF,cAAc,EAAE,sBAAsB,CAAC;CACxC,CAAC;AACF,KAAK,0BAA0B,GAAG,IAAI,CACpC,kCAAkC,EAClC,UAAU,GAAG,gBAAgB,GAAG,aAAa,CAC9C,CAAC;AAuJF,QAAA,MAAM,qBAAqB,2BAGxB,0BAA0B,qDA4C5B,CAAC;AAEF,OAAO,EAAE,qBAAqB,EAAE,KAAK,0BAA0B,EAAE,CAAC"}
1
+ {"version":3,"file":"NextAuthProvider.d.ts","sourceRoot":"","sources":["../../../src/nextjs/providers/NextAuthProvider.tsx"],"names":[],"mappings":"AAWA,OAAO,EAEL,KAAK,sBAAsB,EAC5B,MAAM,oBAAoB,CAAC;AAe5B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAkBrE,KAAK,kCAAkC,GAAG,IAAI,CAC5C,iBAAiB,EACjB,UAAU,CACX,GAAG;IACF,cAAc,EAAE,sBAAsB,CAAC;CACxC,CAAC;AACF,KAAK,0BAA0B,GAAG,IAAI,CACpC,kCAAkC,EAClC,UAAU,GAAG,gBAAgB,GAAG,aAAa,CAC9C,CAAC;AAuJF,QAAA,MAAM,qBAAqB,2BAGxB,0BAA0B,qDA8C5B,CAAC;AAEF,OAAO,EAAE,qBAAqB,EAAE,KAAK,0BAA0B,EAAE,CAAC"}
@@ -120,7 +120,7 @@ const CivicNextAuthProviderInternal = ({ children, ...props }) => {
120
120
  };
121
121
  const CivicNextAuthProvider = ({ children, ...props }) => {
122
122
  const resolvedConfig = resolveAuthConfig();
123
- const { clientId, oauthServer, callbackUrl, challengeUrl, logoutUrl, refreshUrl, logoutCallbackUrl, } = resolvedConfig;
123
+ const { clientId, oauthServer, callbackUrl, loginSuccessUrl, challengeUrl, logoutUrl, refreshUrl, logoutCallbackUrl, } = resolvedConfig;
124
124
  const [redirectUrl, setRedirectUrl] = useState("");
125
125
  useEffect(() => {
126
126
  if (typeof globalThis.window !== "undefined") {
@@ -128,7 +128,7 @@ const CivicNextAuthProvider = ({ children, ...props }) => {
128
128
  setRedirectUrl(resolveCallbackUrl(resolvedConfig, appUrl));
129
129
  }
130
130
  }, [callbackUrl, resolvedConfig]);
131
- return (_jsx(CivicAuthConfigProvider, { oauthServer: oauthServer, clientId: clientId, redirectUrl: redirectUrl, logoutRedirectUrl: logoutCallbackUrl, nonce: props?.nonce, challengeUrl: challengeUrl, refreshUrl: refreshUrl, logoutUrl: logoutUrl, logoutCallbackUrl: logoutCallbackUrl, children: _jsx(AuthStatusProvider, { children: _jsx(IframeProvider, { iframeMode: props.iframeMode, children: _jsx(CivicNextAuthProviderInternal, { ...props, resolvedConfig: resolvedConfig, children: children }) }) }) }));
131
+ return (_jsx(CivicAuthConfigProvider, { oauthServer: oauthServer, clientId: clientId, loginSuccessUrl: loginSuccessUrl, redirectUrl: redirectUrl, logoutRedirectUrl: logoutCallbackUrl, nonce: props?.nonce, challengeUrl: challengeUrl, refreshUrl: refreshUrl, logoutUrl: logoutUrl, logoutCallbackUrl: logoutCallbackUrl, children: _jsx(AuthStatusProvider, { children: _jsx(IframeProvider, { iframeMode: props.iframeMode, children: _jsx(CivicNextAuthProviderInternal, { ...props, resolvedConfig: resolvedConfig, children: children }) }) }) }));
132
132
  };
133
133
  export { CivicNextAuthProvider };
134
134
  //# sourceMappingURL=NextAuthProvider.js.map