@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.
- package/CHANGELOG.md +2 -0
- package/dist/lib/logger.d.ts +1 -0
- package/dist/lib/logger.d.ts.map +1 -1
- package/dist/lib/logger.js +1 -0
- package/dist/lib/logger.js.map +1 -1
- package/dist/nextjs/config.d.ts +29 -0
- package/dist/nextjs/config.d.ts.map +1 -1
- package/dist/nextjs/config.js +53 -24
- package/dist/nextjs/config.js.map +1 -1
- package/dist/nextjs/cookies.d.ts.map +1 -1
- package/dist/nextjs/cookies.js +16 -1
- package/dist/nextjs/cookies.js.map +1 -1
- package/dist/nextjs/hooks/useInitialAuthConfig.d.ts.map +1 -1
- package/dist/nextjs/hooks/useInitialAuthConfig.js +27 -15
- package/dist/nextjs/hooks/useInitialAuthConfig.js.map +1 -1
- package/dist/nextjs/middleware.d.ts.map +1 -1
- package/dist/nextjs/middleware.js +17 -6
- package/dist/nextjs/middleware.js.map +1 -1
- package/dist/nextjs/providers/NextAuthProviderClient.js +1 -1
- package/dist/nextjs/providers/NextAuthProviderClient.js.map +1 -1
- package/dist/nextjs/routeHandler.d.ts.map +1 -1
- package/dist/nextjs/routeHandler.js +0 -11
- package/dist/nextjs/routeHandler.js.map +1 -1
- package/dist/nextjs/utils.d.ts +3 -7
- package/dist/nextjs/utils.d.ts.map +1 -1
- package/dist/nextjs/utils.js +34 -25
- package/dist/nextjs/utils.js.map +1 -1
- package/dist/reactjs/core/GlobalAuthManager.d.ts.map +1 -1
- package/dist/reactjs/core/GlobalAuthManager.js +1 -1
- package/dist/reactjs/core/GlobalAuthManager.js.map +1 -1
- package/dist/shared/hooks/index.d.ts +0 -1
- package/dist/shared/hooks/index.d.ts.map +1 -1
- package/dist/shared/hooks/index.js +0 -1
- package/dist/shared/hooks/index.js.map +1 -1
- package/dist/shared/lib/BrowserAuthenticationRefresher.d.ts.map +1 -1
- package/dist/shared/lib/BrowserAuthenticationRefresher.js +8 -0
- package/dist/shared/lib/BrowserAuthenticationRefresher.js.map +1 -1
- package/dist/shared/lib/GenericAuthenticationRefresher.d.ts +1 -0
- package/dist/shared/lib/GenericAuthenticationRefresher.d.ts.map +1 -1
- package/dist/shared/lib/GenericAuthenticationRefresher.js +2 -0
- package/dist/shared/lib/GenericAuthenticationRefresher.js.map +1 -1
- package/dist/shared/lib/cookieUtils.d.ts +6 -0
- package/dist/shared/lib/cookieUtils.d.ts.map +1 -0
- package/dist/shared/lib/cookieUtils.js +21 -0
- package/dist/shared/lib/cookieUtils.js.map +1 -0
- package/dist/shared/version.d.ts +1 -1
- package/dist/shared/version.d.ts.map +1 -1
- package/dist/shared/version.js +1 -1
- package/dist/shared/version.js.map +1 -1
- package/dist/vanillajs/auth/BackendAuthenticationRefresher.d.ts.map +1 -1
- package/dist/vanillajs/auth/BackendAuthenticationRefresher.js +10 -2
- package/dist/vanillajs/auth/BackendAuthenticationRefresher.js.map +1 -1
- package/dist/vanillajs/auth/SessionManager.d.ts.map +1 -1
- package/dist/vanillajs/auth/SessionManager.js +10 -2
- package/dist/vanillajs/auth/SessionManager.js.map +1 -1
- package/dist/vanillajs/auth/TokenRefresher.d.ts +3 -0
- package/dist/vanillajs/auth/TokenRefresher.d.ts.map +1 -1
- package/dist/vanillajs/auth/TokenRefresher.js +24 -1
- package/dist/vanillajs/auth/TokenRefresher.js.map +1 -1
- package/package.json +1 -1
- package/dist/nextjs/hooks/useRefresh.d.ts +0 -5
- package/dist/nextjs/hooks/useRefresh.d.ts.map +0 -1
- package/dist/nextjs/hooks/useRefresh.js +0 -57
- package/dist/nextjs/hooks/useRefresh.js.map +0 -1
- package/dist/shared/hooks/useRefresh.d.ts +0 -6
- package/dist/shared/hooks/useRefresh.d.ts.map +0 -1
- package/dist/shared/hooks/useRefresh.js +0 -47
- 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
|
|
package/dist/lib/logger.d.ts
CHANGED
package/dist/lib/logger.d.ts.map
CHANGED
|
@@ -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
|
|
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"}
|
package/dist/lib/logger.js
CHANGED
package/dist/lib/logger.js.map
CHANGED
|
@@ -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;
|
|
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"]}
|
package/dist/nextjs/config.d.ts
CHANGED
|
@@ -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":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAGvC,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,kBAAkB,EACxB,MAAM,uBAAuB,CAAC;AAI/B,OAAO,EAEL,KAAK,mBAAmB,EACzB,MAAM,8BAA8B,CAAC;AAGtC,YAAY,EAAE,mBAAmB,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/nextjs/config.ts"],"names":[],"mappings":"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"}
|
package/dist/nextjs/config.js
CHANGED
|
@@ -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
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
|
-
//
|
|
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":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAGN,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AACrC,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EACL,wBAAwB,GAEzB,MAAM,8BAA8B,CAAC;AAKtC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;AAY5C,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,WAAW,EAAE,EAAE,WAAW,EAAE,oBAAoB,EAAE,aAAa,EAAE,IAAI,EAAE;IACvE,YAAY,EAAE,EAAE,WAAW,EAAE,qBAAqB,EAAE,aAAa,EAAE,IAAI,EAAE;IACzE,UAAU,EAAE,EAAE,WAAW,EAAE,mBAAmB,EAAE,aAAa,EAAE,IAAI,EAAE;IACrE,SAAS,EAAE,EAAE,WAAW,EAAE,kBAAkB,EAAE,aAAa,EAAE,IAAI,EAAE;IACnE,YAAY,EAAE,EAAE,WAAW,EAAE,iBAAiB,EAAE,aAAa,EAAE,IAAI,EAAE;IACrE,OAAO,EAAE,EAAE,WAAW,EAAE,gBAAgB,EAAE,aAAa,EAAE,IAAI,EAAE;CAChE,CAAC;AACF,MAAM,UAAU,GAAmC;IACjD,GAAG,gBAAgB;IACnB,iBAAiB,EAAE;QACjB,WAAW,EAAE,EAAE;QACf,aAAa,EAAE,IAAI;QACnB,eAAe,EAAE,IAAI;KACtB;IACD,QAAQ,EAAE;QACR,WAAW,EAAE,EAAE;QACf,aAAa,EAAE,IAAI;QACnB,eAAe,EAAE,IAAI;QACrB,UAAU,EAAE,IAAI;KACjB;CACF,CAAC;AAyEF;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAA6C;IACzE,WAAW,EAAE,mBAAmB;IAChC,sBAAsB;IACtB,4DAA4D;IAC5D,GAAI,MAAM,CAAC,WAAW,CACpB,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC;QACrD,GAAG;QACH,KAAK,CAAC,WAAW;KAClB,CAAC,CAGF;IACF,qBAAqB;IACrB,eAAe,EAAE,SAAS,EAAE,mDAAmD;IAC/E,QAAQ,EAAE,GAAG;IACb,iBAAiB,EAAE,GAAG;IACtB,OAAO,EAAE,CAAC,KAAK,CAAC;IAChB,OAAO,EAAE,CAAC,cAAc,CAAC;IACzB,QAAQ,EAAE,EAAE;IACZ,OAAO,EAAE,SAAS,EAAE,8DAA8D;IAClF,YAAY,EAAE,IAAI,EAAE,8BAA8B;IAClD,OAAO,EAAE,wBAAwB,EAAE;CACpC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,SAA8B,EAAE,EACR,EAAE;IAC1B,0EAA0E;IAC1E,kEAAkE;IAClE,MAAM,kBAAkB,GAAG,MAAM,CAAC,OAAO,CAAC;IAE1C,MAAM,aAAa,GAAG,gBAAgB,CAAC;QACrC,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,qBAAqB;QAC3C,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB;QAC5C,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,wBAAwB;QACjD,eAAe,EAAE,OAAO,CAAC,GAAG,CAAC,6BAA6B;QAC1D,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC,yBAAyB;QACnD,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,qBAAqB;QAC3C,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC,0BAA0B;QACpD,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,sBAAsB;QAC7C,iBAAiB,EAAE,OAAO,CAAC,GAAG,CAAC,+BAA+B;QAC9D,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,uBAAuB;QAC/C,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB;QACzC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,KAAK,CAAC,GAAG,CAAC;QACrD,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,KAAK,CAAC,GAAG,CAAC;QACrD,OAAO,EAAE,kBAAkB;YACzB,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,yBAAyB;gBACrC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC;gBACnD,CAAC,CAAC,SAAS;QACf,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,EAAE;QACjD,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB;QACzC,YAAY,EACV,OAAO,CAAC,GAAG,CAAC,yBAAyB,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;QACvE,sBAAsB,EAAE,OAAO,CAAC,GAAG,CAAC,oCAAoC;KACzE,CAAe,CAAC;IAEjB,2CAA2C;IAC3C,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC;QAC3B,GAAG,iBAAiB,CAAC,OAAO;QAC5B,GAAG,CAAC,aAAa,CAAC,OAAO,IAAI,EAAE,CAAC;QAChC,GAAG,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC;KAC1B,CAAC,CAAC;IAEH,4DAA4D;IAC5D,MAAM,eAAe,GAAG,MAAM,CAAC,OAAO,CAAC;IAEvC,6CAA6C;IAC7C,MAAM,YAAY,GAAG,KAAK,CAAC,WAAW,CACpC,EAAE,WAAW,EAAE,KAAK,EAAE,EACtB,iBAAiB,EACjB,aAAa,EACb,MAAM,CACP,CAAC;IAEF,kDAAkD;IAClD,YAAY,CAAC,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAEhD,6EAA6E;IAC7E,mEAAmE;IACnE,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,aAAa,CAAC,OAAO,IAAI,YAAY,CAAC,QAAQ,EAAE,CAAC;QACvE,YAAY,CAAC,OAAO,GAAG,wBAAwB,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;IACzE,CAAC;IAED,4FAA4F;IAC5F,IAAI,eAAe,IAAI,YAAY,CAAC,OAAO,EAAE,CAAC;QAC5C,YAAY,CAAC,OAAO,GAAG,KAAK,CAAC,WAAW,CACtC,EAAE,WAAW,EAAE,KAAK,EAAE,EACtB,YAAY,CAAC,OAAO,EACpB,eAAe,CAChB,CAAC;IACJ,CAAC;IAED,IAAI,YAAY,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACtD,CAAC;IAED,OAAO,YAA6D,CAAC;AACvE,CAAC,CAAC;AAEF;;GAEG;AACH,SAAS,mBAAmB,CAC1B,UAAsB,EACtB,QAAgB;IAEhB,MAAM,uBAAuB,GAA2B,EAAE,CAAC;IAE3D,IAAI,CAAC,QAAQ;QAAE,OAAO,uBAAuB,CAAC;IAE9C,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,EAAE;QACnD,uCAAuC;QACvC,MAAM,YAAY,GAAG,UAAU,CAAC,GAAuB,CAAC,CAAC;QACzD,IACE,YAAY,KAAK,SAAS;YAC1B,CAAC,CAAC,MAAM,CAAC,UAAU,IAAI,YAAY,KAAK,EAAE,CAAC,EAC3C,CAAC;YACD,OAAO;QACT,CAAC;QAED,uCAAuC;QACvC,MAAM,QAAQ,GAAG,MAAM,CAAC,eAAe;YACrC,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,GAAG,QAAQ,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;QAEvC,uBAAuB,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,OAAO,uBAA8C,CAAC;AACxD,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,UAAsB,EAAE,EAAE;IAC9D,OAAO,CAAC,UAAuB,EAAE,EAAE;QACjC,MAAM,CAAC,KAAK,CACV,kCAAkC,EAClC,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,CACpC,CAAC;QAEF,uCAAuC;QACvC,MAAM,QAAQ,GAAG,gBAAgB,CAAC,UAAU,EAAE,QAAQ,IAAI,EAAE,CAAC,CAAC;QAE9D,yDAAyD;QACzD,MAAM,uBAAuB,GAAG,mBAAmB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAE1E,+DAA+D;QAC/D,MAAM,cAAc,GAAG,iBAAiB,CAAC;YACvC,GAAG,uBAAuB;YAC1B,GAAG,UAAU;YACb,QAAQ;SACT,CAAC,CAAC;QAEH,OAAO;YACL,GAAG,UAAU;YACb,GAAG,EAAE;gBACH,GAAG,UAAU,EAAE,GAAG;gBAClB,6DAA6D;gBAC7D,qBAAqB,EAAE,cAAc,CAAC,QAAQ;gBAC9C,mBAAmB,EAAE,cAAc,CAAC,WAAW;gBAC/C,wBAAwB,EAAE,cAAc,CAAC,WAAW;gBACpD,6BAA6B,EAAE,cAAc,CAAC,eAAe;gBAC7D,yBAAyB,EAAE,cAAc,CAAC,YAAY;gBACtD,qBAAqB,EAAE,cAAc,CAAC,QAAQ;gBAC9C,0BAA0B,EAAE,cAAc,CAAC,YAAY;gBACvD,sBAAsB,EAAE,cAAc,CAAC,SAAS;gBAChD,+BAA+B,EAAE,cAAc,CAAC,iBAAiB;gBACjE,uBAAuB,EAAE,cAAc,CAAC,UAAU;gBAClD,oBAAoB,EAAE,cAAc,CAAC,OAAO;gBAC5C,oBAAoB,EAAE,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC;gBACtD,oBAAoB,EAAE,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC;gBACtD,yBAAyB,EAAE,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,OAAO,CAAC;gBACjE,qBAAqB,EAAE,cAAc,CAAC,QAAQ;gBAC9C,oBAAoB,EAAE,cAAc,CAAC,OAAO;gBAC5C,yBAAyB,EAAE,cAAc,CAAC,YAAY,CAAC,QAAQ,EAAE;aAClE;SACF,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC,CAAC","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":"
|
|
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"}
|
package/dist/nextjs/cookies.js
CHANGED
|
@@ -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
|
-
|
|
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":"AAAA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;
|
|
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;
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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;
|
|
1
|
+
{"version":3,"file":"useInitialAuthConfig.js","sourceRoot":"","sources":["../../../src/nextjs/hooks/useInitialAuthConfig.ts"],"names":[],"mappings":"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","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;
|
|
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
|
-
//
|
|
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
|