@civic/auth 0.10.0-beta.0 → 0.10.0-beta.10
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 +5 -0
- package/README.md +1 -0
- package/dist/browser/storage.d.ts +1 -0
- package/dist/browser/storage.d.ts.map +1 -1
- package/dist/browser/storage.js +3 -0
- package/dist/browser/storage.js.map +1 -1
- package/dist/lib/logger.d.ts +2 -0
- package/dist/lib/logger.d.ts.map +1 -1
- package/dist/lib/logger.js +2 -0
- package/dist/lib/logger.js.map +1 -1
- package/dist/nextjs/config.d.ts +35 -3
- package/dist/nextjs/config.d.ts.map +1 -1
- package/dist/nextjs/config.js +76 -25
- package/dist/nextjs/config.js.map +1 -1
- package/dist/nextjs/cookies.d.ts +2 -1
- package/dist/nextjs/cookies.d.ts.map +1 -1
- package/dist/nextjs/cookies.js +35 -5
- package/dist/nextjs/cookies.js.map +1 -1
- package/dist/nextjs/hooks/useInitialAuthConfig.d.ts.map +1 -1
- package/dist/nextjs/hooks/useInitialAuthConfig.js +36 -13
- package/dist/nextjs/hooks/useInitialAuthConfig.js.map +1 -1
- package/dist/nextjs/middleware.d.ts +2 -1
- package/dist/nextjs/middleware.d.ts.map +1 -1
- package/dist/nextjs/middleware.js +59 -59
- package/dist/nextjs/middleware.js.map +1 -1
- package/dist/nextjs/providers/NextAuthProvider.d.ts.map +1 -1
- package/dist/nextjs/providers/NextAuthProvider.js +8 -5
- package/dist/nextjs/providers/NextAuthProvider.js.map +1 -1
- package/dist/nextjs/providers/NextAuthProviderClient.d.ts +3 -2
- package/dist/nextjs/providers/NextAuthProviderClient.d.ts.map +1 -1
- package/dist/nextjs/providers/NextAuthProviderClient.js +3 -3
- package/dist/nextjs/providers/NextAuthProviderClient.js.map +1 -1
- package/dist/nextjs/providers/ServerUserContext.d.ts +6 -1
- package/dist/nextjs/providers/ServerUserContext.d.ts.map +1 -1
- package/dist/nextjs/providers/ServerUserContext.js.map +1 -1
- package/dist/nextjs/routeHandler.d.ts +3 -0
- package/dist/nextjs/routeHandler.d.ts.map +1 -1
- package/dist/nextjs/routeHandler.js +16 -20
- package/dist/nextjs/routeHandler.js.map +1 -1
- package/dist/nextjs/utils.d.ts +30 -6
- package/dist/nextjs/utils.d.ts.map +1 -1
- package/dist/nextjs/utils.js +159 -35
- package/dist/nextjs/utils.js.map +1 -1
- package/dist/reactjs/core/GlobalAuthManager.d.ts +6 -2
- package/dist/reactjs/core/GlobalAuthManager.d.ts.map +1 -1
- package/dist/reactjs/core/GlobalAuthManager.js +26 -7
- package/dist/reactjs/core/GlobalAuthManager.js.map +1 -1
- package/dist/reactjs/hooks/useUser.d.ts.map +1 -1
- package/dist/reactjs/hooks/useUser.js +83 -130
- package/dist/reactjs/hooks/useUser.js.map +1 -1
- package/dist/server/ServerAuthenticationResolver.d.ts +3 -2
- package/dist/server/ServerAuthenticationResolver.d.ts.map +1 -1
- package/dist/server/ServerAuthenticationResolver.js +23 -6
- package/dist/server/ServerAuthenticationResolver.js.map +1 -1
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server/login.d.ts +2 -1
- package/dist/server/login.d.ts.map +1 -1
- package/dist/server/login.js.map +1 -1
- package/dist/server/session.d.ts +4 -3
- package/dist/server/session.d.ts.map +1 -1
- package/dist/server/session.js.map +1 -1
- package/dist/server/users.d.ts +4 -3
- package/dist/server/users.d.ts.map +1 -1
- package/dist/server/users.js.map +1 -1
- package/dist/services/types.d.ts +1 -1
- package/dist/services/types.d.ts.map +1 -1
- package/dist/services/types.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 +14 -6
- package/dist/shared/lib/BrowserAuthenticationRefresher.js.map +1 -1
- package/dist/shared/lib/BrowserCookieStorage.d.ts.map +1 -1
- package/dist/shared/lib/BrowserCookieStorage.js +5 -1
- package/dist/shared/lib/BrowserCookieStorage.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/UserSession.d.ts +4 -3
- package/dist/shared/lib/UserSession.d.ts.map +1 -1
- package/dist/shared/lib/UserSession.js +4 -0
- package/dist/shared/lib/UserSession.js.map +1 -1
- package/dist/shared/lib/cookieConfig.d.ts +1 -1
- package/dist/shared/lib/cookieConfig.d.ts.map +1 -1
- package/dist/shared/lib/cookieConfig.js +2 -1
- package/dist/shared/lib/cookieConfig.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/lib/session.d.ts +2 -1
- package/dist/shared/lib/session.d.ts.map +1 -1
- package/dist/shared/lib/session.js +11 -2
- package/dist/shared/lib/session.js.map +1 -1
- package/dist/shared/lib/util.d.ts +2 -2
- package/dist/shared/lib/util.d.ts.map +1 -1
- package/dist/shared/lib/util.js +4 -4
- package/dist/shared/lib/util.js.map +1 -1
- 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/types.d.ts +4 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/vanillajs/auth/BackendAuthenticationRefresher.d.ts +4 -3
- package/dist/vanillajs/auth/BackendAuthenticationRefresher.d.ts.map +1 -1
- package/dist/vanillajs/auth/BackendAuthenticationRefresher.js +42 -21
- package/dist/vanillajs/auth/BackendAuthenticationRefresher.js.map +1 -1
- package/dist/vanillajs/auth/CivicAuth.d.ts.map +1 -1
- package/dist/vanillajs/auth/CivicAuth.js +2 -2
- package/dist/vanillajs/auth/CivicAuth.js.map +1 -1
- package/dist/vanillajs/auth/SessionManager.d.ts.map +1 -1
- package/dist/vanillajs/auth/SessionManager.js +23 -16
- 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 +27 -4
- package/dist/vanillajs/auth/TokenRefresher.js.map +1 -1
- package/dist/vanillajs/auth/config/ConfigProcessor.d.ts.map +1 -1
- package/dist/vanillajs/auth/config/ConfigProcessor.js +3 -1
- package/dist/vanillajs/auth/config/ConfigProcessor.js.map +1 -1
- package/dist/vanillajs/auth/handlers/IframeAuthHandler.d.ts.map +1 -1
- package/dist/vanillajs/auth/handlers/IframeAuthHandler.js +18 -0
- package/dist/vanillajs/auth/handlers/IframeAuthHandler.js.map +1 -1
- package/dist/vanillajs/auth/types/AuthTypes.d.ts +3 -0
- package/dist/vanillajs/auth/types/AuthTypes.d.ts.map +1 -1
- package/dist/vanillajs/auth/types/AuthTypes.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
|
@@ -34,7 +34,7 @@ export declare function createReactRouterCookieConfigWithUserStorage(options?: C
|
|
|
34
34
|
/**
|
|
35
35
|
* Creates cookie configuration optimized for NextJS
|
|
36
36
|
*/
|
|
37
|
-
export declare function createNextJSCookieConfig(): CookiesConfigObject;
|
|
37
|
+
export declare function createNextJSCookieConfig(basePath?: string): CookiesConfigObject;
|
|
38
38
|
/**
|
|
39
39
|
* Creates cookie configuration optimized for React Router (iframe compatibility)
|
|
40
40
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cookieConfig.d.ts","sourceRoot":"","sources":["../../../src/shared/lib/cookieConfig.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,WAAW,EACX,KAAK,YAAY,EACjB,KAAK,kBAAkB,EACxB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,mBAAmB;IAClC,oDAAoD;IACpD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,qCAAqC;IACrC,QAAQ,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;IACrC,kDAAkD;IAClD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,4CAA4C;IAC5C,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uBAAuB;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,kBAAkB,CAAC;IAC3B,IAAI,EAAE,YAAY,CAAC;CACpB;AAED,MAAM,WAAW,8BAA8B;IAC7C,MAAM,EAAE,kBAAkB,GAAG;QAC3B,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,YAAY,CAAC;KAClC,CAAC;IACF,IAAI,EAAE,YAAY,CAAC;CACpB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,GAAE,mBAAwB,GAChC,mBAAmB,CAkDrB;AAED;;GAEG;AACH,wBAAgB,4CAA4C,CAC1D,OAAO,GAAE,mBAAwB,GAChC,8BAA8B,CAsBhC;AAED;;GAEG;AACH,wBAAgB,wBAAwB,
|
|
1
|
+
{"version":3,"file":"cookieConfig.d.ts","sourceRoot":"","sources":["../../../src/shared/lib/cookieConfig.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,WAAW,EACX,KAAK,YAAY,EACjB,KAAK,kBAAkB,EACxB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,mBAAmB;IAClC,oDAAoD;IACpD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,qCAAqC;IACrC,QAAQ,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;IACrC,kDAAkD;IAClD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,4CAA4C;IAC5C,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uBAAuB;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,kBAAkB,CAAC;IAC3B,IAAI,EAAE,YAAY,CAAC;CACpB;AAED,MAAM,WAAW,8BAA8B;IAC7C,MAAM,EAAE,kBAAkB,GAAG;QAC3B,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,YAAY,CAAC;KAClC,CAAC;IACF,IAAI,EAAE,YAAY,CAAC;CACpB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,GAAE,mBAAwB,GAChC,mBAAmB,CAkDrB;AAED;;GAEG;AACH,wBAAgB,4CAA4C,CAC1D,OAAO,GAAE,mBAAwB,GAChC,8BAA8B,CAsBhC;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,CAAC,EAAE,MAAM,GAChB,mBAAmB,CAQrB;AAED;;GAEG;AACH,wBAAgB,6BAA6B,IAAI,8BAA8B,CAM9E;AAED;;GAEG;AACH,wBAAgB,6BAA6B,IAAI,mBAAmB,CAKnE"}
|
|
@@ -70,11 +70,12 @@ export function createReactRouterCookieConfigWithUserStorage(options = {}) {
|
|
|
70
70
|
/**
|
|
71
71
|
* Creates cookie configuration optimized for NextJS
|
|
72
72
|
*/
|
|
73
|
-
export function createNextJSCookieConfig() {
|
|
73
|
+
export function createNextJSCookieConfig(basePath) {
|
|
74
74
|
const isProduction = process.env.NODE_ENV !== "development";
|
|
75
75
|
return createCookieConfig({
|
|
76
76
|
secure: isProduction,
|
|
77
77
|
sameSite: "strict",
|
|
78
|
+
path: basePath || "/", // Use basePath as cookie path
|
|
78
79
|
});
|
|
79
80
|
}
|
|
80
81
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cookieConfig.js","sourceRoot":"","sources":["../../../src/shared/lib/cookieConfig.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EACL,YAAY,EACZ,eAAe,EACf,WAAW,GAGZ,MAAM,YAAY,CAAC;AA6BpB;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAChC,UAA+B,EAAE;IAEjC,MAAM,EACJ,MAAM,GAAG,IAAI,EACb,QAAQ,GAAG,QAAQ,EACnB,aAAa,GAAG,EAAE,GAAG,EAAE,EAAE,SAAS;IAClC,kBAAkB,GAAG,sBAAsB,EAC3C,QAAQ,GAAG,IAAI,EACf,IAAI,GAAG,GAAG,GACX,GAAG,OAAO,CAAC;IAEZ,MAAM,gBAAgB,GAAiB;QACrC,MAAM;QACN,QAAQ;QACR,IAAI;QACJ,MAAM,EAAE,aAAa;KACtB,CAAC;IAEF,OAAO;QACL,MAAM,EAAE;YACN,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE;gBAC1B,GAAG,gBAAgB;gBACnB,QAAQ;aACT;YACD,CAAC,eAAe,CAAC,YAAY,CAAC,EAAE;gBAC9B,GAAG,gBAAgB;gBACnB,QAAQ;aACT;YACD,CAAC,eAAe,CAAC,aAAa,CAAC,EAAE;gBAC/B,GAAG,gBAAgB;gBACnB,QAAQ;gBACR,MAAM,EAAE,kBAAkB;aAC3B;YACD,CAAC,eAAe,CAAC,uBAAuB,CAAC,EAAE;gBACzC,GAAG,gBAAgB;gBACnB,QAAQ,EAAE,KAAK,EAAE,2CAA2C;aAC7D;YACD,CAAC,YAAY,CAAC,WAAW,CAAC,EAAE;gBAC1B,GAAG,gBAAgB;gBACnB,QAAQ;aACT;YACD,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE;gBACtB,GAAG,gBAAgB;gBACnB,QAAQ;aACT;SACF;QACD,IAAI,EAAE;YACJ,GAAG,gBAAgB;YACnB,QAAQ,EAAE,KAAK,EAAE,2CAA2C;SAC7D;KACF,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,4CAA4C,CAC1D,UAA+B,EAAE;IAEjC,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAChD,MAAM,EACJ,MAAM,GAAG,IAAI,EACb,QAAQ,GAAG,QAAQ,EACnB,aAAa,GAAG,EAAE,GAAG,EAAE,EAAE,SAAS;IAClC,IAAI,GAAG,GAAG,GACX,GAAG,OAAO,CAAC;IAEZ,OAAO;QACL,GAAG,WAAW;QACd,MAAM,EAAE;YACN,GAAG,WAAW,CAAC,MAAM;YACrB,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE;gBAClB,MAAM;gBACN,QAAQ;gBACR,IAAI;gBACJ,MAAM,EAAE,aAAa;gBACrB,QAAQ,EAAE,KAAK,EAAE,2CAA2C;aAC7D;SACF;KACF,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,wBAAwB;
|
|
1
|
+
{"version":3,"file":"cookieConfig.js","sourceRoot":"","sources":["../../../src/shared/lib/cookieConfig.ts"],"names":[],"mappings":"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","sourcesContent":["import { MAX_COOKIE_AGE_SECONDS } from \"@/constants.js\";\nimport {\n CodeVerifier,\n OAuthTokenTypes,\n UserStorage,\n type CookieConfig,\n type TokensCookieConfig,\n} from \"./types.js\";\n\nexport interface CookieConfigOptions {\n /** Whether cookies should be secure (HTTPS only) */\n secure?: boolean;\n /** SameSite attribute for cookies */\n sameSite?: \"strict\" | \"lax\" | \"none\";\n /** Default max age in seconds for most cookies */\n defaultMaxAge?: number;\n /** Max age in seconds for refresh tokens */\n refreshTokenMaxAge?: number;\n /** Whether to use httpOnly for most cookies */\n httpOnly?: boolean;\n /** Path for cookies */\n path?: string;\n}\n\nexport interface CookiesConfigObject {\n tokens: TokensCookieConfig;\n user: CookieConfig;\n}\n\nexport interface ReactRouterCookiesConfigObject {\n tokens: TokensCookieConfig & {\n [UserStorage.USER]: CookieConfig;\n };\n user: CookieConfig;\n}\n\n/**\n * Creates a standardized cookie configuration for NextJS\n */\nexport function createCookieConfig(\n options: CookieConfigOptions = {},\n): CookiesConfigObject {\n const {\n secure = true,\n sameSite = \"strict\",\n defaultMaxAge = 60 * 60, // 1 hour\n refreshTokenMaxAge = MAX_COOKIE_AGE_SECONDS,\n httpOnly = true,\n path = \"/\",\n } = options;\n\n const baseCookieConfig: CookieConfig = {\n secure,\n sameSite,\n path,\n maxAge: defaultMaxAge,\n };\n\n return {\n tokens: {\n [OAuthTokenTypes.ID_TOKEN]: {\n ...baseCookieConfig,\n httpOnly,\n },\n [OAuthTokenTypes.ACCESS_TOKEN]: {\n ...baseCookieConfig,\n httpOnly,\n },\n [OAuthTokenTypes.REFRESH_TOKEN]: {\n ...baseCookieConfig,\n httpOnly,\n maxAge: refreshTokenMaxAge,\n },\n [OAuthTokenTypes.OIDC_SESSION_EXPIRES_AT]: {\n ...baseCookieConfig,\n httpOnly: false, // we need this to be available client-side\n },\n [CodeVerifier.COOKIE_NAME]: {\n ...baseCookieConfig,\n httpOnly,\n },\n [CodeVerifier.APP_URL]: {\n ...baseCookieConfig,\n httpOnly,\n },\n },\n user: {\n ...baseCookieConfig,\n httpOnly: false, // we need this to be available client-side\n },\n };\n}\n\n/**\n * Creates a standardized cookie configuration for React Router with UserStorage\n */\nexport function createReactRouterCookieConfigWithUserStorage(\n options: CookieConfigOptions = {},\n): ReactRouterCookiesConfigObject {\n const basicConfig = createCookieConfig(options);\n const {\n secure = true,\n sameSite = \"strict\",\n defaultMaxAge = 60 * 60, // 1 hour\n path = \"/\",\n } = options;\n\n return {\n ...basicConfig,\n tokens: {\n ...basicConfig.tokens,\n [UserStorage.USER]: {\n secure,\n sameSite,\n path,\n maxAge: defaultMaxAge,\n httpOnly: false, // we need this to be available client-side\n },\n },\n };\n}\n\n/**\n * Creates cookie configuration optimized for NextJS\n */\nexport function createNextJSCookieConfig(\n basePath?: string,\n): CookiesConfigObject {\n const isProduction = process.env.NODE_ENV !== \"development\";\n\n return createCookieConfig({\n secure: isProduction,\n sameSite: \"strict\",\n path: basePath || \"/\", // Use basePath as cookie path\n });\n}\n\n/**\n * Creates cookie configuration optimized for React Router (iframe compatibility)\n */\nexport function createReactRouterCookieConfig(): ReactRouterCookiesConfigObject {\n return createReactRouterCookieConfigWithUserStorage({\n secure: true, // Required for iframe compatibility\n sameSite: \"none\", // Required for cross-site iframe requests\n refreshTokenMaxAge: 60 * 60 * 24 * 30, // 30 days for refresh token\n });\n}\n\n/**\n * Creates cookie configuration for development environments\n */\nexport function createDevelopmentCookieConfig(): CookiesConfigObject {\n return createCookieConfig({\n secure: false,\n sameSite: \"lax\",\n });\n}\n"]}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility function to extract a specific cookie value from raw cookie header.
|
|
3
|
+
* Returns the first occurrence which should be the most specific path.
|
|
4
|
+
*/
|
|
5
|
+
export declare function extractCookieFromRawHeader(cookieHeader: string | null, key: string): string | null;
|
|
6
|
+
//# sourceMappingURL=cookieUtils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cookieUtils.d.ts","sourceRoot":"","sources":["../../../src/shared/lib/cookieUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,YAAY,EAAE,MAAM,GAAG,IAAI,EAC3B,GAAG,EAAE,MAAM,GACV,MAAM,GAAG,IAAI,CAcf"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility function to extract a specific cookie value from raw cookie header.
|
|
3
|
+
* Returns the first occurrence which should be the most specific path.
|
|
4
|
+
*/
|
|
5
|
+
export function extractCookieFromRawHeader(cookieHeader, key) {
|
|
6
|
+
try {
|
|
7
|
+
if (!cookieHeader)
|
|
8
|
+
return null;
|
|
9
|
+
// Parse first occurrence from raw header (most specific path)
|
|
10
|
+
const firstMatch = cookieHeader.match(`${key}=([^;]*)`)?.[1];
|
|
11
|
+
if (firstMatch !== undefined) {
|
|
12
|
+
// Decode the cookie value to match behavior of other cookie storage methods
|
|
13
|
+
return decodeURIComponent(firstMatch);
|
|
14
|
+
}
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=cookieUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cookieUtils.js","sourceRoot":"","sources":["../../../src/shared/lib/cookieUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,0BAA0B,CACxC,YAA2B,EAC3B,GAAW;IAEX,IAAI,CAAC;QACH,IAAI,CAAC,YAAY;YAAE,OAAO,IAAI,CAAC;QAE/B,8DAA8D;QAC9D,MAAM,UAAU,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,GAAG,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC7D,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YAC7B,4EAA4E;YAC5E,OAAO,kBAAkB,CAAC,UAAU,CAAC,CAAC;QACxC,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC","sourcesContent":["/**\n * Utility function to extract a specific cookie value from raw cookie header.\n * Returns the first occurrence which should be the most specific path.\n */\nexport function extractCookieFromRawHeader(\n cookieHeader: string | null,\n key: string,\n): string | null {\n try {\n if (!cookieHeader) return null;\n\n // Parse first occurrence from raw header (most specific path)\n const firstMatch = cookieHeader.match(`${key}=([^;]*)`)?.[1];\n if (firstMatch !== undefined) {\n // Decode the cookie value to match behavior of other cookie storage methods\n return decodeURIComponent(firstMatch);\n }\n return null;\n } catch {\n return null;\n }\n}\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { type AuthStorage, type OAuthTokens, type User, type EmptyObject, type UnknownObject } from "../../types.js";
|
|
1
|
+
import { type AuthStorage, type OAuthTokens, type User, type EmptyObject, type UnknownObject, type OIDCTokenResponseBody } from "../../types.js";
|
|
2
|
+
export declare function getUserFromTokens<T extends UnknownObject = EmptyObject>(tokens: Partial<OIDCTokenResponseBody> | null): Promise<User<T> | null>;
|
|
2
3
|
export declare function getUser<T extends UnknownObject = EmptyObject>(storage: AuthStorage): Promise<User<T> | null>;
|
|
3
4
|
export declare function getTokens(storage: AuthStorage): Promise<OAuthTokens | null>;
|
|
4
5
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/shared/lib/session.ts"],"names":[],"mappings":"AAOA,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,IAAI,EACT,KAAK,WAAW,EAChB,KAAK,aAAa,
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/shared/lib/session.ts"],"names":[],"mappings":"AAOA,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,IAAI,EACT,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAC3B,MAAM,YAAY,CAAC;AAuBpB,wBAAsB,iBAAiB,CAAC,CAAC,SAAS,aAAa,GAAG,WAAW,EAC3E,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,GAAG,IAAI,GAC5C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAmBzB;AAED,wBAAsB,OAAO,CAAC,CAAC,SAAS,aAAa,GAAG,WAAW,EACjE,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAQzB;AAED,wBAAsB,SAAS,CAC7B,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAS7B;AAED;;;GAGG;AACH,eAAO,MAAM,gBAAgB,YAAmB,WAAW,kBAI1D,CAAC"}
|
|
@@ -2,6 +2,7 @@ import { clearAuthServerSession, clearTokens, clearUser, retrieveTokens, } from
|
|
|
2
2
|
import { decodeJwt } from "jose";
|
|
3
3
|
import { tokenKeys, } from "../../types.js";
|
|
4
4
|
import { JWT_PAYLOAD_KNOWN_CLAIM_KEYS } from "../../constants.js";
|
|
5
|
+
import { GenericUserSession } from "./UserSession.js";
|
|
5
6
|
// Function to omit keys from an object
|
|
6
7
|
const omitKeys = (keys, obj) => {
|
|
7
8
|
const result = { ...obj };
|
|
@@ -14,8 +15,7 @@ const parseJWTToType = (jwt) => {
|
|
|
14
15
|
const parseResult = decodeJwt(jwt);
|
|
15
16
|
return parseResult;
|
|
16
17
|
};
|
|
17
|
-
export async function
|
|
18
|
-
const tokens = await retrieveTokens(storage);
|
|
18
|
+
export async function getUserFromTokens(tokens) {
|
|
19
19
|
if (!tokens || !tokens.id_token)
|
|
20
20
|
return null;
|
|
21
21
|
const parsedToken = parseJWTToType(tokens.id_token);
|
|
@@ -31,6 +31,15 @@ export async function getUser(storage) {
|
|
|
31
31
|
// remove the token keys from the user object to stop it getting too large
|
|
32
32
|
return omitKeys([...JWT_PAYLOAD_KNOWN_CLAIM_KEYS, ...tokenKeys], userWithAdditionalTokenFields);
|
|
33
33
|
}
|
|
34
|
+
export async function getUser(storage) {
|
|
35
|
+
const userStorage = new GenericUserSession(storage);
|
|
36
|
+
const userFromStorage = await userStorage.get();
|
|
37
|
+
if (userFromStorage) {
|
|
38
|
+
return userFromStorage;
|
|
39
|
+
}
|
|
40
|
+
const tokens = await retrieveTokens(storage);
|
|
41
|
+
return getUserFromTokens(tokens);
|
|
42
|
+
}
|
|
34
43
|
export async function getTokens(storage) {
|
|
35
44
|
const storageData = await retrieveTokens(storage);
|
|
36
45
|
if (!storageData)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/shared/lib/session.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,WAAW,EACX,SAAS,EACT,cAAc,GACf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,SAAS,EAAmB,MAAM,MAAM,CAAC;AAClD,OAAO,EACL,SAAS,
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/shared/lib/session.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,WAAW,EACX,SAAS,EACT,cAAc,GACf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,SAAS,EAAmB,MAAM,MAAM,CAAC;AAClD,OAAO,EACL,SAAS,GAOV,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,4BAA4B,EAAE,MAAM,gBAAgB,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEtD,uCAAuC;AACvC,MAAM,QAAQ,GAAG,CACf,IAAS,EACT,GAAM,EACM,EAAE;IACd,MAAM,MAAM,GAAG,EAAE,GAAG,GAAG,EAAE,CAAC;IAC1B,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;QACnB,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF,MAAM,cAAc,GAAG,CACrB,GAAW,EACK,EAAE;IAClB,MAAM,WAAW,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;IACnC,OAAO,WAA6B,CAAC;AACvC,CAAC,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,MAA6C;IAE7C,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAE7C,MAAM,WAAW,GAAG,cAAc,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACpD,uCAAuC;IACvC,IAAI,CAAC,WAAW,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IAElC,qCAAqC;IACrC,MAAM,6BAA6B,GAAG;QACpC,GAAI,WAAiB;QACrB,EAAE,EAAE,WAAW,CAAC,GAAG;KACpB,CAAC;IAEF,6CAA6C;IAC7C,0EAA0E;IAC1E,OAAO,QAAQ,CACb,CAAC,GAAG,4BAA4B,EAAE,GAAG,SAAS,CAAC,EAC/C,6BAA6B,CACnB,CAAC;AACf,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,OAAoB;IAEpB,MAAM,WAAW,GAAG,IAAI,kBAAkB,CAAI,OAAO,CAAC,CAAC;IACvD,MAAM,eAAe,GAAG,MAAM,WAAW,CAAC,GAAG,EAAE,CAAC;IAChD,IAAI,eAAe,EAAE,CAAC;QACpB,OAAO,eAAe,CAAC;IACzB,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,OAAO,CAAC,CAAC;IAC7C,OAAO,iBAAiB,CAAI,MAAM,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,OAAoB;IAEpB,MAAM,WAAW,GAAG,MAAM,cAAc,CAAC,OAAO,CAAC,CAAC;IAClD,IAAI,CAAC,WAAW;QAAE,OAAO,IAAI,CAAC;IAE9B,OAAO;QACL,OAAO,EAAE,WAAW,CAAC,QAAQ;QAC7B,WAAW,EAAE,WAAW,CAAC,YAAY;QACrC,YAAY,EAAE,WAAW,CAAC,aAAa;KACxC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EAAE,OAAoB,EAAE,EAAE;IAC7D,MAAM,WAAW,CAAC,OAAO,CAAC,CAAC;IAC3B,MAAM,SAAS,CAAC,OAAO,CAAC,CAAC;IACzB,MAAM,sBAAsB,CAAC,OAAO,CAAC,CAAC;AACxC,CAAC,CAAC","sourcesContent":["import {\n clearAuthServerSession,\n clearTokens,\n clearUser,\n retrieveTokens,\n} from \"@/shared/lib/util.js\";\nimport { decodeJwt, type JWTPayload } from \"jose\";\nimport {\n tokenKeys,\n type AuthStorage,\n type OAuthTokens,\n type User,\n type EmptyObject,\n type UnknownObject,\n type OIDCTokenResponseBody,\n} from \"@/types.js\";\nimport { JWT_PAYLOAD_KNOWN_CLAIM_KEYS } from \"@/constants.js\";\nimport { GenericUserSession } from \"./UserSession.js\";\n\n// Function to omit keys from an object\nconst omitKeys = <K extends keyof T, T extends Record<string, unknown>>(\n keys: K[],\n obj: T,\n): Omit<T, K> => {\n const result = { ...obj };\n keys.forEach((key) => {\n delete result[key];\n });\n return result;\n};\n\nconst parseJWTToType = <T extends UnknownObject = EmptyObject>(\n jwt: string,\n): JWTPayload & T => {\n const parseResult = decodeJwt(jwt);\n return parseResult as JWTPayload & T;\n};\n\nexport async function getUserFromTokens<T extends UnknownObject = EmptyObject>(\n tokens: Partial<OIDCTokenResponseBody> | null,\n): Promise<User<T> | null> {\n if (!tokens || !tokens.id_token) return null;\n\n const parsedToken = parseJWTToType(tokens.id_token);\n // it might be preferable to throw here\n if (!parsedToken.sub) return null;\n\n // set the user ID from the token sub\n const userWithAdditionalTokenFields = {\n ...(parsedToken as T),\n id: parsedToken.sub,\n };\n\n // Assumes all information is in the ID token\n // remove the token keys from the user object to stop it getting too large\n return omitKeys(\n [...JWT_PAYLOAD_KNOWN_CLAIM_KEYS, ...tokenKeys],\n userWithAdditionalTokenFields,\n ) as User<T>;\n}\n\nexport async function getUser<T extends UnknownObject = EmptyObject>(\n storage: AuthStorage,\n): Promise<User<T> | null> {\n const userStorage = new GenericUserSession<T>(storage);\n const userFromStorage = await userStorage.get();\n if (userFromStorage) {\n return userFromStorage;\n }\n const tokens = await retrieveTokens(storage);\n return getUserFromTokens<T>(tokens);\n}\n\nexport async function getTokens(\n storage: AuthStorage,\n): Promise<OAuthTokens | null> {\n const storageData = await retrieveTokens(storage);\n if (!storageData) return null;\n\n return {\n idToken: storageData.id_token,\n accessToken: storageData.access_token,\n refreshToken: storageData.refresh_token,\n };\n}\n\n/**\n * Use the provided storage to clear all authentication cookies\n * @param storage\n */\nexport const clearAuthCookies = async (storage: AuthStorage) => {\n await clearTokens(storage);\n await clearUser(storage);\n await clearAuthServerSession(storage);\n};\n"]}
|
|
@@ -49,11 +49,11 @@ export declare function storeTokens(storage: AuthStorage, tokens: OIDCTokenRespo
|
|
|
49
49
|
* Refresh token is set with 400 day expiry
|
|
50
50
|
*/
|
|
51
51
|
export declare function storeServerTokens(storage: AuthStorage | CookieStorage, tokens: OIDCTokenResponseBody): Promise<void>;
|
|
52
|
-
export declare function clearTokens(storage: AuthStorage): Promise<void>;
|
|
52
|
+
export declare function clearTokens(storage: AuthStorage | CookieStorage): Promise<void>;
|
|
53
53
|
export declare function clearAuthServerSession(storage: AuthStorage): Promise<void>;
|
|
54
54
|
export declare function clearUser(storage: AuthStorage): Promise<void>;
|
|
55
55
|
export declare function retrieveTokens(storage: AuthStorage): Promise<Partial<OIDCTokenResponseBody> | null>;
|
|
56
|
-
export declare function
|
|
56
|
+
export declare function retrieveOidcSessionExpiredAtSeconds(storage: AuthStorage): Promise<number | null>;
|
|
57
57
|
export declare function validateOauth2Tokens(tokens: OIDCTokenResponseBody, jwksEndpoint: string, oauth2Client: OAuth2Client, issuer: string): Promise<ParsedTokens>;
|
|
58
58
|
/**
|
|
59
59
|
* Get backend endpoints with default values merged with custom configuration
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../../src/shared/lib/util.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,WAAW,EACX,SAAS,EACT,qBAAqB,EACrB,YAAY,EACb,MAAM,YAAY,CAAC;AAMpB,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAI3C,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGtE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAQlD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAG3D;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,YAAY,EAAE,MAAM,EACpB,MAAM,GAAE,OAAO,GAAG,MAAe,GAChC,OAAO,CAAC,MAAM,CAAC,CAajB;AAED,wBAAsB,yBAAyB,CAC7C,WAAW,EAAE,MAAM,EACnB,iBAAiB,GAAE,OAAO,CAAC,SAAS,CAAM,GACzC,OAAO,CAAC,SAAS,CAAC,CAMpB;AAED,wBAAsB,qBAAqB,CAAC,MAAM,EAAE;IAClD,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iBAAiB,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IAEvC,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B,GAAG,OAAO,CAAC,GAAG,CAAC,CAiCf;AAED,wBAAsB,sBAAsB,CAAC,MAAM,EAAE;IACnD,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;CACxC,GAAG,OAAO,CAAC,GAAG,CAAC,CAcf;AAED,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,SAAS,GACnB,YAAY,CAId;AAED,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,YAAY,GAAG,IAAI,EACjC,YAAY,EAAE,YAAY,EAC1B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,SAAS,EACpB,YAAY,CAAC,EAAE,MAAM,kCA8CtB;AACD;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB,WACnB,qBAAqB,KAC5B;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAA;CAiCpD,CAAC;AAEF,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,WAAW,GAAG,aAAa,EACpC,MAAM,EAAE,qBAAqB,iBAS9B;AAED,wBAAsB,WAAW,CAC/B,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,qBAAqB,iBAkB9B;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,WAAW,GAAG,aAAa,EACpC,MAAM,EAAE,qBAAqB,iBAyD9B;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,
|
|
1
|
+
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../../src/shared/lib/util.ts"],"names":[],"mappings":"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"}
|
package/dist/shared/lib/util.js
CHANGED
|
@@ -265,12 +265,12 @@ export async function retrieveTokens(storage) {
|
|
|
265
265
|
: undefined, // Convert string to number
|
|
266
266
|
};
|
|
267
267
|
}
|
|
268
|
-
export async function
|
|
269
|
-
const
|
|
270
|
-
if (!
|
|
268
|
+
export async function retrieveOidcSessionExpiredAtSeconds(storage) {
|
|
269
|
+
const valueSeconds = await storage.get(OAuthTokenTypes.OIDC_SESSION_EXPIRES_AT);
|
|
270
|
+
if (!valueSeconds) {
|
|
271
271
|
return null;
|
|
272
272
|
}
|
|
273
|
-
const expiresAt = Number(
|
|
273
|
+
const expiresAt = Number(valueSeconds);
|
|
274
274
|
return isNaN(expiresAt) ? null : expiresAt;
|
|
275
275
|
}
|
|
276
276
|
// Single JWKS instance that persists for the lifetime of the SDK session
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.js","sourceRoot":"","sources":["../../../src/shared/lib/util.ts"],"names":[],"mappings":"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","sourcesContent":["// Utility functions shared by auth server and client integrations\n// Typically these functions should be used inside AuthenticationInitiator and AuthenticationResolver implementations\nimport type {\n AuthStorage,\n Endpoints,\n OIDCTokenResponseBody,\n ParsedTokens,\n} from \"@/types.js\";\nimport {\n AUTH_SERVER_LEGACY_SESSION,\n AUTH_SERVER_SESSION,\n OAuthTokenTypes,\n} from \"./types.js\";\nimport { OAuth2Client } from \"oslo/oauth2\";\nimport { getIssuerVariations, getOauthEndpoints } from \"@/lib/oauth.js\";\nimport * as jose from \"jose\";\nimport { withoutUndefined } from \"@/utils.js\";\nimport type { PKCEConsumer, PKCEProducer } from \"@/services/types.js\";\nimport { GenericUserSession } from \"@/shared/lib/UserSession.js\";\nimport { decodeJwt, type JWTPayload } from \"jose\";\nimport type { CookieStorage } from \"./storage.js\";\nimport {\n AUTOREFRESH_TIMEOUT_NAME,\n LOGOUT_STATE,\n MAX_COOKIE_AGE_SECONDS,\n REFRESH_IN_PROGRESS,\n} from \"@/constants.js\";\nimport { loggers } from \"@/lib/logger.js\";\nimport type { BackendEndpoints } from \"@/server/config.js\";\n\nconst logger = loggers.services.validation;\n/**\n * Given a PKCE code verifier, derive the code challenge using SHA\n */\nexport async function deriveCodeChallenge(\n codeVerifier: string,\n method: \"Plain\" | \"S256\" = \"S256\",\n): Promise<string> {\n if (method === \"Plain\") {\n console.warn(\"Using insecure plain code challenge method\");\n return codeVerifier;\n }\n\n const encoder = new TextEncoder();\n const data = encoder.encode(codeVerifier);\n const digest = await crypto.subtle.digest(\"SHA-256\", data);\n return btoa(String.fromCharCode(...new Uint8Array(digest)))\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/, \"\");\n}\n\nexport async function getEndpointsWithOverrides(\n oauthServer: string,\n endpointOverrides: Partial<Endpoints> = {},\n): Promise<Endpoints> {\n const endpoints = await getOauthEndpoints(oauthServer);\n return {\n ...endpoints,\n ...endpointOverrides,\n };\n}\n\nexport async function generateOauthLoginUrl(config: {\n clientId: string;\n scopes: string[];\n state: string;\n redirectUrl: string;\n oauthServer: string;\n nonce?: string;\n endpointOverrides?: Partial<Endpoints>;\n // Optional PKCE challenge - not needed for confidential clients using client secrets\n pkceConsumer?: PKCEConsumer;\n}): Promise<URL> {\n const endpoints = await getEndpointsWithOverrides(\n config.oauthServer,\n config.endpointOverrides,\n );\n const oauth2Client = buildOauth2Client(\n config.clientId,\n config.redirectUrl,\n endpoints,\n );\n\n const oAuthUrl = await oauth2Client.createAuthorizationURL({\n state: config.state,\n scopes: config.scopes,\n });\n\n // Only add PKCE parameters if a pkceConsumer is provided\n if (config.pkceConsumer) {\n const challenge = await config.pkceConsumer.getCodeChallenge();\n // The OAuth2 client supports PKCE, but does not allow passing in a code challenge from some other source\n // It only allows passing in a code verifier which it then hashes itself.\n oAuthUrl.searchParams.append(\"code_challenge\", challenge);\n oAuthUrl.searchParams.append(\"code_challenge_method\", \"S256\");\n }\n\n if (config.nonce) {\n // nonce isn't supported by oslo, so we add it manually\n oAuthUrl.searchParams.append(\"nonce\", config.nonce);\n }\n // Required by the auth server for offline_access scope\n oAuthUrl.searchParams.append(\"prompt\", \"consent\");\n\n return oAuthUrl;\n}\n\nexport async function generateOauthLogoutUrl(config: {\n clientId: string;\n redirectUrl: string;\n idToken: string;\n state: string;\n oauthServer: string;\n endpointOverrides?: Partial<Endpoints>;\n}): Promise<URL> {\n const endpoints = await getEndpointsWithOverrides(\n config.oauthServer,\n config.endpointOverrides,\n );\n const endSessionUrl = new URL(endpoints.endsession);\n endSessionUrl.searchParams.append(\"client_id\", config.clientId);\n endSessionUrl.searchParams.append(\"id_token_hint\", config.idToken);\n endSessionUrl.searchParams.append(\"state\", config.state);\n endSessionUrl.searchParams.append(\n \"post_logout_redirect_uri\",\n config.redirectUrl,\n );\n return endSessionUrl;\n}\n\nexport function buildOauth2Client(\n clientId: string,\n redirectUri: string,\n endpoints: Endpoints,\n): OAuth2Client {\n return new OAuth2Client(clientId, endpoints.auth, endpoints.token, {\n redirectURI: redirectUri,\n });\n}\n\nexport async function exchangeTokens(\n code: string,\n state: string,\n pkceProducer: PKCEProducer | null,\n oauth2Client: OAuth2Client,\n oauthServer: string,\n endpoints: Endpoints,\n clientSecret?: string,\n) {\n // Get code verifier if using PKCE\n const codeVerifier = pkceProducer\n ? await pkceProducer.getCodeVerifier()\n : null;\n\n // Ensure at least one authentication method is provided\n if (!codeVerifier && !clientSecret) {\n throw new Error(\n \"Either PKCE code verifier or client secret must be provided\",\n );\n }\n\n // Build options for validateAuthorizationCode\n const validationOptions: Record<string, string> = {};\n\n if (codeVerifier) {\n validationOptions.codeVerifier = codeVerifier;\n }\n\n if (clientSecret) {\n validationOptions.credentials = clientSecret;\n validationOptions.authenticateWith = \"request_body\"; // Use client_secret_post method\n }\n\n const tokens = (await oauth2Client.validateAuthorizationCode(\n code,\n validationOptions,\n )) as OIDCTokenResponseBody;\n\n // Validate relevant tokens\n try {\n await validateOauth2Tokens(\n tokens,\n endpoints.jwks,\n oauth2Client,\n oauthServer,\n );\n } catch (error) {\n console.error(\"tokenExchange error\", { error, tokens });\n throw new Error(\n `OIDC tokens validation failed: ${(error as Error).message}`,\n );\n }\n return tokens;\n}\n/**\n * Calculates the maxAge values for access and refresh token cookies\n * based on the TTL values in the access token\n *\n * maxAge needs to be in seconds from now until expiration\n *\n * @param tokens OIDC tokens response containing the access token\n * @returns Object with accessTokenMaxAge and refreshTokenMaxAge in seconds\n */\nexport const getCookiesMaxAge = (\n tokens: OIDCTokenResponseBody,\n): { idTokenMaxAge: number; accessTokenMaxAge: number } => {\n const DEFAULT_TTL = 60 * 60; // 1 hour default\n\n let idTokenMaxAge = DEFAULT_TTL;\n let accessTokenMaxAge = DEFAULT_TTL;\n\n // The ID token takes priority, as it represents the OIDC session\n if (tokens.id_token) {\n // If no access token exists, try to get expiration from ID token\n const parsedIdToken = decodeJwt(tokens.id_token);\n if (parsedIdToken?.exp) {\n const now = Math.floor(Date.now() / 1000);\n idTokenMaxAge = parsedIdToken.exp - now;\n }\n }\n\n if (tokens.access_token) {\n // Get access token TTL from the token if it exists\n const parsedAccessToken = decodeJwt(tokens.access_token);\n accessTokenMaxAge =\n Number(parsedAccessToken?.accessTokenTTL) || DEFAULT_TTL;\n\n // If access token has exp claim, use that directly\n if (parsedAccessToken?.exp) {\n const now = Math.floor(Date.now() / 1000);\n accessTokenMaxAge = parsedAccessToken.exp - now;\n }\n }\n\n return {\n accessTokenMaxAge,\n idTokenMaxAge,\n };\n};\n\nexport async function setOidcSessionExpiresAt(\n storage: AuthStorage | CookieStorage,\n tokens: OIDCTokenResponseBody,\n) {\n const now = Math.floor(Date.now() / 1000);\n const { idTokenMaxAge } = getCookiesMaxAge(tokens);\n // The OIDC session expiry is linked to the ID token expiry, since this is primarily an OIDC client.\n await storage.set(\n OAuthTokenTypes.OIDC_SESSION_EXPIRES_AT,\n (idTokenMaxAge + now).toString(),\n );\n}\n\nexport async function storeTokens(\n storage: AuthStorage,\n tokens: OIDCTokenResponseBody,\n) {\n // ID token is the primary token and must always be stored\n await storage.set(OAuthTokenTypes.ID_TOKEN, tokens.id_token);\n\n // Only store access token if it exists (no longer required)\n if (tokens.access_token) {\n await storage.set(OAuthTokenTypes.ACCESS_TOKEN, tokens.access_token);\n }\n\n // Store refresh token if it exists\n if (tokens.refresh_token) {\n await storage.set(OAuthTokenTypes.REFRESH_TOKEN, tokens.refresh_token);\n }\n\n // Still set access token expiration even if no access token\n // (will get expiration from ID token in this case)\n await setOidcSessionExpiresAt(storage, tokens);\n}\n\n/**\n * Stores tokens in server-side cookies with appropriate expiration times\n * Uses TTL values from the tokens to set cookie maxAge values\n * Refresh token is set with 400 day expiry\n */\nexport async function storeServerTokens(\n storage: AuthStorage | CookieStorage,\n tokens: OIDCTokenResponseBody,\n) {\n // Get maxAge values based on token TTLs (refresh token TTL will be undefined)\n const now = Math.floor(Date.now() / 1000);\n const { idTokenMaxAge, accessTokenMaxAge } = getCookiesMaxAge(tokens);\n\n // The OIDC session expiry is linked to the ID token expiry, since this is primarily an OIDC client.\n const oidcSessionExpiresAt = now + idTokenMaxAge;\n const cookieStorage = storage as CookieStorage;\n\n // Apply maxAge to cookie options\n const accessTokenCookieOptions = {\n maxAge: accessTokenMaxAge,\n };\n\n const refreshTokenCookieOptions = {\n maxAge: MAX_COOKIE_AGE_SECONDS,\n };\n\n // ID token is always stored (primary authentication token)\n await cookieStorage.set(OAuthTokenTypes.ID_TOKEN, tokens.id_token, {\n maxAge: idTokenMaxAge,\n });\n\n // Access token is optional - only set if it exists\n if (tokens.access_token) {\n await cookieStorage.set(\n OAuthTokenTypes.ACCESS_TOKEN,\n tokens.access_token,\n accessTokenCookieOptions,\n );\n }\n\n // Set refresh token if present with 400 day expiry\n if (tokens.refresh_token) {\n await cookieStorage.set(\n OAuthTokenTypes.REFRESH_TOKEN,\n tokens.refresh_token,\n refreshTokenCookieOptions,\n );\n }\n\n // Still store the access token expiration timestamp even if no access token\n await storage.set(\n OAuthTokenTypes.OIDC_SESSION_EXPIRES_AT,\n oidcSessionExpiresAt.toString(),\n {\n // This is primarily an OIDC client, so we use the ID token max age for the session timeout / refresh scheduling.\n maxAge: idTokenMaxAge,\n },\n );\n logger.debug(\"storeServerTokens\", {\n oidcSessionExpiresAt,\n refreshTokenMaxAge: MAX_COOKIE_AGE_SECONDS,\n idTokenMaxAge,\n hasAccessToken: !!tokens.access_token,\n });\n}\n\nexport async function clearTokens(storage: AuthStorage) {\n // clear all local storage keys related to OAuth and CivicAuth SDK\n const clearOAuthPromises = [\n ...Object.values(OAuthTokenTypes),\n REFRESH_IN_PROGRESS,\n AUTOREFRESH_TIMEOUT_NAME,\n LOGOUT_STATE,\n ].map(async (key) => {\n await storage.delete(key);\n });\n await Promise.all([...clearOAuthPromises]);\n}\n\nexport async function clearAuthServerSession(storage: AuthStorage) {\n await storage.delete(AUTH_SERVER_SESSION);\n await storage.delete(AUTH_SERVER_LEGACY_SESSION);\n}\n\nexport async function clearUser(storage: AuthStorage) {\n const userSession = new GenericUserSession(storage);\n await userSession.clear();\n}\n\n/**\n * Smart token unwrapping for Safari's base64-encoding bug\n * Only unwraps tokens that are:\n * 1. Base64-encoded (Safari bug) - very long strings without dots\n * 2. Contain a JSON object with a 'value' property that's a valid JWT\n *\n * Does NOT unwrap React Router's normal {value: \"token\"} objects\n */\nfunction unwrapSafariTokenIfNeeded(token: string | null): string | null {\n if (!token) return token;\n\n // Safari-specific detection: base64-encoded JSON that's extremely long\n // Normal wrapped objects from React Router are much shorter and have different characteristics\n if (token && !token.includes(\".\") && token.length > 800) {\n try {\n // Try to decode as base64 and parse as JSON\n const decoded = JSON.parse(atob(token));\n\n // Verify this is Safari's bug: wrapped value must be a valid 3-part JWT\n if (\n decoded &&\n typeof decoded === \"object\" &&\n decoded.value &&\n typeof decoded.value === \"string\" &&\n decoded.value.split(\".\").length === 3\n ) {\n return decoded.value;\n }\n } catch (error) {\n console.error(\"HERE UTIL - SAFARI TOKEN UNWRAP FAILED\", error);\n }\n }\n\n return token;\n}\n\nexport async function retrieveTokens(\n storage: AuthStorage,\n): Promise<Partial<OIDCTokenResponseBody> | null> {\n const idToken = await storage.get(OAuthTokenTypes.ID_TOKEN);\n const accessToken = await storage.get(OAuthTokenTypes.ACCESS_TOKEN);\n const refreshToken = await storage.get(OAuthTokenTypes.REFRESH_TOKEN);\n const oidcSessionExpiresAt = await storage.get(\n OAuthTokenTypes.OIDC_SESSION_EXPIRES_AT,\n );\n\n return {\n id_token: unwrapSafariTokenIfNeeded(idToken) ?? undefined,\n access_token: unwrapSafariTokenIfNeeded(accessToken) ?? undefined,\n refresh_token: unwrapSafariTokenIfNeeded(refreshToken) ?? undefined,\n oidc_session_expires_at:\n oidcSessionExpiresAt !== null\n ? parseInt(oidcSessionExpiresAt, 10)\n : undefined, // Convert string to number\n };\n}\n\nexport async function retrieveOidcSessionExpiredAt(\n storage: AuthStorage,\n): Promise<number | null> {\n const value = await storage.get(OAuthTokenTypes.OIDC_SESSION_EXPIRES_AT);\n if (!value) {\n return null;\n }\n const expiresAt = Number(value);\n return isNaN(expiresAt) ? null : expiresAt;\n}\n\n// Single JWKS instance that persists for the lifetime of the SDK session\nlet cachedJWKS: ReturnType<typeof jose.createRemoteJWKSet> | null = null;\nlet cachedJwksUrl: string | null = null;\n\nexport async function validateOauth2Tokens(\n tokens: OIDCTokenResponseBody,\n jwksEndpoint: string,\n oauth2Client: OAuth2Client,\n issuer: string,\n): Promise<ParsedTokens> {\n // Only create a new JWKS instance if one doesn't exist yet\n if (!cachedJWKS || cachedJwksUrl !== jwksEndpoint) {\n cachedJWKS = jose.createRemoteJWKSet(new URL(jwksEndpoint));\n cachedJwksUrl = jwksEndpoint;\n }\n\n // Validate the ID token - this is now the primary token for authentication\n const idTokenResponse = await jose.jwtVerify<JWTPayload>(\n tokens.id_token,\n cachedJWKS,\n {\n issuer: getIssuerVariations(issuer),\n audience: oauth2Client.clientId,\n },\n );\n\n // Only validate the access token if it exists, but if present it must be valid\n let accessTokenPayload;\n if (tokens.access_token) {\n const accessTokenResponse = await jose.jwtVerify<JWTPayload>(\n tokens.access_token,\n cachedJWKS,\n {\n issuer: getIssuerVariations(issuer),\n },\n );\n accessTokenPayload = accessTokenResponse.payload;\n }\n\n return withoutUndefined({\n id_token: idTokenResponse.payload,\n access_token: accessTokenPayload,\n ...(tokens?.refresh_token ? { refresh_token: tokens.refresh_token } : {}),\n });\n}\n\n/**\n * Get backend endpoints with default values merged with custom configuration\n * @param backendEndpoints - Optional custom backend endpoints configuration\n * @returns Backend endpoints with defaults applied\n */\nexport function getBackendEndpoints(\n backendEndpoints?: BackendEndpoints,\n): BackendEndpoints {\n return {\n refresh: backendEndpoints?.refresh ?? \"/auth/refresh\",\n logout: backendEndpoints?.logout ?? \"/auth/logout\",\n user: backendEndpoints?.user ?? \"/auth/user\",\n };\n}\n\n/**\n * Resolves an endpoint URL by checking if it's already a full URL\n * or if it needs to be combined with a base URL\n * @param baseUrl - The base URL (e.g., \"https://api.example.com\")\n * @param endpoint - The endpoint that might be relative (e.g., \"/auth/logout\") or absolute (e.g., \"https://other-server.com/logout\")\n * @returns The resolved URL\n */\nexport function resolveEndpointUrl(\n baseUrl: string,\n endpoint: string | undefined,\n): string {\n // Handle undefined endpoint\n if (!endpoint) {\n throw new Error(\"Endpoint is undefined\");\n }\n\n // Check if endpoint is already a full URL\n if (endpoint.startsWith(\"http://\") || endpoint.startsWith(\"https://\")) {\n return endpoint;\n }\n\n // Concatenate base URL with relative endpoint\n return `${baseUrl}${endpoint}`;\n}\n\n/**\n * Determines the protocol from request headers or environment\n * Checks common proxy headers before falling back to URL or environment\n */\nexport function getProtocolFromRequest(request?: Request): string {\n if (!request) {\n // Fallback when no request available\n return process.env.NODE_ENV === \"production\" ? \"https:\" : \"http:\";\n }\n\n // Check common proxy headers that indicate the original protocol\n const forwardedProto = request.headers.get(\"x-forwarded-proto\");\n if (forwardedProto) {\n return forwardedProto === \"https\" ? \"https:\" : \"http:\";\n }\n\n const forwardedProtocol = request.headers.get(\"x-forwarded-protocol\");\n if (forwardedProtocol) {\n return forwardedProtocol === \"https\" ? \"https:\" : \"http:\";\n }\n\n // Parse the standard Forwarded header (RFC 7239)\n const forwarded = request.headers.get(\"forwarded\");\n if (forwarded) {\n const protoMatch = forwarded.match(/proto=([^;,\\s]+)/i);\n if (protoMatch) {\n return protoMatch[1] === \"https\" ? \"https:\" : \"http:\";\n }\n }\n\n // Extract from the request URL itself\n const url = new URL(request.url);\n return url.protocol;\n}\n\n/**\n * Detect Safari browser from user agent\n */\nexport function isSafariBrowser(request?: Request): boolean {\n if (!request) return false;\n\n const userAgent = request.headers.get(\"user-agent\") || \"\";\n return userAgent.includes(\"Safari\") && !userAgent.includes(\"Chrome\");\n}\n\n/**\n * Detect if running on localhost\n */\nexport function isLocalhostUrl(request?: Request): boolean {\n if (!request) return false;\n\n const url = new URL(request.url);\n return url.hostname === \"localhost\" || url.hostname === \"127.0.0.1\";\n}\n\n/**\n * Get cookie configuration based on environment and browser\n * Handles special cases for Safari on localhost and HTTPS detection\n *\n * @param request - Optional request object for environment detection\n * @returns Cookie configuration with secure and sameSite settings\n *\n * Configuration rules:\n * - Safari on localhost: Uses lax sameSite to avoid cross-origin issues\n * - HTTPS: Uses secure cookies with none sameSite for cross-origin iframe support\n * - HTTP localhost (non-Safari): Uses secure cookies for Chrome's localhost exception\n */\nexport function getCookieConfiguration(request?: Request): {\n secure: boolean;\n sameSite: \"lax\" | \"none\";\n} {\n const isSafari = isSafariBrowser(request);\n const isLocalhost = isLocalhostUrl(request);\n const protocol = getProtocolFromRequest(request);\n const isHttps = protocol === \"https:\";\n\n if (isSafari && isLocalhost) {\n // Safari on localhost: use lax to avoid cross-origin issues\n return {\n secure: false,\n sameSite: \"lax\",\n };\n } else if (isHttps) {\n // HTTPS (production): use none for cross-origin iframe support\n return {\n secure: true,\n sameSite: \"none\",\n };\n } else {\n // HTTP localhost (non-Safari): use secure: true for iframe compatibility\n // Chrome allows secure cookies on localhost HTTP\n // This allows secure: true cookies to work on localhost for iframe compatibility\n // Reference: Chrome's third-party cookie documentation\n return {\n secure: true,\n sameSite: \"none\",\n };\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../../../src/shared/lib/util.ts"],"names":[],"mappings":"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","sourcesContent":["// Utility functions shared by auth server and client integrations\n// Typically these functions should be used inside AuthenticationInitiator and AuthenticationResolver implementations\nimport type {\n AuthStorage,\n Endpoints,\n OIDCTokenResponseBody,\n ParsedTokens,\n} from \"@/types.js\";\nimport {\n AUTH_SERVER_LEGACY_SESSION,\n AUTH_SERVER_SESSION,\n OAuthTokenTypes,\n} from \"./types.js\";\nimport { OAuth2Client } from \"oslo/oauth2\";\nimport { getIssuerVariations, getOauthEndpoints } from \"@/lib/oauth.js\";\nimport * as jose from \"jose\";\nimport { withoutUndefined } from \"@/utils.js\";\nimport type { PKCEConsumer, PKCEProducer } from \"@/services/types.js\";\nimport { GenericUserSession } from \"@/shared/lib/UserSession.js\";\nimport { decodeJwt, type JWTPayload } from \"jose\";\nimport type { CookieStorage } from \"./storage.js\";\nimport {\n AUTOREFRESH_TIMEOUT_NAME,\n LOGOUT_STATE,\n MAX_COOKIE_AGE_SECONDS,\n REFRESH_IN_PROGRESS,\n} from \"@/constants.js\";\nimport { loggers } from \"@/lib/logger.js\";\nimport type { BackendEndpoints } from \"@/server/config.js\";\n\nconst logger = loggers.services.validation;\n/**\n * Given a PKCE code verifier, derive the code challenge using SHA\n */\nexport async function deriveCodeChallenge(\n codeVerifier: string,\n method: \"Plain\" | \"S256\" = \"S256\",\n): Promise<string> {\n if (method === \"Plain\") {\n console.warn(\"Using insecure plain code challenge method\");\n return codeVerifier;\n }\n\n const encoder = new TextEncoder();\n const data = encoder.encode(codeVerifier);\n const digest = await crypto.subtle.digest(\"SHA-256\", data);\n return btoa(String.fromCharCode(...new Uint8Array(digest)))\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/, \"\");\n}\n\nexport async function getEndpointsWithOverrides(\n oauthServer: string,\n endpointOverrides: Partial<Endpoints> = {},\n): Promise<Endpoints> {\n const endpoints = await getOauthEndpoints(oauthServer);\n return {\n ...endpoints,\n ...endpointOverrides,\n };\n}\n\nexport async function generateOauthLoginUrl(config: {\n clientId: string;\n scopes: string[];\n state: string;\n redirectUrl: string;\n oauthServer: string;\n nonce?: string;\n endpointOverrides?: Partial<Endpoints>;\n // Optional PKCE challenge - not needed for confidential clients using client secrets\n pkceConsumer?: PKCEConsumer;\n}): Promise<URL> {\n const endpoints = await getEndpointsWithOverrides(\n config.oauthServer,\n config.endpointOverrides,\n );\n const oauth2Client = buildOauth2Client(\n config.clientId,\n config.redirectUrl,\n endpoints,\n );\n\n const oAuthUrl = await oauth2Client.createAuthorizationURL({\n state: config.state,\n scopes: config.scopes,\n });\n\n // Only add PKCE parameters if a pkceConsumer is provided\n if (config.pkceConsumer) {\n const challenge = await config.pkceConsumer.getCodeChallenge();\n // The OAuth2 client supports PKCE, but does not allow passing in a code challenge from some other source\n // It only allows passing in a code verifier which it then hashes itself.\n oAuthUrl.searchParams.append(\"code_challenge\", challenge);\n oAuthUrl.searchParams.append(\"code_challenge_method\", \"S256\");\n }\n\n if (config.nonce) {\n // nonce isn't supported by oslo, so we add it manually\n oAuthUrl.searchParams.append(\"nonce\", config.nonce);\n }\n // Required by the auth server for offline_access scope\n oAuthUrl.searchParams.append(\"prompt\", \"consent\");\n\n return oAuthUrl;\n}\n\nexport async function generateOauthLogoutUrl(config: {\n clientId: string;\n redirectUrl: string;\n idToken: string;\n state: string;\n oauthServer: string;\n endpointOverrides?: Partial<Endpoints>;\n}): Promise<URL> {\n const endpoints = await getEndpointsWithOverrides(\n config.oauthServer,\n config.endpointOverrides,\n );\n const endSessionUrl = new URL(endpoints.endsession);\n endSessionUrl.searchParams.append(\"client_id\", config.clientId);\n endSessionUrl.searchParams.append(\"id_token_hint\", config.idToken);\n endSessionUrl.searchParams.append(\"state\", config.state);\n endSessionUrl.searchParams.append(\n \"post_logout_redirect_uri\",\n config.redirectUrl,\n );\n return endSessionUrl;\n}\n\nexport function buildOauth2Client(\n clientId: string,\n redirectUri: string,\n endpoints: Endpoints,\n): OAuth2Client {\n return new OAuth2Client(clientId, endpoints.auth, endpoints.token, {\n redirectURI: redirectUri,\n });\n}\n\nexport async function exchangeTokens(\n code: string,\n state: string,\n pkceProducer: PKCEProducer | null,\n oauth2Client: OAuth2Client,\n oauthServer: string,\n endpoints: Endpoints,\n clientSecret?: string,\n) {\n // Get code verifier if using PKCE\n const codeVerifier = pkceProducer\n ? await pkceProducer.getCodeVerifier()\n : null;\n\n // Ensure at least one authentication method is provided\n if (!codeVerifier && !clientSecret) {\n throw new Error(\n \"Either PKCE code verifier or client secret must be provided\",\n );\n }\n\n // Build options for validateAuthorizationCode\n const validationOptions: Record<string, string> = {};\n\n if (codeVerifier) {\n validationOptions.codeVerifier = codeVerifier;\n }\n\n if (clientSecret) {\n validationOptions.credentials = clientSecret;\n validationOptions.authenticateWith = \"request_body\"; // Use client_secret_post method\n }\n\n const tokens = (await oauth2Client.validateAuthorizationCode(\n code,\n validationOptions,\n )) as OIDCTokenResponseBody;\n\n // Validate relevant tokens\n try {\n await validateOauth2Tokens(\n tokens,\n endpoints.jwks,\n oauth2Client,\n oauthServer,\n );\n } catch (error) {\n console.error(\"tokenExchange error\", { error, tokens });\n throw new Error(\n `OIDC tokens validation failed: ${(error as Error).message}`,\n );\n }\n return tokens;\n}\n/**\n * Calculates the maxAge values for access and refresh token cookies\n * based on the TTL values in the access token\n *\n * maxAge needs to be in seconds from now until expiration\n *\n * @param tokens OIDC tokens response containing the access token\n * @returns Object with accessTokenMaxAge and refreshTokenMaxAge in seconds\n */\nexport const getCookiesMaxAge = (\n tokens: OIDCTokenResponseBody,\n): { idTokenMaxAge: number; accessTokenMaxAge: number } => {\n const DEFAULT_TTL = 60 * 60; // 1 hour default\n\n let idTokenMaxAge = DEFAULT_TTL;\n let accessTokenMaxAge = DEFAULT_TTL;\n\n // The ID token takes priority, as it represents the OIDC session\n if (tokens.id_token) {\n // If no access token exists, try to get expiration from ID token\n const parsedIdToken = decodeJwt(tokens.id_token);\n if (parsedIdToken?.exp) {\n const now = Math.floor(Date.now() / 1000);\n idTokenMaxAge = parsedIdToken.exp - now;\n }\n }\n\n if (tokens.access_token) {\n // Get access token TTL from the token if it exists\n const parsedAccessToken = decodeJwt(tokens.access_token);\n accessTokenMaxAge =\n Number(parsedAccessToken?.accessTokenTTL) || DEFAULT_TTL;\n\n // If access token has exp claim, use that directly\n if (parsedAccessToken?.exp) {\n const now = Math.floor(Date.now() / 1000);\n accessTokenMaxAge = parsedAccessToken.exp - now;\n }\n }\n\n return {\n accessTokenMaxAge,\n idTokenMaxAge,\n };\n};\n\nexport async function setOidcSessionExpiresAt(\n storage: AuthStorage | CookieStorage,\n tokens: OIDCTokenResponseBody,\n) {\n const now = Math.floor(Date.now() / 1000);\n const { idTokenMaxAge } = getCookiesMaxAge(tokens);\n // The OIDC session expiry is linked to the ID token expiry, since this is primarily an OIDC client.\n await storage.set(\n OAuthTokenTypes.OIDC_SESSION_EXPIRES_AT,\n (idTokenMaxAge + now).toString(),\n );\n}\n\nexport async function storeTokens(\n storage: AuthStorage,\n tokens: OIDCTokenResponseBody,\n) {\n // ID token is the primary token and must always be stored\n await storage.set(OAuthTokenTypes.ID_TOKEN, tokens.id_token);\n\n // Only store access token if it exists (no longer required)\n if (tokens.access_token) {\n await storage.set(OAuthTokenTypes.ACCESS_TOKEN, tokens.access_token);\n }\n\n // Store refresh token if it exists\n if (tokens.refresh_token) {\n await storage.set(OAuthTokenTypes.REFRESH_TOKEN, tokens.refresh_token);\n }\n\n // Still set access token expiration even if no access token\n // (will get expiration from ID token in this case)\n await setOidcSessionExpiresAt(storage, tokens);\n}\n\n/**\n * Stores tokens in server-side cookies with appropriate expiration times\n * Uses TTL values from the tokens to set cookie maxAge values\n * Refresh token is set with 400 day expiry\n */\nexport async function storeServerTokens(\n storage: AuthStorage | CookieStorage,\n tokens: OIDCTokenResponseBody,\n) {\n // Get maxAge values based on token TTLs (refresh token TTL will be undefined)\n const now = Math.floor(Date.now() / 1000);\n const { idTokenMaxAge, accessTokenMaxAge } = getCookiesMaxAge(tokens);\n\n // The OIDC session expiry is linked to the ID token expiry, since this is primarily an OIDC client.\n const oidcSessionExpiresAt = now + idTokenMaxAge;\n const cookieStorage = storage as CookieStorage;\n\n // Apply maxAge to cookie options\n const accessTokenCookieOptions = {\n maxAge: accessTokenMaxAge,\n };\n\n const refreshTokenCookieOptions = {\n maxAge: MAX_COOKIE_AGE_SECONDS,\n };\n\n // ID token is always stored (primary authentication token)\n await cookieStorage.set(OAuthTokenTypes.ID_TOKEN, tokens.id_token, {\n maxAge: idTokenMaxAge,\n });\n\n // Access token is optional - only set if it exists\n if (tokens.access_token) {\n await cookieStorage.set(\n OAuthTokenTypes.ACCESS_TOKEN,\n tokens.access_token,\n accessTokenCookieOptions,\n );\n }\n\n // Set refresh token if present with 400 day expiry\n if (tokens.refresh_token) {\n await cookieStorage.set(\n OAuthTokenTypes.REFRESH_TOKEN,\n tokens.refresh_token,\n refreshTokenCookieOptions,\n );\n }\n\n // Still store the access token expiration timestamp even if no access token\n await storage.set(\n OAuthTokenTypes.OIDC_SESSION_EXPIRES_AT,\n oidcSessionExpiresAt.toString(),\n {\n // This is primarily an OIDC client, so we use the ID token max age for the session timeout / refresh scheduling.\n maxAge: idTokenMaxAge,\n },\n );\n logger.debug(\"storeServerTokens\", {\n oidcSessionExpiresAt,\n refreshTokenMaxAge: MAX_COOKIE_AGE_SECONDS,\n idTokenMaxAge,\n hasAccessToken: !!tokens.access_token,\n });\n}\n\nexport async function clearTokens(storage: AuthStorage | CookieStorage) {\n // clear all local storage keys related to OAuth and CivicAuth SDK\n const clearOAuthPromises = [\n ...Object.values(OAuthTokenTypes),\n REFRESH_IN_PROGRESS,\n AUTOREFRESH_TIMEOUT_NAME,\n LOGOUT_STATE,\n ].map(async (key) => {\n await storage.delete(key);\n });\n await Promise.all([...clearOAuthPromises]);\n}\n\nexport async function clearAuthServerSession(storage: AuthStorage) {\n await storage.delete(AUTH_SERVER_SESSION);\n await storage.delete(AUTH_SERVER_LEGACY_SESSION);\n}\n\nexport async function clearUser(storage: AuthStorage) {\n const userSession = new GenericUserSession(storage);\n await userSession.clear();\n}\n\n/**\n * Smart token unwrapping for Safari's base64-encoding bug\n * Only unwraps tokens that are:\n * 1. Base64-encoded (Safari bug) - very long strings without dots\n * 2. Contain a JSON object with a 'value' property that's a valid JWT\n *\n * Does NOT unwrap React Router's normal {value: \"token\"} objects\n */\nfunction unwrapSafariTokenIfNeeded(token: string | null): string | null {\n if (!token) return token;\n\n // Safari-specific detection: base64-encoded JSON that's extremely long\n // Normal wrapped objects from React Router are much shorter and have different characteristics\n if (token && !token.includes(\".\") && token.length > 800) {\n try {\n // Try to decode as base64 and parse as JSON\n const decoded = JSON.parse(atob(token));\n\n // Verify this is Safari's bug: wrapped value must be a valid 3-part JWT\n if (\n decoded &&\n typeof decoded === \"object\" &&\n decoded.value &&\n typeof decoded.value === \"string\" &&\n decoded.value.split(\".\").length === 3\n ) {\n return decoded.value;\n }\n } catch (error) {\n console.error(\"HERE UTIL - SAFARI TOKEN UNWRAP FAILED\", error);\n }\n }\n\n return token;\n}\n\nexport async function retrieveTokens(\n storage: AuthStorage,\n): Promise<Partial<OIDCTokenResponseBody> | null> {\n const idToken = await storage.get(OAuthTokenTypes.ID_TOKEN);\n const accessToken = await storage.get(OAuthTokenTypes.ACCESS_TOKEN);\n const refreshToken = await storage.get(OAuthTokenTypes.REFRESH_TOKEN);\n const oidcSessionExpiresAt = await storage.get(\n OAuthTokenTypes.OIDC_SESSION_EXPIRES_AT,\n );\n\n return {\n id_token: unwrapSafariTokenIfNeeded(idToken) ?? undefined,\n access_token: unwrapSafariTokenIfNeeded(accessToken) ?? undefined,\n refresh_token: unwrapSafariTokenIfNeeded(refreshToken) ?? undefined,\n oidc_session_expires_at:\n oidcSessionExpiresAt !== null\n ? parseInt(oidcSessionExpiresAt, 10)\n : undefined, // Convert string to number\n };\n}\n\nexport async function retrieveOidcSessionExpiredAtSeconds(\n storage: AuthStorage,\n): Promise<number | null> {\n const valueSeconds = await storage.get(\n OAuthTokenTypes.OIDC_SESSION_EXPIRES_AT,\n );\n if (!valueSeconds) {\n return null;\n }\n const expiresAt = Number(valueSeconds);\n return isNaN(expiresAt) ? null : expiresAt;\n}\n\n// Single JWKS instance that persists for the lifetime of the SDK session\nlet cachedJWKS: ReturnType<typeof jose.createRemoteJWKSet> | null = null;\nlet cachedJwksUrl: string | null = null;\n\nexport async function validateOauth2Tokens(\n tokens: OIDCTokenResponseBody,\n jwksEndpoint: string,\n oauth2Client: OAuth2Client,\n issuer: string,\n): Promise<ParsedTokens> {\n // Only create a new JWKS instance if one doesn't exist yet\n if (!cachedJWKS || cachedJwksUrl !== jwksEndpoint) {\n cachedJWKS = jose.createRemoteJWKSet(new URL(jwksEndpoint));\n cachedJwksUrl = jwksEndpoint;\n }\n\n // Validate the ID token - this is now the primary token for authentication\n const idTokenResponse = await jose.jwtVerify<JWTPayload>(\n tokens.id_token,\n cachedJWKS,\n {\n issuer: getIssuerVariations(issuer),\n audience: oauth2Client.clientId,\n },\n );\n\n // Only validate the access token if it exists, but if present it must be valid\n let accessTokenPayload;\n if (tokens.access_token) {\n const accessTokenResponse = await jose.jwtVerify<JWTPayload>(\n tokens.access_token,\n cachedJWKS,\n {\n issuer: getIssuerVariations(issuer),\n },\n );\n accessTokenPayload = accessTokenResponse.payload;\n }\n\n return withoutUndefined({\n id_token: idTokenResponse.payload,\n access_token: accessTokenPayload,\n ...(tokens?.refresh_token ? { refresh_token: tokens.refresh_token } : {}),\n });\n}\n\n/**\n * Get backend endpoints with default values merged with custom configuration\n * @param backendEndpoints - Optional custom backend endpoints configuration\n * @returns Backend endpoints with defaults applied\n */\nexport function getBackendEndpoints(\n backendEndpoints?: BackendEndpoints,\n): BackendEndpoints {\n return {\n refresh: backendEndpoints?.refresh ?? \"/auth/refresh\",\n logout: backendEndpoints?.logout ?? \"/auth/logout\",\n user: backendEndpoints?.user ?? \"/auth/user\",\n };\n}\n\n/**\n * Resolves an endpoint URL by checking if it's already a full URL\n * or if it needs to be combined with a base URL\n * @param baseUrl - The base URL (e.g., \"https://api.example.com\")\n * @param endpoint - The endpoint that might be relative (e.g., \"/auth/logout\") or absolute (e.g., \"https://other-server.com/logout\")\n * @returns The resolved URL\n */\nexport function resolveEndpointUrl(\n baseUrl: string,\n endpoint: string | undefined,\n): string {\n // Handle undefined endpoint\n if (!endpoint) {\n throw new Error(\"Endpoint is undefined\");\n }\n\n // Check if endpoint is already a full URL\n if (endpoint.startsWith(\"http://\") || endpoint.startsWith(\"https://\")) {\n return endpoint;\n }\n\n // Concatenate base URL with relative endpoint\n return `${baseUrl}${endpoint}`;\n}\n\n/**\n * Determines the protocol from request headers or environment\n * Checks common proxy headers before falling back to URL or environment\n */\nexport function getProtocolFromRequest(request?: Request): string {\n if (!request) {\n // Fallback when no request available\n return process.env.NODE_ENV === \"production\" ? \"https:\" : \"http:\";\n }\n\n // Check common proxy headers that indicate the original protocol\n const forwardedProto = request.headers.get(\"x-forwarded-proto\");\n if (forwardedProto) {\n return forwardedProto === \"https\" ? \"https:\" : \"http:\";\n }\n\n const forwardedProtocol = request.headers.get(\"x-forwarded-protocol\");\n if (forwardedProtocol) {\n return forwardedProtocol === \"https\" ? \"https:\" : \"http:\";\n }\n\n // Parse the standard Forwarded header (RFC 7239)\n const forwarded = request.headers.get(\"forwarded\");\n if (forwarded) {\n const protoMatch = forwarded.match(/proto=([^;,\\s]+)/i);\n if (protoMatch) {\n return protoMatch[1] === \"https\" ? \"https:\" : \"http:\";\n }\n }\n\n // Extract from the request URL itself\n const url = new URL(request.url);\n return url.protocol;\n}\n\n/**\n * Detect Safari browser from user agent\n */\nexport function isSafariBrowser(request?: Request): boolean {\n if (!request) return false;\n\n const userAgent = request.headers.get(\"user-agent\") || \"\";\n return userAgent.includes(\"Safari\") && !userAgent.includes(\"Chrome\");\n}\n\n/**\n * Detect if running on localhost\n */\nexport function isLocalhostUrl(request?: Request): boolean {\n if (!request) return false;\n\n const url = new URL(request.url);\n return url.hostname === \"localhost\" || url.hostname === \"127.0.0.1\";\n}\n\n/**\n * Get cookie configuration based on environment and browser\n * Handles special cases for Safari on localhost and HTTPS detection\n *\n * @param request - Optional request object for environment detection\n * @returns Cookie configuration with secure and sameSite settings\n *\n * Configuration rules:\n * - Safari on localhost: Uses lax sameSite to avoid cross-origin issues\n * - HTTPS: Uses secure cookies with none sameSite for cross-origin iframe support\n * - HTTP localhost (non-Safari): Uses secure cookies for Chrome's localhost exception\n */\nexport function getCookieConfiguration(request?: Request): {\n secure: boolean;\n sameSite: \"lax\" | \"none\";\n} {\n const isSafari = isSafariBrowser(request);\n const isLocalhost = isLocalhostUrl(request);\n const protocol = getProtocolFromRequest(request);\n const isHttps = protocol === \"https:\";\n\n if (isSafari && isLocalhost) {\n // Safari on localhost: use lax to avoid cross-origin issues\n return {\n secure: false,\n sameSite: \"lax\",\n };\n } else if (isHttps) {\n // HTTPS (production): use none for cross-origin iframe support\n return {\n secure: true,\n sameSite: \"none\",\n };\n } else {\n // HTTP localhost (non-Safari): use secure: true for iframe compatibility\n // Chrome allows secure cookies on localhost HTTP\n // This allows secure: true cookies to work on localhost for iframe compatibility\n // Reference: Chrome's third-party cookie documentation\n return {\n secure: true,\n sameSite: \"none\",\n };\n }\n}\n"]}
|
package/dist/shared/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "@civic/auth:0.10.0-beta.
|
|
1
|
+
export declare const VERSION = "@civic/auth:0.10.0-beta.10";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/shared/version.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,OAAO,
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/shared/version.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,OAAO,+BAA+B,CAAC"}
|
package/dist/shared/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/shared/version.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAE/C,MAAM,CAAC,MAAM,OAAO,GAAG,
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/shared/version.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAE/C,MAAM,CAAC,MAAM,OAAO,GAAG,4BAA4B,CAAC","sourcesContent":["// This is an auto-generated file. Do not edit.\n\nexport const VERSION = \"@civic/auth:0.10.0-beta.10\";\n"]}
|
package/dist/types.d.ts
CHANGED
|
@@ -60,6 +60,7 @@ type SessionData = {
|
|
|
60
60
|
codeVerifier?: string;
|
|
61
61
|
displayMode?: DisplayMode;
|
|
62
62
|
openerUrl?: string;
|
|
63
|
+
wasRehydrated?: boolean;
|
|
63
64
|
};
|
|
64
65
|
type OIDCTokenResponseBody = {
|
|
65
66
|
id_token: string;
|
|
@@ -165,5 +166,8 @@ export interface AuthStorage {
|
|
|
165
166
|
set(key: string, value: string): Promise<void>;
|
|
166
167
|
delete(key: string): Promise<void>;
|
|
167
168
|
}
|
|
169
|
+
export interface SyncAuthStorage extends AuthStorage {
|
|
170
|
+
getSync(key: string): string | null;
|
|
171
|
+
}
|
|
168
172
|
export type IframeMode = "embedded" | "modal";
|
|
169
173
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAKA,MAAM,CAAN,IAAY,UAMX;AAND,WAAY,UAAU;IACpB,6CAA+B,CAAA;IAC/B,iDAAmC,CAAA;IACnC,+CAAiC,CAAA;IACjC,6BAAe,CAAA;IACf,yCAA2B,CAAA;AAC7B,CAAC,EANW,UAAU,KAAV,UAAU,QAMrB;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAKA,MAAM,CAAN,IAAY,UAMX;AAND,WAAY,UAAU;IACpB,6CAA+B,CAAA;IAC/B,iDAAmC,CAAA;IACnC,+CAAiC,CAAA;IACjC,6BAAe,CAAA;IACf,yCAA2B,CAAA;AAC7B,CAAC,EANW,UAAU,KAAV,UAAU,QAMrB;AAgJD,MAAM,SAAS,GAAG;IAChB,KAAK;IACL,SAAS;IACT,aAAa;IACb,cAAc;IACd,iBAAiB;CACT,CAAC;AAsGX,OAAO,EAAE,SAAS,EAAE,CAAC","sourcesContent":["import type { JWTPayload } from \"jose\";\n\ntype UnknownObject = Record<string, unknown>;\ntype EmptyObject = Record<string, never>;\n\nexport enum AuthStatus {\n AUTHENTICATED = \"authenticated\",\n UNAUTHENTICATED = \"unauthenticated\",\n AUTHENTICATING = \"authenticating\",\n ERROR = \"error\",\n SIGNING_OUT = \"signing_out\",\n}\n// Display modes for the auth flow\ntype DisplayMode = \"iframe\" | \"redirect\" | \"new_tab\" | \"custom_tab\";\n\ntype ColorMode = \"light\" | \"dark\" | \"auto\";\n\n// Framework types for analytics\nexport type FrameworkType =\n | \"vanillajs\"\n | \"reactjs\"\n | \"nextjs\"\n | \"server\"\n | \"react-router\";\n\n// Combined Auth and Session Service\ninterface AuthSessionService {\n // TODO DK NOTES: Should be in BrowserAuthSessionService, not relevant on backend\n loadAuthorizationUrl(\n authorizationURL: string,\n displayMode: DisplayMode,\n ): void;\n // TODO DK NOTES: overrideDisplayMode parameter not appropriate here - also - do we need both this and the above in the interface?\n getAuthorizationUrl(\n scopes: string[],\n overrideDisplayMode: DisplayMode,\n nonce?: string,\n ): Promise<string>;\n // TODO DK NOTES: display mode should be in browser version only. Also, do we need this and the above two in the top-level interface?\n signIn(\n displayMode: DisplayMode,\n scopes: string[],\n nonce?: string,\n ): Promise<void>;\n // TODO DK NOTES: Input should be an auth code - do not assume it comes via an url\n tokenExchange(responseUrl: string): Promise<SessionData>;\n // TODO DK NOTES: Should be async for flexibility\n getSessionData(): SessionData;\n // TODO DK NOTES: Should be async for flexibility\n updateSessionData(data: SessionData): void;\n getUserInfoService(): Promise<UserInfoService>;\n}\n\n// Token Service\ninterface TokenService {\n exchangeCodeForTokens(authCode: string): Promise<Tokens>;\n validateIdToken(idToken: string, nonce: string): boolean;\n refreshAccessToken(refreshToken: string): Promise<Tokens>;\n}\n\n// User Info Service\ninterface UserInfoService {\n getUserInfo<T extends UnknownObject>(\n accessToken: string,\n idToken: string | null,\n ): Promise<User<T> | null>;\n}\n\n// Resource Service\ninterface ResourceService {\n getProtectedResource(accessToken: string): Promise<unknown>;\n}\n\n// Auth Request (for internal use in AuthSessionService)\ntype AuthRequest = {\n clientId: string;\n redirectUri: string;\n state: string;\n nonce: string;\n scope: string;\n};\n\ntype Endpoints = {\n jwks: string;\n auth: string;\n token: string;\n userinfo: string;\n challenge?: string;\n endsession: string;\n};\n\ntype Config = {\n oauthServer: string;\n endpoints?: Endpoints;\n};\n\ntype SessionData = {\n authenticated: boolean; // TODO can this be inferred from the presence of the tokens?\n state?: string;\n accessToken?: string;\n refreshToken?: string;\n idToken?: string;\n oidcSessionExpiresAt?: number;\n codeVerifier?: string;\n displayMode?: DisplayMode;\n openerUrl?: string;\n wasRehydrated?: boolean;\n};\n\ntype OIDCTokenResponseBody = {\n id_token: string;\n access_token?: string; // Access token is now optional\n oidc_session_expires_at?: number;\n refresh_token?: string;\n expires_in?: number;\n token_type?: string;\n scope?: string;\n};\n\ntype ParsedTokens = {\n id_token: JWTPayload;\n access_token?: JWTPayload;\n refresh_token?: string;\n};\n\n// The format we expose to the frontend via hooks\ntype ForwardedTokens = Record<\n string,\n {\n idToken?: string;\n accessToken?: string;\n refreshToken?: string;\n }\n>;\n\n// The format in the JWT payload\ntype ForwardedTokensJWT = Record<\n string,\n {\n id_token?: string;\n access_token?: string;\n refresh_token?: string;\n scope?: string;\n }\n>;\n\ntype IdTokenPayload = JWTPayload & {\n forwardedTokens?: ForwardedTokensJWT;\n email?: string;\n name?: string;\n picture?: string;\n nonce: string;\n at_hash: string;\n};\n\nconst tokenKeys = [\n \"sub\",\n \"idToken\",\n \"accessToken\",\n \"refreshToken\",\n \"forwardedTokens\",\n] as const;\n\nexport type OAuthTokens = {\n idToken?: string;\n accessToken?: string;\n refreshToken?: string;\n};\n// Derive the Tokens type from the array\ntype Tokens = {\n [K in (typeof tokenKeys)[number]]: K extends \"forwardedTokens\"\n ? ForwardedTokens\n : string;\n};\n\n// Base user interface\ntype BaseUser = {\n id: string;\n email?: string;\n username?: string;\n name?: string;\n given_name?: string;\n family_name?: string;\n picture?: string;\n updated_at?: Date;\n};\n\ntype User<T extends UnknownObject | EmptyObject = EmptyObject> =\n T extends EmptyObject ? BaseUser : BaseUser & T;\n\ntype OpenIdConfiguration = {\n authorization_endpoint: string;\n claims_parameter_supported: boolean;\n claims_supported: string[];\n code_challenge_methods_supported: string[];\n end_session_endpoint: string;\n grant_types_supported: string[];\n issuer: string;\n jwks_uri: string;\n authorization_response_iss_parameter_supported: boolean;\n response_modes_supported: string[];\n response_types_supported: string[];\n scopes_supported: string[];\n subject_types_supported: string[];\n token_endpoint_auth_methods_supported: string[];\n token_endpoint_auth_signing_alg_values_supported: string[];\n token_endpoint: string;\n id_token_signing_alg_values_supported: string[];\n pushed_authorization_request_endpoint: string;\n request_parameter_supported: boolean;\n request_uri_parameter_supported: boolean;\n userinfo_endpoint: string;\n claim_types_supported: string[];\n};\n\ntype LoginPostMessage = {\n source: string;\n type: string;\n clientId: string;\n data:\n | {\n url: string;\n }\n | LoginAppDesignOptions;\n};\n\nexport type IframeAuthMessage = {\n source: \"civicloginApp\";\n type: \"auth_error\" | \"auth_error_try_again\";\n clientId: string;\n data: {\n url?: string;\n error?: string;\n };\n};\n\nexport type LoginAppDesignOptions = {\n colorMode: ColorMode;\n};\nexport type {\n LoginPostMessage,\n AuthSessionService,\n TokenService,\n UserInfoService,\n ResourceService,\n AuthRequest,\n Tokens,\n Endpoints,\n Config,\n SessionData,\n OIDCTokenResponseBody,\n ParsedTokens,\n BaseUser,\n User,\n DisplayMode,\n UnknownObject,\n EmptyObject,\n ForwardedTokens,\n ForwardedTokensJWT,\n IdTokenPayload,\n OpenIdConfiguration,\n ColorMode,\n};\nexport { tokenKeys };\nexport interface AuthStorage {\n get(key: string): Promise<string | null>;\n set(key: string, value: string): Promise<void>;\n delete(key: string): Promise<void>;\n}\nexport interface SyncAuthStorage extends AuthStorage {\n getSync(key: string): string | null;\n}\n\nexport type IframeMode = \"embedded\" | \"modal\";\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AuthConfig } from "../../server/config.js";
|
|
2
|
-
import type { OIDCTokenResponseBody } from "../../types.js";
|
|
2
|
+
import type { AuthStorage, OIDCTokenResponseBody } from "../../types.js";
|
|
3
3
|
import { GenericAuthenticationRefresher } from "../../shared/lib/GenericAuthenticationRefresher.js";
|
|
4
4
|
import type { AuthenticationEvents } from "./AuthenticationEvents.js";
|
|
5
5
|
/**
|
|
@@ -12,8 +12,8 @@ export declare class BackendAuthenticationRefresher extends GenericAuthenticatio
|
|
|
12
12
|
private loginUrl;
|
|
13
13
|
private autoRefreshTimeoutId?;
|
|
14
14
|
private events?;
|
|
15
|
-
constructor(authConfig: AuthConfig, loginUrl: string, onError: (error: Error) => Promise<void>, events?: AuthenticationEvents);
|
|
16
|
-
static build(authConfig: AuthConfig, loginUrl: string, onError: (error: Error) => Promise<void>, events?: AuthenticationEvents): Promise<BackendAuthenticationRefresher>;
|
|
15
|
+
constructor(authConfig: AuthConfig, storage: AuthStorage, loginUrl: string, onError: (error: Error) => Promise<void>, events?: AuthenticationEvents);
|
|
16
|
+
static build(authConfig: AuthConfig, storage: AuthStorage, loginUrl: string, onError: (error: Error) => Promise<void>, events?: AuthenticationEvents): Promise<BackendAuthenticationRefresher>;
|
|
17
17
|
/**
|
|
18
18
|
* Override getRefreshToken to indicate that backend flows don't need browser-accessible refresh tokens
|
|
19
19
|
*/
|
|
@@ -27,6 +27,7 @@ export declare class BackendAuthenticationRefresher extends GenericAuthenticatio
|
|
|
27
27
|
* since they're managed server-side in HTTP-only cookies
|
|
28
28
|
*/
|
|
29
29
|
storeTokens(tokenResponseBody: OIDCTokenResponseBody | null): Promise<void>;
|
|
30
|
+
handleAutoRefresh(): Promise<void>;
|
|
30
31
|
/**
|
|
31
32
|
* Setup auto-refresh for backend flows
|
|
32
33
|
* Since we can't access token expiration from HTTP-only cookies,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BackendAuthenticationRefresher.d.ts","sourceRoot":"","sources":["../../../src/vanillajs/auth/BackendAuthenticationRefresher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"BackendAuthenticationRefresher.d.ts","sourceRoot":"","sources":["../../../src/vanillajs/auth/BackendAuthenticationRefresher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACzE,OAAO,EAAE,8BAA8B,EAAE,MAAM,oDAAoD,CAAC;AAOpG,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAGtE;;;;GAIG;AACH,qBAAa,8BAA+B,SAAQ,8BAA8B;IAChF,OAAO,CAAC,MAAM,CAA0C;IACxD,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,oBAAoB,CAAC,CAAS;IACtC,OAAO,CAAC,MAAM,CAAC,CAAuB;gBAEpC,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,WAAW,EACpB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,IAAI,CAAC,EACxC,MAAM,CAAC,EAAE,oBAAoB;WAalB,KAAK,CAChB,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,WAAW,EACpB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,IAAI,CAAC,EACxC,MAAM,CAAC,EAAE,oBAAoB,GAC5B,OAAO,CAAC,8BAA8B,CAAC;IAU1C;;OAEG;IACY,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC;IAOjD;;OAEG;IACY,kBAAkB,IAAI,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC;IAuD1E;;;OAGG;IACG,WAAW,CACf,iBAAiB,EAAE,qBAAqB,GAAG,IAAI,GAC9C,OAAO,CAAC,IAAI,CAAC;IAQV,iBAAiB;IAkBvB;;;;OAIG;IACG,gBAAgB;IAgCtB;;OAEG;IACH,gBAAgB,IAAI,IAAI;CASzB"}
|