@civic/auth 0.6.1-beta.3 → 0.7.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/README.md +7 -0
- package/dist/nextjs/config.d.ts.map +1 -1
- package/dist/nextjs/config.js +0 -2
- package/dist/nextjs/config.js.map +1 -1
- package/dist/nextjs/middleware.d.ts.map +1 -1
- package/dist/nextjs/middleware.js +51 -18
- package/dist/nextjs/middleware.js.map +1 -1
- package/dist/nextjs/routeHandler.d.ts.map +1 -1
- package/dist/nextjs/routeHandler.js +8 -0
- package/dist/nextjs/routeHandler.js.map +1 -1
- package/dist/shared/version.d.ts +1 -1
- package/dist/shared/version.js +1 -1
- package/dist/shared/version.js.map +1 -1
- package/dist/vanillajs/auth/CivicAuth.d.ts +3 -2
- package/dist/vanillajs/auth/CivicAuth.d.ts.map +1 -1
- package/dist/vanillajs/auth/CivicAuth.js +39 -41
- package/dist/vanillajs/auth/CivicAuth.js.map +1 -1
- package/dist/vanillajs/auth/config/ConfigProcessor.d.ts.map +1 -1
- package/dist/vanillajs/auth/config/ConfigProcessor.js +16 -7
- package/dist/vanillajs/auth/config/ConfigProcessor.js.map +1 -1
- package/dist/vanillajs/auth/handlers/OAuthCallbackHandler.d.ts +16 -25
- package/dist/vanillajs/auth/handlers/OAuthCallbackHandler.d.ts.map +1 -1
- package/dist/vanillajs/auth/handlers/OAuthCallbackHandler.js +16 -25
- package/dist/vanillajs/auth/handlers/OAuthCallbackHandler.js.map +1 -1
- package/dist/vanillajs/auth/types/AuthTypes.d.ts +11 -4
- 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
|
@@ -4,9 +4,11 @@ import { createMainLogger, configureLogging, setCurrentLogger, } from "../utils/
|
|
|
4
4
|
import { GenericPublicClientPKCEProducer } from "../../services/PKCE.js";
|
|
5
5
|
import { generateState } from "../../lib/oauth.js";
|
|
6
6
|
import { SessionManager } from "./SessionManager.js";
|
|
7
|
+
import { AuthenticationEvents } from "./AuthenticationEvents.js";
|
|
7
8
|
import { PopupError } from "../../services/types.js";
|
|
8
9
|
import { handleOAuthRedirectPage } from "./handlers/OAuthCallbackHandler.js";
|
|
9
10
|
import { generateOauthLogoutUrl, clearTokens, retrieveTokens, } from "../../shared/lib/util.js";
|
|
11
|
+
import { getOauthEndpoints } from "../../lib/oauth.js";
|
|
10
12
|
import { CivicAuthError, CivicAuthErrorCode, CIVIC_AUTH_CONSTANTS, } from "./types/AuthTypes.js";
|
|
11
13
|
import { processConfigWithDefaults } from "./config/ConfigProcessor.js";
|
|
12
14
|
import { MessageHandler } from "./handlers/MessageHandler.js";
|
|
@@ -23,6 +25,7 @@ export class CivicAuth {
|
|
|
23
25
|
endpoints;
|
|
24
26
|
logger;
|
|
25
27
|
sessionManager;
|
|
28
|
+
events;
|
|
26
29
|
initialDisplayMode;
|
|
27
30
|
// Authentication state
|
|
28
31
|
authPromise;
|
|
@@ -59,10 +62,10 @@ export class CivicAuth {
|
|
|
59
62
|
}
|
|
60
63
|
setCurrentLogger(this.logger);
|
|
61
64
|
this.storage = this.config.storageAdapter;
|
|
62
|
-
//
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
65
|
+
// Always initialize events - use provided events or create default instance
|
|
66
|
+
this.events = config.events || new AuthenticationEvents();
|
|
67
|
+
// Always initialize SessionManager
|
|
68
|
+
this.sessionManager = new SessionManager(this.storage, this.events);
|
|
66
69
|
// Initialize handlers
|
|
67
70
|
this.initializeHandlers();
|
|
68
71
|
}
|
|
@@ -80,7 +83,7 @@ export class CivicAuth {
|
|
|
80
83
|
* clientId: "your-client-id",
|
|
81
84
|
* // redirectUrl is optional - defaults to current page (window.location.origin + window.location.pathname)
|
|
82
85
|
* redirectUrl: "https://your-app.com/callback", // optional
|
|
83
|
-
* // oauthServerBaseUrl is optional - defaults to "https://auth.civic.com/oauth
|
|
86
|
+
* // oauthServerBaseUrl is optional - defaults to "https://auth.civic.com/oauth"
|
|
84
87
|
* oauthServerBaseUrl: "https://auth-server.com/", // optional
|
|
85
88
|
* // scopes is optional - defaults to ['openid', 'profile', 'email', 'offline_access']
|
|
86
89
|
* scopes: ["openid", "profile"], // optional
|
|
@@ -107,14 +110,8 @@ export class CivicAuth {
|
|
|
107
110
|
isCallbackUrl: window.location.href.startsWith(this.config.redirectUrl),
|
|
108
111
|
});
|
|
109
112
|
try {
|
|
110
|
-
// Get OAuth endpoints
|
|
111
|
-
this.endpoints =
|
|
112
|
-
auth: `${this.config.oauthServerBaseUrl}auth`,
|
|
113
|
-
token: `${this.config.oauthServerBaseUrl}token`,
|
|
114
|
-
jwks: `${this.config.oauthServerBaseUrl}jwks`,
|
|
115
|
-
userinfo: `${this.config.oauthServerBaseUrl}userinfo`,
|
|
116
|
-
endsession: `${this.config.oauthServerBaseUrl}endsession`,
|
|
117
|
-
};
|
|
113
|
+
// Get OAuth endpoints using shared function (handles trailing slash automatically)
|
|
114
|
+
this.endpoints = await getOauthEndpoints(this.config.oauthServerBaseUrl);
|
|
118
115
|
this.logger.info("🔗 OAuth endpoints configured", {
|
|
119
116
|
endpoints: this.endpoints,
|
|
120
117
|
});
|
|
@@ -153,7 +150,7 @@ export class CivicAuth {
|
|
|
153
150
|
error: errorMessage,
|
|
154
151
|
stack: error instanceof Error ? error.stack : undefined,
|
|
155
152
|
});
|
|
156
|
-
this.
|
|
153
|
+
this.events.emit(AuthEvent.SIGN_IN_ERROR, {
|
|
157
154
|
detail: errorMessage,
|
|
158
155
|
});
|
|
159
156
|
throw new CivicAuthError(errorMessage, CivicAuthErrorCode.INIT_FAILED);
|
|
@@ -220,7 +217,7 @@ export class CivicAuth {
|
|
|
220
217
|
this.logger.error("❌ Endpoints not initialized", {
|
|
221
218
|
error: error.message,
|
|
222
219
|
});
|
|
223
|
-
this.
|
|
220
|
+
this.events.emit(AuthEvent.SIGN_IN_ERROR, {
|
|
224
221
|
detail: error.message,
|
|
225
222
|
});
|
|
226
223
|
throw error;
|
|
@@ -292,7 +289,7 @@ export class CivicAuth {
|
|
|
292
289
|
originalDisplayMode: this.config.displayMode,
|
|
293
290
|
error: error.message,
|
|
294
291
|
});
|
|
295
|
-
this.
|
|
292
|
+
this.events.emit(AuthEvent.SIGN_IN_ERROR, {
|
|
296
293
|
detail: "Popup blocked, falling back to redirect mode",
|
|
297
294
|
});
|
|
298
295
|
try {
|
|
@@ -313,7 +310,7 @@ export class CivicAuth {
|
|
|
313
310
|
redirectUrl: fullAuthUrl,
|
|
314
311
|
});
|
|
315
312
|
const fallbackError = new CivicAuthError("Failed to open popup window and redirect fallback failed. Please check your browser's popup settings.", CivicAuthErrorCode.INIT_FAILED);
|
|
316
|
-
this.
|
|
313
|
+
this.events.emit(AuthEvent.SIGN_IN_ERROR, {
|
|
317
314
|
detail: fallbackError.message,
|
|
318
315
|
});
|
|
319
316
|
this.handleAuthError(fallbackError);
|
|
@@ -323,18 +320,29 @@ export class CivicAuth {
|
|
|
323
320
|
* Setup authentication timeout
|
|
324
321
|
*/
|
|
325
322
|
setupAuthenticationTimeout() {
|
|
323
|
+
// Skip timeout for embedded iframe mode - embedded iframes should stay persistent
|
|
324
|
+
if (this.config.displayMode === "iframe" &&
|
|
325
|
+
this.config.iframeDisplayMode === "embedded") {
|
|
326
|
+
this.logger.debug("⏰ Skipping authentication timeout for embedded iframe mode", {
|
|
327
|
+
displayMode: this.config.displayMode,
|
|
328
|
+
iframeDisplayMode: this.config.iframeDisplayMode,
|
|
329
|
+
});
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
326
332
|
if (this.config.authProcessTimeout && this.config.authProcessTimeout > 0) {
|
|
327
333
|
this.logger.debug("⏰ Setting up authentication timeout", {
|
|
328
334
|
authProcessTimeout: this.config.authProcessTimeout,
|
|
329
335
|
displayMode: this.config.displayMode,
|
|
336
|
+
iframeDisplayMode: this.config.iframeDisplayMode,
|
|
330
337
|
});
|
|
331
338
|
this.authProcessTimeoutHandle = window.setTimeout(() => {
|
|
332
339
|
this.logger.error("⏰ Authentication timed out", {
|
|
333
340
|
displayMode: this.config.displayMode,
|
|
341
|
+
iframeDisplayMode: this.config.iframeDisplayMode,
|
|
334
342
|
currentOrigin: window.location.origin,
|
|
335
343
|
authProcessTimeout: this.config.authProcessTimeout,
|
|
336
344
|
});
|
|
337
|
-
this.
|
|
345
|
+
this.events.emit(AuthEvent.SIGN_IN_ERROR, {
|
|
338
346
|
detail: "Authentication timed out",
|
|
339
347
|
});
|
|
340
348
|
const error = new CivicAuthError("Authentication timed out", CivicAuthErrorCode.AUTH_PROCESS_TIMEOUT);
|
|
@@ -432,7 +440,7 @@ export class CivicAuth {
|
|
|
432
440
|
setupPopupFailureTimeout() {
|
|
433
441
|
this.popupFailureTimeoutHandle = window.setTimeout(() => {
|
|
434
442
|
this.logger.info("⏰ Popup failure timeout reached");
|
|
435
|
-
this.
|
|
443
|
+
this.events.emit(AuthEvent.SIGN_IN_ERROR, {
|
|
436
444
|
detail: "Authentication timeout - popup failure scenario",
|
|
437
445
|
});
|
|
438
446
|
const error = new CivicAuthError("Authentication timeout - popup failure scenario", CivicAuthErrorCode.AUTH_PROCESS_TIMEOUT);
|
|
@@ -487,14 +495,14 @@ export class CivicAuth {
|
|
|
487
495
|
this.logger.error("❌ Failed to parse user info", { error });
|
|
488
496
|
}
|
|
489
497
|
}
|
|
490
|
-
this.
|
|
498
|
+
this.events.emit(AuthEvent.SIGN_IN_COMPLETE, {
|
|
491
499
|
detail: "Callback processed successfully",
|
|
492
500
|
user: userInfo,
|
|
493
501
|
});
|
|
494
502
|
}
|
|
495
503
|
else if (errorSignal) {
|
|
496
504
|
this.logger.error("❌ Error signal found");
|
|
497
|
-
this.
|
|
505
|
+
this.events.emit(AuthEvent.SIGN_IN_ERROR, {
|
|
498
506
|
detail: errorSignal.textContent || "Unknown error during callback",
|
|
499
507
|
});
|
|
500
508
|
}
|
|
@@ -502,7 +510,7 @@ export class CivicAuth {
|
|
|
502
510
|
}
|
|
503
511
|
catch (error) {
|
|
504
512
|
this.logger.error("❌ Callback handling failed", { error });
|
|
505
|
-
this.
|
|
513
|
+
this.events.emit(AuthEvent.SIGN_IN_ERROR, {
|
|
506
514
|
detail: error instanceof Error
|
|
507
515
|
? error.message
|
|
508
516
|
: "Unknown error during callback",
|
|
@@ -539,43 +547,37 @@ export class CivicAuth {
|
|
|
539
547
|
* Get the current session
|
|
540
548
|
*/
|
|
541
549
|
async getCurrentSession() {
|
|
542
|
-
return this.sessionManager
|
|
550
|
+
return this.sessionManager.getCurrentSession() || null;
|
|
543
551
|
}
|
|
544
552
|
/**
|
|
545
553
|
* Check if user is authenticated
|
|
546
554
|
*/
|
|
547
555
|
async isAuthenticated() {
|
|
548
|
-
return this.sessionManager
|
|
556
|
+
return this.sessionManager.isAuthenticated() || false;
|
|
549
557
|
}
|
|
550
558
|
/**
|
|
551
559
|
* Get the current user
|
|
552
560
|
*/
|
|
553
561
|
async getCurrentUser() {
|
|
554
|
-
return this.sessionManager
|
|
562
|
+
return this.sessionManager.getCurrentUser() || null;
|
|
555
563
|
}
|
|
556
564
|
/**
|
|
557
565
|
* Clear the current session
|
|
558
566
|
*/
|
|
559
567
|
async clearSession() {
|
|
560
|
-
if (!this.sessionManager) {
|
|
561
|
-
throw new Error("SessionManager not initialized. Provide events in config.");
|
|
562
|
-
}
|
|
563
568
|
return this.sessionManager.clearSession();
|
|
564
569
|
}
|
|
565
570
|
/**
|
|
566
571
|
* Manually refresh tokens
|
|
567
572
|
*/
|
|
568
573
|
async refreshTokens() {
|
|
569
|
-
if (!this.sessionManager) {
|
|
570
|
-
throw new Error("SessionManager not initialized. Provide events in config.");
|
|
571
|
-
}
|
|
572
574
|
return this.sessionManager.refreshTokens();
|
|
573
575
|
}
|
|
574
576
|
/**
|
|
575
577
|
* Get token refresher state for debugging
|
|
576
578
|
*/
|
|
577
579
|
getTokenRefresherState() {
|
|
578
|
-
return this.sessionManager
|
|
580
|
+
return this.sessionManager.getTokenRefresherState() || null;
|
|
579
581
|
}
|
|
580
582
|
/**
|
|
581
583
|
* Update the iframe display mode
|
|
@@ -597,20 +599,16 @@ export class CivicAuth {
|
|
|
597
599
|
*/
|
|
598
600
|
async destroy() {
|
|
599
601
|
this.cleanup();
|
|
600
|
-
await this.sessionManager
|
|
601
|
-
this.sessionManager = undefined;
|
|
602
|
+
await this.sessionManager.destroy();
|
|
602
603
|
this.logger.info("CivicAuth destroyed");
|
|
603
604
|
}
|
|
604
605
|
/**
|
|
605
606
|
* Handle logout
|
|
606
607
|
*/
|
|
607
608
|
async logout() {
|
|
608
|
-
if (!this.sessionManager) {
|
|
609
|
-
throw new Error("SessionManager not initialized. Provide events in config.");
|
|
610
|
-
}
|
|
611
609
|
try {
|
|
612
610
|
this.logger.info("🔄 Starting logout process");
|
|
613
|
-
this.
|
|
611
|
+
this.events.emit(AuthEvent.SIGN_OUT_STARTED, {
|
|
614
612
|
detail: "Logout process started",
|
|
615
613
|
});
|
|
616
614
|
// Get current tokens before clearing them
|
|
@@ -619,7 +617,7 @@ export class CivicAuth {
|
|
|
619
617
|
this.logger.warn("⚠️ No ID token found, clearing local session only");
|
|
620
618
|
await clearTokens(this.storage);
|
|
621
619
|
await this.sessionManager.clearSession();
|
|
622
|
-
this.
|
|
620
|
+
this.events.emit(AuthEvent.SIGN_OUT_COMPLETE, {
|
|
623
621
|
detail: "Local session cleared",
|
|
624
622
|
});
|
|
625
623
|
return;
|
|
@@ -646,7 +644,7 @@ export class CivicAuth {
|
|
|
646
644
|
await clearTokens(this.storage);
|
|
647
645
|
await this.sessionManager.clearSession();
|
|
648
646
|
// Emit logout complete event before redirect
|
|
649
|
-
this.
|
|
647
|
+
this.events.emit(AuthEvent.SIGN_OUT_COMPLETE, {
|
|
650
648
|
detail: "Logout successful",
|
|
651
649
|
});
|
|
652
650
|
// Redirect to logout URL
|
|
@@ -655,7 +653,7 @@ export class CivicAuth {
|
|
|
655
653
|
}
|
|
656
654
|
catch (error) {
|
|
657
655
|
this.logger.error("❌ Logout failed", { error });
|
|
658
|
-
this.
|
|
656
|
+
this.events.emit(AuthEvent.SIGN_OUT_ERROR, {
|
|
659
657
|
detail: error instanceof Error ? error.message : String(error),
|
|
660
658
|
});
|
|
661
659
|
throw new CivicAuthError("Logout failed", CivicAuthErrorCode.LOGOUT_FAILED);
|
|
@@ -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 } 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 { PopupError } from \"../../services/types.js\";\nimport { handleOAuthRedirectPage } from \"./handlers/OAuthCallbackHandler.js\";\nimport {\n generateOauthLogoutUrl,\n clearTokens,\n retrieveTokens,\n} from \"../../shared/lib/util.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\";\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 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\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 // 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 // Initialize SessionManager if events are provided\n if (config.events) {\n this.sessionManager = new SessionManager(this.storage, config.events);\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 * 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 * // 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 */\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\n this.endpoints = {\n auth: `${this.config.oauthServerBaseUrl}auth`,\n token: `${this.config.oauthServerBaseUrl}token`,\n jwks: `${this.config.oauthServerBaseUrl}jwks`,\n userinfo: `${this.config.oauthServerBaseUrl}userinfo`,\n endsession: `${this.config.oauthServerBaseUrl}endsession`,\n };\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 };\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 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 } 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.config.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 });\n\n this.popupHandler = new PopupHandler(handlerConfig);\n\n this.iframeAuthHandler = new IframeAuthHandler({\n ...handlerConfig,\n messageHandler: this.messageHandler.handleMessage,\n });\n }\n\n /**\n * Builds the authentication URL with PKCE challenge\n */\n private async buildAuthUrl(): Promise<string> {\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 });\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 * 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 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.config.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 /**\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 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.config.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.config.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 if (this.config.authProcessTimeout && this.config.authProcessTimeout > 0) {\n this.logger.debug(\"⏰ Setting up authentication timeout\", {\n authProcessTimeout: this.config.authProcessTimeout,\n displayMode: this.config.displayMode,\n });\n\n this.authProcessTimeoutHandle = window.setTimeout(() => {\n this.logger.error(\"⏰ Authentication timed out\", {\n displayMode: this.config.displayMode,\n currentOrigin: window.location.origin,\n authProcessTimeout: this.config.authProcessTimeout,\n });\n\n this.config.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.config.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.config.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.config.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.config.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 * 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 if (!this.sessionManager) {\n throw new Error(\n \"SessionManager not initialized. Provide events in config.\",\n );\n }\n return this.sessionManager.clearSession();\n }\n\n /**\n * Manually refresh tokens\n */\n public async refreshTokens(): Promise<void> {\n if (!this.sessionManager) {\n throw new Error(\n \"SessionManager not initialized. Provide events in config.\",\n );\n }\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 * 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.sessionManager = undefined;\n this.logger.info(\"CivicAuth destroyed\");\n }\n\n /**\n * Handle logout\n */\n public async logout(): Promise<void> {\n if (!this.sessionManager) {\n throw new Error(\n \"SessionManager not initialized. Provide events in config.\",\n );\n }\n\n try {\n this.logger.info(\"🔄 Starting logout process\");\n this.config.events?.emit(AuthEvent.SIGN_OUT_STARTED, {\n detail: \"Logout process started\",\n });\n\n // Get current tokens before clearing them\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.config.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 });\n\n // Generate logout URL\n const logoutUrl = await generateOauthLogoutUrl({\n clientId: this.config.clientId,\n redirectUrl: this.config.redirectUrl,\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\n await clearTokens(this.storage);\n await this.sessionManager.clearSession();\n\n // Emit logout complete event before redirect\n this.config.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.config.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// 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 } 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 { handleOAuthRedirectPage } from \"./handlers/OAuthCallbackHandler.js\";\nimport {\n generateOauthLogoutUrl,\n clearTokens,\n retrieveTokens,\n} from \"../../shared/lib/util.js\";\nimport { getOauthEndpoints } from \"../../lib/oauth.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\";\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\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 // 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(this.storage, this.events);\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 * 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 * // 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 */\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 };\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 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 } 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 });\n\n this.popupHandler = new PopupHandler(handlerConfig);\n\n this.iframeAuthHandler = new IframeAuthHandler({\n ...handlerConfig,\n messageHandler: this.messageHandler.handleMessage,\n });\n }\n\n /**\n * Builds the authentication URL with PKCE challenge\n */\n private async buildAuthUrl(): Promise<string> {\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 });\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 * 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 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 /**\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 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 if (this.config.authProcessTimeout && this.config.authProcessTimeout > 0) {\n this.logger.debug(\"⏰ Setting up authentication timeout\", {\n authProcessTimeout: this.config.authProcessTimeout,\n displayMode: this.config.displayMode,\n iframeDisplayMode: this.config.iframeDisplayMode,\n });\n\n this.authProcessTimeoutHandle = window.setTimeout(() => {\n this.logger.error(\"⏰ Authentication timed out\", {\n displayMode: this.config.displayMode,\n iframeDisplayMode: this.config.iframeDisplayMode,\n currentOrigin: window.location.origin,\n authProcessTimeout: this.config.authProcessTimeout,\n });\n\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 * 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 * 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 // Get current tokens before clearing them\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 });\n\n // Generate logout URL\n const logoutUrl = await generateOauthLogoutUrl({\n clientId: this.config.clientId,\n redirectUrl: this.config.redirectUrl,\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\n await clearTokens(this.storage);\n await this.sessionManager.clearSession();\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// Export types for external use\nexport type { CivicAuthClientConfig } from \"./types/AuthTypes.js\";\nexport { CivicAuthErrorCode } from \"./types/AuthTypes.js\";\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConfigProcessor.d.ts","sourceRoot":"","sources":["../../../../src/vanillajs/auth/config/ConfigProcessor.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ConfigProcessor.d.ts","sourceRoot":"","sources":["../../../../src/vanillajs/auth/config/ConfigProcessor.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,qBAAqB,EACrB,wBAAwB,EAEzB,MAAM,uBAAuB,CAAC;AAO/B;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,qBAAqB,GAC5B,wBAAwB,CAyC1B"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LocalStorageAdapter } from "../../../browser/storage.js";
|
|
2
|
-
import { DEFAULT_SCOPES } from "../../../constants.js";
|
|
2
|
+
import { DEFAULT_SCOPES, DEFAULT_AUTH_SERVER } from "../../../constants.js";
|
|
3
3
|
import { CivicAuthError, CivicAuthErrorCode, CIVIC_AUTH_CONSTANTS, } from "../types/AuthTypes.js";
|
|
4
4
|
/**
|
|
5
5
|
* Process the configuration with defaults and validation
|
|
@@ -8,22 +8,28 @@ export function processConfigWithDefaults(config) {
|
|
|
8
8
|
// Validate required configuration
|
|
9
9
|
validateRequiredConfig(config);
|
|
10
10
|
const loggingConfig = {
|
|
11
|
-
enabled:
|
|
11
|
+
enabled: false,
|
|
12
12
|
namespace: "*",
|
|
13
13
|
level: "debug",
|
|
14
14
|
...config.logging,
|
|
15
15
|
};
|
|
16
|
+
// Handle displayMode proxy: map "embedded" to "iframe" + iframeDisplayMode: "embedded"
|
|
17
|
+
// the original displaymode doesn't suppors embedded, so we need to proxy it to iframe + iframeDisplayMode: "embedded"
|
|
18
|
+
const originalDisplayMode = config.displayMode || "iframe";
|
|
19
|
+
const processedDisplayMode = originalDisplayMode === "embedded" ? "iframe" : originalDisplayMode;
|
|
20
|
+
const processedIframeDisplayMode = originalDisplayMode === "embedded" ? "embedded" : config.iframeDisplayMode;
|
|
16
21
|
return {
|
|
17
22
|
...config,
|
|
18
23
|
redirectUrl: config.redirectUrl ||
|
|
19
24
|
`${window.location.origin}${window.location.pathname}`,
|
|
20
|
-
oauthServerBaseUrl: config.oauthServerBaseUrl ||
|
|
25
|
+
oauthServerBaseUrl: config.oauthServerBaseUrl || DEFAULT_AUTH_SERVER,
|
|
21
26
|
scopes: config.scopes || DEFAULT_SCOPES,
|
|
22
27
|
textSignals: config.textSignals || {
|
|
23
28
|
success: "Authentication successful!",
|
|
24
29
|
error: "Authentication failed. Please try again.",
|
|
25
30
|
},
|
|
26
|
-
displayMode:
|
|
31
|
+
displayMode: processedDisplayMode,
|
|
32
|
+
iframeDisplayMode: processedIframeDisplayMode,
|
|
27
33
|
authProcessTimeout: config.authProcessTimeout ||
|
|
28
34
|
CIVIC_AUTH_CONSTANTS.DEFAULT_AUTH_PROCESS_TIMEOUT,
|
|
29
35
|
iframeId: config.iframeId || CIVIC_AUTH_CONSTANTS.DEFAULT_IFRAME_ID,
|
|
@@ -45,14 +51,17 @@ function validateRequiredConfig(config) {
|
|
|
45
51
|
}
|
|
46
52
|
}
|
|
47
53
|
// Conditional validation for targetContainerElement
|
|
48
|
-
//
|
|
54
|
+
// Handle both the new "embedded" displayMode and the legacy iframe + iframeDisplayMode approach
|
|
49
55
|
const displayMode = config.displayMode || "iframe";
|
|
50
56
|
const iframeDisplayMode = config.iframeDisplayMode;
|
|
51
57
|
// Check if we need a container element
|
|
52
|
-
const needsContainer = displayMode === "
|
|
58
|
+
const needsContainer = displayMode === "embedded" || // New simplified API
|
|
59
|
+
(displayMode === "iframe" && iframeDisplayMode === "embedded"); // Legacy API
|
|
53
60
|
if (needsContainer && !config.targetContainerElement) {
|
|
54
61
|
throw new CivicAuthError("CivicAuth: targetContainerElement is required for embedded iframe mode. " +
|
|
55
|
-
"
|
|
62
|
+
"You can use displayMode: 'embedded' for a simplified API, " +
|
|
63
|
+
"or use displayMode: 'iframe' with iframeDisplayMode: 'embedded'. " +
|
|
64
|
+
"For modal iframe mode, use displayMode: 'iframe' (default). " +
|
|
56
65
|
"For non-iframe modes, use displayMode 'redirect' or 'new_tab'.", CivicAuthErrorCode.CONFIG_REQUIRED);
|
|
57
66
|
}
|
|
58
67
|
}
|
|
@@ -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,cAAc,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"ConfigProcessor.js","sourceRoot":"","sources":["../../../../src/vanillajs/auth/config/ConfigProcessor.ts"],"names":[],"mappings":"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","sourcesContent":["import { LocalStorageAdapter } from \"../../../browser/storage.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 return {\n ...config,\n redirectUrl:\n config.redirectUrl ||\n `${window.location.origin}${window.location.pathname}`,\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: config.storageAdapter || new LocalStorageAdapter(),\n };\n}\n\n/**\n * Validates required configuration properties\n */\nfunction validateRequiredConfig(config: CivicAuthClientConfig): void {\n // Always required configurations\n const requiredConfigs = [{ key: \"clientId\", value: config.clientId }];\n\n // Validate always-required fields\n for (const { key, value } of requiredConfigs) {\n if (!value) {\n throw new CivicAuthError(\n `CivicAuth: ${key} is required.`,\n CivicAuthErrorCode.CONFIG_REQUIRED,\n );\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"]}
|