@civic/auth 0.9.0-beta.2 → 0.9.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/dist/server/ServerAuthenticationResolver.d.ts.map +1 -1
- package/dist/server/ServerAuthenticationResolver.js +0 -4
- package/dist/server/ServerAuthenticationResolver.js.map +1 -1
- package/dist/server/config.d.ts +3 -11
- package/dist/server/config.d.ts.map +1 -1
- package/dist/server/config.js.map +1 -1
- package/dist/server/login.d.ts.map +1 -1
- package/dist/server/login.js +0 -5
- package/dist/server/login.js.map +1 -1
- package/dist/server/logout.d.ts.map +1 -1
- package/dist/server/logout.js +0 -5
- package/dist/server/logout.js.map +1 -1
- package/dist/server/session.d.ts.map +1 -1
- package/dist/server/session.js +0 -4
- package/dist/server/session.js.map +1 -1
- package/dist/shared/lib/AuthenticationRefresherImpl.d.ts.map +1 -1
- package/dist/shared/lib/AuthenticationRefresherImpl.js +0 -4
- package/dist/shared/lib/AuthenticationRefresherImpl.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/vanillajs/auth/CivicAuth.d.ts.map +1 -1
- package/dist/vanillajs/auth/CivicAuth.js +9 -35
- package/dist/vanillajs/auth/CivicAuth.js.map +1 -1
- package/dist/vanillajs/auth/config/ConfigProcessor.js +1 -1
- package/dist/vanillajs/auth/config/ConfigProcessor.js.map +1 -1
- package/dist/vanillajs/auth/types/AuthTypes.d.ts +12 -31
- 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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ServerAuthenticationResolver.d.ts","sourceRoot":"","sources":["../../src/server/ServerAuthenticationResolver.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,WAAW,EACX,SAAS,EACT,qBAAqB,EACrB,WAAW,EACZ,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAUrD,OAAO,KAAK,EAAE,sBAAsB,EAAgB,MAAM,qBAAqB,CAAC;AAOhF,qBAAa,4BAA6B,YAAW,sBAAsB;IAMvE,QAAQ,CAAC,UAAU,EAAE,UAAU;IAC/B,QAAQ,CAAC,OAAO,EAAE,WAAW;IAC7B,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC;IAPjD,OAAO,CAAC,YAAY,CAAsB;IAC1C,OAAO,CAAC,YAAY,CAA2B;IAC/C,OAAO,CAAC,SAAS,CAAwB;IAEzC,OAAO;IAeP;;;;OAIG;IACG,gBAAgB,CACpB,WAAW,EAAE,WAAW,GAAG,IAAI,GAC9B,OAAO,CAAC,WAAW,CAAC;IA+DvB;;;OAGG;IACG,uBAAuB,CAAC,WAAW,UAAO,GAAG,OAAO,CAAC,WAAW,CAAC;IAmDvE,IAAI,WAAW,IAAI,MAAM,CAExB;IAEK,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"ServerAuthenticationResolver.d.ts","sourceRoot":"","sources":["../../src/server/ServerAuthenticationResolver.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,WAAW,EACX,SAAS,EACT,qBAAqB,EACrB,WAAW,EACZ,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAUrD,OAAO,KAAK,EAAE,sBAAsB,EAAgB,MAAM,qBAAqB,CAAC;AAOhF,qBAAa,4BAA6B,YAAW,sBAAsB;IAMvE,QAAQ,CAAC,UAAU,EAAE,UAAU;IAC/B,QAAQ,CAAC,OAAO,EAAE,WAAW;IAC7B,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC;IAPjD,OAAO,CAAC,YAAY,CAAsB;IAC1C,OAAO,CAAC,YAAY,CAA2B;IAC/C,OAAO,CAAC,SAAS,CAAwB;IAEzC,OAAO;IAeP;;;;OAIG;IACG,gBAAgB,CACpB,WAAW,EAAE,WAAW,GAAG,IAAI,GAC9B,OAAO,CAAC,WAAW,CAAC;IA+DvB;;;OAGG;IACG,uBAAuB,CAAC,WAAW,UAAO,GAAG,OAAO,CAAC,WAAW,CAAC;IAmDvE,IAAI,WAAW,IAAI,MAAM,CAExB;IAEK,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAkBrB,aAAa,CACjB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,qBAAqB,CAAC;IA4B3B,cAAc,IAAI,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAc7C,qBAAqB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;WAOxC,KAAK,CAChB,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,WAAW,EACpB,iBAAiB,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,GACrC,OAAO,CAAC,sBAAsB,CAAC;CAUnC"}
|
|
@@ -125,10 +125,6 @@ export class ServerAuthenticationResolver {
|
|
|
125
125
|
return this.authConfig.oauthServer || DEFAULT_AUTH_SERVER;
|
|
126
126
|
}
|
|
127
127
|
async init() {
|
|
128
|
-
// Ensure clientId is present for OAuth operations
|
|
129
|
-
if (!this.authConfig.clientId) {
|
|
130
|
-
throw new Error("clientId is required for OAuth server operations");
|
|
131
|
-
}
|
|
132
128
|
// resolve oauth config
|
|
133
129
|
this.endpoints = await getEndpointsWithOverrides(this.oauthServer, this.endpointOverrides);
|
|
134
130
|
this.oauth2client = new OAuth2Client(this.authConfig.clientId, this.endpoints.auth, this.endpoints.token, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ServerAuthenticationResolver.js","sourceRoot":"","sources":["../../src/server/ServerAuthenticationResolver.ts"],"names":[],"mappings":"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","sourcesContent":["import { GenericPublicClientPKCEProducer } from \"@/services/PKCE.js\";\nimport { OAuth2Client } from \"oslo/oauth2\";\nimport type {\n AuthStorage,\n Endpoints,\n OIDCTokenResponseBody,\n SessionData,\n} from \"@/types.js\";\nimport type { AuthConfig } from \"@/server/config.js\";\nimport {\n clearTokens,\n clearUser,\n exchangeTokens,\n getEndpointsWithOverrides,\n retrieveTokens,\n storeServerTokens,\n validateOauth2Tokens,\n} from \"@/shared/lib/util.js\";\nimport type { AuthenticationResolver, PKCEProducer } from \"@/services/types.ts\";\nimport { DEFAULT_AUTH_SERVER } from \"@/constants.js\";\nimport { CodeVerifier } from \"@/shared/lib/types.js\";\nimport { loggers } from \"@/lib/logger.js\";\n\nconst logger = loggers.services.validation;\n\nexport class ServerAuthenticationResolver implements AuthenticationResolver {\n private pkceProducer: PKCEProducer | null;\n private oauth2client: OAuth2Client | undefined;\n private endpoints: Endpoints | undefined;\n\n private constructor(\n readonly authConfig: AuthConfig,\n readonly storage: AuthStorage,\n readonly endpointOverrides?: Partial<Endpoints>,\n ) {\n // Determine if PKCE should be used based on config\n // Default to true\n const usePkce = authConfig.pkce !== false;\n\n // Only create PKCE producer if we're using PKCE\n this.pkceProducer = usePkce\n ? new GenericPublicClientPKCEProducer(storage)\n : null;\n }\n\n /**\n * Attempts to refresh tokens if a refresh token is available\n * @param sessionData Current session data\n * @returns Updated session data\n */\n async tryRefreshTokens(\n sessionData: SessionData | null,\n ): Promise<SessionData> {\n logger.debug(\"tryRefreshTokens\", { sessionData });\n // If there's a refresh token, attempt to refresh tokens\n if (sessionData?.refreshToken) {\n try {\n // Only attempt refresh if we have necessary components\n if (!this.oauth2client || !this.endpoints?.jwks) {\n await this.init();\n }\n\n if (!this.oauth2client || !this.endpoints?.jwks) {\n throw new Error(\n \"Failed to initialize OAuth client for token refresh\",\n );\n }\n\n // Use the oauth2client to refresh the access token\n const refreshOptions: Record<string, string> = {};\n if (this.authConfig.clientSecret) {\n refreshOptions.credentials = this.authConfig.clientSecret;\n refreshOptions.authenticateWith = \"request_body\";\n }\n\n const tokenResponseBody = (await this.oauth2client.refreshAccessToken(\n sessionData.refreshToken,\n refreshOptions,\n )) as OIDCTokenResponseBody;\n\n if (!tokenResponseBody) {\n throw new Error(\"Failed to get token response from refresh\");\n }\n\n // Validate the refreshed tokens\n await validateOauth2Tokens(\n tokenResponseBody,\n this.endpoints.jwks,\n this.oauth2client,\n this.oauthServer,\n );\n\n // Store the refreshed tokens\n await storeServerTokens(this.storage, tokenResponseBody);\n\n // Construct a refreshed session with the new tokens\n return {\n authenticated: true,\n idToken: tokenResponseBody.id_token,\n accessToken: tokenResponseBody.access_token,\n refreshToken: tokenResponseBody.refresh_token,\n oidcSessionExpiresAt: tokenResponseBody.oidc_session_expires_at,\n };\n } catch (error) {\n logger.warn(\"Failed to refresh tokens\", error);\n await clearTokens(this.storage);\n await clearUser(this.storage);\n return { ...sessionData, authenticated: false };\n }\n }\n\n // No refresh token available\n return { ...sessionData, authenticated: false };\n }\n\n /**\n * returns The session data if the session is valid, otherwise an unauthenticated session\n * @returns {Promise<SessionData>}\n */\n async validateExistingSession(autoRefresh = true): Promise<SessionData> {\n // TODO: investigate a more peformant way to validate a server session\n // other than using JWKS and JWT verification which is what validateOauth2Tokens uses\n const sessionData = await this.getSessionData();\n\n // If we don't have an ID token, try to refresh if we have a refresh token\n // Access token is no longer required for authentication\n if (!sessionData?.idToken) {\n if (autoRefresh) {\n const refreshedSessionData = await this.tryRefreshTokens(sessionData);\n if (refreshedSessionData.authenticated) {\n return refreshedSessionData;\n }\n }\n return { ...sessionData, authenticated: false };\n }\n\n // Initialize if needed\n if (!this.endpoints?.jwks || !this.oauth2client) await this.init();\n\n if (!this.endpoints?.jwks) {\n throw new Error(\"JWKS endpoint not found\");\n }\n\n try {\n // Validate existing tokens - access token validation happens only if it exists\n await validateOauth2Tokens(\n {\n access_token: sessionData.accessToken, // May be undefined\n id_token: sessionData.idToken, // Always required\n refresh_token: sessionData.refreshToken,\n oidc_session_expires_at: sessionData.oidcSessionExpiresAt,\n },\n this.endpoints.jwks,\n this.oauth2client!,\n this.oauthServer,\n );\n return sessionData;\n } catch (error) {\n logger.warn(\"Error validating tokens\", { error, autoRefresh });\n if (autoRefresh) {\n // If token validation fails, try to refresh tokens\n const refreshedSessionData = await this.tryRefreshTokens(sessionData);\n if (refreshedSessionData.authenticated) {\n return refreshedSessionData;\n }\n }\n return { ...sessionData, authenticated: false };\n }\n }\n\n get oauthServer(): string {\n return this.authConfig.oauthServer || DEFAULT_AUTH_SERVER;\n }\n\n async init(): Promise<this> {\n // Ensure clientId is present for OAuth operations\n if (!this.authConfig.clientId) {\n throw new Error(\"clientId is required for OAuth server operations\");\n }\n\n // resolve oauth config\n this.endpoints = await getEndpointsWithOverrides(\n this.oauthServer,\n this.endpointOverrides,\n );\n this.oauth2client = new OAuth2Client(\n this.authConfig.clientId,\n this.endpoints.auth,\n this.endpoints.token,\n {\n redirectURI: this.authConfig.redirectUrl,\n },\n );\n\n return this;\n }\n\n async tokenExchange(\n code: string,\n state: string,\n ): Promise<OIDCTokenResponseBody> {\n if (!this.oauth2client) await this.init();\n\n // Check if we're using PKCE and validate code verifier if needed\n if (this.pkceProducer) {\n const codeVerifier = await this.pkceProducer.getCodeVerifier();\n if (!codeVerifier) throw new Error(\"Code verifier not found in storage\");\n }\n\n // exchange auth code for tokens\n const tokens = await exchangeTokens(\n code,\n state,\n this.pkceProducer,\n this.oauth2client!, // clean up types here to avoid the ! operator\n this.oauthServer,\n this.endpoints!, // clean up types here to avoid the ! operator\n this.authConfig.clientSecret,\n );\n\n await storeServerTokens(this.storage, tokens);\n // the code verifier should be single-use, so we delete it if using PKCE\n if (this.pkceProducer) {\n await this.storage.delete(CodeVerifier.COOKIE_NAME);\n }\n return tokens;\n }\n\n async getSessionData(): Promise<SessionData | null> {\n const storageData = await retrieveTokens(this.storage);\n\n if (!storageData) return null;\n\n return {\n authenticated: !!storageData.id_token, // User is authenticated if they have an ID token\n idToken: storageData.id_token,\n accessToken: storageData.access_token, // Optional\n refreshToken: storageData.refresh_token,\n oidcSessionExpiresAt: storageData.oidc_session_expires_at,\n };\n }\n\n async getEndSessionEndpoint(): Promise<string | null> {\n if (!this.endpoints) {\n return null;\n }\n return this.endpoints.endsession;\n }\n\n static async build(\n authConfig: AuthConfig,\n storage: AuthStorage,\n endpointOverrides?: Partial<Endpoints>,\n ): Promise<AuthenticationResolver> {\n const resolver = new ServerAuthenticationResolver(\n authConfig,\n storage,\n endpointOverrides,\n );\n await resolver.init();\n\n return resolver;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ServerAuthenticationResolver.js","sourceRoot":"","sources":["../../src/server/ServerAuthenticationResolver.ts"],"names":[],"mappings":"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","sourcesContent":["import { GenericPublicClientPKCEProducer } from \"@/services/PKCE.js\";\nimport { OAuth2Client } from \"oslo/oauth2\";\nimport type {\n AuthStorage,\n Endpoints,\n OIDCTokenResponseBody,\n SessionData,\n} from \"@/types.js\";\nimport type { AuthConfig } from \"@/server/config.js\";\nimport {\n clearTokens,\n clearUser,\n exchangeTokens,\n getEndpointsWithOverrides,\n retrieveTokens,\n storeServerTokens,\n validateOauth2Tokens,\n} from \"@/shared/lib/util.js\";\nimport type { AuthenticationResolver, PKCEProducer } from \"@/services/types.ts\";\nimport { DEFAULT_AUTH_SERVER } from \"@/constants.js\";\nimport { CodeVerifier } from \"@/shared/lib/types.js\";\nimport { loggers } from \"@/lib/logger.js\";\n\nconst logger = loggers.services.validation;\n\nexport class ServerAuthenticationResolver implements AuthenticationResolver {\n private pkceProducer: PKCEProducer | null;\n private oauth2client: OAuth2Client | undefined;\n private endpoints: Endpoints | undefined;\n\n private constructor(\n readonly authConfig: AuthConfig,\n readonly storage: AuthStorage,\n readonly endpointOverrides?: Partial<Endpoints>,\n ) {\n // Determine if PKCE should be used based on config\n // Default to true\n const usePkce = authConfig.pkce !== false;\n\n // Only create PKCE producer if we're using PKCE\n this.pkceProducer = usePkce\n ? new GenericPublicClientPKCEProducer(storage)\n : null;\n }\n\n /**\n * Attempts to refresh tokens if a refresh token is available\n * @param sessionData Current session data\n * @returns Updated session data\n */\n async tryRefreshTokens(\n sessionData: SessionData | null,\n ): Promise<SessionData> {\n logger.debug(\"tryRefreshTokens\", { sessionData });\n // If there's a refresh token, attempt to refresh tokens\n if (sessionData?.refreshToken) {\n try {\n // Only attempt refresh if we have necessary components\n if (!this.oauth2client || !this.endpoints?.jwks) {\n await this.init();\n }\n\n if (!this.oauth2client || !this.endpoints?.jwks) {\n throw new Error(\n \"Failed to initialize OAuth client for token refresh\",\n );\n }\n\n // Use the oauth2client to refresh the access token\n const refreshOptions: Record<string, string> = {};\n if (this.authConfig.clientSecret) {\n refreshOptions.credentials = this.authConfig.clientSecret;\n refreshOptions.authenticateWith = \"request_body\";\n }\n\n const tokenResponseBody = (await this.oauth2client.refreshAccessToken(\n sessionData.refreshToken,\n refreshOptions,\n )) as OIDCTokenResponseBody;\n\n if (!tokenResponseBody) {\n throw new Error(\"Failed to get token response from refresh\");\n }\n\n // Validate the refreshed tokens\n await validateOauth2Tokens(\n tokenResponseBody,\n this.endpoints.jwks,\n this.oauth2client,\n this.oauthServer,\n );\n\n // Store the refreshed tokens\n await storeServerTokens(this.storage, tokenResponseBody);\n\n // Construct a refreshed session with the new tokens\n return {\n authenticated: true,\n idToken: tokenResponseBody.id_token,\n accessToken: tokenResponseBody.access_token,\n refreshToken: tokenResponseBody.refresh_token,\n oidcSessionExpiresAt: tokenResponseBody.oidc_session_expires_at,\n };\n } catch (error) {\n logger.warn(\"Failed to refresh tokens\", error);\n await clearTokens(this.storage);\n await clearUser(this.storage);\n return { ...sessionData, authenticated: false };\n }\n }\n\n // No refresh token available\n return { ...sessionData, authenticated: false };\n }\n\n /**\n * returns The session data if the session is valid, otherwise an unauthenticated session\n * @returns {Promise<SessionData>}\n */\n async validateExistingSession(autoRefresh = true): Promise<SessionData> {\n // TODO: investigate a more peformant way to validate a server session\n // other than using JWKS and JWT verification which is what validateOauth2Tokens uses\n const sessionData = await this.getSessionData();\n\n // If we don't have an ID token, try to refresh if we have a refresh token\n // Access token is no longer required for authentication\n if (!sessionData?.idToken) {\n if (autoRefresh) {\n const refreshedSessionData = await this.tryRefreshTokens(sessionData);\n if (refreshedSessionData.authenticated) {\n return refreshedSessionData;\n }\n }\n return { ...sessionData, authenticated: false };\n }\n\n // Initialize if needed\n if (!this.endpoints?.jwks || !this.oauth2client) await this.init();\n\n if (!this.endpoints?.jwks) {\n throw new Error(\"JWKS endpoint not found\");\n }\n\n try {\n // Validate existing tokens - access token validation happens only if it exists\n await validateOauth2Tokens(\n {\n access_token: sessionData.accessToken, // May be undefined\n id_token: sessionData.idToken, // Always required\n refresh_token: sessionData.refreshToken,\n oidc_session_expires_at: sessionData.oidcSessionExpiresAt,\n },\n this.endpoints.jwks,\n this.oauth2client!,\n this.oauthServer,\n );\n return sessionData;\n } catch (error) {\n logger.warn(\"Error validating tokens\", { error, autoRefresh });\n if (autoRefresh) {\n // If token validation fails, try to refresh tokens\n const refreshedSessionData = await this.tryRefreshTokens(sessionData);\n if (refreshedSessionData.authenticated) {\n return refreshedSessionData;\n }\n }\n return { ...sessionData, authenticated: false };\n }\n }\n\n get oauthServer(): string {\n return this.authConfig.oauthServer || DEFAULT_AUTH_SERVER;\n }\n\n async init(): Promise<this> {\n // resolve oauth config\n this.endpoints = await getEndpointsWithOverrides(\n this.oauthServer,\n this.endpointOverrides,\n );\n this.oauth2client = new OAuth2Client(\n this.authConfig.clientId,\n this.endpoints.auth,\n this.endpoints.token,\n {\n redirectURI: this.authConfig.redirectUrl,\n },\n );\n\n return this;\n }\n\n async tokenExchange(\n code: string,\n state: string,\n ): Promise<OIDCTokenResponseBody> {\n if (!this.oauth2client) await this.init();\n\n // Check if we're using PKCE and validate code verifier if needed\n if (this.pkceProducer) {\n const codeVerifier = await this.pkceProducer.getCodeVerifier();\n if (!codeVerifier) throw new Error(\"Code verifier not found in storage\");\n }\n\n // exchange auth code for tokens\n const tokens = await exchangeTokens(\n code,\n state,\n this.pkceProducer,\n this.oauth2client!, // clean up types here to avoid the ! operator\n this.oauthServer,\n this.endpoints!, // clean up types here to avoid the ! operator\n this.authConfig.clientSecret,\n );\n\n await storeServerTokens(this.storage, tokens);\n // the code verifier should be single-use, so we delete it if using PKCE\n if (this.pkceProducer) {\n await this.storage.delete(CodeVerifier.COOKIE_NAME);\n }\n return tokens;\n }\n\n async getSessionData(): Promise<SessionData | null> {\n const storageData = await retrieveTokens(this.storage);\n\n if (!storageData) return null;\n\n return {\n authenticated: !!storageData.id_token, // User is authenticated if they have an ID token\n idToken: storageData.id_token,\n accessToken: storageData.access_token, // Optional\n refreshToken: storageData.refresh_token,\n oidcSessionExpiresAt: storageData.oidc_session_expires_at,\n };\n }\n\n async getEndSessionEndpoint(): Promise<string | null> {\n if (!this.endpoints) {\n return null;\n }\n return this.endpoints.endsession;\n }\n\n static async build(\n authConfig: AuthConfig,\n storage: AuthStorage,\n endpointOverrides?: Partial<Endpoints>,\n ): Promise<AuthenticationResolver> {\n const resolver = new ServerAuthenticationResolver(\n authConfig,\n storage,\n endpointOverrides,\n );\n await resolver.init();\n\n return resolver;\n }\n}\n"]}
|
package/dist/server/config.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export interface BackendEndpoints {
|
|
|
12
12
|
user?: string;
|
|
13
13
|
}
|
|
14
14
|
export type AuthConfig = {
|
|
15
|
+
clientId: string;
|
|
15
16
|
clientSecret?: string;
|
|
16
17
|
pkce?: boolean;
|
|
17
18
|
redirectUrl: string;
|
|
@@ -20,6 +21,7 @@ export type AuthConfig = {
|
|
|
20
21
|
refreshUrl?: string;
|
|
21
22
|
endpointOverrides?: Partial<Endpoints> | undefined;
|
|
22
23
|
postLogoutRedirectUrl?: string;
|
|
24
|
+
loginUrl?: string;
|
|
23
25
|
/**
|
|
24
26
|
* Custom backend endpoints configuration for backend integration
|
|
25
27
|
* Only used when loginUrl is provided. Allows overriding default endpoints.
|
|
@@ -54,15 +56,5 @@ export type AuthConfig = {
|
|
|
54
56
|
* Useful for testing environments like Cypress where iframe detection may interfere with expected redirects.
|
|
55
57
|
*/
|
|
56
58
|
disableIframeDetection?: boolean;
|
|
57
|
-
}
|
|
58
|
-
/** OAuth client ID - required for standard OAuth flow */
|
|
59
|
-
clientId: string;
|
|
60
|
-
/** Custom login URL for backend integration - optional */
|
|
61
|
-
loginUrl?: string;
|
|
62
|
-
} | {
|
|
63
|
-
/** OAuth client ID - optional when using backend integration */
|
|
64
|
-
clientId?: string;
|
|
65
|
-
/** Custom login URL for backend integration - required when clientId is not provided */
|
|
66
|
-
loginUrl: string;
|
|
67
|
-
});
|
|
59
|
+
};
|
|
68
60
|
//# sourceMappingURL=config.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/server/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oDAAoD;IACpD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4EAA4E;IAC5E,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC;IACnD,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC;;;;;OAKG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;OAEG;IACH,IAAI,CAAC,EAAE;QACL,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC;QACrC,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,oBAAoB,CAAC,EAAE,MAAM,CAAC;QAC9B,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;QAC1B,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;KAC3B,CAAC;IACF;;OAEG;IACH,MAAM,CAAC,EAAE;QACP,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB,CAAC;IACF;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/server/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oDAAoD;IACpD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4EAA4E;IAC5E,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC;IACnD,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC;;;;;OAKG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;OAEG;IACH,IAAI,CAAC,EAAE;QACL,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC;QACrC,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,oBAAoB,CAAC,EAAE,MAAM,CAAC;QAC9B,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;QAC1B,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;KAC3B,CAAC;IACF;;OAEG;IACH,MAAM,CAAC,EAAE;QACP,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB,CAAC;IACF;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/server/config.ts"],"names":[],"mappings":"","sourcesContent":["import type { Endpoints } from \"@/types.ts\";\n\n/**\n * Configuration for backend authentication endpoints\n * Allows customization of API endpoints when using backend integration (loginUrl)\n */\nexport interface BackendEndpoints {\n /** Endpoint for token refresh (default: \"/auth/refresh\") */\n refresh?: string;\n /** Endpoint for logout (default: \"/auth/logout\") */\n logout?: string;\n /** Endpoint for user info and session validation (default: \"/auth/user\") */\n user?: string;\n}\n\nexport type AuthConfig = {\n clientSecret?: string; // Optional client secret for confidential clients\n pkce?: boolean; // Optional PKCE flag, defaults to true if not specified\n redirectUrl: string;\n oauthServer?: string;\n challengeUrl?: string;\n refreshUrl?: string;\n endpointOverrides?: Partial<Endpoints> | undefined;\n postLogoutRedirectUrl?: string;\n /**\n * Custom backend endpoints configuration for backend integration\n * Only used when loginUrl is provided. Allows overriding default endpoints.\n */\n backendEndpoints?: BackendEndpoints;\n /**\n * Optional URL to redirect frontend clients back to after successful authentication.\n * When provided, the backend will automatically redirect SPA clients to this URL\n * instead of traditional server-side redirects. Useful for backend + frontend integration.\n * Example: \"http://localhost:5173\" or \"https://your-spa.com\"\n */\n loginSuccessUrl?: string;\n /**\n * Optional CORS configuration for authentication endpoints\n */\n cors?: {\n origin?: string | string[] | boolean;\n credentials?: boolean;\n optionsSuccessStatus?: number;\n allowedHeaders?: string[];\n exposedHeaders?: string[];\n };\n /**\n * Optional logger configuration for authentication middleware\n */\n logger?: {\n enabled?: boolean; // Defaults to true if not specified\n };\n /**\n * Optional flag to disable iframe detection in handleCallback.\n * When true, callbacks will always attempt to redirect instead of returning HTML content for iframes.\n * Useful for testing environments like Cypress where iframe detection may interfere with expected redirects.\n */\n disableIframeDetection?: boolean;\n}
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/server/config.ts"],"names":[],"mappings":"","sourcesContent":["import type { Endpoints } from \"@/types.ts\";\n\n/**\n * Configuration for backend authentication endpoints\n * Allows customization of API endpoints when using backend integration (loginUrl)\n */\nexport interface BackendEndpoints {\n /** Endpoint for token refresh (default: \"/auth/refresh\") */\n refresh?: string;\n /** Endpoint for logout (default: \"/auth/logout\") */\n logout?: string;\n /** Endpoint for user info and session validation (default: \"/auth/user\") */\n user?: string;\n}\n\nexport type AuthConfig = {\n clientId: string;\n clientSecret?: string; // Optional client secret for confidential clients\n pkce?: boolean; // Optional PKCE flag, defaults to true if not specified\n redirectUrl: string;\n oauthServer?: string;\n challengeUrl?: string;\n refreshUrl?: string;\n endpointOverrides?: Partial<Endpoints> | undefined;\n postLogoutRedirectUrl?: string;\n loginUrl?: string;\n /**\n * Custom backend endpoints configuration for backend integration\n * Only used when loginUrl is provided. Allows overriding default endpoints.\n */\n backendEndpoints?: BackendEndpoints;\n /**\n * Optional URL to redirect frontend clients back to after successful authentication.\n * When provided, the backend will automatically redirect SPA clients to this URL\n * instead of traditional server-side redirects. Useful for backend + frontend integration.\n * Example: \"http://localhost:5173\" or \"https://your-spa.com\"\n */\n loginSuccessUrl?: string;\n /**\n * Optional CORS configuration for authentication endpoints\n */\n cors?: {\n origin?: string | string[] | boolean;\n credentials?: boolean;\n optionsSuccessStatus?: number;\n allowedHeaders?: string[];\n exposedHeaders?: string[];\n };\n /**\n * Optional logger configuration for authentication middleware\n */\n logger?: {\n enabled?: boolean; // Defaults to true if not specified\n };\n /**\n * Optional flag to disable iframe detection in handleCallback.\n * When true, callbacks will always attempt to redirect instead of returning HTML content for iframes.\n * Useful for testing environments like Cypress where iframe detection may interfere with expected redirects.\n */\n disableIframeDetection?: boolean;\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/server/login.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,qBAAqB,EACrB,aAAa,EACd,MAAM,YAAY,CAAC;AAKpB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGrD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;;;;;GAMG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,qBAAqB,CAAC,CAWhC;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAEvE;AAED,wBAAsB,aAAa,CACjC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,UAAU,GAAG,aAAa,CAAC,GAClD,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,GAAG,MAAM,GAAG,cAAc,CAAC,CAAC,GAAG;IACnE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,EACH,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/server/login.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,qBAAqB,EACrB,aAAa,EACd,MAAM,YAAY,CAAC;AAKpB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGrD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;;;;;GAMG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,qBAAqB,CAAC,CAWhC;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAEvE;AAED,wBAAsB,aAAa,CACjC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,UAAU,GAAG,aAAa,CAAC,GAClD,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,GAAG,MAAM,GAAG,cAAc,CAAC,CAAC,GAAG;IACnE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,EACH,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,GAAG,CAAC,CAsCd"}
|
package/dist/server/login.js
CHANGED
|
@@ -44,13 +44,8 @@ export async function buildLoginUrl(config, storage) {
|
|
|
44
44
|
const usePkce = config.pkce !== false;
|
|
45
45
|
// Only create PKCE producer if we're using PKCE and have storage
|
|
46
46
|
const pkceProducer = usePkce && storage ? new GenericPublicClientPKCEProducer(storage) : null;
|
|
47
|
-
// Ensure clientId is present for OAuth operations
|
|
48
|
-
if (!config.clientId) {
|
|
49
|
-
throw new Error("clientId is required for OAuth login operations");
|
|
50
|
-
}
|
|
51
47
|
const authInitiator = new GenericAuthenticationInitiator({
|
|
52
48
|
...config,
|
|
53
|
-
clientId: config.clientId,
|
|
54
49
|
state,
|
|
55
50
|
scopes,
|
|
56
51
|
oauthServer: config.oauthServer ?? DEFAULT_AUTH_SERVER,
|
package/dist/server/login.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/server/login.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrE,OAAO,EAAE,8BAA8B,EAAE,MAAM,qCAAqC,CAAC;AACrF,OAAO,EAAE,+BAA+B,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,4BAA4B,EAAE,MAAM,0CAA0C,CAAC;AAExF,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAY/C;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,IAAY,EACZ,KAAa,EACb,OAAoB,EACpB,MAAkB;IAElB,MAAM,kBAAkB,GAAG,MAAM,4BAA4B,CAAC,KAAK,CACjE;QACE,GAAG,MAAM;QACT,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,mBAAmB;KACvD,EACD,OAAO,EACP,MAAM,CAAC,iBAAiB,CACzB,CAAC;IAEF,OAAO,kBAAkB,CAAC,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,OAAoB;IACnD,OAAO,CAAC,CAAC,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAOG,EACH,OAAqB;IAErB,oFAAoF;IACpF,IAAI,KAAa,CAAC;IAClB,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,sEAAsE;QACtE,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;IACvB,CAAC;SAAM,IAAI,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;QACjD,wDAAwD;QACxD,KAAK,GAAG,aAAa,CAAC;YACpB,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,UAAU,EAAE,MAAM,CAAC,UAAU;SAC9B,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,oCAAoC;QACpC,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAClD,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,cAAc,CAAC;IAE/C,mDAAmD;IACnD,8DAA8D;IAC9D,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,KAAK,KAAK,CAAC;IAEtC,iEAAiE;IACjE,MAAM,YAAY,GAChB,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,IAAI,+BAA+B,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAE3E,
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/server/login.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrE,OAAO,EAAE,8BAA8B,EAAE,MAAM,qCAAqC,CAAC;AACrF,OAAO,EAAE,+BAA+B,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,4BAA4B,EAAE,MAAM,0CAA0C,CAAC;AAExF,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAY/C;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,IAAY,EACZ,KAAa,EACb,OAAoB,EACpB,MAAkB;IAElB,MAAM,kBAAkB,GAAG,MAAM,4BAA4B,CAAC,KAAK,CACjE;QACE,GAAG,MAAM;QACT,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,mBAAmB;KACvD,EACD,OAAO,EACP,MAAM,CAAC,iBAAiB,CACzB,CAAC;IAEF,OAAO,kBAAkB,CAAC,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,OAAoB;IACnD,OAAO,CAAC,CAAC,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAOG,EACH,OAAqB;IAErB,oFAAoF;IACpF,IAAI,KAAa,CAAC;IAClB,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,sEAAsE;QACtE,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;IACvB,CAAC;SAAM,IAAI,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;QACjD,wDAAwD;QACxD,KAAK,GAAG,aAAa,CAAC;YACpB,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,UAAU,EAAE,MAAM,CAAC,UAAU;SAC9B,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,oCAAoC;QACpC,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAClD,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,cAAc,CAAC;IAE/C,mDAAmD;IACnD,8DAA8D;IAC9D,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,KAAK,KAAK,CAAC;IAEtC,iEAAiE;IACjE,MAAM,YAAY,GAChB,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,IAAI,+BAA+B,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAE3E,MAAM,aAAa,GAAG,IAAI,8BAA8B,CAAC;QACvD,GAAG,MAAM;QACT,KAAK;QACL,MAAM;QACN,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,mBAAmB;QACtD,mGAAmG;QACnG,kEAAkE;QAClE,YAAY,EAAE,YAAY,IAAI,SAAS;KACxC,CAAC,CAAC;IAEH,OAAO,aAAa,CAAC,MAAM,EAAE,CAAC;AAChC,CAAC","sourcesContent":["import type {\n AuthStorage,\n OIDCTokenResponseBody,\n FrameworkType,\n} from \"@/types.js\";\nimport { DEFAULT_AUTH_SERVER, DEFAULT_SCOPES } from \"@/constants.js\";\nimport { GenericAuthenticationInitiator } from \"@/services/AuthenticationService.js\";\nimport { GenericPublicClientPKCEProducer } from \"@/services/PKCE.js\";\nimport { ServerAuthenticationResolver } from \"@/server/ServerAuthenticationResolver.js\";\nimport type { AuthConfig } from \"@/server/config.ts\";\nimport { generateState } from \"@/lib/oauth.js\";\n\n/**\n * Context interface for detecting frontend vs backend requests\n */\nexport interface RequestContext {\n referer?: string;\n origin?: string;\n userAgent?: string;\n acceptsJson?: boolean;\n}\n\n/**\n * Resolve an OAuth access code to a set of OIDC tokens\n * @param code The access code, typically from a query parameter in the redirect url\n * @param state The oauth random state string, used to distinguish between requests. Typically also passed in the redirect url\n * @param storage The place that this server uses to store session data (e.g. a cookie store)\n * @param config Oauth Server configuration\n */\nexport async function resolveOAuthAccessCode(\n code: string,\n state: string,\n storage: AuthStorage,\n config: AuthConfig,\n): Promise<OIDCTokenResponseBody> {\n const authSessionService = await ServerAuthenticationResolver.build(\n {\n ...config,\n oauthServer: config.oauthServer ?? DEFAULT_AUTH_SERVER,\n },\n storage,\n config.endpointOverrides,\n );\n\n return authSessionService.tokenExchange(code, state);\n}\n\nexport async function isLoggedIn(storage: AuthStorage): Promise<boolean> {\n return !!(await storage.get(\"id_token\"));\n}\n\nexport async function buildLoginUrl(\n config: Pick<AuthConfig, \"clientId\" | \"redirectUrl\"> &\n Partial<Pick<AuthConfig, \"oauthServer\" | \"pkce\" | \"clientSecret\">> & {\n scopes?: string[];\n state?: string;\n nonce?: string;\n framework?: FrameworkType;\n sdkVersion?: string;\n },\n storage?: AuthStorage,\n): Promise<URL> {\n // Generate state: prioritize provided state (which preserves frontend display mode)\n let state: string;\n if (config.state) {\n // Use the provided state (e.g., from frontend with display mode info)\n state = config.state;\n } else if (config.sdkVersion || config.framework) {\n // Generate new structured state with framework/SDK info\n state = generateState({\n framework: config.framework,\n sdkVersion: config.sdkVersion,\n });\n } else {\n // Generate random state as fallback\n state = Math.random().toString(36).substring(2);\n }\n\n const scopes = config.scopes ?? DEFAULT_SCOPES;\n\n // Determine if PKCE should be used based on config\n // Default to true for backward compatibility if not specified\n const usePkce = config.pkce !== false;\n\n // Only create PKCE producer if we're using PKCE and have storage\n const pkceProducer =\n usePkce && storage ? new GenericPublicClientPKCEProducer(storage) : null;\n\n const authInitiator = new GenericAuthenticationInitiator({\n ...config,\n state,\n scopes,\n oauthServer: config.oauthServer ?? DEFAULT_AUTH_SERVER,\n // When retrieving the PKCE challenge on the server-side, we produce it and store it in the session\n // For confidential clients not using PKCE, this will be undefined\n pkceConsumer: pkceProducer ?? undefined,\n });\n\n return authInitiator.signIn();\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logout.d.ts","sourceRoot":"","sources":["../../src/server/logout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAM9C,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,UAAU,GAAG,uBAAuB,CAAC,GAC5D,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC,GAAG;IACzC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,EACH,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"logout.d.ts","sourceRoot":"","sources":["../../src/server/logout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAM9C,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,UAAU,GAAG,uBAAuB,CAAC,GAC5D,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC,GAAG;IACzC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,EACH,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,GAAG,CAAC,CAkBd"}
|
package/dist/server/logout.js
CHANGED
|
@@ -3,17 +3,12 @@ import { GenericPublicClientPKCEProducer } from "../services/PKCE.js";
|
|
|
3
3
|
import { GenericAuthenticationInitiator } from "../services/AuthenticationService.js";
|
|
4
4
|
import { OAuthTokenTypes } from "../shared/lib/types.js";
|
|
5
5
|
export async function buildLogoutRedirectUrl(config, storage) {
|
|
6
|
-
// Ensure clientId is present for OAuth operations
|
|
7
|
-
if (!config.clientId) {
|
|
8
|
-
throw new Error("clientId is required for OAuth logout operations");
|
|
9
|
-
}
|
|
10
6
|
// generate a random state if not provided
|
|
11
7
|
const state = config.state ?? Math.random().toString(36).substring(2);
|
|
12
8
|
const scopes = config.scopes ?? DEFAULT_SCOPES;
|
|
13
9
|
const pkceProducer = new GenericPublicClientPKCEProducer(storage);
|
|
14
10
|
const authInitiator = new GenericAuthenticationInitiator({
|
|
15
11
|
...config,
|
|
16
|
-
clientId: config.clientId,
|
|
17
12
|
state,
|
|
18
13
|
scopes,
|
|
19
14
|
oauthServer: config.oauthServer ?? DEFAULT_AUTH_SERVER,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logout.js","sourceRoot":"","sources":["../../src/server/logout.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrE,OAAO,EAAE,+BAA+B,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,8BAA8B,EAAE,MAAM,qCAAqC,CAAC;AACrF,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,MAIG,EACH,OAAoB;IAEpB,
|
|
1
|
+
{"version":3,"file":"logout.js","sourceRoot":"","sources":["../../src/server/logout.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrE,OAAO,EAAE,+BAA+B,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,8BAA8B,EAAE,MAAM,qCAAqC,CAAC;AACrF,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,MAIG,EACH,OAAoB;IAEpB,0CAA0C;IAC1C,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IACtE,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,cAAc,CAAC;IAC/C,MAAM,YAAY,GAAG,IAAI,+BAA+B,CAAC,OAAO,CAAC,CAAC;IAClE,MAAM,aAAa,GAAG,IAAI,8BAA8B,CAAC;QACvD,GAAG,MAAM;QACT,KAAK;QACL,MAAM;QACN,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,mBAAmB;QACtD,YAAY,EAAE,YAAY;QAC1B,WAAW,EAAE,MAAM,CAAC,qBAAqB,IAAI,GAAG;KACjD,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;IAC5D,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAE9D,OAAO,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;AACxC,CAAC","sourcesContent":["import type { AuthConfig } from \"@/server/config.js\";\nimport type { AuthStorage } from \"@/types.js\";\nimport { DEFAULT_AUTH_SERVER, DEFAULT_SCOPES } from \"@/constants.js\";\nimport { GenericPublicClientPKCEProducer } from \"@/services/PKCE.js\";\nimport { GenericAuthenticationInitiator } from \"@/services/AuthenticationService.js\";\nimport { OAuthTokenTypes } from \"@/shared/lib/types.js\";\n\nexport async function buildLogoutRedirectUrl(\n config: Pick<AuthConfig, \"clientId\" | \"postLogoutRedirectUrl\"> &\n Partial<Pick<AuthConfig, \"oauthServer\">> & {\n scopes?: string[];\n state?: string;\n },\n storage: AuthStorage,\n): Promise<URL> {\n // generate a random state if not provided\n const state = config.state ?? Math.random().toString(36).substring(2);\n const scopes = config.scopes ?? DEFAULT_SCOPES;\n const pkceProducer = new GenericPublicClientPKCEProducer(storage);\n const authInitiator = new GenericAuthenticationInitiator({\n ...config,\n state,\n scopes,\n oauthServer: config.oauthServer ?? DEFAULT_AUTH_SERVER,\n pkceConsumer: pkceProducer,\n redirectUrl: config.postLogoutRedirectUrl || \"/\",\n });\n\n const idToken = await storage.get(OAuthTokenTypes.ID_TOKEN);\n if (!idToken) throw new Error(\"No id_token found in storage\");\n\n return authInitiator.signOut(idToken);\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/server/session.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,IAAI,EACT,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAE3B,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAgBrD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAIlE,MAAM,MAAM,qBAAqB,GAAG;IAClC,OAAO,EAAE;QACP,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC;QAC7C,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;KAC3B,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,qBAAqB,CAAC;CAC5B,CAAC;AAwCF;;;GAGG;AACH,qBAAa,SAAS;IAGlB,QAAQ,CAAC,OAAO,EAAE,WAAW;IAC7B,QAAQ,CAAC,UAAU,EAAE,UAAU;IAHjC,aAAa,EAAE,sBAAsB,GAAG,IAAI,CAAQ;gBAEzC,OAAO,EAAE,WAAW,EACpB,UAAU,EAAE,UAAU;IAGjC,IAAI,WAAW,IAAI,MAAM,CAExB;IAEK,eAAe,IAAI,OAAO,CAAC,sBAAsB,CAAC;IAaxD;;;OAGG;IACG,OAAO,CACX,CAAC,SAAS,aAAa,GAAG,WAAW,KAClC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAkB5B;;;OAGG;IACG,SAAS,IAAI,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAoB9C;;;;;OAKG;IACG,sBAAsB,CAC1B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,qBAAqB,CAAC;IAIjC;;;OAGG;IACG,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IAMpC;;;;OAIG;IACG,aAAa,CAAC,OAAO,CAAC,EAAE;QAC5B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,GAAG,OAAO,CAAC,GAAG,CAAC;IAchB;;;;OAIG;IACG,sBAAsB,CAAC,OAAO,CAAC,EAAE;QACrC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,GAAG,OAAO,CAAC,GAAG,CAAC;
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/server/session.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,IAAI,EACT,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAE3B,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAgBrD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAIlE,MAAM,MAAM,qBAAqB,GAAG;IAClC,OAAO,EAAE;QACP,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC;QAC7C,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;KAC3B,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,qBAAqB,CAAC;CAC5B,CAAC;AAwCF;;;GAGG;AACH,qBAAa,SAAS;IAGlB,QAAQ,CAAC,OAAO,EAAE,WAAW;IAC7B,QAAQ,CAAC,UAAU,EAAE,UAAU;IAHjC,aAAa,EAAE,sBAAsB,GAAG,IAAI,CAAQ;gBAEzC,OAAO,EAAE,WAAW,EACpB,UAAU,EAAE,UAAU;IAGjC,IAAI,WAAW,IAAI,MAAM,CAExB;IAEK,eAAe,IAAI,OAAO,CAAC,sBAAsB,CAAC;IAaxD;;;OAGG;IACG,OAAO,CACX,CAAC,SAAS,aAAa,GAAG,WAAW,KAClC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAkB5B;;;OAGG;IACG,SAAS,IAAI,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAoB9C;;;;;OAKG;IACG,sBAAsB,CAC1B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,qBAAqB,CAAC;IAIjC;;;OAGG;IACG,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IAMpC;;;;OAIG;IACG,aAAa,CAAC,OAAO,CAAC,EAAE;QAC5B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,GAAG,OAAO,CAAC,GAAG,CAAC;IAchB;;;;OAIG;IACG,sBAAsB,CAAC,OAAO,CAAC,EAAE;QACrC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,GAAG,OAAO,CAAC,GAAG,CAAC;IAyChB;;;OAGG;IACG,aAAa,IAAI,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC;IAI5D;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAIlC;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACG,cAAc,CAClB,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,oBAAoB,EAC1C,OAAO,CAAC,EAAE;QACR,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,WAAW,CAAC,EAAE,OAAO,CAAC;KACvB,GACA,OAAO,CAAC;QACT,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,OAAO,CAAC,EAAE,MAAM,GAAG;YAAE,OAAO,EAAE,OAAO,CAAC;YAAC,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAA;SAAE,CAAC;KAC7D,CAAC;IAyFF;;OAEG;IACH,OAAO,CAAC,4BAA4B;CA0DrC"}
|
package/dist/server/session.js
CHANGED
|
@@ -150,10 +150,6 @@ export class CivicAuth {
|
|
|
150
150
|
// since for logout we just need the raw ID token, not validated tokens
|
|
151
151
|
const tokens = await getTokensFromShared(this.storage);
|
|
152
152
|
if (tokens?.idToken) {
|
|
153
|
-
// Ensure clientId is present for OAuth operations
|
|
154
|
-
if (!this.authConfig.clientId) {
|
|
155
|
-
throw new Error("clientId is required for OAuth logout operations");
|
|
156
|
-
}
|
|
157
153
|
// We have access to the ID token from HTTP-only cookies
|
|
158
154
|
// Build the logout URL manually using the shared utility
|
|
159
155
|
const logoutUrl = await generateOauthLogoutUrl({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/server/session.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type AuthStorage,\n type OAuthTokens,\n type User,\n type EmptyObject,\n type UnknownObject,\n type OIDCTokenResponseBody,\n tokenKeys,\n} from \"@/types.js\";\nimport type { AuthConfig } from \"@/server/config.js\";\nimport {\n getUser as getUserFromShared,\n getTokens as getTokensFromShared,\n} from \"@/shared/lib/session.js\";\nimport { clearTokens as clearTokensUtil } from \"@/shared/lib/util.js\";\nimport { resolveOAuthAccessCode } from \"@/server/login.js\";\nimport { buildLoginUrl } from \"@/server/login.js\";\nimport { buildLogoutRedirectUrl } from \"@/server/logout.js\";\nimport { refreshTokens } from \"@/server/refresh.js\";\nimport { getVersion } from \"@/shared/index.js\";\nimport { ServerAuthenticationResolver } from \"@/server/ServerAuthenticationResolver.js\";\nimport {\n DEFAULT_AUTH_SERVER,\n JWT_PAYLOAD_KNOWN_CLAIM_KEYS,\n} from \"@/constants.js\";\nimport type { AuthenticationResolver } from \"@/services/types.js\";\nimport { displayModeFromState } from \"@/lib/oauth.js\";\nimport { decodeJwt, type JWTPayload } from \"jose\";\nimport { generateOauthLogoutUrl } from \"@/shared/lib/util.js\";\nexport type HandleCallbackRequest = {\n headers: {\n [key: string]: string | string[] | undefined;\n referer?: string;\n origin?: string;\n \"user-agent\"?: string;\n accept?: string;\n \"sec-fetch-dest\"?: string;\n };\n};\n\nexport type HandleCallbackParams = {\n code: string;\n state: string;\n req: HandleCallbackRequest;\n};\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\n/**\n * Extract user information directly from OIDC tokens\n * @param tokens The OIDC tokens response\n * @returns The user object or null if no valid ID token\n */\nfunction getUserFromTokens<T extends UnknownObject = EmptyObject>(\n tokens: OIDCTokenResponseBody,\n): User<T> | null {\n if (!tokens.id_token) return null;\n\n const parsedToken = decodeJwt(tokens.id_token) as JWTPayload & T;\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 // 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\n/**\n * CivicAuth is the main entry point for server-side authentication operations.\n * It provides a unified interface to all the authentication functions.\n */\nexport class CivicAuth {\n _authResolver: AuthenticationResolver | null = null;\n constructor(\n readonly storage: AuthStorage,\n readonly authConfig: AuthConfig,\n ) {}\n\n get oauthServer(): string {\n return this.authConfig.oauthServer || DEFAULT_AUTH_SERVER;\n }\n\n async getAuthResolver(): Promise<AuthenticationResolver> {\n if (this._authResolver) {\n return Promise.resolve(this._authResolver);\n }\n this._authResolver = await ServerAuthenticationResolver.build(\n {\n ...this.authConfig,\n oauthServer: this.oauthServer,\n },\n this.storage,\n );\n return this._authResolver;\n }\n /**\n * Gets the authenticated user with token validation\n * @returns The user object if authenticated, null otherwise\n */\n async getUser<\n T extends UnknownObject = EmptyObject,\n >(): Promise<User<T> | null> {\n const resolver = await this.getAuthResolver();\n\n try {\n // Validate the session before returning the user\n const session = await resolver.validateExistingSession();\n if (!session?.authenticated) {\n return null;\n }\n\n // If session is valid, use the shared implementation to get the user\n return getUserFromShared<T>(this.storage);\n } catch (error) {\n console.error(\"Token validation failed during getUser\", error);\n return null;\n }\n }\n\n /**\n * Gets the authentication tokens with token validation\n * @returns The tokens if authenticated, null otherwise\n */\n async getTokens(): Promise<OAuthTokens | null> {\n const resolver = await this.getAuthResolver();\n\n try {\n // Validate the session before returning the tokens\n const session = await resolver.validateExistingSession();\n\n if (!session?.authenticated) {\n return null;\n }\n\n // If session is valid, use the shared implementation to get the tokens\n const tokens = await getTokensFromShared(this.storage);\n return tokens;\n } catch (error) {\n console.error(\"❌ Token validation failed during getTokens\", error);\n return null;\n }\n }\n\n /**\n * Resolve an OAuth access code to a set of OIDC tokens\n * @param code The access code from the query parameter\n * @param state The OAuth state parameter\n * @returns OIDC tokens\n */\n async resolveOAuthAccessCode(\n code: string,\n state: string,\n ): Promise<OIDCTokenResponseBody> {\n return resolveOAuthAccessCode(code, state, this.storage, this.authConfig);\n }\n\n /**\n * Check if the user is currently logged in\n * @returns true if logged in, false otherwise\n */\n async isLoggedIn(): Promise<boolean> {\n const resolver = await this.getAuthResolver();\n const session = await resolver.validateExistingSession();\n return session?.authenticated ?? false;\n }\n\n /**\n * Build a login URL to redirect the user to\n * @param options Additional options for building the login URL\n * @returns The login URL\n */\n async buildLoginUrl(options?: {\n scopes?: string[];\n state?: string;\n nonce?: string;\n }): Promise<URL> {\n return buildLoginUrl(\n {\n ...this.authConfig,\n scopes: options?.scopes,\n state: options?.state,\n nonce: options?.nonce,\n framework: \"server\",\n sdkVersion: getVersion(),\n },\n this.storage,\n );\n }\n\n /**\n * Build a logout URL to redirect the user to\n * @param options Additional options for building the logout URL\n * @returns The logout URL\n */\n async buildLogoutRedirectUrl(options?: {\n scopes?: string[];\n state?: string;\n }): Promise<URL> {\n // For backend flows with HTTP-only cookies, try to get tokens directly\n // For logout, we don't need valid/authenticated tokens - just the ID token to build logout URL\n try {\n // Use the shared getTokens function directly - this bypasses session validation\n // since for logout we just need the raw ID token, not validated tokens\n const tokens = await getTokensFromShared(this.storage);\n\n if (tokens?.idToken) {\n // Ensure clientId is present for OAuth operations\n if (!this.authConfig.clientId) {\n throw new Error(\"clientId is required for OAuth logout operations\");\n }\n\n // We have access to the ID token from HTTP-only cookies\n // Build the logout URL manually using the shared utility\n\n const logoutUrl = await generateOauthLogoutUrl({\n clientId: this.authConfig.clientId,\n redirectUrl: this.authConfig.postLogoutRedirectUrl || \"/\",\n idToken: tokens.idToken,\n state: options?.state ?? Math.random().toString(36).substring(2),\n oauthServer: this.oauthServer,\n });\n\n return logoutUrl;\n }\n } catch (error) {\n // If direct token access fails, fall back to the generic function\n console.warn(\n \"❌ Could not get tokens directly from storage, falling back to generic logout method:\",\n error,\n );\n }\n\n // Fallback to the generic function for other storage types or when tokens aren't accessible\n return buildLogoutRedirectUrl(\n {\n ...this.authConfig,\n scopes: options?.scopes,\n state: options?.state,\n },\n this.storage,\n );\n }\n\n /**\n * Refresh the current set of OIDC tokens\n * @returns The refreshed tokens or null for backend flows where tokens are managed in HTTP-only cookies\n */\n async refreshTokens(): Promise<OIDCTokenResponseBody | null> {\n return refreshTokens(this.storage, this.authConfig);\n }\n\n /**\n * Clear all authentication tokens from storage\n */\n async clearTokens(): Promise<void> {\n return clearTokensUtil(this.storage);\n }\n\n /**\n * Smart callback handler that automatically detects frontend vs backend requests\n * and redirects appropriately. Use this instead of resolveOAuthAccessCode + manual redirect.\n *\n * @param params An object containing the authorization code, state, and the incoming request.\n * @param params.code The authorization code from query parameters.\n * @param params.state The OAuth state parameter.\n * @param params.req The incoming request object (e.g., from Express).\n * @param options Configuration options (frontendUrl override, apiResponse flag).\n * @returns Object with redirect information or HTML content for iframe completion.\n *\n * @example\n * ```javascript\n * app.get('/auth/callback', async (req, res) => {\n * const { code, state } = req.query;\n * // The request object 'req' is passed directly\n * const result = await req.civicAuth.handleCallback({ code, state, req });\n *\n * if (result.htmlContent) {\n * res.setHeader('Content-Type', 'text/html');\n * res.send(result.htmlContent);\n * } else if (result.redirectTo) {\n * res.redirect(result.redirectTo);\n * } else {\n * res.json({ success: true, user: result.user });\n * }\n * });\n * ```\n */\n async handleCallback(\n { code, state, req }: HandleCallbackParams,\n options?: {\n frontendUrl?: string;\n apiResponse?: boolean;\n },\n ): Promise<{\n redirectTo?: string;\n content?: string | { success: boolean; user?: User | null };\n }> {\n // First, resolve the OAuth code and create session\n const tokens = await this.resolveOAuthAccessCode(code, state);\n\n // Extract user info directly from tokens\n const user = getUserFromTokens(tokens);\n\n const frontendUrl = options?.frontendUrl || this.authConfig.loginSuccessUrl;\n\n // Priority 1: Check state for display mode configuration\n const stateDisplayMode = displayModeFromState(state, undefined);\n const isConfiguredForIframe = stateDisplayMode === \"iframe\";\n\n // Determine if this should be treated as an iframe request\n // Configuration (from state) takes precedence over auto-detection\n const shouldTreatAsIframe =\n isConfiguredForIframe && !this.authConfig.disableIframeDetection;\n\n const isTopLevelRedirect = req.headers[\"sec-fetch-dest\"] === \"document\";\n const isApiRequest =\n options?.apiResponse || req.headers.accept?.includes(\"application/json\");\n\n // Detect Safari or other browsers where iframe postMessage may fail due to cross-origin restrictions\n const userAgent = req.headers[\"user-agent\"] || \"\";\n const isSafari =\n userAgent.includes(\"Safari\") && !userAgent.includes(\"Chrome\");\n const isLikelyCrossOriginIframe =\n isSafari ||\n (userAgent.includes(\"WebKit\") && !userAgent.includes(\"Chrome\"));\n\n // Case 1: The request should be treated as iframe. Return HTML content.\n // Unless iframe detection is disabled via configuration OR we detect cross-origin issues\n if (\n shouldTreatAsIframe &&\n user &&\n frontendUrl &&\n !isLikelyCrossOriginIframe\n ) {\n const completionHtml = this.generateIframeCompletionHtml(user);\n return { content: completionHtml };\n }\n\n // Case 1b: Safari/cross-origin iframe case - redirect instead of HTML\n if (\n shouldTreatAsIframe &&\n user &&\n frontendUrl &&\n isLikelyCrossOriginIframe\n ) {\n return { redirectTo: frontendUrl };\n }\n\n // Case 2: The request is a top-level navigation. Return redirect URL.\n if (isTopLevelRedirect && frontendUrl) {\n return { redirectTo: frontendUrl };\n }\n\n // Case 3: The request is an API call. Return JSON content.\n if (isApiRequest) {\n return {\n content: {\n success: true,\n user,\n },\n };\n }\n\n // Fallback for older browsers or other contexts: if a frontend URL is configured,\n // assume a redirect to it.\n if (frontendUrl) {\n return { redirectTo: frontendUrl };\n }\n\n // Server-side fallback: if no frontend URL is configured but we have a postLogoutRedirectUrl,\n // redirect there instead of returning JSON content\n if (this.authConfig.postLogoutRedirectUrl) {\n return { redirectTo: this.authConfig.postLogoutRedirectUrl };\n }\n\n // Absolute fallback: return success as JSON content if no other conditions are met.\n // This could happen if no loginSuccessUrl or postLogoutRedirectUrl is configured.\n return {\n content: {\n success: true,\n user,\n },\n };\n }\n\n /**\n * Generate HTML content for iframe completion that sends postMessage to parent\n */\n private generateIframeCompletionHtml(user: User): string {\n const escapedUser = JSON.stringify(user).replace(/'/g, \"\\\\'\");\n const clientId = this.authConfig.clientId;\n\n return `\n <!DOCTYPE html>\n <html>\n <head>\n <title>Authentication Complete</title>\n <meta charset=\"utf-8\">\n </head>\n <body>\n <div style=\"text-align: center; padding: 20px; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\">\n <p>Authentication successful! Completing login...</p>\n </div>\n \n <!-- Success signal for SignalObserver -->\n <div id=\"civic-auth-success-signal\" style=\"display: none;\" data-user-info='${escapedUser}'>\n Authentication successful!\n </div>\n \n <script> \n // Send postMessage to parent to resolve authentication promise\n if (window.parent && window.parent !== window) {\n console.log('📤 Sending auth success postMessage to parent');\n try {\n window.parent.postMessage({\n type: 'auth_success',\n detail: 'Authentication successful',\n data: {\n user: ${escapedUser}\n }\n }, '*');\n } catch (error) {\n console.error('❌ Failed to send postMessage:', error);\n }\n \n // Also send civicloginApp format message for compatibility\n try {\n window.parent.postMessage({\n source: 'civicloginApp',\n type: 'auth_success',\n clientId: '${clientId}',\n data: {\n user: ${escapedUser}\n }\n }, '*');\n } catch (error) {\n console.error('❌ Failed to send civicloginApp message:', error);\n }\n } else {\n console.log('❌ Not in iframe context or no parent window');\n }\n </script>\n </body>\n </html>\n `;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/server/session.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type AuthStorage,\n type OAuthTokens,\n type User,\n type EmptyObject,\n type UnknownObject,\n type OIDCTokenResponseBody,\n tokenKeys,\n} from \"@/types.js\";\nimport type { AuthConfig } from \"@/server/config.js\";\nimport {\n getUser as getUserFromShared,\n getTokens as getTokensFromShared,\n} from \"@/shared/lib/session.js\";\nimport { clearTokens as clearTokensUtil } from \"@/shared/lib/util.js\";\nimport { resolveOAuthAccessCode } from \"@/server/login.js\";\nimport { buildLoginUrl } from \"@/server/login.js\";\nimport { buildLogoutRedirectUrl } from \"@/server/logout.js\";\nimport { refreshTokens } from \"@/server/refresh.js\";\nimport { getVersion } from \"@/shared/index.js\";\nimport { ServerAuthenticationResolver } from \"@/server/ServerAuthenticationResolver.js\";\nimport {\n DEFAULT_AUTH_SERVER,\n JWT_PAYLOAD_KNOWN_CLAIM_KEYS,\n} from \"@/constants.js\";\nimport type { AuthenticationResolver } from \"@/services/types.js\";\nimport { displayModeFromState } from \"@/lib/oauth.js\";\nimport { decodeJwt, type JWTPayload } from \"jose\";\nimport { generateOauthLogoutUrl } from \"@/shared/lib/util.js\";\nexport type HandleCallbackRequest = {\n headers: {\n [key: string]: string | string[] | undefined;\n referer?: string;\n origin?: string;\n \"user-agent\"?: string;\n accept?: string;\n \"sec-fetch-dest\"?: string;\n };\n};\n\nexport type HandleCallbackParams = {\n code: string;\n state: string;\n req: HandleCallbackRequest;\n};\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\n/**\n * Extract user information directly from OIDC tokens\n * @param tokens The OIDC tokens response\n * @returns The user object or null if no valid ID token\n */\nfunction getUserFromTokens<T extends UnknownObject = EmptyObject>(\n tokens: OIDCTokenResponseBody,\n): User<T> | null {\n if (!tokens.id_token) return null;\n\n const parsedToken = decodeJwt(tokens.id_token) as JWTPayload & T;\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 // 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\n/**\n * CivicAuth is the main entry point for server-side authentication operations.\n * It provides a unified interface to all the authentication functions.\n */\nexport class CivicAuth {\n _authResolver: AuthenticationResolver | null = null;\n constructor(\n readonly storage: AuthStorage,\n readonly authConfig: AuthConfig,\n ) {}\n\n get oauthServer(): string {\n return this.authConfig.oauthServer || DEFAULT_AUTH_SERVER;\n }\n\n async getAuthResolver(): Promise<AuthenticationResolver> {\n if (this._authResolver) {\n return Promise.resolve(this._authResolver);\n }\n this._authResolver = await ServerAuthenticationResolver.build(\n {\n ...this.authConfig,\n oauthServer: this.oauthServer,\n },\n this.storage,\n );\n return this._authResolver;\n }\n /**\n * Gets the authenticated user with token validation\n * @returns The user object if authenticated, null otherwise\n */\n async getUser<\n T extends UnknownObject = EmptyObject,\n >(): Promise<User<T> | null> {\n const resolver = await this.getAuthResolver();\n\n try {\n // Validate the session before returning the user\n const session = await resolver.validateExistingSession();\n if (!session?.authenticated) {\n return null;\n }\n\n // If session is valid, use the shared implementation to get the user\n return getUserFromShared<T>(this.storage);\n } catch (error) {\n console.error(\"Token validation failed during getUser\", error);\n return null;\n }\n }\n\n /**\n * Gets the authentication tokens with token validation\n * @returns The tokens if authenticated, null otherwise\n */\n async getTokens(): Promise<OAuthTokens | null> {\n const resolver = await this.getAuthResolver();\n\n try {\n // Validate the session before returning the tokens\n const session = await resolver.validateExistingSession();\n\n if (!session?.authenticated) {\n return null;\n }\n\n // If session is valid, use the shared implementation to get the tokens\n const tokens = await getTokensFromShared(this.storage);\n return tokens;\n } catch (error) {\n console.error(\"❌ Token validation failed during getTokens\", error);\n return null;\n }\n }\n\n /**\n * Resolve an OAuth access code to a set of OIDC tokens\n * @param code The access code from the query parameter\n * @param state The OAuth state parameter\n * @returns OIDC tokens\n */\n async resolveOAuthAccessCode(\n code: string,\n state: string,\n ): Promise<OIDCTokenResponseBody> {\n return resolveOAuthAccessCode(code, state, this.storage, this.authConfig);\n }\n\n /**\n * Check if the user is currently logged in\n * @returns true if logged in, false otherwise\n */\n async isLoggedIn(): Promise<boolean> {\n const resolver = await this.getAuthResolver();\n const session = await resolver.validateExistingSession();\n return session?.authenticated ?? false;\n }\n\n /**\n * Build a login URL to redirect the user to\n * @param options Additional options for building the login URL\n * @returns The login URL\n */\n async buildLoginUrl(options?: {\n scopes?: string[];\n state?: string;\n nonce?: string;\n }): Promise<URL> {\n return buildLoginUrl(\n {\n ...this.authConfig,\n scopes: options?.scopes,\n state: options?.state,\n nonce: options?.nonce,\n framework: \"server\",\n sdkVersion: getVersion(),\n },\n this.storage,\n );\n }\n\n /**\n * Build a logout URL to redirect the user to\n * @param options Additional options for building the logout URL\n * @returns The logout URL\n */\n async buildLogoutRedirectUrl(options?: {\n scopes?: string[];\n state?: string;\n }): Promise<URL> {\n // For backend flows with HTTP-only cookies, try to get tokens directly\n // For logout, we don't need valid/authenticated tokens - just the ID token to build logout URL\n try {\n // Use the shared getTokens function directly - this bypasses session validation\n // since for logout we just need the raw ID token, not validated tokens\n const tokens = await getTokensFromShared(this.storage);\n\n if (tokens?.idToken) {\n // We have access to the ID token from HTTP-only cookies\n // Build the logout URL manually using the shared utility\n\n const logoutUrl = await generateOauthLogoutUrl({\n clientId: this.authConfig.clientId,\n redirectUrl: this.authConfig.postLogoutRedirectUrl || \"/\",\n idToken: tokens.idToken,\n state: options?.state ?? Math.random().toString(36).substring(2),\n oauthServer: this.oauthServer,\n });\n\n return logoutUrl;\n }\n } catch (error) {\n // If direct token access fails, fall back to the generic function\n console.warn(\n \"❌ Could not get tokens directly from storage, falling back to generic logout method:\",\n error,\n );\n }\n\n // Fallback to the generic function for other storage types or when tokens aren't accessible\n return buildLogoutRedirectUrl(\n {\n ...this.authConfig,\n scopes: options?.scopes,\n state: options?.state,\n },\n this.storage,\n );\n }\n\n /**\n * Refresh the current set of OIDC tokens\n * @returns The refreshed tokens or null for backend flows where tokens are managed in HTTP-only cookies\n */\n async refreshTokens(): Promise<OIDCTokenResponseBody | null> {\n return refreshTokens(this.storage, this.authConfig);\n }\n\n /**\n * Clear all authentication tokens from storage\n */\n async clearTokens(): Promise<void> {\n return clearTokensUtil(this.storage);\n }\n\n /**\n * Smart callback handler that automatically detects frontend vs backend requests\n * and redirects appropriately. Use this instead of resolveOAuthAccessCode + manual redirect.\n *\n * @param params An object containing the authorization code, state, and the incoming request.\n * @param params.code The authorization code from query parameters.\n * @param params.state The OAuth state parameter.\n * @param params.req The incoming request object (e.g., from Express).\n * @param options Configuration options (frontendUrl override, apiResponse flag).\n * @returns Object with redirect information or HTML content for iframe completion.\n *\n * @example\n * ```javascript\n * app.get('/auth/callback', async (req, res) => {\n * const { code, state } = req.query;\n * // The request object 'req' is passed directly\n * const result = await req.civicAuth.handleCallback({ code, state, req });\n *\n * if (result.htmlContent) {\n * res.setHeader('Content-Type', 'text/html');\n * res.send(result.htmlContent);\n * } else if (result.redirectTo) {\n * res.redirect(result.redirectTo);\n * } else {\n * res.json({ success: true, user: result.user });\n * }\n * });\n * ```\n */\n async handleCallback(\n { code, state, req }: HandleCallbackParams,\n options?: {\n frontendUrl?: string;\n apiResponse?: boolean;\n },\n ): Promise<{\n redirectTo?: string;\n content?: string | { success: boolean; user?: User | null };\n }> {\n // First, resolve the OAuth code and create session\n const tokens = await this.resolveOAuthAccessCode(code, state);\n\n // Extract user info directly from tokens\n const user = getUserFromTokens(tokens);\n\n const frontendUrl = options?.frontendUrl || this.authConfig.loginSuccessUrl;\n\n // Priority 1: Check state for display mode configuration\n const stateDisplayMode = displayModeFromState(state, undefined);\n const isConfiguredForIframe = stateDisplayMode === \"iframe\";\n\n // Determine if this should be treated as an iframe request\n // Configuration (from state) takes precedence over auto-detection\n const shouldTreatAsIframe =\n isConfiguredForIframe && !this.authConfig.disableIframeDetection;\n\n const isTopLevelRedirect = req.headers[\"sec-fetch-dest\"] === \"document\";\n const isApiRequest =\n options?.apiResponse || req.headers.accept?.includes(\"application/json\");\n\n // Detect Safari or other browsers where iframe postMessage may fail due to cross-origin restrictions\n const userAgent = req.headers[\"user-agent\"] || \"\";\n const isSafari =\n userAgent.includes(\"Safari\") && !userAgent.includes(\"Chrome\");\n const isLikelyCrossOriginIframe =\n isSafari ||\n (userAgent.includes(\"WebKit\") && !userAgent.includes(\"Chrome\"));\n\n // Case 1: The request should be treated as iframe. Return HTML content.\n // Unless iframe detection is disabled via configuration OR we detect cross-origin issues\n if (\n shouldTreatAsIframe &&\n user &&\n frontendUrl &&\n !isLikelyCrossOriginIframe\n ) {\n const completionHtml = this.generateIframeCompletionHtml(user);\n return { content: completionHtml };\n }\n\n // Case 1b: Safari/cross-origin iframe case - redirect instead of HTML\n if (\n shouldTreatAsIframe &&\n user &&\n frontendUrl &&\n isLikelyCrossOriginIframe\n ) {\n return { redirectTo: frontendUrl };\n }\n\n // Case 2: The request is a top-level navigation. Return redirect URL.\n if (isTopLevelRedirect && frontendUrl) {\n return { redirectTo: frontendUrl };\n }\n\n // Case 3: The request is an API call. Return JSON content.\n if (isApiRequest) {\n return {\n content: {\n success: true,\n user,\n },\n };\n }\n\n // Fallback for older browsers or other contexts: if a frontend URL is configured,\n // assume a redirect to it.\n if (frontendUrl) {\n return { redirectTo: frontendUrl };\n }\n\n // Server-side fallback: if no frontend URL is configured but we have a postLogoutRedirectUrl,\n // redirect there instead of returning JSON content\n if (this.authConfig.postLogoutRedirectUrl) {\n return { redirectTo: this.authConfig.postLogoutRedirectUrl };\n }\n\n // Absolute fallback: return success as JSON content if no other conditions are met.\n // This could happen if no loginSuccessUrl or postLogoutRedirectUrl is configured.\n return {\n content: {\n success: true,\n user,\n },\n };\n }\n\n /**\n * Generate HTML content for iframe completion that sends postMessage to parent\n */\n private generateIframeCompletionHtml(user: User): string {\n const escapedUser = JSON.stringify(user).replace(/'/g, \"\\\\'\");\n const clientId = this.authConfig.clientId;\n\n return `\n <!DOCTYPE html>\n <html>\n <head>\n <title>Authentication Complete</title>\n <meta charset=\"utf-8\">\n </head>\n <body>\n <div style=\"text-align: center; padding: 20px; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\">\n <p>Authentication successful! Completing login...</p>\n </div>\n \n <!-- Success signal for SignalObserver -->\n <div id=\"civic-auth-success-signal\" style=\"display: none;\" data-user-info='${escapedUser}'>\n Authentication successful!\n </div>\n \n <script> \n // Send postMessage to parent to resolve authentication promise\n if (window.parent && window.parent !== window) {\n console.log('📤 Sending auth success postMessage to parent');\n try {\n window.parent.postMessage({\n type: 'auth_success',\n detail: 'Authentication successful',\n data: {\n user: ${escapedUser}\n }\n }, '*');\n } catch (error) {\n console.error('❌ Failed to send postMessage:', error);\n }\n \n // Also send civicloginApp format message for compatibility\n try {\n window.parent.postMessage({\n source: 'civicloginApp',\n type: 'auth_success',\n clientId: '${clientId}',\n data: {\n user: ${escapedUser}\n }\n }, '*');\n } catch (error) {\n console.error('❌ Failed to send civicloginApp message:', error);\n }\n } else {\n console.log('❌ Not in iframe context or no parent window');\n }\n </script>\n </body>\n </html>\n `;\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthenticationRefresherImpl.d.ts","sourceRoot":"","sources":["../../../src/shared/lib/AuthenticationRefresherImpl.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAQrD,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAEhF,OAAO,EAAE,8BAA8B,EAAE,MAAM,qCAAqC,CAAC;AAErF,qBAAa,2BAA4B,SAAQ,8BAA8B;IAO3E,SAAS,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC;IANlD,OAAO,CAAC,SAAS,CAAwB;IACzC,OAAO,CAAC,YAAY,CAA2B;gBAE7C,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,IAAI,CAAC,EAC9B,iBAAiB,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,YAAA;IAQ5C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"AuthenticationRefresherImpl.d.ts","sourceRoot":"","sources":["../../../src/shared/lib/AuthenticationRefresherImpl.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAQrD,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAEhF,OAAO,EAAE,8BAA8B,EAAE,MAAM,qCAAqC,CAAC;AAErF,qBAAa,2BAA4B,SAAQ,8BAA8B;IAO3E,SAAS,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC;IANlD,OAAO,CAAC,SAAS,CAAwB;IACzC,OAAO,CAAC,YAAY,CAA2B;gBAE7C,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,IAAI,CAAC,EAC9B,iBAAiB,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,YAAA;IAQ5C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;WAmBd,KAAK,CAChB,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,IAAI,CAAC,EACxC,iBAAiB,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,GACrC,OAAO,CAAC,2BAA2B,CAAC;IAYjC,WAAW,CACf,iBAAiB,EAAE,qBAAqB,GAAG,IAAI,GAC9C,OAAO,CAAC,IAAI,CAAC;IAQV,kBAAkB,IAAI,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC;CA8ClE"}
|
|
@@ -15,10 +15,6 @@ export class AuthenticationRefresherImpl extends GenericAuthenticationRefresher
|
|
|
15
15
|
async init() {
|
|
16
16
|
if (!this.authConfig)
|
|
17
17
|
throw new Error("No auth config available");
|
|
18
|
-
// Ensure clientId is present for OAuth operations
|
|
19
|
-
if (!this.authConfig.clientId) {
|
|
20
|
-
throw new Error("clientId is required for OAuth refresh operations");
|
|
21
|
-
}
|
|
22
18
|
// resolve oauth config
|
|
23
19
|
this.endpoints = await getEndpointsWithOverrides(this.oauthServer, this.endpointOverrides);
|
|
24
20
|
this.oauth2client = new OAuth2Client(this.authConfig.clientId, this.endpoints.auth, this.endpoints.token, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthenticationRefresherImpl.js","sourceRoot":"","sources":["../../../src/shared/lib/AuthenticationRefresherImpl.ts"],"names":[],"mappings":"AACA,OAAO,EACL,WAAW,EACX,SAAS,EACT,yBAAyB,EACzB,WAAW,EACX,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,8BAA8B,EAAE,MAAM,qCAAqC,CAAC;AAErF,MAAM,OAAO,2BAA4B,SAAQ,8BAA8B;IAOjE;IANJ,SAAS,CAAwB;IACjC,YAAY,CAA2B;IAC/C,YACE,UAAsB,EACtB,OAAoB,EACpB,OAAwC,EAC9B,iBAAsC;QAEhD,KAAK,CAAC,OAAO,CAAC,CAAC;QAFL,sBAAiB,GAAjB,iBAAiB,CAAqB;QAGhD,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,IAAI,EAAE,CAAC;IACd,CAAC;IAED,KAAK,CAAC,IAAI;QACR,IAAI,CAAC,IAAI,CAAC,UAAU;YAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"AuthenticationRefresherImpl.js","sourceRoot":"","sources":["../../../src/shared/lib/AuthenticationRefresherImpl.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AuthConfig } from \"@/server/config.js\";\nimport {\n clearTokens,\n clearUser,\n getEndpointsWithOverrides,\n storeTokens,\n validateOauth2Tokens,\n} from \"@/shared/lib/util.js\";\nimport type { AuthStorage, Endpoints, OIDCTokenResponseBody } from \"@/types.js\";\nimport { OAuth2Client } from \"oslo/oauth2\";\nimport { GenericAuthenticationRefresher } from \"./GenericAuthenticationRefresher.js\";\n\nexport class AuthenticationRefresherImpl extends GenericAuthenticationRefresher {\n private endpoints: Endpoints | undefined;\n private oauth2client: OAuth2Client | undefined;\n constructor(\n authConfig: AuthConfig,\n storage: AuthStorage,\n onError: (error: Error) => Promise<void>,\n protected endpointOverrides?: Partial<Endpoints>,\n ) {\n super(onError);\n this.authConfig = authConfig;\n this.storage = storage;\n this.init();\n }\n\n async init(): Promise<this> {\n if (!this.authConfig) throw new Error(\"No auth config available\");\n // resolve oauth config\n this.endpoints = await getEndpointsWithOverrides(\n this.oauthServer,\n this.endpointOverrides,\n );\n this.oauth2client = new OAuth2Client(\n this.authConfig.clientId,\n this.endpoints.auth,\n this.endpoints.token,\n {\n redirectURI: this.authConfig.redirectUrl,\n },\n );\n\n return this;\n }\n\n static async build(\n authConfig: AuthConfig,\n storage: AuthStorage,\n onError: (error: Error) => Promise<void>,\n endpointOverrides?: Partial<Endpoints>,\n ): Promise<AuthenticationRefresherImpl> {\n const refresher = new AuthenticationRefresherImpl(\n authConfig,\n storage,\n onError,\n endpointOverrides,\n );\n await refresher.init();\n\n return refresher;\n }\n\n async storeTokens(\n tokenResponseBody: OIDCTokenResponseBody | null,\n ): Promise<void> {\n if (!this.storage) throw new Error(\"No storage available\");\n // For null tokenResponseBody, we skip storage since tokens might be managed elsewhere (e.g., HTTP-only cookies)\n if (!tokenResponseBody) return;\n\n await storeTokens(this.storage, tokenResponseBody);\n }\n\n async refreshAccessToken(): Promise<OIDCTokenResponseBody | null> {\n if (!this.storage) throw new Error(\"No storage available\");\n\n try {\n const refreshToken = await this.getRefreshToken();\n if (!this.oauth2client) {\n await this.init();\n }\n\n if (!this.endpoints?.jwks) {\n throw new Error(\"No jwks endpoint\");\n }\n const oauth2Client = this.oauth2client!;\n\n try {\n const tokenResponseBody = (await oauth2Client.refreshAccessToken(\n refreshToken,\n )) as OIDCTokenResponseBody;\n\n // Validate the refreshed tokens - ID token is the primary token\n // Access token validation is now optional\n await validateOauth2Tokens(\n tokenResponseBody,\n this.endpoints.jwks,\n oauth2Client,\n this.oauthServer,\n );\n\n await this.storeTokens(tokenResponseBody);\n return tokenResponseBody;\n } catch (tokenRequestError) {\n console.error(\n \"Error during refresh token network request:\",\n tokenRequestError,\n );\n throw new Error(\n `Token refresh failed: ${(tokenRequestError as Error).message}`,\n );\n }\n } catch (error) {\n console.warn(\"refreshAccessToken failed\");\n await clearTokens(this.storage);\n await clearUser(this.storage);\n throw error;\n }\n }\n}\n"]}
|
package/dist/shared/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "@civic/auth:0.9.0
|
|
1
|
+
export declare const VERSION = "@civic/auth:0.9.0";
|
|
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,sBAAsB,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,mBAAmB,CAAC","sourcesContent":["// This is an auto-generated file. Do not edit.\n\nexport const VERSION = \"@civic/auth:0.9.0\";\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CivicAuth.d.ts","sourceRoot":"","sources":["../../../src/vanillajs/auth/CivicAuth.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"CivicAuth.d.ts","sourceRoot":"","sources":["../../../src/vanillajs/auth/CivicAuth.ts"],"names":[],"mappings":"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"}
|
|
@@ -135,24 +135,15 @@ export class CivicAuth {
|
|
|
135
135
|
});
|
|
136
136
|
// Initialize SessionManager with auth config
|
|
137
137
|
if (this.sessionManager) {
|
|
138
|
-
const
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
}
|
|
148
|
-
: {
|
|
149
|
-
// Standard OAuth mode: clientId required, loginUrl optional
|
|
150
|
-
clientId: this.config.clientId,
|
|
151
|
-
loginUrl,
|
|
152
|
-
redirectUrl: this.config.redirectUrl,
|
|
153
|
-
oauthServer: this.config.oauthServerBaseUrl,
|
|
154
|
-
backendEndpoints: this.config.backendEndpoints,
|
|
155
|
-
};
|
|
138
|
+
const authConfig = {
|
|
139
|
+
clientId: this.config.clientId,
|
|
140
|
+
redirectUrl: this.config.redirectUrl,
|
|
141
|
+
oauthServer: this.config.oauthServerBaseUrl,
|
|
142
|
+
scopes: this.config.scopes,
|
|
143
|
+
endpoints: this.endpoints,
|
|
144
|
+
loginUrl: this.config.loginUrl || this.loginUrl, // Include loginUrl for backend flows
|
|
145
|
+
backendEndpoints: this.config.backendEndpoints, // Pass backend endpoints config
|
|
146
|
+
};
|
|
156
147
|
this.logger.info("🔧 Initializing SessionManager", { authConfig });
|
|
157
148
|
await this.sessionManager.initializeWithAuthConfig(authConfig);
|
|
158
149
|
}
|
|
@@ -312,10 +303,6 @@ export class CivicAuth {
|
|
|
312
303
|
if (!this.endpoints) {
|
|
313
304
|
throw new CivicAuthError("OAuth endpoints not initialized. Please wait for initialization to complete.", CivicAuthErrorCode.ENDPOINTS_NOT_INITIALIZED);
|
|
314
305
|
}
|
|
315
|
-
// Ensure clientId is present for OAuth flow (it should be according to our discriminated union)
|
|
316
|
-
if (!this.config.clientId) {
|
|
317
|
-
throw new CivicAuthError("ClientId is required for OAuth flow when loginUrl is not provided.", CivicAuthErrorCode.CONFIG_REQUIRED);
|
|
318
|
-
}
|
|
319
306
|
const pkceProducer = new GenericPublicClientPKCEProducer(this.storage);
|
|
320
307
|
const codeChallenge = await pkceProducer.getCodeChallenge();
|
|
321
308
|
const state = this.config.initialState ||
|
|
@@ -726,15 +713,6 @@ export class CivicAuth {
|
|
|
726
713
|
redirectUrl: this.config.redirectUrl,
|
|
727
714
|
});
|
|
728
715
|
try {
|
|
729
|
-
// Only handle OAuth callback if not using backend integration
|
|
730
|
-
if (!this.config.clientId && this.config.loginUrl) {
|
|
731
|
-
this.logger.info("📞 Backend integration mode - skipping OAuth callback handling");
|
|
732
|
-
return;
|
|
733
|
-
}
|
|
734
|
-
// Ensure clientId is available for OAuth callback
|
|
735
|
-
if (!this.config.clientId) {
|
|
736
|
-
throw new Error("ClientId is required for OAuth callback handling");
|
|
737
|
-
}
|
|
738
716
|
const callbackHandled = await handleOAuthRedirectPage({
|
|
739
717
|
clientId: this.config.clientId,
|
|
740
718
|
oauthServer: this.config.oauthServerBaseUrl,
|
|
@@ -981,10 +959,6 @@ export class CivicAuth {
|
|
|
981
959
|
// Store logout state for cleanup after redirect
|
|
982
960
|
// This matches the React implementation - only store state for redirect flow
|
|
983
961
|
await this.storage.set(LOGOUT_STATE, state);
|
|
984
|
-
// Ensure clientId is available for OAuth logout
|
|
985
|
-
if (!this.config.clientId) {
|
|
986
|
-
throw new Error("ClientId is required for OAuth logout flow");
|
|
987
|
-
}
|
|
988
962
|
// Generate logout URL
|
|
989
963
|
const logoutUrl = await generateOauthLogoutUrl({
|
|
990
964
|
clientId: this.config.clientId,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CivicAuth.js","sourceRoot":"","sources":["../../../src/vanillajs/auth/CivicAuth.ts"],"names":[],"mappings":"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","sourcesContent":["import { AuthEvent } from \"../types/index.js\";\nimport type { Endpoints, AuthStorage } from \"../../types.js\";\nimport { buildAuthUrl, extractTokensFromSession } from \"../utils/auth-utils.js\";\nimport type { AuthResult, Session } from \"../types/index.js\";\nimport type { createLogger } from \"../utils/logger.js\";\nimport {\n createMainLogger,\n configureLogging,\n setCurrentLogger,\n} from \"../utils/logger.js\";\nimport { GenericPublicClientPKCEProducer } from \"../../services/PKCE.js\";\nimport { generateState } from \"../../lib/oauth.js\";\nimport { SessionManager } from \"./SessionManager.js\";\nimport { AuthenticationEvents } from \"./AuthenticationEvents.js\";\nimport { PopupError } from \"../../services/types.js\";\nimport { getVersion } from \"../../shared/index.js\";\nimport { handleOAuthRedirectPage } from \"./handlers/OAuthCallbackHandler.js\";\nimport {\n generateOauthLogoutUrl,\n clearTokens,\n retrieveTokens,\n getBackendEndpoints,\n} from \"../../shared/lib/util.js\";\nimport { LOGOUT_STATE } from \"../../constants.js\";\nimport { getOauthEndpoints } from \"../../lib/oauth.js\";\nimport { collectAndSendSDKAnalytics } from \"../../lib/analytics.js\";\nimport type { AuthConfig } from \"../../server/config.js\";\n\n// Import new modular components\nimport type {\n CivicAuthClientConfig,\n ProcessedCivicAuthConfig,\n} from \"./types/AuthTypes.js\";\nimport {\n CivicAuthError,\n CivicAuthErrorCode,\n CIVIC_AUTH_CONSTANTS,\n} from \"./types/AuthTypes.js\";\nimport { processConfigWithDefaults } from \"./config/ConfigProcessor.js\";\nimport { MessageHandler } from \"./handlers/MessageHandler.js\";\nimport { PopupHandler } from \"./handlers/PopupHandler.js\";\nimport { IframeAuthHandler } from \"./handlers/IframeAuthHandler.js\";\nimport { IframeManager } from \"../iframe/IframeManager.js\";\n\n/**\n * CivicAuth client for handling OAuth authentication\n *\n * This is a refactored version that uses a modular architecture for better maintainability.\n */\nexport class CivicAuth {\n private config: ProcessedCivicAuthConfig;\n private storage: AuthStorage;\n private endpoints?: Endpoints;\n private logger: ReturnType<typeof createLogger>;\n private sessionManager: SessionManager;\n private events: AuthenticationEvents;\n private initialDisplayMode:\n | \"iframe\"\n | \"modal\"\n | \"redirect\"\n | \"new_tab\"\n | \"custom_tab\";\n\n // Authentication state\n private authPromise?: Promise<AuthResult>;\n private authPromiseResolve?: (value: AuthResult) => void;\n private authPromiseReject?: (reason?: Error) => void;\n private authProcessTimeoutHandle?: number;\n private popupFailureTimeoutHandle?: number;\n private hasPopupFailed: boolean = false;\n private hasSignInStarted: boolean = false;\n\n // Backend integration - custom login URL\n private loginUrl?: string;\n\n // Handlers\n private messageHandler?: MessageHandler;\n private popupHandler?: PopupHandler;\n private iframeAuthHandler?: IframeAuthHandler;\n\n /**\n * Private constructor - initializes configuration and handlers.\n * Use {@link CivicAuth.create} to create a new instance.\n */\n private constructor(config: CivicAuthClientConfig) {\n // Process config with defaults and validation\n this.config = processConfigWithDefaults(config);\n this.initialDisplayMode = this.config.displayMode;\n\n // Set loginUrl from config if provided\n this.loginUrl = this.config.loginUrl;\n\n // Configure logging\n configureLogging(this.config.logging);\n\n // Initialize logger - always use \"vanillajs\" as base namespace\n if (this.config.logging?.enabled) {\n this.logger = createMainLogger(\"vanillajs\"); // Always use \"vanillajs\"\n } else {\n this.logger = {\n debug: () => {},\n info: () => {},\n warn: () => {},\n error: () => {},\n };\n }\n\n setCurrentLogger(this.logger);\n this.storage = this.config.storageAdapter;\n\n // Always initialize events - use provided events or create default instance\n this.events = config.events || new AuthenticationEvents();\n\n // Always initialize SessionManager\n this.sessionManager = new SessionManager(\n this.storage,\n this.events,\n this.config,\n );\n\n // Initialize handlers\n this.initializeHandlers();\n }\n\n /**\n * Creates and initializes a new instance of CivicAuth.\n * This is the recommended way to create a CivicAuth instance.\n *\n * @param config - Configuration options for the auth client\n * @returns A promise that resolves with the initialized CivicAuth instance\n * @throws {CivicAuthError} If initialization fails or required configuration is missing\n *\n * @example\n * ```typescript\n * // Standard SPA authentication\n * const auth = await CivicAuth.create({\n * clientId: \"your-client-id\",\n * // redirectUrl is optional - defaults to current page (window.location.origin + window.location.pathname)\n * redirectUrl: \"https://your-app.com/callback\", // optional\n * // logoutRedirectUrl is optional - defaults to redirectUrl if not provided\n * logoutRedirectUrl: \"https://your-app.com/logout\", // optional\n * // oauthServerBaseUrl is optional - defaults to \"https://auth.civic.com/oauth\"\n * oauthServerBaseUrl: \"https://auth-server.com/\", // optional\n * // scopes is optional - defaults to ['openid', 'profile', 'email', 'offline_access']\n * scopes: [\"openid\", \"profile\"], // optional\n * targetContainerElement: \"auth-container\",\n * textSignals: {\n * success: \"Authentication successful!\"\n * }\n * });\n *\n * // Backend integration authentication\n * const authWithBackend = await CivicAuth.create({\n * clientId: \"your-client-id\",\n * loginUrl: \"http://example.com/custom-backendurl\" // Automatically uses BrowserCookieStorage\n * });\n * ```\n */\n public static async create(\n config: CivicAuthClientConfig,\n ): Promise<CivicAuth> {\n const instance = new CivicAuth(config);\n await instance.init();\n return instance;\n }\n\n /**\n * Initializes the auth client and checks for callback handling\n */\n private async init(): Promise<void> {\n this.logger.info(\"🚀 Initializing CivicAuth\", {\n currentUrl: window.location.href,\n redirectUrl: this.config.redirectUrl,\n oauthServerBaseUrl: this.config.oauthServerBaseUrl,\n isCallbackUrl: window.location.href.startsWith(this.config.redirectUrl),\n });\n\n try {\n // Get OAuth endpoints using shared function (handles trailing slash automatically)\n this.endpoints = await getOauthEndpoints(this.config.oauthServerBaseUrl);\n\n this.logger.info(\"🔗 OAuth endpoints configured\", {\n endpoints: this.endpoints,\n });\n\n // Initialize SessionManager with auth config\n if (this.sessionManager) {\n const loginUrl = this.config.loginUrl || this.loginUrl;\n\n // Construct authConfig based on our discriminated union pattern\n const authConfig: AuthConfig =\n loginUrl && !this.config.clientId\n ? {\n // Backend integration mode: loginUrl required, clientId optional\n loginUrl,\n redirectUrl: this.config.redirectUrl,\n oauthServer: this.config.oauthServerBaseUrl,\n backendEndpoints: this.config.backendEndpoints,\n }\n : {\n // Standard OAuth mode: clientId required, loginUrl optional\n clientId: this.config.clientId!,\n loginUrl,\n redirectUrl: this.config.redirectUrl,\n oauthServer: this.config.oauthServerBaseUrl,\n backendEndpoints: this.config.backendEndpoints,\n };\n\n this.logger.info(\"🔧 Initializing SessionManager\", { authConfig });\n await this.sessionManager.initializeWithAuthConfig(authConfig);\n }\n\n // Check if we're on the callback page\n const isCallbackPage = window.location.href.startsWith(\n this.config.redirectUrl,\n );\n this.logger.info(\"🔍 Callback page check\", {\n isCallbackPage,\n currentUrl: window.location.href,\n redirectUrl: this.config.redirectUrl,\n });\n\n // Handle logout state cleanup first (before processing auth callbacks)\n await this.handleLogoutStateCleanup();\n\n if (isCallbackPage) {\n this.logger.info(\"📞 Processing callback page\");\n await this.handleCallback();\n } else {\n this.logger.info(\"🏠 Not a callback page, initialization complete\");\n }\n\n // Automatically preload iframe if enabled and user is not authenticated\n // This runs after both callback processing and normal initialization\n this.logger.info(\"🔍 Checking auto-preload conditions\", {\n preloadIframe: this.config.preloadIframe,\n displayMode: this.config.displayMode,\n });\n\n if (this.config.preloadIframe && this.config.displayMode === \"iframe\") {\n try {\n const isAuthenticated = await this.isAuthenticated();\n this.logger.info(\"🔍 Authentication check for preload\", {\n isAuthenticated,\n });\n\n if (!isAuthenticated) {\n this.logger.info(\n \"🔄 Auto-preloading iframe for instant sign-in...\",\n );\n await this.preloadAuthentication();\n this.logger.info(\"✅ Iframe auto-preloaded successfully\");\n } else {\n this.logger.debug(\n \"ℹ️ User already authenticated, skipping preload\",\n );\n }\n } catch (error) {\n // Don't fail initialization if preloading fails - graceful degradation\n this.logger.warn(\n \"⚠️ Auto-preloading failed (graceful degradation):\",\n {\n error: error instanceof Error ? error.message : String(error),\n },\n );\n }\n } else {\n this.logger.info(\"ℹ️ Auto-preload conditions not met\", {\n preloadIframe: this.config.preloadIframe,\n displayMode: this.config.displayMode,\n reason: !this.config.preloadIframe\n ? \"preloadIframe is disabled\"\n : \"displayMode is not iframe\",\n });\n }\n } catch (error) {\n const errorMessage =\n error instanceof Error\n ? error.message\n : \"Failed to initialize authentication\";\n this.logger.error(\"❌ CivicAuth initialization failed\", {\n error: errorMessage,\n stack: error instanceof Error ? error.stack : undefined,\n });\n this.events.emit(AuthEvent.SIGN_IN_ERROR, {\n detail: errorMessage,\n });\n throw new CivicAuthError(errorMessage, CivicAuthErrorCode.INIT_FAILED);\n }\n }\n\n /**\n * Initialize all handlers with proper configuration\n */\n private initializeHandlers(): void {\n const handlerConfig = {\n config: this.config,\n logger: this.logger,\n onAuthSuccess: this.handleAuthSuccess.bind(this),\n onAuthError: this.handleAuthError.bind(this),\n cleanup: this.cleanup.bind(this),\n };\n\n this.messageHandler = new MessageHandler({\n ...handlerConfig,\n onPopupFailure: this.handlePopupFailure.bind(this),\n onBrowserCorsFailsSilently: async () => {\n if (this.hasSignInStarted) {\n await this.handleBrowserCorsFailsSilently();\n }\n },\n });\n\n this.popupHandler = new PopupHandler(handlerConfig);\n\n this.iframeAuthHandler = new IframeAuthHandler({\n ...handlerConfig,\n messageHandler: this.messageHandler.handleMessage,\n });\n\n // Set up automatic re-preloading when authentication is cancelled\n this.setupAutoRepreload();\n }\n\n /**\n * Set up automatic re-preloading when authentication is cancelled by user\n * This maintains instant sign-in experience for subsequent attempts\n */\n private setupAutoRepreload(): void {\n this.events.on(AuthEvent.SIGN_IN_STARTED, () => {\n this.hasSignInStarted = true;\n });\n this.events.on(AuthEvent.SIGN_IN_ERROR, (event?: { detail?: string }) => {\n // Only re-preload for iframe mode with user cancellation and preload enabled\n if (\n this.config.displayMode === \"iframe\" &&\n this.config.preloadIframe &&\n event?.detail === \"Authentication cancelled by user\"\n ) {\n this.logger.debug(\n \"🔄 Authentication cancelled, scheduling re-preload for instant subsequent sign-in\",\n );\n\n // Small delay to ensure cleanup is complete\n setTimeout(async () => {\n try {\n await this.preloadAuthentication();\n this.logger.debug(\n \"✅ Re-preloaded iframe after cancellation for instant sign-in\",\n );\n } catch (error) {\n // Don't fail silently, but don't crash either - just log the issue\n this.logger.warn(\n \"⚠️ Failed to re-preload iframe after cancellation:\",\n {\n error: error instanceof Error ? error.message : String(error),\n },\n );\n }\n }, 200); // Small delay to ensure cleanup completion\n }\n });\n }\n\n /**\n * Builds the authentication URL with PKCE challenge\n */\n private async buildAuthUrl(): Promise<string> {\n // If a login URL is set (for backend integration), use that instead\n if (this.loginUrl) {\n this.logger.info(\"🔗 Using login URL for backend integration\", {\n loginUrl: this.loginUrl,\n });\n\n // Generate state with display mode information for backend integration\n const state =\n this.config.initialState ||\n generateState({\n displayMode: this.config.displayMode || \"iframe\",\n iframeDisplayMode: this.config.iframeDisplayMode,\n framework: this.config.framework || \"vanillajs\",\n sdkVersion: getVersion(),\n });\n\n // Append state as query parameter to loginUrl\n const url = new URL(this.loginUrl, window.location.origin);\n url.searchParams.set(\"state\", state);\n\n this.logger.info(\"🔗 Built login URL with display mode state\", {\n loginUrl: url.toString(),\n displayMode: this.config.displayMode,\n iframeDisplayMode: this.config.iframeDisplayMode,\n });\n\n return url.toString();\n }\n\n if (!this.endpoints) {\n throw new CivicAuthError(\n \"OAuth endpoints not initialized. Please wait for initialization to complete.\",\n CivicAuthErrorCode.ENDPOINTS_NOT_INITIALIZED,\n );\n }\n\n // Ensure clientId is present for OAuth flow (it should be according to our discriminated union)\n if (!this.config.clientId) {\n throw new CivicAuthError(\n \"ClientId is required for OAuth flow when loginUrl is not provided.\",\n CivicAuthErrorCode.CONFIG_REQUIRED,\n );\n }\n\n const pkceProducer = new GenericPublicClientPKCEProducer(this.storage);\n const codeChallenge = await pkceProducer.getCodeChallenge();\n const state =\n this.config.initialState ||\n generateState({\n displayMode: this.config.displayMode || \"iframe\",\n iframeDisplayMode: this.config.iframeDisplayMode,\n framework: this.config.framework || \"vanillajs\",\n sdkVersion: getVersion(),\n });\n\n return buildAuthUrl({\n endpoints: this.endpoints,\n clientId: this.config.clientId,\n redirectUrl: this.config.redirectUrl,\n scopes: this.config.scopes,\n codeChallenge,\n state,\n prompt: this.config.prompt,\n nonce: this.config.nonce,\n });\n }\n\n /**\n * Preloads the authentication iframe for instant sign-in\n * This creates the iframe in the background but keeps it hidden until startAuthentication() is called\n * @throws {CivicAuthError} If preloading fails or is not supported\n * @private - This method is used internally for automatic preloading\n */\n private async preloadAuthentication(): Promise<void> {\n this.logger.info(\"🎬 Preloading authentication for instant sign-in\", {\n displayMode: this.config.displayMode,\n userAgent: navigator.userAgent,\n currentUrl: window.location.href,\n });\n\n if (!this.endpoints) {\n const error = new CivicAuthError(\n \"OAuth endpoints not initialized. Please wait for initialization to complete.\",\n CivicAuthErrorCode.ENDPOINTS_NOT_INITIALIZED,\n );\n this.logger.error(\"❌ Endpoints not initialized for preload\", {\n error: error.message,\n });\n throw error;\n }\n\n // Only support preloading for iframe mode\n if (this.config.displayMode !== \"iframe\") {\n this.logger.warn(\n \"⚠️ Iframe preloading only supported for iframe display mode\",\n {\n displayMode: this.config.displayMode,\n },\n );\n return;\n }\n\n if (!this.iframeAuthHandler) {\n const error = new CivicAuthError(\n \"Iframe handler not initialized for preloading\",\n CivicAuthErrorCode.INIT_FAILED,\n );\n this.logger.error(\"❌ Iframe handler not initialized\", {\n error: error.message,\n });\n throw error;\n }\n\n const fullAuthUrl = await this.buildAuthUrl();\n this.logger.info(\"🔗 Built authentication URL for preload\", {\n url: fullAuthUrl,\n displayMode: this.config.displayMode,\n });\n\n try {\n await this.iframeAuthHandler.preloadIframe(fullAuthUrl);\n const iframeElement = this.iframeAuthHandler.getIframeElement();\n if (iframeElement) {\n this.messageHandler?.updateIframeElement(iframeElement);\n }\n\n this.logger.info(\"✅ Authentication iframe preloaded successfully\");\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : \"Failed to preload iframe\";\n this.logger.error(\"❌ Failed to preload authentication iframe\", {\n error: errorMessage,\n });\n throw new CivicAuthError(\n errorMessage,\n CivicAuthErrorCode.IFRAME_PRELOAD_FAILED,\n );\n }\n }\n\n /**\n * Check if authentication is preloaded and ready for instant sign-in\n * @returns True if an iframe is preloaded and ready\n */\n isAuthenticationPreloaded(): boolean {\n if (this.config.displayMode !== \"iframe\" || !this.iframeAuthHandler) {\n return false;\n }\n return this.iframeAuthHandler.hasPreloadedIframe();\n }\n\n /**\n * Enable or disable iframe preloading\n * @param enabled Whether to enable iframe preloading\n */\n setPreloadEnabled(enabled: boolean): void {\n // Preloading only makes sense for iframe mode\n if (this.config.displayMode !== \"iframe\") {\n this.logger.debug(\n \"🎯 Iframe preloading not applicable for non-iframe mode\",\n {\n displayMode: this.config.displayMode,\n enabled,\n },\n );\n return;\n }\n\n if (this.iframeAuthHandler) {\n this.iframeAuthHandler.setPreloadEnabled(enabled);\n this.logger.info(\"🎯 Iframe preloading\", { enabled });\n } else {\n this.logger.warn(\n \"⚠️ Cannot set preload enabled: iframe handler not initialized\",\n );\n }\n }\n\n /**\n * Check if iframe preloading is enabled\n * @returns True if iframe preloading is enabled\n */\n getPreloadEnabled(): boolean {\n // Preloading only makes sense for iframe mode\n if (this.config.displayMode !== \"iframe\") {\n return false;\n }\n return this.iframeAuthHandler?.getPreloadEnabled() ?? false;\n }\n\n /**\n * Starts the authentication process\n * @returns A promise that resolves with the authentication result\n * @throws {CivicAuthError} If authentication fails or times out\n */\n async startAuthentication(): Promise<AuthResult> {\n this.logger.info(\"🎬 Starting authentication process\", {\n displayMode: this.config.displayMode,\n userAgent: navigator.userAgent,\n currentUrl: window.location.href,\n });\n\n // Send SDK analytics when authentication starts\n // Fire and forget - don't block authentication if analytics fails\n collectAndSendSDKAnalytics(\n this.config.clientId,\n this.config.oauthServerBaseUrl,\n this.config.framework || \"vanillajs\",\n );\n\n if (!this.endpoints) {\n const error = new CivicAuthError(\n \"OAuth endpoints not initialized. Please wait for initialization to complete.\",\n CivicAuthErrorCode.ENDPOINTS_NOT_INITIALIZED,\n );\n this.logger.error(\"❌ Endpoints not initialized\", {\n error: error.message,\n });\n this.events.emit(AuthEvent.SIGN_IN_ERROR, {\n detail: error.message,\n });\n throw error;\n }\n\n if (this.authPromise) {\n this.logger.info(\n \"⏳ Authentication already in progress, returning existing promise\",\n );\n return this.authPromise;\n }\n\n const fullAuthUrl = await this.buildAuthUrl();\n this.logger.info(\"🔗 Built authentication URL\", {\n url: fullAuthUrl,\n displayMode: this.config.displayMode,\n authProcessTimeout: this.config.authProcessTimeout,\n });\n\n this.authPromise = new Promise<AuthResult>((resolve, reject) => {\n this.authPromiseResolve = resolve;\n this.authPromiseReject = reject;\n\n this.handleAuthenticationByDisplayMode(fullAuthUrl);\n this.setupAuthenticationTimeout();\n });\n\n return this.authPromise;\n }\n\n private async handleBrowserCorsFailsSilently(): Promise<Promise<void>> {\n this.logger.warn(\n \"🚨 Browser CORS fails silently - switching to redirect mode\",\n {\n displayMode: this.config.displayMode,\n iframeAuthHandler: !!this.iframeAuthHandler,\n messageHandler: !!this.messageHandler,\n },\n );\n if (!this.iframeAuthHandler || !this.messageHandler) {\n throw new Error(\"Iframe handler not initialized\");\n }\n this.iframeAuthHandler.forceHideIframe();\n const rebuiltUrl = await this.buildAuthUrl();\n this.config.events?.emit(AuthEvent.SIGN_IN_ERROR, {\n detail:\n \"Browser doesn't support popups and passkey with CORS in iframe - switching to redirect mode\",\n error: {\n type: \"browser_cors_fails_silently\",\n failedUrl: IframeManager.browserCorsFailsSilentlyUrl,\n suggestion:\n \"Browser doesn't support popups and passkey with CORS in iframe - switching to redirect mode\",\n },\n });\n // use a small delay to ensure the loader is shown\n setTimeout(() => {\n window.location.href = rebuiltUrl;\n }, 100);\n }\n\n /**\n * Handle authentication based on display mode\n */\n private async handleAuthenticationByDisplayMode(\n fullAuthUrl: string,\n ): Promise<void> {\n this.logger.info(\"🎯 Handling authentication with display mode\", {\n displayMode: this.config.displayMode,\n });\n\n try {\n switch (this.config.displayMode) {\n case \"redirect\":\n this.logger.info(\"🌐 Using redirect mode\");\n window.location.href = fullAuthUrl;\n break;\n\n case \"new_tab\":\n this.logger.info(\"📱 Using new_tab mode\");\n if (!this.popupHandler) {\n throw new Error(\"Popup handler not initialized\");\n }\n await this.popupHandler.handleNewTabAuth(fullAuthUrl);\n break;\n\n case \"iframe\":\n default: {\n this.logger.info(\"🖼️ Using iframe mode\");\n if (!this.iframeAuthHandler || !this.messageHandler) {\n throw new Error(\"Iframe handler not initialized\");\n }\n if (IframeManager.browserCorsFailsSilentlyUrl) {\n return this.handleBrowserCorsFailsSilently();\n }\n\n const iframeElement =\n await this.iframeAuthHandler.handleIframeAuth(fullAuthUrl);\n this.messageHandler.updateIframeElement(iframeElement);\n break;\n }\n }\n } catch (error) {\n if (error instanceof PopupError) {\n await this.handlePopupErrorWithFallback(fullAuthUrl, error);\n } else {\n this.handleAuthError(\n error instanceof Error ? error : new Error(String(error)),\n );\n }\n }\n }\n\n /**\n * Handle popup error with redirect fallback\n */\n private async handlePopupErrorWithFallback(\n fullAuthUrl: string,\n error: PopupError,\n ): Promise<void> {\n this.logger.warn(\"🚫 Popup failed, falling back to redirect mode\", {\n originalDisplayMode: this.config.displayMode,\n error: error.message,\n });\n\n this.events.emit(AuthEvent.SIGN_IN_ERROR, {\n detail: \"Popup blocked, falling back to redirect mode\",\n });\n\n try {\n this.logger.info(\"🔄 Attempting redirect fallback\");\n\n // Clean up current authentication attempt\n this.cleanup();\n\n // Always switch to redirect mode for Safari compatibility\n this.config.displayMode = \"redirect\";\n\n // Regenerate the auth URL with updated display mode in state\n const fallbackAuthUrl = await this.buildAuthUrl();\n\n this.logger.info(\"🌐 Redirecting to auth URL\", { url: fallbackAuthUrl });\n window.location.href = fallbackAuthUrl;\n this.logger.info(\"✅ Redirect initiated successfully\");\n } catch (redirectError) {\n this.logger.error(\"❌ Redirect fallback failed\", {\n error: redirectError,\n redirectUrl: fullAuthUrl,\n });\n\n const fallbackError = new CivicAuthError(\n \"Failed to open popup window and redirect fallback failed. Please check your browser's popup settings.\",\n CivicAuthErrorCode.INIT_FAILED,\n );\n this.events.emit(AuthEvent.SIGN_IN_ERROR, {\n detail: fallbackError.message,\n });\n this.handleAuthError(fallbackError);\n }\n }\n\n /**\n * Setup authentication timeout\n */\n private setupAuthenticationTimeout(): void {\n // Skip timeout for embedded iframe mode - embedded iframes should stay persistent\n if (\n this.config.displayMode === \"iframe\" &&\n this.config.iframeDisplayMode === \"embedded\"\n ) {\n this.logger.debug(\n \"⏰ Skipping authentication timeout for embedded iframe mode\",\n {\n displayMode: this.config.displayMode,\n iframeDisplayMode: this.config.iframeDisplayMode,\n },\n );\n return;\n }\n\n // Set up timeout for other modes\n if (this.config.authProcessTimeout && this.config.authProcessTimeout > 0) {\n this.logger.debug(\"⏰ Setting up authentication timeout\", {\n timeout: this.config.authProcessTimeout,\n displayMode: this.config.displayMode,\n iframeDisplayMode: this.config.iframeDisplayMode,\n });\n\n this.authProcessTimeoutHandle = window.setTimeout(() => {\n this.logger.info(\"⏰ Authentication timeout reached\");\n this.events.emit(AuthEvent.SIGN_IN_ERROR, {\n detail: \"Authentication timed out\",\n });\n\n const error = new CivicAuthError(\n \"Authentication timed out\",\n CivicAuthErrorCode.AUTH_PROCESS_TIMEOUT,\n );\n this.handleAuthError(error);\n }, this.config.authProcessTimeout);\n }\n }\n\n /**\n * Handle successful authentication\n */\n private handleAuthSuccess(result: AuthResult): void {\n this.logger.info(\"✅ Authentication successful\");\n this.authPromiseResolve?.(result);\n this.cleanup();\n }\n\n /**\n * Handle authentication error\n */\n private handleAuthError(error: Error): void {\n this.logger.error(\"❌ Authentication failed\", { error: error.message });\n this.authPromiseReject?.(error);\n this.cleanup();\n }\n\n /**\n * Handle popup failure - simplified like React implementation\n */\n private handlePopupFailure(failedUrl?: string): void {\n this.hasPopupFailed = true;\n\n this.logger.warn(\"Popup failed, using redirect mode instead...\", {\n failedUrl,\n });\n\n // Clean up iframe if it exists\n if (this.iframeAuthHandler) {\n this.iframeAuthHandler.cleanupIframe();\n }\n\n // Always redirect to the failed URL or build a new one\n if (failedUrl) {\n window.location.href = failedUrl;\n } else {\n this.buildAuthUrl()\n .then((authUrl) => {\n window.location.href = authUrl;\n })\n .catch((error) => {\n this.logger.error(\"Failed to build auth URL for redirect fallback\", {\n error,\n });\n const fallbackError = new CivicAuthError(\n \"Failed to redirect for authentication\",\n CivicAuthErrorCode.INIT_FAILED,\n );\n this.handleAuthError(fallbackError);\n });\n }\n }\n\n /**\n * Show popup failure message to user\n */\n private showPopupFailureMessage(\n customMessage: string = \"Authentication will continue in this window. Please wait...\",\n ): void {\n const container = this.getContainerElement();\n if (!container) {\n this.logger.warn(\n \"Cannot show popup failure message - container not found\",\n );\n return;\n }\n const existingMessage = document.getElementById(\n \"civic-auth-popup-failure-message\",\n );\n if (existingMessage && existingMessage.parentNode) {\n existingMessage.parentNode.removeChild(existingMessage);\n }\n const messageOverlay = document.createElement(\"div\");\n messageOverlay.id = \"civic-auth-popup-failure-message\";\n messageOverlay.style.cssText =\n \"position:absolute;top:0;left:0;right:0;background:rgba(255,249,196,.95);border:1px solid #f59e0b;border-radius:6px;padding:12px;margin:8px;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;font-size:14px;color:#92400e;z-index:1000;box-shadow:0 2px 4px rgba(0,0,0,.1);\";\n messageOverlay.innerHTML =\n '<div style=\"display:flex;align-items:center;gap:8px;\">' +\n '<span style=\"font-size:16px;\">⚠️</span>' +\n \"<div>\" +\n \"<strong>Popup blocked</strong><br>\" +\n '<span style=\"font-size:12px;\">' +\n customMessage +\n \"</span>\" +\n \"</div>\" +\n \"</div>\";\n\n if (getComputedStyle(container).position === \"static\") {\n container.style.position = \"relative\";\n }\n\n container.appendChild(messageOverlay);\n\n setTimeout(() => {\n if (messageOverlay.parentNode) {\n messageOverlay.parentNode.removeChild(messageOverlay);\n }\n }, 10000);\n this.logger.info(\"Popup failure message displayed to user\");\n }\n\n /**\n * Setup popup failure timeout\n */\n private setupPopupFailureTimeout(): void {\n this.popupFailureTimeoutHandle = window.setTimeout(() => {\n this.logger.info(\"⏰ Popup failure timeout reached\");\n this.events.emit(AuthEvent.SIGN_IN_ERROR, {\n detail: \"Authentication timeout - popup failure scenario\",\n });\n\n const error = new CivicAuthError(\n \"Authentication timeout - popup failure scenario\",\n CivicAuthErrorCode.AUTH_PROCESS_TIMEOUT,\n );\n this.handleAuthError(error);\n }, 20000); // 20 seconds\n }\n\n /**\n * Gets the container element for the auth iframe\n */\n private getContainerElement(): HTMLElement | null {\n if (typeof this.config.targetContainerElement === \"string\") {\n const element = document.getElementById(\n this.config.targetContainerElement,\n );\n if (!element) {\n this.logger.warn(\n `Container element with ID \"${this.config.targetContainerElement}\" not found`,\n );\n }\n return element;\n }\n return this.config.targetContainerElement ?? null;\n }\n\n /**\n * Handle OAuth callback\n */\n private async handleCallback(): Promise<void> {\n this.logger.info(\"🔄 Handling OAuth callback\", {\n currentUrl: window.location.href,\n redirectUrl: this.config.redirectUrl,\n });\n\n try {\n // Only handle OAuth callback if not using backend integration\n if (!this.config.clientId && this.config.loginUrl) {\n this.logger.info(\n \"📞 Backend integration mode - skipping OAuth callback handling\",\n );\n return;\n }\n\n // Ensure clientId is available for OAuth callback\n if (!this.config.clientId) {\n throw new Error(\"ClientId is required for OAuth callback handling\");\n }\n\n const callbackHandled = await handleOAuthRedirectPage({\n clientId: this.config.clientId,\n oauthServer: this.config.oauthServerBaseUrl,\n redirectUrl: this.config.redirectUrl,\n textSignals: {\n success: this.config.textSignals.success,\n error: this.config.textSignals.error || \"Authentication failed\",\n },\n storageAdapter: this.storage,\n });\n\n this.logger.info(\"📋 Callback processing result\", { callbackHandled });\n\n if (callbackHandled) {\n const successSignal = document.getElementById(\n CIVIC_AUTH_CONSTANTS.SUCCESS_SIGNAL_ID,\n );\n const errorSignal = document.getElementById(\n CIVIC_AUTH_CONSTANTS.ERROR_SIGNAL_ID,\n );\n\n if (successSignal) {\n this.logger.info(\"✅ Success signal found\");\n let userInfo = null;\n const userInfoAttr = successSignal.getAttribute(\"data-user-info\");\n if (userInfoAttr) {\n try {\n userInfo = JSON.parse(userInfoAttr);\n } catch (error) {\n this.logger.error(\"❌ Failed to parse user info\", { error });\n }\n }\n this.events.emit(AuthEvent.SIGN_IN_COMPLETE, {\n detail: \"Callback processed successfully\",\n user: userInfo,\n });\n } else if (errorSignal) {\n this.logger.error(\"❌ Error signal found\");\n this.events.emit(AuthEvent.SIGN_IN_ERROR, {\n detail: errorSignal.textContent || \"Unknown error during callback\",\n });\n }\n }\n } catch (error) {\n this.logger.error(\"❌ Callback handling failed\", { error });\n this.events.emit(AuthEvent.SIGN_IN_ERROR, {\n detail:\n error instanceof Error\n ? error.message\n : \"Unknown error during callback\",\n });\n }\n }\n\n /**\n * Cleans up resources and event listeners\n */\n public cleanup(): void {\n this.logger.info(\"Cleaning up authentication client\");\n\n // Clean up handlers\n this.iframeAuthHandler?.cleanupIframe();\n\n // Clean up timeouts\n if (this.authProcessTimeoutHandle) {\n window.clearTimeout(this.authProcessTimeoutHandle);\n this.authProcessTimeoutHandle = undefined;\n }\n\n if (this.popupFailureTimeoutHandle) {\n window.clearTimeout(this.popupFailureTimeoutHandle);\n this.popupFailureTimeoutHandle = undefined;\n }\n\n // Reset state\n this.hasPopupFailed = false;\n this.authPromise = undefined;\n this.authPromiseResolve = undefined;\n this.authPromiseReject = undefined;\n\n // Remove message event listener\n if (this.messageHandler) {\n window.removeEventListener(\"message\", this.messageHandler.handleMessage);\n }\n }\n\n /**\n * Get the current session\n */\n public async getCurrentSession(): Promise<Session | null> {\n return this.sessionManager.getCurrentSession() || null;\n }\n\n /**\n * Get current session tokens including decoded forwarded tokens\n * This method extracts and decodes forwarded tokens from the ID token JWT\n */\n public async getTokensWithForwardedTokens() {\n const session = await this.getCurrentSession();\n return extractTokensFromSession(session);\n }\n\n /**\n * Check if user is authenticated\n */\n public async isAuthenticated(): Promise<boolean> {\n return this.sessionManager.isAuthenticated() || false;\n }\n\n /**\n * Get the current user\n */\n public async getCurrentUser() {\n return this.sessionManager.getCurrentUser() || null;\n }\n\n /**\n * Clear the current session\n */\n public async clearSession(): Promise<void> {\n return this.sessionManager.clearSession();\n }\n\n /**\n * Manually refresh tokens\n */\n public async refreshTokens(): Promise<void> {\n return this.sessionManager.refreshTokens();\n }\n\n /**\n * Get token refresher state for debugging\n */\n public getTokenRefresherState() {\n return this.sessionManager.getTokenRefresherState() || null;\n }\n\n /**\n * Set a custom login URL for backend integration.\n * This is useful when integrating with a backend that handles the OAuth flow.\n * Alternatively, you can configure this directly in CivicAuth.create().\n *\n * @param loginUrl - The custom login URL to use (e.g., \"http://localhost:3020/auth/login\")\n *\n * @example\n * ```typescript\n * // Option 1: Configure in create()\n * const authClient = await CivicAuth.create({\n * clientId: \"YOUR_CLIENT_ID\",\n * loginUrl: \"http://example.com/custom-backendurl\"\n * });\n *\n * // Option 2: Set after creation\n * civicAuth.setLoginUrl(\"http://localhost:3020/auth/login\");\n * await civicAuth.startAuthentication();\n * ```\n */\n public setLoginUrl(loginUrl: string): void {\n this.loginUrl = loginUrl;\n\n // Update MessageHandler to expect messages from the custom origin\n if (this.messageHandler) {\n this.messageHandler.setCustomExpectedOrigin(loginUrl);\n }\n\n this.logger.info(\"🔗 Custom login URL set for backend integration\", {\n loginUrl: this.loginUrl,\n });\n }\n\n /**\n * Clear the login URL and return to standard OAuth flow\n */\n public clearLoginUrl(): void {\n this.loginUrl = undefined;\n\n // Clear custom expected origin from MessageHandler\n if (this.messageHandler) {\n this.messageHandler.clearCustomExpectedOrigin();\n }\n\n this.logger.info(\"🔗 Login URL cleared, returning to standard OAuth flow\");\n }\n\n /**\n * Get the current login URL\n * @returns The current login URL or undefined if not set\n */\n public getLoginUrl(): string | undefined {\n return this.loginUrl;\n }\n\n /**\n * Update the iframe display mode\n * @param mode - The display mode to use for the iframe\n */\n public setIframeDisplayMode(mode: \"modal\" | \"embedded\"): void {\n this.config.iframeDisplayMode = mode;\n this.logger.debug(`Iframe display mode updated to: ${mode}`);\n }\n\n /**\n * Get the current iframe display mode\n * @returns The current iframe display mode\n */\n public getIframeDisplayMode(): \"modal\" | \"embedded\" | undefined {\n return this.config.iframeDisplayMode;\n }\n\n /**\n * Destroy the auth client and clean up all resources\n */\n public async destroy(): Promise<void> {\n this.cleanup();\n await this.sessionManager.destroy();\n this.logger.info(\"CivicAuth destroyed\");\n }\n\n /**\n * Handle logout\n */\n public async logout(): Promise<void> {\n try {\n this.logger.info(\"🔄 Starting logout process\");\n this.events.emit(AuthEvent.SIGN_OUT_STARTED, {\n detail: \"Logout process started\",\n });\n\n // If a loginUrl is configured, redirect to the backend's logout endpoint.\n // The backend will then handle redirecting to the OIDC provider.\n if (this.loginUrl) {\n this.logger.info(\n \"🚪 Redirecting to backend for logout in backend-integrated flow\",\n );\n const backendUrl = new URL(this.loginUrl).origin;\n const endpoints = getBackendEndpoints(this.config.backendEndpoints);\n const backendLogoutUrl = `${backendUrl}${endpoints.logout}`;\n\n // Clear local SDK session state before redirecting\n await this.sessionManager.clearSession();\n this.events.emit(AuthEvent.SIGN_OUT_COMPLETE, {\n detail: \"Local session cleared, redirecting to backend for logout.\",\n });\n\n // Perform top-level redirect to the backend logout endpoint\n this.logger.info(\"🌐 Redirecting to backend logout endpoint\", {\n url: backendLogoutUrl,\n });\n window.location.href = backendLogoutUrl;\n return;\n }\n\n // --- Existing SPA redirect-based logout flow ---\n this.logger.info(\"🚪 Using redirect-based logout for SPA flow\");\n const tokens = await retrieveTokens(this.storage);\n\n if (!tokens?.id_token) {\n this.logger.warn(\"⚠️ No ID token found, clearing local session only\");\n await clearTokens(this.storage);\n await this.sessionManager.clearSession();\n this.events.emit(AuthEvent.SIGN_OUT_COMPLETE, {\n detail: \"Local session cleared\",\n });\n return;\n }\n\n if (!this.endpoints) {\n throw new Error(\"OAuth endpoints not initialized\");\n }\n\n // Generate a state for logout\n const state = generateState({\n displayMode: this.config.displayMode || \"iframe\",\n framework: this.config.framework || \"vanillajs\",\n sdkVersion: getVersion(),\n });\n\n this.logger.info(\"🔄 Storing logout state\", {\n generatedState: state,\n logoutStateKey: LOGOUT_STATE,\n displayMode: this.config.displayMode,\n });\n\n // Store logout state for cleanup after redirect\n // This matches the React implementation - only store state for redirect flow\n await this.storage.set(LOGOUT_STATE, state);\n\n // Ensure clientId is available for OAuth logout\n if (!this.config.clientId) {\n throw new Error(\"ClientId is required for OAuth logout flow\");\n }\n\n // Generate logout URL\n const logoutUrl = await generateOauthLogoutUrl({\n clientId: this.config.clientId,\n redirectUrl: this.config.logoutRedirectUrl,\n idToken: tokens.id_token,\n state: state,\n oauthServer: this.config.oauthServerBaseUrl,\n });\n\n this.logger.info(\"🔗 Generated logout URL\", {\n logoutUrl: logoutUrl.toString(),\n });\n\n // Clear local tokens and session but NOT the logout state (needed for cleanup after redirect)\n await this.sessionManager.clearSession(true); // preserveLogoutState = true\n\n // Emit logout complete event before redirect\n this.events.emit(AuthEvent.SIGN_OUT_COMPLETE, {\n detail: \"Logout successful\",\n });\n\n // Redirect to logout URL\n this.logger.info(\"🌐 Redirecting to logout URL\");\n window.location.href = logoutUrl.toString();\n } catch (error) {\n this.logger.error(\"❌ Logout failed\", { error });\n this.events.emit(AuthEvent.SIGN_OUT_ERROR, {\n detail: error instanceof Error ? error.message : String(error),\n });\n throw new CivicAuthError(\n \"Logout failed\",\n CivicAuthErrorCode.LOGOUT_FAILED,\n );\n }\n }\n\n /**\n * Handle logout state cleanup\n * This mirrors the logic from useSignIn.ts to properly clean up after logout\n */\n private async handleLogoutStateCleanup(): Promise<void> {\n try {\n const params = new URLSearchParams(window.location.search);\n const state = params.get(\"state\");\n\n this.logger.info(\"🔍 Checking for logout state cleanup\", {\n currentUrl: window.location.href,\n hasStateParam: !!state,\n stateValue: state,\n rawSearch: window.location.search,\n });\n\n if (!state) {\n this.logger.info(\n \"🔍 No state parameter found, skipping logout cleanup\",\n );\n return; // No state parameter, nothing to cleanup\n }\n\n // Check if we have a stored logout state that matches\n const storedLogoutState = await this.storage.get(LOGOUT_STATE);\n\n // The state might be URL-decoded by URLSearchParams, but stored as plain\n // Let's try both the decoded and encoded versions\n const decodedState = decodeURIComponent(state);\n\n this.logger.info(\"🔍 Comparing logout states\", {\n urlState: state,\n decodedState,\n storedLogoutState,\n directMatch: state === storedLogoutState,\n decodedMatch: decodedState === storedLogoutState,\n });\n\n if (state === storedLogoutState || decodedState === storedLogoutState) {\n this.logger.info(\"🧹 Cleaning up logout state\", {\n state,\n storedLogoutState,\n });\n\n // Clear tokens and user data from storage\n await clearTokens(this.storage);\n await this.sessionManager.clearSession();\n\n // Clean up the logout state from storage\n await this.storage.delete(LOGOUT_STATE);\n\n // Emit logout complete event\n this.events.emit(AuthEvent.SIGN_OUT_COMPLETE, {\n detail: \"Logout cleanup completed\",\n });\n\n // Clean up URL by removing query parameters\n const cleanUrl = window.location.href.split(\"?\")[0];\n window.history.replaceState({}, document.title, cleanUrl);\n\n this.logger.info(\"✅ Logout state cleanup completed\", {\n cleanUrl,\n });\n } else {\n this.logger.info(\"🔍 Logout states don't match, skipping cleanup\", {\n urlState: state,\n storedLogoutState,\n });\n }\n } catch (error) {\n this.logger.warn(\"⚠️ Error during logout state cleanup\", { error });\n // Don't throw error to prevent initialization failure\n }\n }\n}\n\n// Export types for external use\nexport type { CivicAuthClientConfig } from \"./types/AuthTypes.js\";\nexport { CivicAuthErrorCode } from \"./types/AuthTypes.js\";\n"]}
|
|
1
|
+
{"version":3,"file":"CivicAuth.js","sourceRoot":"","sources":["../../../src/vanillajs/auth/CivicAuth.ts"],"names":[],"mappings":"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","sourcesContent":["import { AuthEvent } from \"../types/index.js\";\nimport type { Endpoints, AuthStorage } from \"../../types.js\";\nimport { buildAuthUrl, extractTokensFromSession } from \"../utils/auth-utils.js\";\nimport type { AuthResult, Session } from \"../types/index.js\";\nimport type { createLogger } from \"../utils/logger.js\";\nimport {\n createMainLogger,\n configureLogging,\n setCurrentLogger,\n} from \"../utils/logger.js\";\nimport { GenericPublicClientPKCEProducer } from \"../../services/PKCE.js\";\nimport { generateState } from \"../../lib/oauth.js\";\nimport { SessionManager } from \"./SessionManager.js\";\nimport { AuthenticationEvents } from \"./AuthenticationEvents.js\";\nimport { PopupError } from \"../../services/types.js\";\nimport { getVersion } from \"../../shared/index.js\";\nimport { handleOAuthRedirectPage } from \"./handlers/OAuthCallbackHandler.js\";\nimport {\n generateOauthLogoutUrl,\n clearTokens,\n retrieveTokens,\n getBackendEndpoints,\n} from \"../../shared/lib/util.js\";\nimport { LOGOUT_STATE } from \"../../constants.js\";\nimport { getOauthEndpoints } from \"../../lib/oauth.js\";\nimport { collectAndSendSDKAnalytics } from \"../../lib/analytics.js\";\n\n// Import new modular components\nimport type {\n CivicAuthClientConfig,\n ProcessedCivicAuthConfig,\n} from \"./types/AuthTypes.js\";\nimport {\n CivicAuthError,\n CivicAuthErrorCode,\n CIVIC_AUTH_CONSTANTS,\n} from \"./types/AuthTypes.js\";\nimport { processConfigWithDefaults } from \"./config/ConfigProcessor.js\";\nimport { MessageHandler } from \"./handlers/MessageHandler.js\";\nimport { PopupHandler } from \"./handlers/PopupHandler.js\";\nimport { IframeAuthHandler } from \"./handlers/IframeAuthHandler.js\";\nimport { IframeManager } from \"../iframe/IframeManager.js\";\n\n/**\n * CivicAuth client for handling OAuth authentication\n *\n * This is a refactored version that uses a modular architecture for better maintainability.\n */\nexport class CivicAuth {\n private config: ProcessedCivicAuthConfig;\n private storage: AuthStorage;\n private endpoints?: Endpoints;\n private logger: ReturnType<typeof createLogger>;\n private sessionManager: SessionManager;\n private events: AuthenticationEvents;\n private initialDisplayMode:\n | \"iframe\"\n | \"modal\"\n | \"redirect\"\n | \"new_tab\"\n | \"custom_tab\";\n\n // Authentication state\n private authPromise?: Promise<AuthResult>;\n private authPromiseResolve?: (value: AuthResult) => void;\n private authPromiseReject?: (reason?: Error) => void;\n private authProcessTimeoutHandle?: number;\n private popupFailureTimeoutHandle?: number;\n private hasPopupFailed: boolean = false;\n private hasSignInStarted: boolean = false;\n\n // Backend integration - custom login URL\n private loginUrl?: string;\n\n // Handlers\n private messageHandler?: MessageHandler;\n private popupHandler?: PopupHandler;\n private iframeAuthHandler?: IframeAuthHandler;\n\n /**\n * Private constructor - initializes configuration and handlers.\n * Use {@link CivicAuth.create} to create a new instance.\n */\n private constructor(config: CivicAuthClientConfig) {\n // Process config with defaults and validation\n this.config = processConfigWithDefaults(config);\n this.initialDisplayMode = this.config.displayMode;\n\n // Set loginUrl from config if provided\n this.loginUrl = this.config.loginUrl;\n\n // Configure logging\n configureLogging(this.config.logging);\n\n // Initialize logger - always use \"vanillajs\" as base namespace\n if (this.config.logging?.enabled) {\n this.logger = createMainLogger(\"vanillajs\"); // Always use \"vanillajs\"\n } else {\n this.logger = {\n debug: () => {},\n info: () => {},\n warn: () => {},\n error: () => {},\n };\n }\n\n setCurrentLogger(this.logger);\n this.storage = this.config.storageAdapter;\n\n // Always initialize events - use provided events or create default instance\n this.events = config.events || new AuthenticationEvents();\n\n // Always initialize SessionManager\n this.sessionManager = new SessionManager(\n this.storage,\n this.events,\n this.config,\n );\n\n // Initialize handlers\n this.initializeHandlers();\n }\n\n /**\n * Creates and initializes a new instance of CivicAuth.\n * This is the recommended way to create a CivicAuth instance.\n *\n * @param config - Configuration options for the auth client\n * @returns A promise that resolves with the initialized CivicAuth instance\n * @throws {CivicAuthError} If initialization fails or required configuration is missing\n *\n * @example\n * ```typescript\n * // Standard SPA authentication\n * const auth = await CivicAuth.create({\n * clientId: \"your-client-id\",\n * // redirectUrl is optional - defaults to current page (window.location.origin + window.location.pathname)\n * redirectUrl: \"https://your-app.com/callback\", // optional\n * // logoutRedirectUrl is optional - defaults to redirectUrl if not provided\n * logoutRedirectUrl: \"https://your-app.com/logout\", // optional\n * // oauthServerBaseUrl is optional - defaults to \"https://auth.civic.com/oauth\"\n * oauthServerBaseUrl: \"https://auth-server.com/\", // optional\n * // scopes is optional - defaults to ['openid', 'profile', 'email', 'offline_access']\n * scopes: [\"openid\", \"profile\"], // optional\n * targetContainerElement: \"auth-container\",\n * textSignals: {\n * success: \"Authentication successful!\"\n * }\n * });\n *\n * // Backend integration authentication\n * const authWithBackend = await CivicAuth.create({\n * clientId: \"your-client-id\",\n * loginUrl: \"http://example.com/custom-backendurl\" // Automatically uses BrowserCookieStorage\n * });\n * ```\n */\n public static async create(\n config: CivicAuthClientConfig,\n ): Promise<CivicAuth> {\n const instance = new CivicAuth(config);\n await instance.init();\n return instance;\n }\n\n /**\n * Initializes the auth client and checks for callback handling\n */\n private async init(): Promise<void> {\n this.logger.info(\"🚀 Initializing CivicAuth\", {\n currentUrl: window.location.href,\n redirectUrl: this.config.redirectUrl,\n oauthServerBaseUrl: this.config.oauthServerBaseUrl,\n isCallbackUrl: window.location.href.startsWith(this.config.redirectUrl),\n });\n\n try {\n // Get OAuth endpoints using shared function (handles trailing slash automatically)\n this.endpoints = await getOauthEndpoints(this.config.oauthServerBaseUrl);\n\n this.logger.info(\"🔗 OAuth endpoints configured\", {\n endpoints: this.endpoints,\n });\n\n // Initialize SessionManager with auth config\n if (this.sessionManager) {\n const authConfig = {\n clientId: this.config.clientId,\n redirectUrl: this.config.redirectUrl,\n oauthServer: this.config.oauthServerBaseUrl,\n scopes: this.config.scopes,\n endpoints: this.endpoints,\n loginUrl: this.config.loginUrl || this.loginUrl, // Include loginUrl for backend flows\n backendEndpoints: this.config.backendEndpoints, // Pass backend endpoints config\n };\n this.logger.info(\"🔧 Initializing SessionManager\", { authConfig });\n await this.sessionManager.initializeWithAuthConfig(authConfig);\n }\n\n // Check if we're on the callback page\n const isCallbackPage = window.location.href.startsWith(\n this.config.redirectUrl,\n );\n this.logger.info(\"🔍 Callback page check\", {\n isCallbackPage,\n currentUrl: window.location.href,\n redirectUrl: this.config.redirectUrl,\n });\n\n // Handle logout state cleanup first (before processing auth callbacks)\n await this.handleLogoutStateCleanup();\n\n if (isCallbackPage) {\n this.logger.info(\"📞 Processing callback page\");\n await this.handleCallback();\n } else {\n this.logger.info(\"🏠 Not a callback page, initialization complete\");\n }\n\n // Automatically preload iframe if enabled and user is not authenticated\n // This runs after both callback processing and normal initialization\n this.logger.info(\"🔍 Checking auto-preload conditions\", {\n preloadIframe: this.config.preloadIframe,\n displayMode: this.config.displayMode,\n });\n\n if (this.config.preloadIframe && this.config.displayMode === \"iframe\") {\n try {\n const isAuthenticated = await this.isAuthenticated();\n this.logger.info(\"🔍 Authentication check for preload\", {\n isAuthenticated,\n });\n\n if (!isAuthenticated) {\n this.logger.info(\n \"🔄 Auto-preloading iframe for instant sign-in...\",\n );\n await this.preloadAuthentication();\n this.logger.info(\"✅ Iframe auto-preloaded successfully\");\n } else {\n this.logger.debug(\n \"ℹ️ User already authenticated, skipping preload\",\n );\n }\n } catch (error) {\n // Don't fail initialization if preloading fails - graceful degradation\n this.logger.warn(\n \"⚠️ Auto-preloading failed (graceful degradation):\",\n {\n error: error instanceof Error ? error.message : String(error),\n },\n );\n }\n } else {\n this.logger.info(\"ℹ️ Auto-preload conditions not met\", {\n preloadIframe: this.config.preloadIframe,\n displayMode: this.config.displayMode,\n reason: !this.config.preloadIframe\n ? \"preloadIframe is disabled\"\n : \"displayMode is not iframe\",\n });\n }\n } catch (error) {\n const errorMessage =\n error instanceof Error\n ? error.message\n : \"Failed to initialize authentication\";\n this.logger.error(\"❌ CivicAuth initialization failed\", {\n error: errorMessage,\n stack: error instanceof Error ? error.stack : undefined,\n });\n this.events.emit(AuthEvent.SIGN_IN_ERROR, {\n detail: errorMessage,\n });\n throw new CivicAuthError(errorMessage, CivicAuthErrorCode.INIT_FAILED);\n }\n }\n\n /**\n * Initialize all handlers with proper configuration\n */\n private initializeHandlers(): void {\n const handlerConfig = {\n config: this.config,\n logger: this.logger,\n onAuthSuccess: this.handleAuthSuccess.bind(this),\n onAuthError: this.handleAuthError.bind(this),\n cleanup: this.cleanup.bind(this),\n };\n\n this.messageHandler = new MessageHandler({\n ...handlerConfig,\n onPopupFailure: this.handlePopupFailure.bind(this),\n onBrowserCorsFailsSilently: async () => {\n if (this.hasSignInStarted) {\n await this.handleBrowserCorsFailsSilently();\n }\n },\n });\n\n this.popupHandler = new PopupHandler(handlerConfig);\n\n this.iframeAuthHandler = new IframeAuthHandler({\n ...handlerConfig,\n messageHandler: this.messageHandler.handleMessage,\n });\n\n // Set up automatic re-preloading when authentication is cancelled\n this.setupAutoRepreload();\n }\n\n /**\n * Set up automatic re-preloading when authentication is cancelled by user\n * This maintains instant sign-in experience for subsequent attempts\n */\n private setupAutoRepreload(): void {\n this.events.on(AuthEvent.SIGN_IN_STARTED, () => {\n this.hasSignInStarted = true;\n });\n this.events.on(AuthEvent.SIGN_IN_ERROR, (event?: { detail?: string }) => {\n // Only re-preload for iframe mode with user cancellation and preload enabled\n if (\n this.config.displayMode === \"iframe\" &&\n this.config.preloadIframe &&\n event?.detail === \"Authentication cancelled by user\"\n ) {\n this.logger.debug(\n \"🔄 Authentication cancelled, scheduling re-preload for instant subsequent sign-in\",\n );\n\n // Small delay to ensure cleanup is complete\n setTimeout(async () => {\n try {\n await this.preloadAuthentication();\n this.logger.debug(\n \"✅ Re-preloaded iframe after cancellation for instant sign-in\",\n );\n } catch (error) {\n // Don't fail silently, but don't crash either - just log the issue\n this.logger.warn(\n \"⚠️ Failed to re-preload iframe after cancellation:\",\n {\n error: error instanceof Error ? error.message : String(error),\n },\n );\n }\n }, 200); // Small delay to ensure cleanup completion\n }\n });\n }\n\n /**\n * Builds the authentication URL with PKCE challenge\n */\n private async buildAuthUrl(): Promise<string> {\n // If a login URL is set (for backend integration), use that instead\n if (this.loginUrl) {\n this.logger.info(\"🔗 Using login URL for backend integration\", {\n loginUrl: this.loginUrl,\n });\n\n // Generate state with display mode information for backend integration\n const state =\n this.config.initialState ||\n generateState({\n displayMode: this.config.displayMode || \"iframe\",\n iframeDisplayMode: this.config.iframeDisplayMode,\n framework: this.config.framework || \"vanillajs\",\n sdkVersion: getVersion(),\n });\n\n // Append state as query parameter to loginUrl\n const url = new URL(this.loginUrl, window.location.origin);\n url.searchParams.set(\"state\", state);\n\n this.logger.info(\"🔗 Built login URL with display mode state\", {\n loginUrl: url.toString(),\n displayMode: this.config.displayMode,\n iframeDisplayMode: this.config.iframeDisplayMode,\n });\n\n return url.toString();\n }\n\n if (!this.endpoints) {\n throw new CivicAuthError(\n \"OAuth endpoints not initialized. Please wait for initialization to complete.\",\n CivicAuthErrorCode.ENDPOINTS_NOT_INITIALIZED,\n );\n }\n\n const pkceProducer = new GenericPublicClientPKCEProducer(this.storage);\n const codeChallenge = await pkceProducer.getCodeChallenge();\n const state =\n this.config.initialState ||\n generateState({\n displayMode: this.config.displayMode || \"iframe\",\n iframeDisplayMode: this.config.iframeDisplayMode,\n framework: this.config.framework || \"vanillajs\",\n sdkVersion: getVersion(),\n });\n\n return buildAuthUrl({\n endpoints: this.endpoints,\n clientId: this.config.clientId,\n redirectUrl: this.config.redirectUrl,\n scopes: this.config.scopes,\n codeChallenge,\n state,\n prompt: this.config.prompt,\n nonce: this.config.nonce,\n });\n }\n\n /**\n * Preloads the authentication iframe for instant sign-in\n * This creates the iframe in the background but keeps it hidden until startAuthentication() is called\n * @throws {CivicAuthError} If preloading fails or is not supported\n * @private - This method is used internally for automatic preloading\n */\n private async preloadAuthentication(): Promise<void> {\n this.logger.info(\"🎬 Preloading authentication for instant sign-in\", {\n displayMode: this.config.displayMode,\n userAgent: navigator.userAgent,\n currentUrl: window.location.href,\n });\n\n if (!this.endpoints) {\n const error = new CivicAuthError(\n \"OAuth endpoints not initialized. Please wait for initialization to complete.\",\n CivicAuthErrorCode.ENDPOINTS_NOT_INITIALIZED,\n );\n this.logger.error(\"❌ Endpoints not initialized for preload\", {\n error: error.message,\n });\n throw error;\n }\n\n // Only support preloading for iframe mode\n if (this.config.displayMode !== \"iframe\") {\n this.logger.warn(\n \"⚠️ Iframe preloading only supported for iframe display mode\",\n {\n displayMode: this.config.displayMode,\n },\n );\n return;\n }\n\n if (!this.iframeAuthHandler) {\n const error = new CivicAuthError(\n \"Iframe handler not initialized for preloading\",\n CivicAuthErrorCode.INIT_FAILED,\n );\n this.logger.error(\"❌ Iframe handler not initialized\", {\n error: error.message,\n });\n throw error;\n }\n\n const fullAuthUrl = await this.buildAuthUrl();\n this.logger.info(\"🔗 Built authentication URL for preload\", {\n url: fullAuthUrl,\n displayMode: this.config.displayMode,\n });\n\n try {\n await this.iframeAuthHandler.preloadIframe(fullAuthUrl);\n const iframeElement = this.iframeAuthHandler.getIframeElement();\n if (iframeElement) {\n this.messageHandler?.updateIframeElement(iframeElement);\n }\n\n this.logger.info(\"✅ Authentication iframe preloaded successfully\");\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : \"Failed to preload iframe\";\n this.logger.error(\"❌ Failed to preload authentication iframe\", {\n error: errorMessage,\n });\n throw new CivicAuthError(\n errorMessage,\n CivicAuthErrorCode.IFRAME_PRELOAD_FAILED,\n );\n }\n }\n\n /**\n * Check if authentication is preloaded and ready for instant sign-in\n * @returns True if an iframe is preloaded and ready\n */\n isAuthenticationPreloaded(): boolean {\n if (this.config.displayMode !== \"iframe\" || !this.iframeAuthHandler) {\n return false;\n }\n return this.iframeAuthHandler.hasPreloadedIframe();\n }\n\n /**\n * Enable or disable iframe preloading\n * @param enabled Whether to enable iframe preloading\n */\n setPreloadEnabled(enabled: boolean): void {\n // Preloading only makes sense for iframe mode\n if (this.config.displayMode !== \"iframe\") {\n this.logger.debug(\n \"🎯 Iframe preloading not applicable for non-iframe mode\",\n {\n displayMode: this.config.displayMode,\n enabled,\n },\n );\n return;\n }\n\n if (this.iframeAuthHandler) {\n this.iframeAuthHandler.setPreloadEnabled(enabled);\n this.logger.info(\"🎯 Iframe preloading\", { enabled });\n } else {\n this.logger.warn(\n \"⚠️ Cannot set preload enabled: iframe handler not initialized\",\n );\n }\n }\n\n /**\n * Check if iframe preloading is enabled\n * @returns True if iframe preloading is enabled\n */\n getPreloadEnabled(): boolean {\n // Preloading only makes sense for iframe mode\n if (this.config.displayMode !== \"iframe\") {\n return false;\n }\n return this.iframeAuthHandler?.getPreloadEnabled() ?? false;\n }\n\n /**\n * Starts the authentication process\n * @returns A promise that resolves with the authentication result\n * @throws {CivicAuthError} If authentication fails or times out\n */\n async startAuthentication(): Promise<AuthResult> {\n this.logger.info(\"🎬 Starting authentication process\", {\n displayMode: this.config.displayMode,\n userAgent: navigator.userAgent,\n currentUrl: window.location.href,\n });\n\n // Send SDK analytics when authentication starts\n // Fire and forget - don't block authentication if analytics fails\n collectAndSendSDKAnalytics(\n this.config.clientId,\n this.config.oauthServerBaseUrl,\n this.config.framework || \"vanillajs\",\n );\n\n if (!this.endpoints) {\n const error = new CivicAuthError(\n \"OAuth endpoints not initialized. Please wait for initialization to complete.\",\n CivicAuthErrorCode.ENDPOINTS_NOT_INITIALIZED,\n );\n this.logger.error(\"❌ Endpoints not initialized\", {\n error: error.message,\n });\n this.events.emit(AuthEvent.SIGN_IN_ERROR, {\n detail: error.message,\n });\n throw error;\n }\n\n if (this.authPromise) {\n this.logger.info(\n \"⏳ Authentication already in progress, returning existing promise\",\n );\n return this.authPromise;\n }\n\n const fullAuthUrl = await this.buildAuthUrl();\n this.logger.info(\"🔗 Built authentication URL\", {\n url: fullAuthUrl,\n displayMode: this.config.displayMode,\n authProcessTimeout: this.config.authProcessTimeout,\n });\n\n this.authPromise = new Promise<AuthResult>((resolve, reject) => {\n this.authPromiseResolve = resolve;\n this.authPromiseReject = reject;\n\n this.handleAuthenticationByDisplayMode(fullAuthUrl);\n this.setupAuthenticationTimeout();\n });\n\n return this.authPromise;\n }\n\n private async handleBrowserCorsFailsSilently(): Promise<Promise<void>> {\n this.logger.warn(\n \"🚨 Browser CORS fails silently - switching to redirect mode\",\n {\n displayMode: this.config.displayMode,\n iframeAuthHandler: !!this.iframeAuthHandler,\n messageHandler: !!this.messageHandler,\n },\n );\n if (!this.iframeAuthHandler || !this.messageHandler) {\n throw new Error(\"Iframe handler not initialized\");\n }\n this.iframeAuthHandler.forceHideIframe();\n const rebuiltUrl = await this.buildAuthUrl();\n this.config.events?.emit(AuthEvent.SIGN_IN_ERROR, {\n detail:\n \"Browser doesn't support popups and passkey with CORS in iframe - switching to redirect mode\",\n error: {\n type: \"browser_cors_fails_silently\",\n failedUrl: IframeManager.browserCorsFailsSilentlyUrl,\n suggestion:\n \"Browser doesn't support popups and passkey with CORS in iframe - switching to redirect mode\",\n },\n });\n // use a small delay to ensure the loader is shown\n setTimeout(() => {\n window.location.href = rebuiltUrl;\n }, 100);\n }\n\n /**\n * Handle authentication based on display mode\n */\n private async handleAuthenticationByDisplayMode(\n fullAuthUrl: string,\n ): Promise<void> {\n this.logger.info(\"🎯 Handling authentication with display mode\", {\n displayMode: this.config.displayMode,\n });\n\n try {\n switch (this.config.displayMode) {\n case \"redirect\":\n this.logger.info(\"🌐 Using redirect mode\");\n window.location.href = fullAuthUrl;\n break;\n\n case \"new_tab\":\n this.logger.info(\"📱 Using new_tab mode\");\n if (!this.popupHandler) {\n throw new Error(\"Popup handler not initialized\");\n }\n await this.popupHandler.handleNewTabAuth(fullAuthUrl);\n break;\n\n case \"iframe\":\n default: {\n this.logger.info(\"🖼️ Using iframe mode\");\n if (!this.iframeAuthHandler || !this.messageHandler) {\n throw new Error(\"Iframe handler not initialized\");\n }\n if (IframeManager.browserCorsFailsSilentlyUrl) {\n return this.handleBrowserCorsFailsSilently();\n }\n\n const iframeElement =\n await this.iframeAuthHandler.handleIframeAuth(fullAuthUrl);\n this.messageHandler.updateIframeElement(iframeElement);\n break;\n }\n }\n } catch (error) {\n if (error instanceof PopupError) {\n await this.handlePopupErrorWithFallback(fullAuthUrl, error);\n } else {\n this.handleAuthError(\n error instanceof Error ? error : new Error(String(error)),\n );\n }\n }\n }\n\n /**\n * Handle popup error with redirect fallback\n */\n private async handlePopupErrorWithFallback(\n fullAuthUrl: string,\n error: PopupError,\n ): Promise<void> {\n this.logger.warn(\"🚫 Popup failed, falling back to redirect mode\", {\n originalDisplayMode: this.config.displayMode,\n error: error.message,\n });\n\n this.events.emit(AuthEvent.SIGN_IN_ERROR, {\n detail: \"Popup blocked, falling back to redirect mode\",\n });\n\n try {\n this.logger.info(\"🔄 Attempting redirect fallback\");\n\n // Clean up current authentication attempt\n this.cleanup();\n\n // Always switch to redirect mode for Safari compatibility\n this.config.displayMode = \"redirect\";\n\n // Regenerate the auth URL with updated display mode in state\n const fallbackAuthUrl = await this.buildAuthUrl();\n\n this.logger.info(\"🌐 Redirecting to auth URL\", { url: fallbackAuthUrl });\n window.location.href = fallbackAuthUrl;\n this.logger.info(\"✅ Redirect initiated successfully\");\n } catch (redirectError) {\n this.logger.error(\"❌ Redirect fallback failed\", {\n error: redirectError,\n redirectUrl: fullAuthUrl,\n });\n\n const fallbackError = new CivicAuthError(\n \"Failed to open popup window and redirect fallback failed. Please check your browser's popup settings.\",\n CivicAuthErrorCode.INIT_FAILED,\n );\n this.events.emit(AuthEvent.SIGN_IN_ERROR, {\n detail: fallbackError.message,\n });\n this.handleAuthError(fallbackError);\n }\n }\n\n /**\n * Setup authentication timeout\n */\n private setupAuthenticationTimeout(): void {\n // Skip timeout for embedded iframe mode - embedded iframes should stay persistent\n if (\n this.config.displayMode === \"iframe\" &&\n this.config.iframeDisplayMode === \"embedded\"\n ) {\n this.logger.debug(\n \"⏰ Skipping authentication timeout for embedded iframe mode\",\n {\n displayMode: this.config.displayMode,\n iframeDisplayMode: this.config.iframeDisplayMode,\n },\n );\n return;\n }\n\n // Set up timeout for other modes\n if (this.config.authProcessTimeout && this.config.authProcessTimeout > 0) {\n this.logger.debug(\"⏰ Setting up authentication timeout\", {\n timeout: this.config.authProcessTimeout,\n displayMode: this.config.displayMode,\n iframeDisplayMode: this.config.iframeDisplayMode,\n });\n\n this.authProcessTimeoutHandle = window.setTimeout(() => {\n this.logger.info(\"⏰ Authentication timeout reached\");\n this.events.emit(AuthEvent.SIGN_IN_ERROR, {\n detail: \"Authentication timed out\",\n });\n\n const error = new CivicAuthError(\n \"Authentication timed out\",\n CivicAuthErrorCode.AUTH_PROCESS_TIMEOUT,\n );\n this.handleAuthError(error);\n }, this.config.authProcessTimeout);\n }\n }\n\n /**\n * Handle successful authentication\n */\n private handleAuthSuccess(result: AuthResult): void {\n this.logger.info(\"✅ Authentication successful\");\n this.authPromiseResolve?.(result);\n this.cleanup();\n }\n\n /**\n * Handle authentication error\n */\n private handleAuthError(error: Error): void {\n this.logger.error(\"❌ Authentication failed\", { error: error.message });\n this.authPromiseReject?.(error);\n this.cleanup();\n }\n\n /**\n * Handle popup failure - simplified like React implementation\n */\n private handlePopupFailure(failedUrl?: string): void {\n this.hasPopupFailed = true;\n\n this.logger.warn(\"Popup failed, using redirect mode instead...\", {\n failedUrl,\n });\n\n // Clean up iframe if it exists\n if (this.iframeAuthHandler) {\n this.iframeAuthHandler.cleanupIframe();\n }\n\n // Always redirect to the failed URL or build a new one\n if (failedUrl) {\n window.location.href = failedUrl;\n } else {\n this.buildAuthUrl()\n .then((authUrl) => {\n window.location.href = authUrl;\n })\n .catch((error) => {\n this.logger.error(\"Failed to build auth URL for redirect fallback\", {\n error,\n });\n const fallbackError = new CivicAuthError(\n \"Failed to redirect for authentication\",\n CivicAuthErrorCode.INIT_FAILED,\n );\n this.handleAuthError(fallbackError);\n });\n }\n }\n\n /**\n * Show popup failure message to user\n */\n private showPopupFailureMessage(\n customMessage: string = \"Authentication will continue in this window. Please wait...\",\n ): void {\n const container = this.getContainerElement();\n if (!container) {\n this.logger.warn(\n \"Cannot show popup failure message - container not found\",\n );\n return;\n }\n const existingMessage = document.getElementById(\n \"civic-auth-popup-failure-message\",\n );\n if (existingMessage && existingMessage.parentNode) {\n existingMessage.parentNode.removeChild(existingMessage);\n }\n const messageOverlay = document.createElement(\"div\");\n messageOverlay.id = \"civic-auth-popup-failure-message\";\n messageOverlay.style.cssText =\n \"position:absolute;top:0;left:0;right:0;background:rgba(255,249,196,.95);border:1px solid #f59e0b;border-radius:6px;padding:12px;margin:8px;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;font-size:14px;color:#92400e;z-index:1000;box-shadow:0 2px 4px rgba(0,0,0,.1);\";\n messageOverlay.innerHTML =\n '<div style=\"display:flex;align-items:center;gap:8px;\">' +\n '<span style=\"font-size:16px;\">⚠️</span>' +\n \"<div>\" +\n \"<strong>Popup blocked</strong><br>\" +\n '<span style=\"font-size:12px;\">' +\n customMessage +\n \"</span>\" +\n \"</div>\" +\n \"</div>\";\n\n if (getComputedStyle(container).position === \"static\") {\n container.style.position = \"relative\";\n }\n\n container.appendChild(messageOverlay);\n\n setTimeout(() => {\n if (messageOverlay.parentNode) {\n messageOverlay.parentNode.removeChild(messageOverlay);\n }\n }, 10000);\n this.logger.info(\"Popup failure message displayed to user\");\n }\n\n /**\n * Setup popup failure timeout\n */\n private setupPopupFailureTimeout(): void {\n this.popupFailureTimeoutHandle = window.setTimeout(() => {\n this.logger.info(\"⏰ Popup failure timeout reached\");\n this.events.emit(AuthEvent.SIGN_IN_ERROR, {\n detail: \"Authentication timeout - popup failure scenario\",\n });\n\n const error = new CivicAuthError(\n \"Authentication timeout - popup failure scenario\",\n CivicAuthErrorCode.AUTH_PROCESS_TIMEOUT,\n );\n this.handleAuthError(error);\n }, 20000); // 20 seconds\n }\n\n /**\n * Gets the container element for the auth iframe\n */\n private getContainerElement(): HTMLElement | null {\n if (typeof this.config.targetContainerElement === \"string\") {\n const element = document.getElementById(\n this.config.targetContainerElement,\n );\n if (!element) {\n this.logger.warn(\n `Container element with ID \"${this.config.targetContainerElement}\" not found`,\n );\n }\n return element;\n }\n return this.config.targetContainerElement ?? null;\n }\n\n /**\n * Handle OAuth callback\n */\n private async handleCallback(): Promise<void> {\n this.logger.info(\"🔄 Handling OAuth callback\", {\n currentUrl: window.location.href,\n redirectUrl: this.config.redirectUrl,\n });\n\n try {\n const callbackHandled = await handleOAuthRedirectPage({\n clientId: this.config.clientId,\n oauthServer: this.config.oauthServerBaseUrl,\n redirectUrl: this.config.redirectUrl,\n textSignals: {\n success: this.config.textSignals.success,\n error: this.config.textSignals.error || \"Authentication failed\",\n },\n storageAdapter: this.storage,\n });\n\n this.logger.info(\"📋 Callback processing result\", { callbackHandled });\n\n if (callbackHandled) {\n const successSignal = document.getElementById(\n CIVIC_AUTH_CONSTANTS.SUCCESS_SIGNAL_ID,\n );\n const errorSignal = document.getElementById(\n CIVIC_AUTH_CONSTANTS.ERROR_SIGNAL_ID,\n );\n\n if (successSignal) {\n this.logger.info(\"✅ Success signal found\");\n let userInfo = null;\n const userInfoAttr = successSignal.getAttribute(\"data-user-info\");\n if (userInfoAttr) {\n try {\n userInfo = JSON.parse(userInfoAttr);\n } catch (error) {\n this.logger.error(\"❌ Failed to parse user info\", { error });\n }\n }\n this.events.emit(AuthEvent.SIGN_IN_COMPLETE, {\n detail: \"Callback processed successfully\",\n user: userInfo,\n });\n } else if (errorSignal) {\n this.logger.error(\"❌ Error signal found\");\n this.events.emit(AuthEvent.SIGN_IN_ERROR, {\n detail: errorSignal.textContent || \"Unknown error during callback\",\n });\n }\n }\n } catch (error) {\n this.logger.error(\"❌ Callback handling failed\", { error });\n this.events.emit(AuthEvent.SIGN_IN_ERROR, {\n detail:\n error instanceof Error\n ? error.message\n : \"Unknown error during callback\",\n });\n }\n }\n\n /**\n * Cleans up resources and event listeners\n */\n public cleanup(): void {\n this.logger.info(\"Cleaning up authentication client\");\n\n // Clean up handlers\n this.iframeAuthHandler?.cleanupIframe();\n\n // Clean up timeouts\n if (this.authProcessTimeoutHandle) {\n window.clearTimeout(this.authProcessTimeoutHandle);\n this.authProcessTimeoutHandle = undefined;\n }\n\n if (this.popupFailureTimeoutHandle) {\n window.clearTimeout(this.popupFailureTimeoutHandle);\n this.popupFailureTimeoutHandle = undefined;\n }\n\n // Reset state\n this.hasPopupFailed = false;\n this.authPromise = undefined;\n this.authPromiseResolve = undefined;\n this.authPromiseReject = undefined;\n\n // Remove message event listener\n if (this.messageHandler) {\n window.removeEventListener(\"message\", this.messageHandler.handleMessage);\n }\n }\n\n /**\n * Get the current session\n */\n public async getCurrentSession(): Promise<Session | null> {\n return this.sessionManager.getCurrentSession() || null;\n }\n\n /**\n * Get current session tokens including decoded forwarded tokens\n * This method extracts and decodes forwarded tokens from the ID token JWT\n */\n public async getTokensWithForwardedTokens() {\n const session = await this.getCurrentSession();\n return extractTokensFromSession(session);\n }\n\n /**\n * Check if user is authenticated\n */\n public async isAuthenticated(): Promise<boolean> {\n return this.sessionManager.isAuthenticated() || false;\n }\n\n /**\n * Get the current user\n */\n public async getCurrentUser() {\n return this.sessionManager.getCurrentUser() || null;\n }\n\n /**\n * Clear the current session\n */\n public async clearSession(): Promise<void> {\n return this.sessionManager.clearSession();\n }\n\n /**\n * Manually refresh tokens\n */\n public async refreshTokens(): Promise<void> {\n return this.sessionManager.refreshTokens();\n }\n\n /**\n * Get token refresher state for debugging\n */\n public getTokenRefresherState() {\n return this.sessionManager.getTokenRefresherState() || null;\n }\n\n /**\n * Set a custom login URL for backend integration.\n * This is useful when integrating with a backend that handles the OAuth flow.\n * Alternatively, you can configure this directly in CivicAuth.create().\n *\n * @param loginUrl - The custom login URL to use (e.g., \"http://localhost:3020/auth/login\")\n *\n * @example\n * ```typescript\n * // Option 1: Configure in create()\n * const authClient = await CivicAuth.create({\n * clientId: \"YOUR_CLIENT_ID\",\n * loginUrl: \"http://example.com/custom-backendurl\"\n * });\n *\n * // Option 2: Set after creation\n * civicAuth.setLoginUrl(\"http://localhost:3020/auth/login\");\n * await civicAuth.startAuthentication();\n * ```\n */\n public setLoginUrl(loginUrl: string): void {\n this.loginUrl = loginUrl;\n\n // Update MessageHandler to expect messages from the custom origin\n if (this.messageHandler) {\n this.messageHandler.setCustomExpectedOrigin(loginUrl);\n }\n\n this.logger.info(\"🔗 Custom login URL set for backend integration\", {\n loginUrl: this.loginUrl,\n });\n }\n\n /**\n * Clear the login URL and return to standard OAuth flow\n */\n public clearLoginUrl(): void {\n this.loginUrl = undefined;\n\n // Clear custom expected origin from MessageHandler\n if (this.messageHandler) {\n this.messageHandler.clearCustomExpectedOrigin();\n }\n\n this.logger.info(\"🔗 Login URL cleared, returning to standard OAuth flow\");\n }\n\n /**\n * Get the current login URL\n * @returns The current login URL or undefined if not set\n */\n public getLoginUrl(): string | undefined {\n return this.loginUrl;\n }\n\n /**\n * Update the iframe display mode\n * @param mode - The display mode to use for the iframe\n */\n public setIframeDisplayMode(mode: \"modal\" | \"embedded\"): void {\n this.config.iframeDisplayMode = mode;\n this.logger.debug(`Iframe display mode updated to: ${mode}`);\n }\n\n /**\n * Get the current iframe display mode\n * @returns The current iframe display mode\n */\n public getIframeDisplayMode(): \"modal\" | \"embedded\" | undefined {\n return this.config.iframeDisplayMode;\n }\n\n /**\n * Destroy the auth client and clean up all resources\n */\n public async destroy(): Promise<void> {\n this.cleanup();\n await this.sessionManager.destroy();\n this.logger.info(\"CivicAuth destroyed\");\n }\n\n /**\n * Handle logout\n */\n public async logout(): Promise<void> {\n try {\n this.logger.info(\"🔄 Starting logout process\");\n this.events.emit(AuthEvent.SIGN_OUT_STARTED, {\n detail: \"Logout process started\",\n });\n\n // If a loginUrl is configured, redirect to the backend's logout endpoint.\n // The backend will then handle redirecting to the OIDC provider.\n if (this.loginUrl) {\n this.logger.info(\n \"🚪 Redirecting to backend for logout in backend-integrated flow\",\n );\n const backendUrl = new URL(this.loginUrl).origin;\n const endpoints = getBackendEndpoints(this.config.backendEndpoints);\n const backendLogoutUrl = `${backendUrl}${endpoints.logout}`;\n\n // Clear local SDK session state before redirecting\n await this.sessionManager.clearSession();\n this.events.emit(AuthEvent.SIGN_OUT_COMPLETE, {\n detail: \"Local session cleared, redirecting to backend for logout.\",\n });\n\n // Perform top-level redirect to the backend logout endpoint\n this.logger.info(\"🌐 Redirecting to backend logout endpoint\", {\n url: backendLogoutUrl,\n });\n window.location.href = backendLogoutUrl;\n return;\n }\n\n // --- Existing SPA redirect-based logout flow ---\n this.logger.info(\"🚪 Using redirect-based logout for SPA flow\");\n const tokens = await retrieveTokens(this.storage);\n\n if (!tokens?.id_token) {\n this.logger.warn(\"⚠️ No ID token found, clearing local session only\");\n await clearTokens(this.storage);\n await this.sessionManager.clearSession();\n this.events.emit(AuthEvent.SIGN_OUT_COMPLETE, {\n detail: \"Local session cleared\",\n });\n return;\n }\n\n if (!this.endpoints) {\n throw new Error(\"OAuth endpoints not initialized\");\n }\n\n // Generate a state for logout\n const state = generateState({\n displayMode: this.config.displayMode || \"iframe\",\n framework: this.config.framework || \"vanillajs\",\n sdkVersion: getVersion(),\n });\n\n this.logger.info(\"🔄 Storing logout state\", {\n generatedState: state,\n logoutStateKey: LOGOUT_STATE,\n displayMode: this.config.displayMode,\n });\n\n // Store logout state for cleanup after redirect\n // This matches the React implementation - only store state for redirect flow\n await this.storage.set(LOGOUT_STATE, state);\n\n // Generate logout URL\n const logoutUrl = await generateOauthLogoutUrl({\n clientId: this.config.clientId,\n redirectUrl: this.config.logoutRedirectUrl,\n idToken: tokens.id_token,\n state: state,\n oauthServer: this.config.oauthServerBaseUrl,\n });\n\n this.logger.info(\"🔗 Generated logout URL\", {\n logoutUrl: logoutUrl.toString(),\n });\n\n // Clear local tokens and session but NOT the logout state (needed for cleanup after redirect)\n await this.sessionManager.clearSession(true); // preserveLogoutState = true\n\n // Emit logout complete event before redirect\n this.events.emit(AuthEvent.SIGN_OUT_COMPLETE, {\n detail: \"Logout successful\",\n });\n\n // Redirect to logout URL\n this.logger.info(\"🌐 Redirecting to logout URL\");\n window.location.href = logoutUrl.toString();\n } catch (error) {\n this.logger.error(\"❌ Logout failed\", { error });\n this.events.emit(AuthEvent.SIGN_OUT_ERROR, {\n detail: error instanceof Error ? error.message : String(error),\n });\n throw new CivicAuthError(\n \"Logout failed\",\n CivicAuthErrorCode.LOGOUT_FAILED,\n );\n }\n }\n\n /**\n * Handle logout state cleanup\n * This mirrors the logic from useSignIn.ts to properly clean up after logout\n */\n private async handleLogoutStateCleanup(): Promise<void> {\n try {\n const params = new URLSearchParams(window.location.search);\n const state = params.get(\"state\");\n\n this.logger.info(\"🔍 Checking for logout state cleanup\", {\n currentUrl: window.location.href,\n hasStateParam: !!state,\n stateValue: state,\n rawSearch: window.location.search,\n });\n\n if (!state) {\n this.logger.info(\n \"🔍 No state parameter found, skipping logout cleanup\",\n );\n return; // No state parameter, nothing to cleanup\n }\n\n // Check if we have a stored logout state that matches\n const storedLogoutState = await this.storage.get(LOGOUT_STATE);\n\n // The state might be URL-decoded by URLSearchParams, but stored as plain\n // Let's try both the decoded and encoded versions\n const decodedState = decodeURIComponent(state);\n\n this.logger.info(\"🔍 Comparing logout states\", {\n urlState: state,\n decodedState,\n storedLogoutState,\n directMatch: state === storedLogoutState,\n decodedMatch: decodedState === storedLogoutState,\n });\n\n if (state === storedLogoutState || decodedState === storedLogoutState) {\n this.logger.info(\"🧹 Cleaning up logout state\", {\n state,\n storedLogoutState,\n });\n\n // Clear tokens and user data from storage\n await clearTokens(this.storage);\n await this.sessionManager.clearSession();\n\n // Clean up the logout state from storage\n await this.storage.delete(LOGOUT_STATE);\n\n // Emit logout complete event\n this.events.emit(AuthEvent.SIGN_OUT_COMPLETE, {\n detail: \"Logout cleanup completed\",\n });\n\n // Clean up URL by removing query parameters\n const cleanUrl = window.location.href.split(\"?\")[0];\n window.history.replaceState({}, document.title, cleanUrl);\n\n this.logger.info(\"✅ Logout state cleanup completed\", {\n cleanUrl,\n });\n } else {\n this.logger.info(\"🔍 Logout states don't match, skipping cleanup\", {\n urlState: state,\n storedLogoutState,\n });\n }\n } catch (error) {\n this.logger.warn(\"⚠️ Error during logout state cleanup\", { error });\n // Don't throw error to prevent initialization failure\n }\n }\n}\n\n// Export types for external use\nexport type { CivicAuthClientConfig } from \"./types/AuthTypes.js\";\nexport { CivicAuthErrorCode } from \"./types/AuthTypes.js\";\n"]}
|
|
@@ -52,7 +52,7 @@ export function processConfigWithDefaults(config) {
|
|
|
52
52
|
backendEndpoints: config.backendEndpoints, // Include backend endpoints in processed config
|
|
53
53
|
preloadIframe: config.preloadIframe !== false, // Default to true unless explicitly set to false
|
|
54
54
|
autoRedirect: config.autoRedirect !== false, // Default to true unless explicitly set to false
|
|
55
|
-
};
|
|
55
|
+
};
|
|
56
56
|
}
|
|
57
57
|
/**
|
|
58
58
|
* Validates required configuration properties
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConfigProcessor.js","sourceRoot":"","sources":["../../../../src/vanillajs/auth/config/ConfigProcessor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,6CAA6C,CAAC;AACnF,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAO5E,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAE/B;;GAEG;AACH,MAAM,UAAU,yBAAyB,CACvC,MAA6B;IAE7B,kCAAkC;IAClC,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAE/B,MAAM,aAAa,GAAkB;QACnC,OAAO,EAAE,KAAK;QACd,SAAS,EAAE,GAAG;QACd,KAAK,EAAE,OAAgB;QACvB,GAAG,MAAM,CAAC,OAAO;KAClB,CAAC;IAEF,uFAAuF;IACvF,sHAAsH;IACtH,MAAM,mBAAmB,GAAG,MAAM,CAAC,WAAW,IAAI,QAAQ,CAAC;IAC3D,MAAM,oBAAoB,GACxB,mBAAmB,KAAK,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,mBAAmB,CAAC;IAEtE,MAAM,0BAA0B,GAC9B,mBAAmB,KAAK,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC;IAE7E,yEAAyE;IACzE,MAAM,WAAW,GACf,MAAM,CAAC,WAAW;QAClB,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;IAEzD,+GAA+G;IAC/G,MAAM,iBAAiB,GAAG,MAAM,CAAC,iBAAiB,IAAI,WAAW,CAAC;IAElE,gDAAgD;IAChD,wFAAwF;IACxF,2EAA2E;IAC3E,MAAM,cAAc,GAAG,MAAM,CAAC,QAAQ;QACpC,CAAC,CAAC,IAAI,oBAAoB,EAAE;QAC5B,CAAC,CAAC,MAAM,CAAC,cAAc,IAAI,IAAI,mBAAmB,EAAE,CAAC;IAEvD,OAAO;QACL,GAAG,MAAM;QACT,WAAW;QACX,iBAAiB;QACjB,kBAAkB,EAAE,MAAM,CAAC,kBAAkB,IAAI,mBAAmB;QACpE,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,cAAc;QACvC,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI;YACjC,OAAO,EAAE,4BAA4B;YACrC,KAAK,EAAE,0CAA0C;SAClD;QACD,WAAW,EAAE,oBAAoB;QACjC,iBAAiB,EAAE,0BAA0B;QAC7C,kBAAkB,EAChB,MAAM,CAAC,kBAAkB;YACzB,oBAAoB,CAAC,4BAA4B;QACnD,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,oBAAoB,CAAC,iBAAiB;QACnE,MAAM,EAAE,SAAS;QACjB,OAAO,EAAE,aAAa;QACtB,cAAc;QACd,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,uCAAuC;QAClE,gBAAgB,EAAE,MAAM,CAAC,gBAAgB,EAAE,gDAAgD;QAC3F,aAAa,EAAE,MAAM,CAAC,aAAa,KAAK,KAAK,EAAE,iDAAiD;QAChG,YAAY,EAAE,MAAM,CAAC,YAAY,KAAK,KAAK,EAAE,iDAAiD;
|
|
1
|
+
{"version":3,"file":"ConfigProcessor.js","sourceRoot":"","sources":["../../../../src/vanillajs/auth/config/ConfigProcessor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,6CAA6C,CAAC;AACnF,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAO5E,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAE/B;;GAEG;AACH,MAAM,UAAU,yBAAyB,CACvC,MAA6B;IAE7B,kCAAkC;IAClC,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAE/B,MAAM,aAAa,GAAkB;QACnC,OAAO,EAAE,KAAK;QACd,SAAS,EAAE,GAAG;QACd,KAAK,EAAE,OAAgB;QACvB,GAAG,MAAM,CAAC,OAAO;KAClB,CAAC;IAEF,uFAAuF;IACvF,sHAAsH;IACtH,MAAM,mBAAmB,GAAG,MAAM,CAAC,WAAW,IAAI,QAAQ,CAAC;IAC3D,MAAM,oBAAoB,GACxB,mBAAmB,KAAK,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,mBAAmB,CAAC;IAEtE,MAAM,0BAA0B,GAC9B,mBAAmB,KAAK,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC;IAE7E,yEAAyE;IACzE,MAAM,WAAW,GACf,MAAM,CAAC,WAAW;QAClB,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;IAEzD,+GAA+G;IAC/G,MAAM,iBAAiB,GAAG,MAAM,CAAC,iBAAiB,IAAI,WAAW,CAAC;IAElE,gDAAgD;IAChD,wFAAwF;IACxF,2EAA2E;IAC3E,MAAM,cAAc,GAAG,MAAM,CAAC,QAAQ;QACpC,CAAC,CAAC,IAAI,oBAAoB,EAAE;QAC5B,CAAC,CAAC,MAAM,CAAC,cAAc,IAAI,IAAI,mBAAmB,EAAE,CAAC;IAEvD,OAAO;QACL,GAAG,MAAM;QACT,WAAW;QACX,iBAAiB;QACjB,kBAAkB,EAAE,MAAM,CAAC,kBAAkB,IAAI,mBAAmB;QACpE,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,cAAc;QACvC,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI;YACjC,OAAO,EAAE,4BAA4B;YACrC,KAAK,EAAE,0CAA0C;SAClD;QACD,WAAW,EAAE,oBAAoB;QACjC,iBAAiB,EAAE,0BAA0B;QAC7C,kBAAkB,EAChB,MAAM,CAAC,kBAAkB;YACzB,oBAAoB,CAAC,4BAA4B;QACnD,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,oBAAoB,CAAC,iBAAiB;QACnE,MAAM,EAAE,SAAS;QACjB,OAAO,EAAE,aAAa;QACtB,cAAc;QACd,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,uCAAuC;QAClE,gBAAgB,EAAE,MAAM,CAAC,gBAAgB,EAAE,gDAAgD;QAC3F,aAAa,EAAE,MAAM,CAAC,aAAa,KAAK,KAAK,EAAE,iDAAiD;QAChG,YAAY,EAAE,MAAM,CAAC,YAAY,KAAK,KAAK,EAAE,iDAAiD;KAC/F,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,sBAAsB,CAAC,MAA6B;IAC3D,4EAA4E;IAC5E,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;QACzC,MAAM,IAAI,cAAc,CACtB,gEAAgE,EAChE,kBAAkB,CAAC,eAAe,CACnC,CAAC;IACJ,CAAC;IAED,oDAAoD;IACpD,gGAAgG;IAChG,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,IAAI,QAAQ,CAAC;IACnD,MAAM,iBAAiB,GAAG,MAAM,CAAC,iBAAiB,CAAC;IAEnD,uCAAuC;IACvC,MAAM,cAAc,GAClB,WAAW,KAAK,UAAU,IAAI,qBAAqB;QACnD,CAAC,WAAW,KAAK,QAAQ,IAAI,iBAAiB,KAAK,UAAU,CAAC,CAAC,CAAC,aAAa;IAE/E,IAAI,cAAc,IAAI,CAAC,MAAM,CAAC,sBAAsB,EAAE,CAAC;QACrD,MAAM,IAAI,cAAc,CACtB,0EAA0E;YACxE,4DAA4D;YAC5D,mEAAmE;YACnE,8DAA8D;YAC9D,gEAAgE,EAClE,kBAAkB,CAAC,eAAe,CACnC,CAAC;IACJ,CAAC;AACH,CAAC","sourcesContent":["import { LocalStorageAdapter } from \"../../../browser/storage.js\";\nimport { BrowserCookieStorage } from \"../../../shared/lib/BrowserCookieStorage.js\";\nimport { DEFAULT_SCOPES, DEFAULT_AUTH_SERVER } from \"../../../constants.js\";\nimport type { DisplayMode } from \"../../../types.js\";\nimport type {\n CivicAuthClientConfig,\n ProcessedCivicAuthConfig,\n LoggingConfig,\n} from \"../types/AuthTypes.js\";\nimport {\n CivicAuthError,\n CivicAuthErrorCode,\n CIVIC_AUTH_CONSTANTS,\n} from \"../types/AuthTypes.js\";\n\n/**\n * Process the configuration with defaults and validation\n */\nexport function processConfigWithDefaults(\n config: CivicAuthClientConfig,\n): ProcessedCivicAuthConfig {\n // Validate required configuration\n validateRequiredConfig(config);\n\n const loggingConfig: LoggingConfig = {\n enabled: false,\n namespace: \"*\",\n level: \"debug\" as const,\n ...config.logging,\n };\n\n // Handle displayMode proxy: map \"embedded\" to \"iframe\" + iframeDisplayMode: \"embedded\"\n // the original displaymode doesn't suppors embedded, so we need to proxy it to iframe + iframeDisplayMode: \"embedded\"\n const originalDisplayMode = config.displayMode || \"iframe\";\n const processedDisplayMode: DisplayMode =\n originalDisplayMode === \"embedded\" ? \"iframe\" : originalDisplayMode;\n\n const processedIframeDisplayMode =\n originalDisplayMode === \"embedded\" ? \"embedded\" : config.iframeDisplayMode;\n\n // Process redirectUrl - default to current page without query parameters\n const redirectUrl =\n config.redirectUrl ||\n `${window.location.origin}${window.location.pathname}`;\n\n // Process logoutRedirectUrl - default to redirectUrl if not provided (same behavior as reactjs implementation)\n const logoutRedirectUrl = config.logoutRedirectUrl || redirectUrl;\n\n // Auto-select storage adapter based on loginUrl\n // If loginUrl is provided (backend integration), automatically use BrowserCookieStorage\n // Otherwise, use provided storageAdapter or default to LocalStorageAdapter\n const storageAdapter = config.loginUrl\n ? new BrowserCookieStorage()\n : config.storageAdapter || new LocalStorageAdapter();\n\n return {\n ...config,\n redirectUrl,\n logoutRedirectUrl,\n oauthServerBaseUrl: config.oauthServerBaseUrl || DEFAULT_AUTH_SERVER,\n scopes: config.scopes || DEFAULT_SCOPES,\n textSignals: config.textSignals || {\n success: \"Authentication successful!\",\n error: \"Authentication failed. Please try again.\",\n },\n displayMode: processedDisplayMode,\n iframeDisplayMode: processedIframeDisplayMode,\n authProcessTimeout:\n config.authProcessTimeout ||\n CIVIC_AUTH_CONSTANTS.DEFAULT_AUTH_PROCESS_TIMEOUT,\n iframeId: config.iframeId || CIVIC_AUTH_CONSTANTS.DEFAULT_IFRAME_ID,\n prompt: \"consent\",\n logging: loggingConfig,\n storageAdapter,\n loginUrl: config.loginUrl, // Include loginUrl in processed config\n backendEndpoints: config.backendEndpoints, // Include backend endpoints in processed config\n preloadIframe: config.preloadIframe !== false, // Default to true unless explicitly set to false\n autoRedirect: config.autoRedirect !== false, // Default to true unless explicitly set to false\n };\n}\n\n/**\n * Validates required configuration properties\n */\nfunction validateRequiredConfig(config: CivicAuthClientConfig): void {\n // Dynamic validation: clientId is only required if loginUrl is not provided\n if (!config.loginUrl && !config.clientId) {\n throw new CivicAuthError(\n \"CivicAuth: clientId is required when loginUrl is not provided.\",\n CivicAuthErrorCode.CONFIG_REQUIRED,\n );\n }\n\n // Conditional validation for targetContainerElement\n // Handle both the new \"embedded\" displayMode and the legacy iframe + iframeDisplayMode approach\n const displayMode = config.displayMode || \"iframe\";\n const iframeDisplayMode = config.iframeDisplayMode;\n\n // Check if we need a container element\n const needsContainer =\n displayMode === \"embedded\" || // New simplified API\n (displayMode === \"iframe\" && iframeDisplayMode === \"embedded\"); // Legacy API\n\n if (needsContainer && !config.targetContainerElement) {\n throw new CivicAuthError(\n \"CivicAuth: targetContainerElement is required for embedded iframe mode. \" +\n \"You can use displayMode: 'embedded' for a simplified API, \" +\n \"or use displayMode: 'iframe' with iframeDisplayMode: 'embedded'. \" +\n \"For modal iframe mode, use displayMode: 'iframe' (default). \" +\n \"For non-iframe modes, use displayMode 'redirect' or 'new_tab'.\",\n CivicAuthErrorCode.CONFIG_REQUIRED,\n );\n }\n}\n"]}
|
|
@@ -68,9 +68,10 @@ export declare class CivicAuthError extends Error {
|
|
|
68
68
|
}
|
|
69
69
|
/**
|
|
70
70
|
* Configuration options for the CivicAuth client
|
|
71
|
-
* Uses discriminated union to make clientId optional when loginUrl is provided
|
|
72
71
|
*/
|
|
73
|
-
export
|
|
72
|
+
export interface CivicAuthClientConfig {
|
|
73
|
+
/** OAuth client ID */
|
|
74
|
+
clientId: string;
|
|
74
75
|
/** URL to redirect to after authentication */
|
|
75
76
|
redirectUrl?: string;
|
|
76
77
|
/** URL to redirect to after logout - if not provided, will use redirectUrl */
|
|
@@ -111,6 +112,11 @@ export type CivicAuthClientConfig = {
|
|
|
111
112
|
initialState?: string;
|
|
112
113
|
/** Logging configuration */
|
|
113
114
|
logging?: LoggingConfig;
|
|
115
|
+
/**
|
|
116
|
+
* Custom login URL for backend integration (e.g., "http://example.com/custom-backendurl")
|
|
117
|
+
* When provided, automatically uses BrowserCookieStorage for session sharing with backend
|
|
118
|
+
*/
|
|
119
|
+
loginUrl?: string;
|
|
114
120
|
/**
|
|
115
121
|
* Custom backend endpoints configuration for backend integration
|
|
116
122
|
* Only used when loginUrl is provided. Allows overriding default endpoints.
|
|
@@ -122,17 +128,7 @@ export type CivicAuthClientConfig = {
|
|
|
122
128
|
preloadIframe?: boolean;
|
|
123
129
|
/** Whether to automatically switch to redirect mode when browser doesn't support iframe-based auth (defaults to true) */
|
|
124
130
|
autoRedirect?: boolean;
|
|
125
|
-
}
|
|
126
|
-
/** OAuth client ID - required for standard OAuth flow */
|
|
127
|
-
clientId: string;
|
|
128
|
-
/** Custom login URL for backend integration - optional */
|
|
129
|
-
loginUrl?: string;
|
|
130
|
-
} | {
|
|
131
|
-
/** OAuth client ID - optional when using backend integration */
|
|
132
|
-
clientId?: string;
|
|
133
|
-
/** Custom login URL for backend integration - required when clientId is not provided */
|
|
134
|
-
loginUrl: string;
|
|
135
|
-
});
|
|
131
|
+
}
|
|
136
132
|
export interface LoggingConfig {
|
|
137
133
|
enabled: boolean;
|
|
138
134
|
namespace?: string;
|
|
@@ -140,9 +136,8 @@ export interface LoggingConfig {
|
|
|
140
136
|
}
|
|
141
137
|
/**
|
|
142
138
|
* Internal configuration with all optional properties resolved to required ones.
|
|
143
|
-
* Maintains the discriminated union structure for clientId/loginUrl
|
|
144
139
|
*/
|
|
145
|
-
export type ProcessedCivicAuthConfig = {
|
|
140
|
+
export type ProcessedCivicAuthConfig = CivicAuthClientConfig & {
|
|
146
141
|
redirectUrl: string;
|
|
147
142
|
logoutRedirectUrl: string;
|
|
148
143
|
oauthServerBaseUrl: string;
|
|
@@ -158,23 +153,9 @@ export type ProcessedCivicAuthConfig = {
|
|
|
158
153
|
iframeId: string;
|
|
159
154
|
prompt: string;
|
|
160
155
|
nonce?: string;
|
|
156
|
+
loginUrl?: string;
|
|
161
157
|
backendEndpoints?: BackendEndpoints;
|
|
162
158
|
preloadIframe: boolean;
|
|
163
159
|
autoRedirect: boolean;
|
|
164
|
-
|
|
165
|
-
iframeDisplayMode?: "modal" | "embedded";
|
|
166
|
-
events?: AuthenticationEvents;
|
|
167
|
-
initialState?: string;
|
|
168
|
-
framework?: FrameworkType;
|
|
169
|
-
} & ({
|
|
170
|
-
/** OAuth client ID - required for standard OAuth flow */
|
|
171
|
-
clientId: string;
|
|
172
|
-
/** Custom login URL for backend integration - optional */
|
|
173
|
-
loginUrl?: string;
|
|
174
|
-
} | {
|
|
175
|
-
/** OAuth client ID - optional when using backend integration */
|
|
176
|
-
clientId?: string;
|
|
177
|
-
/** Custom login URL for backend integration - required when clientId is not provided */
|
|
178
|
-
loginUrl: string;
|
|
179
|
-
});
|
|
160
|
+
};
|
|
180
161
|
//# sourceMappingURL=AuthTypes.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthTypes.d.ts","sourceRoot":"","sources":["../../../../src/vanillajs/auth/types/AuthTypes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,KAAK,EACV,WAAW,IAAI,eAAe,EAC9B,WAAW,EACX,aAAa,EACd,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAElE;;;;GAIG;AACH,MAAM,MAAM,oBAAoB,GAAG,eAAe,GAAG,UAAU,CAAC;AAEhE;;GAEG;AACH,oBAAY,kBAAkB;IAC5B,eAAe,oBAAoB;IACnC,WAAW,gBAAgB;IAC3B,yBAAyB,8BAA8B;IACvD,mBAAmB,wBAAwB;IAC3C,oBAAoB,yBAAyB;IAC7C,iBAAiB,sBAAsB;IACvC,qBAAqB,0BAA0B;IAC/C,eAAe,oBAAoB;IACnC,aAAa,kBAAkB;IAC/B,aAAa,kBAAkB;IAC/B,cAAc,mBAAmB;IACjC,mBAAmB,wBAAwB;IAC3C,oBAAoB,yBAAyB;IAC7C,iBAAiB,sBAAsB;IACvC,aAAa,kBAAkB;IAC/B,gBAAgB,qBAAqB;IACrC,cAAc,mBAAmB;CAClC;AAED;;GAEG;AACH,eAAO,MAAM,4BAA4B,SAAS,CAAC;AAEnD,eAAO,MAAM,oBAAoB;;;;;CAKvB,CAAC;AAEX;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,cAAc,GAAG,YAAY,CAAC;AAE5D,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,eAAe,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,eAAe,CAAC;IACxB,IAAI,EAAE,QAAQ,GAAG,qBAAqB,GAAG,cAAc,GAAG,MAAM,CAAC;IACjE,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,MAAM,aAAa,GACrB,WAAW,GACX,eAAe,GACf,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE5B,qBAAa,cAAe,SAAQ,KAAK;aAGrB,IAAI,EAAE,kBAAkB;gBADxC,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,kBAAkB;CAK3C;AAED
|
|
1
|
+
{"version":3,"file":"AuthTypes.d.ts","sourceRoot":"","sources":["../../../../src/vanillajs/auth/types/AuthTypes.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthTypes.js","sourceRoot":"","sources":["../../../../src/vanillajs/auth/types/AuthTypes.ts"],"names":[],"mappings":"AAeA;;GAEG;AACH,MAAM,CAAN,IAAY,kBAkBX;AAlBD,WAAY,kBAAkB;IAC5B,yDAAmC,CAAA;IACnC,iDAA2B,CAAA;IAC3B,6EAAuD,CAAA;IACvD,iEAA2C,CAAA;IAC3C,mEAA6C,CAAA;IAC7C,6DAAuC,CAAA;IACvC,qEAA+C,CAAA;IAC/C,yDAAmC,CAAA;IACnC,qDAA+B,CAAA;IAC/B,qDAA+B,CAAA;IAC/B,uDAAiC,CAAA;IACjC,iEAA2C,CAAA;IAC3C,mEAA6C,CAAA;IAC7C,6DAAuC,CAAA;IACvC,qDAA+B,CAAA;IAC/B,2DAAqC,CAAA;IACrC,uDAAiC,CAAA;AACnC,CAAC,EAlBW,kBAAkB,KAAlB,kBAAkB,QAkB7B;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,MAAM,CAAC,CAAC,aAAa;AAEjE,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,iBAAiB,EAAE,mBAAmB;IACtC,4BAA4B;IAC5B,iBAAiB,EAAE,2BAA2B;IAC9C,eAAe,EAAE,yBAAyB;CAClC,CAAC;AAgCX,MAAM,OAAO,cAAe,SAAQ,KAAK;IAGrB;IAFlB,YACE,OAAe,EACC,IAAwB;QAExC,KAAK,CAAC,OAAO,CAAC,CAAC;QAFC,SAAI,GAAJ,IAAI,CAAoB;QAGxC,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF","sourcesContent":["import type { AuthenticationEvents } from \"../AuthenticationEvents.js\";\nimport type {\n DisplayMode as BaseDisplayMode,\n AuthStorage,\n FrameworkType,\n} from \"../../../types.js\";\nimport type { BackendEndpoints } from \"../../../server/config.js\";\n\n/**\n * Extended DisplayMode for VanillaJS that includes \"embedded\" option\n * This provides a cleaner API where users can simply use displayMode: \"embedded\"\n * instead of displayMode: \"iframe\" + iframeDisplayMode: \"embedded\"\n */\nexport type VanillaJSDisplayMode = BaseDisplayMode | \"embedded\";\n\n/**\n * Error codes for CivicAuth errors\n */\nexport enum CivicAuthErrorCode {\n CONFIG_REQUIRED = \"CONFIG_REQUIRED\",\n INIT_FAILED = \"INIT_FAILED\",\n ENDPOINTS_NOT_INITIALIZED = \"ENDPOINTS_NOT_INITIALIZED\",\n CONTAINER_NOT_FOUND = \"CONTAINER_NOT_FOUND\",\n AUTH_PROCESS_TIMEOUT = \"AUTH_PROCESS_TIMEOUT\",\n IFRAME_LOAD_ERROR = \"IFRAME_LOAD_ERROR\",\n IFRAME_PRELOAD_FAILED = \"IFRAME_PRELOAD_FAILED\",\n INVALID_MESSAGE = \"INVALID_MESSAGE\",\n LOGOUT_FAILED = \"LOGOUT_FAILED\",\n POPUP_BLOCKED = \"popup_blocked\",\n USER_CANCELLED = \"user_cancelled\",\n CONFIGURATION_ERROR = \"configuration_error\",\n TOKEN_REFRESH_FAILED = \"token_refresh_failed\",\n SESSION_NOT_FOUND = \"session_not_found\",\n STORAGE_ERROR = \"storage_error\",\n IFRAME_NOT_FOUND = \"iframe_not_found\",\n INTERNAL_ERROR = \"internal_error\",\n}\n\n/**\n * Constants for the auth client\n */\nexport const DEFAULT_AUTH_PROCESS_TIMEOUT = 600000; // 10 minutes\n\nexport const CIVIC_AUTH_CONSTANTS = {\n DEFAULT_IFRAME_ID: \"civic-auth-iframe\",\n DEFAULT_AUTH_PROCESS_TIMEOUT,\n SUCCESS_SIGNAL_ID: \"civic-auth-success-signal\",\n ERROR_SIGNAL_ID: \"civic-auth-error-signal\",\n} as const;\n\n/**\n * Message types for postMessage communication\n */\nexport type AuthMessageType = \"auth_success\" | \"auth_error\";\n\nexport interface AuthMessage {\n type: AuthMessageType;\n detail?: string;\n data?: unknown;\n error?: unknown;\n}\n\n/**\n * Login app message types for postMessage communication\n */\nexport interface LoginAppMessage {\n source: \"civicloginApp\";\n type: \"design\" | \"generatePopupFailed\" | \"auth_success\" | string;\n clientId: string;\n data?: unknown;\n}\n\n/**\n * Combined message type for all iframe communications\n */\nexport type IframeMessage =\n | AuthMessage\n | LoginAppMessage\n | Record<string, unknown>;\n\nexport class CivicAuthError extends Error {\n constructor(\n message: string,\n public readonly code: CivicAuthErrorCode,\n ) {\n super(message);\n this.name = \"CivicAuthError\";\n }\n}\n\n/**\n * Configuration options for the CivicAuth client\n
|
|
1
|
+
{"version":3,"file":"AuthTypes.js","sourceRoot":"","sources":["../../../../src/vanillajs/auth/types/AuthTypes.ts"],"names":[],"mappings":"AAeA;;GAEG;AACH,MAAM,CAAN,IAAY,kBAkBX;AAlBD,WAAY,kBAAkB;IAC5B,yDAAmC,CAAA;IACnC,iDAA2B,CAAA;IAC3B,6EAAuD,CAAA;IACvD,iEAA2C,CAAA;IAC3C,mEAA6C,CAAA;IAC7C,6DAAuC,CAAA;IACvC,qEAA+C,CAAA;IAC/C,yDAAmC,CAAA;IACnC,qDAA+B,CAAA;IAC/B,qDAA+B,CAAA;IAC/B,uDAAiC,CAAA;IACjC,iEAA2C,CAAA;IAC3C,mEAA6C,CAAA;IAC7C,6DAAuC,CAAA;IACvC,qDAA+B,CAAA;IAC/B,2DAAqC,CAAA;IACrC,uDAAiC,CAAA;AACnC,CAAC,EAlBW,kBAAkB,KAAlB,kBAAkB,QAkB7B;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,MAAM,CAAC,CAAC,aAAa;AAEjE,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,iBAAiB,EAAE,mBAAmB;IACtC,4BAA4B;IAC5B,iBAAiB,EAAE,2BAA2B;IAC9C,eAAe,EAAE,yBAAyB;CAClC,CAAC;AAgCX,MAAM,OAAO,cAAe,SAAQ,KAAK;IAGrB;IAFlB,YACE,OAAe,EACC,IAAwB;QAExC,KAAK,CAAC,OAAO,CAAC,CAAC;QAFC,SAAI,GAAJ,IAAI,CAAoB;QAGxC,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF","sourcesContent":["import type { AuthenticationEvents } from \"../AuthenticationEvents.js\";\nimport type {\n DisplayMode as BaseDisplayMode,\n AuthStorage,\n FrameworkType,\n} from \"../../../types.js\";\nimport type { BackendEndpoints } from \"../../../server/config.js\";\n\n/**\n * Extended DisplayMode for VanillaJS that includes \"embedded\" option\n * This provides a cleaner API where users can simply use displayMode: \"embedded\"\n * instead of displayMode: \"iframe\" + iframeDisplayMode: \"embedded\"\n */\nexport type VanillaJSDisplayMode = BaseDisplayMode | \"embedded\";\n\n/**\n * Error codes for CivicAuth errors\n */\nexport enum CivicAuthErrorCode {\n CONFIG_REQUIRED = \"CONFIG_REQUIRED\",\n INIT_FAILED = \"INIT_FAILED\",\n ENDPOINTS_NOT_INITIALIZED = \"ENDPOINTS_NOT_INITIALIZED\",\n CONTAINER_NOT_FOUND = \"CONTAINER_NOT_FOUND\",\n AUTH_PROCESS_TIMEOUT = \"AUTH_PROCESS_TIMEOUT\",\n IFRAME_LOAD_ERROR = \"IFRAME_LOAD_ERROR\",\n IFRAME_PRELOAD_FAILED = \"IFRAME_PRELOAD_FAILED\",\n INVALID_MESSAGE = \"INVALID_MESSAGE\",\n LOGOUT_FAILED = \"LOGOUT_FAILED\",\n POPUP_BLOCKED = \"popup_blocked\",\n USER_CANCELLED = \"user_cancelled\",\n CONFIGURATION_ERROR = \"configuration_error\",\n TOKEN_REFRESH_FAILED = \"token_refresh_failed\",\n SESSION_NOT_FOUND = \"session_not_found\",\n STORAGE_ERROR = \"storage_error\",\n IFRAME_NOT_FOUND = \"iframe_not_found\",\n INTERNAL_ERROR = \"internal_error\",\n}\n\n/**\n * Constants for the auth client\n */\nexport const DEFAULT_AUTH_PROCESS_TIMEOUT = 600000; // 10 minutes\n\nexport const CIVIC_AUTH_CONSTANTS = {\n DEFAULT_IFRAME_ID: \"civic-auth-iframe\",\n DEFAULT_AUTH_PROCESS_TIMEOUT,\n SUCCESS_SIGNAL_ID: \"civic-auth-success-signal\",\n ERROR_SIGNAL_ID: \"civic-auth-error-signal\",\n} as const;\n\n/**\n * Message types for postMessage communication\n */\nexport type AuthMessageType = \"auth_success\" | \"auth_error\";\n\nexport interface AuthMessage {\n type: AuthMessageType;\n detail?: string;\n data?: unknown;\n error?: unknown;\n}\n\n/**\n * Login app message types for postMessage communication\n */\nexport interface LoginAppMessage {\n source: \"civicloginApp\";\n type: \"design\" | \"generatePopupFailed\" | \"auth_success\" | string;\n clientId: string;\n data?: unknown;\n}\n\n/**\n * Combined message type for all iframe communications\n */\nexport type IframeMessage =\n | AuthMessage\n | LoginAppMessage\n | Record<string, unknown>;\n\nexport class CivicAuthError extends Error {\n constructor(\n message: string,\n public readonly code: CivicAuthErrorCode,\n ) {\n super(message);\n this.name = \"CivicAuthError\";\n }\n}\n\n/**\n * Configuration options for the CivicAuth client\n */\nexport interface CivicAuthClientConfig {\n /** OAuth client ID */\n clientId: string;\n /** URL to redirect to after authentication */\n redirectUrl?: string;\n /** URL to redirect to after logout - if not provided, will use redirectUrl */\n logoutRedirectUrl?: string;\n /** Base URL of the OAuth server */\n oauthServerBaseUrl?: string;\n /** Array of OAuth scopes to request */\n scopes?: string[];\n /** HTML element or element ID where the auth iframe will be mounted (required for embedded iframe mode) */\n targetContainerElement?: HTMLElement | string;\n /** Text signals for success and error states */\n textSignals?: {\n /** Text to display on successful authentication */\n success: string;\n /** Optional text to display on authentication error */\n error?: string;\n };\n /** Display mode for the authentication UI - VanillaJS supports \"embedded\" for simplified API */\n displayMode?: VanillaJSDisplayMode;\n /** Display mode for iframe rendering - modal (full-screen overlay) or embedded (within container) */\n iframeDisplayMode?: \"modal\" | \"embedded\";\n /**\n * Timeout duration in milliseconds for the entire authentication process.\n * If the authentication process takes longer than this duration, it will be cancelled\n * and an error will be thrown.\n * Note: This timeout is not applied to embedded iframe mode, where the iframe remains persistent.\n */\n authProcessTimeout?: number;\n /** Event handlers for authentication events */\n events?: AuthenticationEvents;\n /** Custom ID for the auth iframe */\n iframeId?: string;\n /** Custom storage adapter for auth state - uses shared AuthStorage interface */\n storageAdapter?: AuthStorage;\n /** OAuth nonce parameter for security */\n nonce?: string;\n /** Initial state for OAuth flow */\n initialState?: string;\n /** Logging configuration */\n logging?: LoggingConfig;\n /**\n * Custom login URL for backend integration (e.g., \"http://example.com/custom-backendurl\")\n * When provided, automatically uses BrowserCookieStorage for session sharing with backend\n */\n loginUrl?: string;\n /**\n * Custom backend endpoints configuration for backend integration\n * Only used when loginUrl is provided. Allows overriding default endpoints.\n */\n backendEndpoints?: BackendEndpoints;\n /** Framework being used (for analytics) - internal use only */\n framework?: FrameworkType;\n /** Whether to automatically preload the iframe for instant sign-in (defaults to true) */\n preloadIframe?: boolean;\n /** Whether to automatically switch to redirect mode when browser doesn't support iframe-based auth (defaults to true) */\n autoRedirect?: boolean;\n}\n\nexport interface LoggingConfig {\n enabled: boolean;\n namespace?: string;\n level?: \"debug\" | \"info\" | \"warn\" | \"error\";\n}\n\n/**\n * Internal configuration with all optional properties resolved to required ones.\n */\nexport type ProcessedCivicAuthConfig = CivicAuthClientConfig & {\n redirectUrl: string;\n logoutRedirectUrl: string;\n oauthServerBaseUrl: string;\n scopes: string[];\n textSignals: {\n success: string;\n error?: string;\n };\n storageAdapter: AuthStorage;\n logging: LoggingConfig;\n displayMode: BaseDisplayMode; // Internal config uses base DisplayMode after processing\n authProcessTimeout: number;\n iframeId: string;\n prompt: string;\n nonce?: string;\n loginUrl?: string;\n backendEndpoints?: BackendEndpoints;\n preloadIframe: boolean;\n autoRedirect: boolean;\n // targetContainerElement remains optional as it's not needed for all display modes\n};\n"]}
|