@civic/auth 0.6.0 → 0.6.1-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.
Files changed (74) hide show
  1. package/dist/shared/components/CivicAuthIframeContainer.js +1 -1
  2. package/dist/shared/components/CivicAuthIframeContainer.js.map +1 -1
  3. package/dist/shared/lib/BrowserAuthenticationRefresher.d.ts +7 -1
  4. package/dist/shared/lib/BrowserAuthenticationRefresher.d.ts.map +1 -1
  5. package/dist/shared/lib/BrowserAuthenticationRefresher.js +15 -2
  6. package/dist/shared/lib/BrowserAuthenticationRefresher.js.map +1 -1
  7. package/dist/shared/lib/util.d.ts +1 -1
  8. package/dist/shared/lib/util.d.ts.map +1 -1
  9. package/dist/shared/lib/util.js +6 -1
  10. package/dist/shared/lib/util.js.map +1 -1
  11. package/dist/shared/version.d.ts +1 -1
  12. package/dist/shared/version.d.ts.map +1 -1
  13. package/dist/shared/version.js +1 -1
  14. package/dist/shared/version.js.map +1 -1
  15. package/dist/vanillajs/auth/CivicAuth.d.ts +63 -5
  16. package/dist/vanillajs/auth/CivicAuth.d.ts.map +1 -1
  17. package/dist/vanillajs/auth/CivicAuth.js +202 -26
  18. package/dist/vanillajs/auth/CivicAuth.js.map +1 -1
  19. package/dist/vanillajs/auth/OAuthCallbackHandler.d.ts +90 -0
  20. package/dist/vanillajs/auth/OAuthCallbackHandler.d.ts.map +1 -0
  21. package/dist/vanillajs/auth/OAuthCallbackHandler.js +143 -0
  22. package/dist/vanillajs/auth/OAuthCallbackHandler.js.map +1 -0
  23. package/dist/vanillajs/auth/SessionManager.d.ts +40 -9
  24. package/dist/vanillajs/auth/SessionManager.d.ts.map +1 -1
  25. package/dist/vanillajs/auth/SessionManager.js +96 -61
  26. package/dist/vanillajs/auth/SessionManager.js.map +1 -1
  27. package/dist/vanillajs/auth/TokenRefresher.d.ts +54 -0
  28. package/dist/vanillajs/auth/TokenRefresher.d.ts.map +1 -0
  29. package/dist/vanillajs/auth/TokenRefresher.js +166 -0
  30. package/dist/vanillajs/auth/TokenRefresher.js.map +1 -0
  31. package/dist/vanillajs/iframe/IframeManager.d.ts +82 -0
  32. package/dist/vanillajs/iframe/IframeManager.d.ts.map +1 -0
  33. package/dist/vanillajs/iframe/IframeManager.js +487 -0
  34. package/dist/vanillajs/iframe/IframeManager.js.map +1 -0
  35. package/dist/vanillajs/iframe/IframeResizer.d.ts +15 -0
  36. package/dist/vanillajs/iframe/IframeResizer.d.ts.map +1 -0
  37. package/dist/vanillajs/iframe/IframeResizer.js +127 -0
  38. package/dist/vanillajs/iframe/IframeResizer.js.map +1 -0
  39. package/dist/vanillajs/index.d.ts +8 -7
  40. package/dist/vanillajs/index.d.ts.map +1 -1
  41. package/dist/vanillajs/index.js +10 -7
  42. package/dist/vanillajs/index.js.map +1 -1
  43. package/dist/vanillajs/types/index.d.ts +2 -2
  44. package/dist/vanillajs/types/index.d.ts.map +1 -1
  45. package/dist/vanillajs/types/index.js.map +1 -1
  46. package/dist/vanillajs/ui/LoadingComponents.d.ts +51 -0
  47. package/dist/vanillajs/ui/LoadingComponents.d.ts.map +1 -0
  48. package/dist/vanillajs/ui/LoadingComponents.js +363 -0
  49. package/dist/vanillajs/ui/LoadingComponents.js.map +1 -0
  50. package/package.json +1 -1
  51. package/dist/vanillajs/iframe/domUtils.d.ts +0 -4
  52. package/dist/vanillajs/iframe/domUtils.d.ts.map +0 -1
  53. package/dist/vanillajs/iframe/domUtils.js +0 -25
  54. package/dist/vanillajs/iframe/domUtils.js.map +0 -1
  55. package/dist/vanillajs/storage/BrowserCookieStorageAdapter.d.ts +0 -19
  56. package/dist/vanillajs/storage/BrowserCookieStorageAdapter.d.ts.map +0 -1
  57. package/dist/vanillajs/storage/BrowserCookieStorageAdapter.js +0 -101
  58. package/dist/vanillajs/storage/BrowserCookieStorageAdapter.js.map +0 -1
  59. package/dist/vanillajs/storage/BrowserLocalStorageAdapter.d.ts +0 -9
  60. package/dist/vanillajs/storage/BrowserLocalStorageAdapter.d.ts.map +0 -1
  61. package/dist/vanillajs/storage/BrowserLocalStorageAdapter.js +0 -36
  62. package/dist/vanillajs/storage/BrowserLocalStorageAdapter.js.map +0 -1
  63. package/dist/vanillajs/storage/InMemoryStorageAdapter.d.ts +0 -9
  64. package/dist/vanillajs/storage/InMemoryStorageAdapter.d.ts.map +0 -1
  65. package/dist/vanillajs/storage/InMemoryStorageAdapter.js +0 -16
  66. package/dist/vanillajs/storage/InMemoryStorageAdapter.js.map +0 -1
  67. package/dist/vanillajs/storage/StorageAdapter.d.ts +0 -15
  68. package/dist/vanillajs/storage/StorageAdapter.d.ts.map +0 -1
  69. package/dist/vanillajs/storage/StorageAdapter.js +0 -16
  70. package/dist/vanillajs/storage/StorageAdapter.js.map +0 -1
  71. package/dist/vanillajs/utils/page-handlers.d.ts +0 -29
  72. package/dist/vanillajs/utils/page-handlers.d.ts.map +0 -1
  73. package/dist/vanillajs/utils/page-handlers.js +0 -165
  74. package/dist/vanillajs/utils/page-handlers.js.map +0 -1
@@ -1,13 +1,13 @@
1
- import { createIframe, removeIframe } from "../iframe/domUtils.js";
2
1
  import { AuthEvent } from "../types/index.js";
3
- import { StorageAdapterToAuthStorage, } from "../storage/StorageAdapter.js";
4
- import { BrowserCookieStorageAdapter } from "../storage/BrowserCookieStorageAdapter.js";
5
- import { handleOAuthRedirectPage } from "../utils/page-handlers.js";
2
+ import { LocalStorageAdapter } from "../../browser/storage.js";
3
+ import { handleOAuthRedirectPage } from "./OAuthCallbackHandler.js";
6
4
  import { buildAuthUrl } from "../utils/auth-utils.js";
7
5
  import { createLogger, configureLogging, setCurrentLogger, } from "../utils/logger.js";
8
6
  import { SignalObserver } from "../iframe/SignalObserver.js";
9
7
  import { GenericPublicClientPKCEProducer } from "../../services/PKCE.js";
10
8
  import { generateState } from "../../lib/oauth.js";
9
+ import { SessionManager } from "./SessionManager.js";
10
+ import { IframeManager } from "../iframe/IframeManager.js";
11
11
  /**
12
12
  * Error codes for CivicAuth errors
13
13
  */
@@ -38,10 +38,36 @@ class CivicAuthError extends Error {
38
38
  this.name = "CivicAuthError";
39
39
  }
40
40
  }
41
+ /**
42
+ * Process the configuration with defaults
43
+ */
44
+ function processConfigWithDefaults(config) {
45
+ const loggingConfig = {
46
+ enabled: true,
47
+ namespace: "iframe",
48
+ level: "debug",
49
+ ...config.logging,
50
+ };
51
+ return {
52
+ ...config,
53
+ displayMode: config.displayMode || "iframe",
54
+ authProcessTimeout: config.authProcessTimeout || CONSTANTS.DEFAULT_AUTH_PROCESS_TIMEOUT,
55
+ iframeId: config.iframeId || CONSTANTS.DEFAULT_IFRAME_ID,
56
+ logging: loggingConfig,
57
+ storageAdapter: config.storageAdapter || new LocalStorageAdapter(),
58
+ };
59
+ }
41
60
  /**
42
61
  * CivicAuth client for handling OAuth authentication
43
62
  */
44
63
  export class CivicAuth {
64
+ /**
65
+ * Internal configuration with all optional properties resolved to required ones.
66
+ *
67
+ * We extend CivicAuthClientConfig rather than making these properties required
68
+ * in the public interface to maintain better DX (optional properties) while
69
+ * ensuring type safety internally after defaults are applied.
70
+ */
45
71
  config;
46
72
  iframeElement;
47
73
  observer;
@@ -53,6 +79,8 @@ export class CivicAuth {
53
79
  storage;
54
80
  endpoints;
55
81
  logger;
82
+ sessionManager;
83
+ iframeManager;
56
84
  /**
57
85
  * Private constructor for CivicAuth.
58
86
  * Use {@link CivicAuth.create} to create a new instance.
@@ -61,21 +89,10 @@ export class CivicAuth {
61
89
  * @private
62
90
  */
63
91
  constructor(config) {
64
- const loggingConfig = {
65
- enabled: true,
66
- namespace: "iframe",
67
- level: "debug",
68
- ...config.logging,
69
- };
70
- this.config = {
71
- displayMode: "iframe",
72
- authProcessTimeout: config.authProcessTimeout || CONSTANTS.DEFAULT_AUTH_PROCESS_TIMEOUT,
73
- iframeId: config.iframeId || CONSTANTS.DEFAULT_IFRAME_ID,
74
- logging: loggingConfig,
75
- ...config,
76
- };
92
+ // Process config with defaults
93
+ this.config = processConfigWithDefaults(config);
77
94
  // Configure logging based on config
78
- configureLogging(loggingConfig);
95
+ configureLogging(this.config.logging);
79
96
  // Initialize logger based on config
80
97
  if (this.config.logging?.enabled) {
81
98
  const namespace = this.config.logging.namespace || "iframe";
@@ -92,7 +109,12 @@ export class CivicAuth {
92
109
  }
93
110
  // Set this logger as the current logger
94
111
  setCurrentLogger(this.logger);
95
- this.storage = config.storageAdapter || new BrowserCookieStorageAdapter();
112
+ // Use the storage adapter from processed config (guaranteed to be present)
113
+ this.storage = this.config.storageAdapter;
114
+ // Initialize SessionManager if events are provided
115
+ if (config.events) {
116
+ this.sessionManager = new SessionManager(this.storage, config.events);
117
+ }
96
118
  // Validate required configuration
97
119
  const requiredConfigs = [
98
120
  { key: "clientId", value: config.clientId },
@@ -147,6 +169,17 @@ export class CivicAuth {
147
169
  userinfo: `${this.config.oauthServerBaseUrl}userinfo`,
148
170
  endsession: `${this.config.oauthServerBaseUrl}endsession`,
149
171
  };
172
+ // Initialize SessionManager with auth config for token refresh
173
+ if (this.sessionManager) {
174
+ const authConfig = {
175
+ clientId: this.config.clientId,
176
+ redirectUrl: this.config.redirectUrl,
177
+ oauthServer: this.config.oauthServerBaseUrl,
178
+ scopes: this.config.scopes,
179
+ endpoints: this.endpoints,
180
+ };
181
+ await this.sessionManager.initializeWithAuthConfig(authConfig);
182
+ }
150
183
  // Check if we're on the callback page
151
184
  if (window.location.href.startsWith(this.config.redirectUrl)) {
152
185
  await this.handleCallback();
@@ -177,6 +210,59 @@ export class CivicAuth {
177
210
  }
178
211
  return this.config.targetContainerElement;
179
212
  }
213
+ /**
214
+ * Determines the appropriate iframe display mode based on container characteristics
215
+ * @param container The HTML element that will contain the iframe
216
+ * @returns "modal" for full-screen overlay or "embedded" for in-container display
217
+ */
218
+ determineIframeDisplayMode(container) {
219
+ // Use explicit config if provided
220
+ if (this.config.iframeDisplayMode) {
221
+ this.logger.debug(`Using configured iframe display mode: ${this.config.iframeDisplayMode}`);
222
+ return this.config.iframeDisplayMode;
223
+ }
224
+ // Analyze container characteristics to determine best display mode
225
+ const containerRect = container.getBoundingClientRect();
226
+ const containerStyles = window.getComputedStyle(container);
227
+ // Get container dimensions
228
+ const containerWidth = containerRect.width;
229
+ const containerHeight = containerRect.height;
230
+ // Check if container is positioned in a way that suggests it's meant for modal display
231
+ const isFullScreenContainer = containerStyles.position === "fixed" &&
232
+ (containerWidth >= window.innerWidth * 0.9 ||
233
+ containerHeight >= window.innerHeight * 0.9);
234
+ // Modal mode thresholds - if container is too small, use modal for better UX
235
+ const MIN_EMBEDDED_WIDTH = 320; // Same as modal content wrapper width
236
+ const MIN_EMBEDDED_HEIGHT = 400; // Reasonable minimum for embedded auth flow
237
+ // Determine mode based on container characteristics
238
+ if (isFullScreenContainer) {
239
+ this.logger.debug("Container appears to be full-screen positioned, using modal mode", { containerWidth, containerHeight, position: containerStyles.position });
240
+ return "modal";
241
+ }
242
+ if (containerWidth < MIN_EMBEDDED_WIDTH ||
243
+ containerHeight < MIN_EMBEDDED_HEIGHT) {
244
+ this.logger.debug(`Container too small for embedded mode (${containerWidth}x${containerHeight}), using modal mode`, {
245
+ containerWidth,
246
+ containerHeight,
247
+ MIN_EMBEDDED_WIDTH,
248
+ MIN_EMBEDDED_HEIGHT,
249
+ });
250
+ return "modal";
251
+ }
252
+ // Check if container has sufficient space and is properly positioned for embedding
253
+ const hasAdequateSpace = containerWidth >= MIN_EMBEDDED_WIDTH &&
254
+ containerHeight >= MIN_EMBEDDED_HEIGHT;
255
+ const isEmbeddablePosition = containerStyles.position === "relative" ||
256
+ containerStyles.position === "static" ||
257
+ containerStyles.position === "";
258
+ if (hasAdequateSpace && isEmbeddablePosition) {
259
+ this.logger.debug("Container has adequate space and positioning for embedded mode", { containerWidth, containerHeight, position: containerStyles.position });
260
+ return "embedded";
261
+ }
262
+ // Default to modal mode if container characteristics are unclear
263
+ this.logger.debug("Container characteristics unclear, defaulting to modal mode for better UX", { containerWidth, containerHeight, position: containerStyles.position });
264
+ return "modal";
265
+ }
180
266
  /**
181
267
  * Builds the authentication URL with PKCE challenge
182
268
  * @returns The complete authentication URL
@@ -186,8 +272,8 @@ export class CivicAuth {
186
272
  if (!this.endpoints) {
187
273
  throw new CivicAuthError("OAuth endpoints not initialized. Please wait for initialization to complete.", CivicAuthErrorCode.ENDPOINTS_NOT_INITIALIZED);
188
274
  }
189
- const authStorage = new StorageAdapterToAuthStorage(this.storage);
190
- const pkceProducer = new GenericPublicClientPKCEProducer(authStorage);
275
+ // Use storage directly since it's now AuthStorage
276
+ const pkceProducer = new GenericPublicClientPKCEProducer(this.storage);
191
277
  const codeChallenge = await pkceProducer.getCodeChallenge();
192
278
  const state = this.config.initialState ||
193
279
  generateState({
@@ -299,15 +385,34 @@ export class CivicAuth {
299
385
  reject(error);
300
386
  return;
301
387
  }
302
- this.logger.debug("Creating iframe", {
388
+ this.logger.debug("Creating iframe with modal backdrop", {
303
389
  url: fullAuthUrl,
304
390
  containerId: container?.id,
305
391
  iframeId: this.config.iframeId,
306
392
  origin: window.location.origin,
307
393
  });
308
- this.iframeElement = createIframe(fullAuthUrl, container, this.config.iframeId);
394
+ // Determine the actual display mode for IframeManager
395
+ // For iframe displayMode, we need to decide between modal and embedded based on container
396
+ const iframeDisplayMode = this.determineIframeDisplayMode(container);
397
+ this.logger.debug(`🎯 CivicAuth: Creating IframeManager with display mode: ${iframeDisplayMode}`);
398
+ // Create IframeManager with appropriate display mode
399
+ this.iframeManager = new IframeManager({
400
+ container: container,
401
+ displayMode: iframeDisplayMode,
402
+ iframeId: this.config.iframeId,
403
+ onClose: () => {
404
+ this.logger.debug("Authentication close requested by user (backdrop click, close button, or Escape key)");
405
+ this.config.events?.emit(AuthEvent.SIGN_IN_ERROR, {
406
+ detail: "Authentication cancelled by user",
407
+ });
408
+ reject(new CivicAuthError("Authentication cancelled by user", CivicAuthErrorCode.AUTH_PROCESS_TIMEOUT));
409
+ this.cleanup();
410
+ },
411
+ });
412
+ // Create the iframe using IframeManager
413
+ this.iframeElement = this.iframeManager.createIframe(fullAuthUrl);
309
414
  this.config.events?.emit(AuthEvent.SIGN_IN_STARTED, {
310
- detail: "Iframe created",
415
+ detail: "Iframe created with modal backdrop",
311
416
  });
312
417
  this.iframeElement.onload = () => {
313
418
  this.logger.info("Iframe loaded", {
@@ -449,9 +554,13 @@ export class CivicAuth {
449
554
  window.removeEventListener("message", this.messageEventHandler);
450
555
  this.logger.debug("Removed 'message' event listener from window.");
451
556
  }
557
+ if (this.iframeManager) {
558
+ this.logger.debug("Cleaning up iframe manager");
559
+ this.iframeManager.cleanup();
560
+ this.iframeManager = undefined;
561
+ }
562
+ // Reset iframe element reference (actual removal handled by IframeManager)
452
563
  if (this.iframeElement) {
453
- this.logger.debug("Removing iframe element");
454
- removeIframe(this.iframeElement);
455
564
  this.iframeElement = undefined;
456
565
  }
457
566
  if (this.authProcessTimeoutHandle) {
@@ -474,6 +583,7 @@ export class CivicAuth {
474
583
  success: this.config.textSignals.success,
475
584
  error: this.config.textSignals.error || "Authentication failed",
476
585
  },
586
+ storageAdapter: this.storage,
477
587
  });
478
588
  if (callbackHandled) {
479
589
  const successSignal = document.getElementById(CONSTANTS.SUCCESS_SIGNAL_ID);
@@ -509,5 +619,71 @@ export class CivicAuth {
509
619
  });
510
620
  }
511
621
  }
622
+ /**
623
+ * Get the current session
624
+ */
625
+ async getCurrentSession() {
626
+ return this.sessionManager?.getCurrentSession() || null;
627
+ }
628
+ /**
629
+ * Check if user is authenticated
630
+ */
631
+ async isAuthenticated() {
632
+ return this.sessionManager?.isAuthenticated() || false;
633
+ }
634
+ /**
635
+ * Get the current user
636
+ */
637
+ async getCurrentUser() {
638
+ return this.sessionManager?.getCurrentUser() || null;
639
+ }
640
+ /**
641
+ * Clear the current session
642
+ */
643
+ async clearSession() {
644
+ if (!this.sessionManager) {
645
+ throw new Error("SessionManager not initialized. Provide events in config.");
646
+ }
647
+ return this.sessionManager.clearSession();
648
+ }
649
+ /**
650
+ * Manually refresh tokens
651
+ */
652
+ async refreshTokens() {
653
+ if (!this.sessionManager) {
654
+ throw new Error("SessionManager not initialized. Provide events in config.");
655
+ }
656
+ return this.sessionManager.refreshTokens();
657
+ }
658
+ /**
659
+ * Get token refresher state for debugging
660
+ */
661
+ getTokenRefresherState() {
662
+ return this.sessionManager?.getTokenRefresherState() || null;
663
+ }
664
+ /**
665
+ * Update the iframe display mode
666
+ * @param mode - The display mode to use for the iframe
667
+ */
668
+ setIframeDisplayMode(mode) {
669
+ this.config.iframeDisplayMode = mode;
670
+ this.logger.debug(`Iframe display mode updated to: ${mode}`);
671
+ }
672
+ /**
673
+ * Get the current iframe display mode
674
+ * @returns The current iframe display mode
675
+ */
676
+ getIframeDisplayMode() {
677
+ return this.config.iframeDisplayMode;
678
+ }
679
+ /**
680
+ * Destroy the auth client and clean up all resources
681
+ */
682
+ async destroy() {
683
+ this.cleanup();
684
+ await this.sessionManager?.destroy();
685
+ this.sessionManager = undefined;
686
+ this.logger.info("CivicAuth destroyed");
687
+ }
512
688
  }
513
689
  //# sourceMappingURL=CivicAuth.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CivicAuth.js","sourceRoot":"","sources":["../../../src/vanillajs/auth/CivicAuth.ts"],"names":[],"mappings":"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","sourcesContent":["import { createIframe, removeIframe } from \"../iframe/domUtils.js\";\nimport { AuthEvent } from \"../types/index.js\";\nimport type { AuthenticationEvents } from \"./AuthenticationEvents.js\";\nimport {\n StorageAdapterToAuthStorage,\n type StorageAdapter,\n} from \"../storage/StorageAdapter.js\";\nimport { BrowserCookieStorageAdapter } from \"../storage/BrowserCookieStorageAdapter.js\";\nimport { handleOAuthRedirectPage } from \"../utils/page-handlers.js\";\nimport type { Endpoints, DisplayMode } from \"../../types.js\";\nimport { buildAuthUrl } from \"../utils/auth-utils.js\";\nimport type { AuthResult } from \"../types/index.js\";\nimport {\n createLogger,\n configureLogging,\n setCurrentLogger,\n} from \"../utils/logger.js\";\nimport { SignalObserver } from \"../iframe/SignalObserver.js\";\nimport { GenericPublicClientPKCEProducer } from \"../../services/PKCE.js\";\nimport { generateState } from \"../../lib/oauth.js\";\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 INVALID_MESSAGE = \"INVALID_MESSAGE\",\n}\n\n/**\n * Constants for the auth client\n */\nconst CONSTANTS = {\n DEFAULT_IFRAME_ID: \"civic-auth-iframe\",\n DEFAULT_AUTH_PROCESS_TIMEOUT: 60000, // 60 seconds\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 */\ntype AuthMessageType = \"auth_success\" | \"auth_error\";\n\ninterface AuthMessage {\n type: AuthMessageType;\n detail?: string;\n data?: unknown;\n error?: unknown;\n}\n\nclass 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 /** 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 */\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 */\n displayMode?: DisplayMode;\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 */\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 */\n storageAdapter?: StorageAdapter;\n /** OAuth prompt parameter */\n prompt?: string;\n /** Initial state for OAuth flow */\n initialState?: string;\n /** Logging configuration */\n logging?: LoggingConfig;\n}\n\nexport interface LoggingConfig {\n enabled: boolean;\n namespace?: string;\n level?: \"debug\" | \"info\" | \"warn\" | \"error\";\n}\n\n/**\n * CivicAuth client for handling OAuth authentication\n */\nexport class CivicAuth {\n private config: CivicAuthClientConfig;\n private iframeElement?: HTMLIFrameElement;\n private observer?: MutationObserver;\n private authPromise?: Promise<AuthResult>;\n private authPromiseResolve?: (value: AuthResult) => void;\n private authPromiseReject?: (reason?: Error) => void;\n private authProcessTimeoutHandle?: number;\n private messageEventHandler?: (event: MessageEvent) => void;\n private storage: StorageAdapter;\n private endpoints?: Endpoints;\n private logger: ReturnType<typeof createLogger>;\n\n /**\n * Private constructor for CivicAuth.\n * Use {@link CivicAuth.create} to create a new instance.\n * @param config - Configuration options for the auth client\n * @throws {CivicAuthError} If required configuration is missing\n * @private\n */\n private constructor(config: CivicAuthClientConfig) {\n const loggingConfig = {\n enabled: true,\n namespace: \"iframe\",\n level: \"debug\" as const,\n ...config.logging,\n };\n\n this.config = {\n displayMode: \"iframe\",\n authProcessTimeout:\n config.authProcessTimeout || CONSTANTS.DEFAULT_AUTH_PROCESS_TIMEOUT,\n iframeId: config.iframeId || CONSTANTS.DEFAULT_IFRAME_ID,\n logging: loggingConfig,\n ...config,\n };\n\n // Configure logging based on config\n configureLogging(loggingConfig);\n\n // Initialize logger based on config\n if (this.config.logging?.enabled) {\n const namespace = this.config.logging.namespace || \"iframe\";\n this.logger = createLogger(namespace);\n } else {\n // Create a no-op logger when logging is disabled\n this.logger = {\n debug: () => {},\n info: () => {},\n warn: () => {},\n error: () => {},\n };\n }\n\n // Set this logger as the current logger\n setCurrentLogger(this.logger);\n\n this.storage = config.storageAdapter || new BrowserCookieStorageAdapter();\n\n // Validate required configuration\n const requiredConfigs = [\n { key: \"clientId\", value: config.clientId },\n { key: \"targetContainerElement\", value: config.targetContainerElement },\n { key: \"textSignals.success\", value: config.textSignals?.success },\n ];\n\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 this.messageEventHandler = this.handleIframeMessage.bind(this);\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: \"https://your-app.com/callback\",\n * oauthServerBaseUrl: \"https://auth-server.com/\",\n * scopes: [\"openid\", \"profile\"],\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 * @throws {CivicAuthError} If initialization fails\n */\n private async init(): Promise<void> {\n try {\n // Get OAuth endpoints from well-known configuration\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 // Check if we're on the callback page\n if (window.location.href.startsWith(this.config.redirectUrl)) {\n await this.handleCallback();\n }\n } catch (error) {\n const errorMessage =\n error instanceof Error\n ? error.message\n : \"Failed to initialize authentication\";\n this.logger.error(\"Failed to initialize CivicAuth:\", { error });\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 * Gets the container element for the auth iframe\n * @returns The container element or null if not found\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;\n }\n\n /**\n * Builds the authentication URL with PKCE challenge\n * @returns The complete authentication URL\n * @throws {CivicAuthError} If endpoints are not initialized\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 authStorage = new StorageAdapterToAuthStorage(this.storage);\n const pkceProducer = new GenericPublicClientPKCEProducer(authStorage);\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 });\n }\n\n private handleIframeMessage(event: MessageEvent): void {\n const expectedOrigin = new URL(this.config.oauthServerBaseUrl).origin;\n this.logIncomingMessage(event, expectedOrigin);\n\n if (!this.isValidMessageSource(event, expectedOrigin)) {\n return;\n }\n\n this.handleValidMessage(event);\n }\n\n private logIncomingMessage(\n event: MessageEvent,\n expectedOrigin: string,\n ): void {\n this.logger.debug(\"Global window received message:\", {\n data: event.data,\n origin: event.origin,\n sourceProvided: !!event.source,\n iframeContentWindow: this.iframeElement?.contentWindow,\n expectedIframeOrigin: expectedOrigin,\n });\n }\n\n private isValidMessageSource(\n event: MessageEvent,\n expectedOrigin: string,\n ): boolean {\n const isValidOrigin = event.origin === expectedOrigin;\n const isValidSource = event.source === this.iframeElement?.contentWindow;\n\n if (!isValidOrigin) {\n this.logger.warn(\"Ignored message from unexpected origin.\", {\n receivedOrigin: event.origin,\n expectedOrigin,\n iframeSrc: this.iframeElement?.src,\n });\n }\n\n if (!isValidSource) {\n this.logger.warn(\"Ignored message from unexpected source.\", {\n isSourceProvided: !!event.source,\n isIframeContentWindowAvailable: !!this.iframeElement?.contentWindow,\n iframeSrc: this.iframeElement?.src,\n });\n }\n\n return isValidOrigin && isValidSource;\n }\n\n private handleValidMessage(event: MessageEvent): void {\n this.logger.info(\n \"Message from configured iframe source and origin received\",\n {\n data: event.data,\n iframeSrc: this.iframeElement?.src,\n },\n );\n\n const message = event.data as AuthMessage;\n const messageType = message?.type;\n\n switch (messageType) {\n case \"auth_success\":\n this.handleAuthSuccess(message);\n break;\n case \"auth_error\":\n this.handleAuthError(message);\n break;\n default:\n this.logger.debug(\n \"Message from iframe did not match expected types (auth_success, auth_error)\",\n { data: event.data },\n );\n }\n }\n\n private handleAuthSuccess(data: AuthMessage): void {\n this.config.events?.emit(AuthEvent.SIGN_IN_COMPLETE, {\n detail: \"Success signal received via postMessage\",\n data,\n });\n this.authPromiseResolve?.((data?.data as AuthResult) || {});\n this.cleanup();\n }\n\n private handleAuthError(data: AuthMessage): void {\n this.config.events?.emit(AuthEvent.SIGN_IN_ERROR, {\n detail: \"Error signal received via postMessage\",\n error: data,\n });\n this.authPromiseReject?.(\n new CivicAuthError(\n data?.detail || \"Error signal received via postMessage\",\n CivicAuthErrorCode.INVALID_MESSAGE,\n ),\n );\n this.cleanup();\n }\n\n private setupSignalObserver(iframeDoc: Document): void {\n const signalObserver = new SignalObserver(\n {\n textSignals: this.config.textSignals,\n events: this.config.events,\n logger: this.logger,\n },\n this.authPromiseResolve,\n this.authPromiseReject,\n () => this.cleanup(),\n );\n\n signalObserver.setup(iframeDoc);\n }\n\n private async handleNewTabAuth(\n fullAuthUrl: string,\n reject: (error: Error) => void,\n ): Promise<void> {\n const popupWindow = window.open(fullAuthUrl, \"_blank\");\n if (!popupWindow) {\n const error = new CivicAuthError(\n \"Failed to open popup window. Please check your browser's popup settings.\",\n CivicAuthErrorCode.INIT_FAILED,\n );\n this.config.events?.emit(AuthEvent.SIGN_IN_ERROR, {\n detail: error.message,\n });\n reject(error);\n }\n }\n\n private async handleIframeAuth(\n fullAuthUrl: string,\n reject: (error: Error) => void,\n ): Promise<void> {\n const container = this.getContainerElement();\n if (!container) {\n const error = new CivicAuthError(\n \"Target container element not found.\",\n CivicAuthErrorCode.CONTAINER_NOT_FOUND,\n );\n this.logger.error(error.message);\n reject(error);\n return;\n }\n\n this.logger.debug(\"Creating iframe\", {\n url: fullAuthUrl,\n containerId: container?.id,\n iframeId: this.config.iframeId,\n origin: window.location.origin,\n });\n\n this.iframeElement = createIframe(\n fullAuthUrl,\n container,\n this.config.iframeId,\n );\n this.config.events?.emit(AuthEvent.SIGN_IN_STARTED, {\n detail: \"Iframe created\",\n });\n\n this.iframeElement.onload = () => {\n this.logger.info(\"Iframe loaded\", {\n iframeSrc: this.iframeElement?.src,\n currentOrigin: window.location.origin,\n expectedAuthServerOrigin: new URL(this.config.oauthServerBaseUrl)\n .origin,\n });\n\n if (!this.iframeElement?.contentWindow) {\n const errorMsg = \"Iframe content window not available after load.\";\n this.logger.error(errorMsg, {\n iframeSrc: this.iframeElement?.src,\n });\n reject(new Error(errorMsg));\n this.cleanup();\n return;\n }\n\n // Set up postMessage listener for cross-origin communication\n if (this.messageEventHandler) {\n window.addEventListener(\"message\", this.messageEventHandler);\n this.logger.info(\n \"Added cross-origin message event listener for auth server communication\",\n {\n parentOrigin: window.location.origin,\n authServerOrigin: new URL(this.config.oauthServerBaseUrl).origin,\n },\n );\n } else {\n this.logger.error(\n \"messageEventHandler was not defined when trying to add listener.\",\n );\n }\n\n // Try to detect redirect to our domain\n try {\n const currentIframeHref =\n this.iframeElement.contentWindow.location.href;\n\n if (currentIframeHref.startsWith(this.config.redirectUrl)) {\n this.logger.info(\n \"Iframe has navigated to redirectUrl (same-origin). Setting up DOM observer.\",\n );\n\n if (\n this.iframeElement.contentDocument &&\n this.iframeElement.contentDocument.body\n ) {\n this.setupSignalObserver(this.iframeElement.contentDocument);\n }\n }\n } catch (error) {\n this.logger.error(\"Error checking iframe href\", {\n error,\n iframeSrc: this.iframeElement?.src,\n });\n // This is expected when the iframe is on the auth server domain\n this.logger.info(\n \"Iframe is on auth server domain - using postMessage for communication\",\n {\n parentOrigin: window.location.origin,\n authServerOrigin: new URL(this.config.oauthServerBaseUrl).origin,\n },\n );\n }\n };\n\n this.iframeElement.onerror = (event) => {\n this.logger.error(\"Iframe load error\", {\n event,\n iframeSrc: this.iframeElement?.src,\n currentOrigin: window.location.origin,\n });\n this.config.events?.emit(AuthEvent.SIGN_IN_ERROR, {\n detail: \"Iframe load error\",\n error: event,\n });\n reject(new Error(\"Iframe failed to load.\"));\n this.cleanup();\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 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.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\n this.logger.info(\"Starting authentication process\", {\n constructedIframeUrl: 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 // Handle different display modes\n switch (this.config.displayMode) {\n case \"redirect\":\n // For redirect mode, just navigate to the auth URL\n window.location.href = fullAuthUrl;\n break;\n\n case \"new_tab\":\n this.handleNewTabAuth(fullAuthUrl, reject);\n break;\n\n case \"iframe\":\n default:\n this.handleIframeAuth(fullAuthUrl, reject);\n break;\n }\n\n // Set up timeout for all display modes\n if (\n this.config.authProcessTimeout &&\n this.config.authProcessTimeout > 0\n ) {\n this.logger.debug(\"Setting up authentication timeout\", {\n authProcessTimeout: this.config.authProcessTimeout,\n displayMode: this.config.displayMode,\n });\n this.authProcessTimeoutHandle = window.setTimeout(() => {\n this.logger.warn(\"Authentication timed out\", {\n displayMode: this.config.displayMode,\n currentOrigin: window.location.origin,\n });\n this.config.events?.emit(AuthEvent.SIGN_IN_ERROR, {\n detail: \"Authentication timed out\",\n });\n reject(new Error(\"Authentication timed out.\"));\n this.cleanup();\n }, this.config.authProcessTimeout);\n }\n });\n\n return this.authPromise;\n }\n\n /**\n * Cleans up resources and event listeners\n */\n public cleanup(): void {\n this.logger.info(\"Cleaning up iframe authentication client\");\n\n if (this.observer) {\n this.logger.debug(\"Disconnecting mutation observer\");\n this.observer.disconnect();\n this.observer = undefined;\n }\n\n if (this.messageEventHandler) {\n window.removeEventListener(\"message\", this.messageEventHandler);\n this.logger.debug(\"Removed 'message' event listener from window.\");\n }\n\n if (this.iframeElement) {\n this.logger.debug(\"Removing iframe element\");\n removeIframe(this.iframeElement);\n this.iframeElement = undefined;\n }\n\n if (this.authProcessTimeoutHandle) {\n this.logger.debug(\"Clearing authentication process timeout\");\n window.clearTimeout(this.authProcessTimeoutHandle);\n this.authProcessTimeoutHandle = undefined;\n }\n\n this.logger.debug(\"Resetting promise state\");\n this.authPromise = undefined;\n this.authPromiseResolve = undefined;\n this.authPromiseReject = undefined;\n }\n\n private async handleCallback(): Promise<void> {\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 });\n\n if (callbackHandled) {\n const successSignal = document.getElementById(\n CONSTANTS.SUCCESS_SIGNAL_ID,\n );\n const errorSignal = document.getElementById(CONSTANTS.ERROR_SIGNAL_ID);\n\n if (successSignal) {\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.config.events?.emit(AuthEvent.SIGN_IN_ERROR, {\n detail: errorSignal.textContent || \"Unknown error during callback\",\n });\n }\n }\n } catch (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"]}
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 { AuthenticationEvents } from \"./AuthenticationEvents.js\";\nimport { LocalStorageAdapter } from \"../../browser/storage.js\";\nimport { handleOAuthRedirectPage } from \"./OAuthCallbackHandler.js\";\nimport type { Endpoints, DisplayMode, AuthStorage } from \"../../types.js\";\nimport { buildAuthUrl } from \"../utils/auth-utils.js\";\nimport type { AuthResult, Session } from \"../types/index.js\";\nimport {\n createLogger,\n configureLogging,\n setCurrentLogger,\n} from \"../utils/logger.js\";\nimport { SignalObserver } from \"../iframe/SignalObserver.js\";\nimport { GenericPublicClientPKCEProducer } from \"../../services/PKCE.js\";\nimport { generateState } from \"../../lib/oauth.js\";\nimport { SessionManager } from \"./SessionManager.js\";\nimport { IframeManager } from \"../iframe/IframeManager.js\";\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 INVALID_MESSAGE = \"INVALID_MESSAGE\",\n}\n\n/**\n * Constants for the auth client\n */\nconst CONSTANTS = {\n DEFAULT_IFRAME_ID: \"civic-auth-iframe\",\n DEFAULT_AUTH_PROCESS_TIMEOUT: 60000, // 60 seconds\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 */\ntype AuthMessageType = \"auth_success\" | \"auth_error\";\n\ninterface AuthMessage {\n type: AuthMessageType;\n detail?: string;\n data?: unknown;\n error?: unknown;\n}\n\nclass 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 /** 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 */\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 */\n displayMode?: DisplayMode;\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 */\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 prompt parameter */\n prompt?: string;\n /** Initial state for OAuth flow */\n initialState?: string;\n /** Logging configuration */\n logging?: LoggingConfig;\n}\n\nexport interface LoggingConfig {\n enabled: boolean;\n namespace?: string;\n level?: \"debug\" | \"info\" | \"warn\" | \"error\";\n}\n\n/**\n * Process the configuration with defaults\n */\nfunction processConfigWithDefaults(\n config: CivicAuthClientConfig,\n): CivicAuthClientConfig & {\n storageAdapter: AuthStorage;\n logging: LoggingConfig;\n displayMode: DisplayMode;\n authProcessTimeout: number;\n iframeId: string;\n} {\n const loggingConfig: LoggingConfig = {\n enabled: true,\n namespace: \"iframe\",\n level: \"debug\" as const,\n ...config.logging,\n };\n\n return {\n ...config,\n displayMode: config.displayMode || \"iframe\",\n authProcessTimeout:\n config.authProcessTimeout || CONSTANTS.DEFAULT_AUTH_PROCESS_TIMEOUT,\n iframeId: config.iframeId || CONSTANTS.DEFAULT_IFRAME_ID,\n logging: loggingConfig,\n storageAdapter: config.storageAdapter || new LocalStorageAdapter(),\n };\n}\n\n/**\n * CivicAuth client for handling OAuth authentication\n */\nexport class CivicAuth {\n /**\n * Internal configuration with all optional properties resolved to required ones.\n *\n * We extend CivicAuthClientConfig rather than making these properties required\n * in the public interface to maintain better DX (optional properties) while\n * ensuring type safety internally after defaults are applied.\n */\n private config: CivicAuthClientConfig & {\n storageAdapter: AuthStorage;\n logging: LoggingConfig;\n displayMode: DisplayMode;\n authProcessTimeout: number;\n iframeId: string;\n };\n private iframeElement?: HTMLIFrameElement;\n private observer?: MutationObserver;\n private authPromise?: Promise<AuthResult>;\n private authPromiseResolve?: (value: AuthResult) => void;\n private authPromiseReject?: (reason?: Error) => void;\n private authProcessTimeoutHandle?: number;\n private messageEventHandler?: (event: MessageEvent) => void;\n private storage: AuthStorage;\n private endpoints?: Endpoints;\n private logger: ReturnType<typeof createLogger>;\n private sessionManager?: SessionManager;\n private iframeManager?: IframeManager;\n\n /**\n * Private constructor for CivicAuth.\n * Use {@link CivicAuth.create} to create a new instance.\n * @param config - Configuration options for the auth client\n * @throws {CivicAuthError} If required configuration is missing\n * @private\n */\n private constructor(config: CivicAuthClientConfig) {\n // Process config with defaults\n this.config = processConfigWithDefaults(config);\n\n // Configure logging based on config\n configureLogging(this.config.logging);\n\n // Initialize logger based on config\n if (this.config.logging?.enabled) {\n const namespace = this.config.logging.namespace || \"iframe\";\n this.logger = createLogger(namespace);\n } else {\n // Create a no-op logger when logging is disabled\n this.logger = {\n debug: () => {},\n info: () => {},\n warn: () => {},\n error: () => {},\n };\n }\n\n // Set this logger as the current logger\n setCurrentLogger(this.logger);\n\n // Use the storage adapter from processed config (guaranteed to be present)\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 // Validate required configuration\n const requiredConfigs = [\n { key: \"clientId\", value: config.clientId },\n { key: \"targetContainerElement\", value: config.targetContainerElement },\n { key: \"textSignals.success\", value: config.textSignals?.success },\n ];\n\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 this.messageEventHandler = this.handleIframeMessage.bind(this);\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: \"https://your-app.com/callback\",\n * oauthServerBaseUrl: \"https://auth-server.com/\",\n * scopes: [\"openid\", \"profile\"],\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 * @throws {CivicAuthError} If initialization fails\n */\n private async init(): Promise<void> {\n try {\n // Get OAuth endpoints from well-known configuration\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 // Initialize SessionManager with auth config for token refresh\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 await this.sessionManager.initializeWithAuthConfig(authConfig);\n }\n\n // Check if we're on the callback page\n if (window.location.href.startsWith(this.config.redirectUrl)) {\n await this.handleCallback();\n }\n } catch (error) {\n const errorMessage =\n error instanceof Error\n ? error.message\n : \"Failed to initialize authentication\";\n this.logger.error(\"Failed to initialize CivicAuth:\", { error });\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 * Gets the container element for the auth iframe\n * @returns The container element or null if not found\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;\n }\n\n /**\n * Determines the appropriate iframe display mode based on container characteristics\n * @param container The HTML element that will contain the iframe\n * @returns \"modal\" for full-screen overlay or \"embedded\" for in-container display\n */\n private determineIframeDisplayMode(\n container: HTMLElement,\n ): \"modal\" | \"embedded\" {\n // Use explicit config if provided\n if (this.config.iframeDisplayMode) {\n this.logger.debug(\n `Using configured iframe display mode: ${this.config.iframeDisplayMode}`,\n );\n return this.config.iframeDisplayMode;\n }\n\n // Analyze container characteristics to determine best display mode\n const containerRect = container.getBoundingClientRect();\n const containerStyles = window.getComputedStyle(container);\n\n // Get container dimensions\n const containerWidth = containerRect.width;\n const containerHeight = containerRect.height;\n\n // Check if container is positioned in a way that suggests it's meant for modal display\n const isFullScreenContainer =\n containerStyles.position === \"fixed\" &&\n (containerWidth >= window.innerWidth * 0.9 ||\n containerHeight >= window.innerHeight * 0.9);\n\n // Modal mode thresholds - if container is too small, use modal for better UX\n const MIN_EMBEDDED_WIDTH = 320; // Same as modal content wrapper width\n const MIN_EMBEDDED_HEIGHT = 400; // Reasonable minimum for embedded auth flow\n\n // Determine mode based on container characteristics\n if (isFullScreenContainer) {\n this.logger.debug(\n \"Container appears to be full-screen positioned, using modal mode\",\n { containerWidth, containerHeight, position: containerStyles.position },\n );\n return \"modal\";\n }\n\n if (\n containerWidth < MIN_EMBEDDED_WIDTH ||\n containerHeight < MIN_EMBEDDED_HEIGHT\n ) {\n this.logger.debug(\n `Container too small for embedded mode (${containerWidth}x${containerHeight}), using modal mode`,\n {\n containerWidth,\n containerHeight,\n MIN_EMBEDDED_WIDTH,\n MIN_EMBEDDED_HEIGHT,\n },\n );\n return \"modal\";\n }\n\n // Check if container has sufficient space and is properly positioned for embedding\n const hasAdequateSpace =\n containerWidth >= MIN_EMBEDDED_WIDTH &&\n containerHeight >= MIN_EMBEDDED_HEIGHT;\n const isEmbeddablePosition =\n containerStyles.position === \"relative\" ||\n containerStyles.position === \"static\" ||\n containerStyles.position === \"\";\n\n if (hasAdequateSpace && isEmbeddablePosition) {\n this.logger.debug(\n \"Container has adequate space and positioning for embedded mode\",\n { containerWidth, containerHeight, position: containerStyles.position },\n );\n return \"embedded\";\n }\n\n // Default to modal mode if container characteristics are unclear\n this.logger.debug(\n \"Container characteristics unclear, defaulting to modal mode for better UX\",\n { containerWidth, containerHeight, position: containerStyles.position },\n );\n return \"modal\";\n }\n\n /**\n * Builds the authentication URL with PKCE challenge\n * @returns The complete authentication URL\n * @throws {CivicAuthError} If endpoints are not initialized\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 // Use storage directly since it's now AuthStorage\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 });\n }\n\n private handleIframeMessage(event: MessageEvent): void {\n const expectedOrigin = new URL(this.config.oauthServerBaseUrl).origin;\n this.logIncomingMessage(event, expectedOrigin);\n\n if (!this.isValidMessageSource(event, expectedOrigin)) {\n return;\n }\n\n this.handleValidMessage(event);\n }\n\n private logIncomingMessage(\n event: MessageEvent,\n expectedOrigin: string,\n ): void {\n this.logger.debug(\"Global window received message:\", {\n data: event.data,\n origin: event.origin,\n sourceProvided: !!event.source,\n iframeContentWindow: this.iframeElement?.contentWindow,\n expectedIframeOrigin: expectedOrigin,\n });\n }\n\n private isValidMessageSource(\n event: MessageEvent,\n expectedOrigin: string,\n ): boolean {\n const isValidOrigin = event.origin === expectedOrigin;\n const isValidSource = event.source === this.iframeElement?.contentWindow;\n\n if (!isValidOrigin) {\n this.logger.warn(\"Ignored message from unexpected origin.\", {\n receivedOrigin: event.origin,\n expectedOrigin,\n iframeSrc: this.iframeElement?.src,\n });\n }\n\n if (!isValidSource) {\n this.logger.warn(\"Ignored message from unexpected source.\", {\n isSourceProvided: !!event.source,\n isIframeContentWindowAvailable: !!this.iframeElement?.contentWindow,\n iframeSrc: this.iframeElement?.src,\n });\n }\n\n return isValidOrigin && isValidSource;\n }\n\n private handleValidMessage(event: MessageEvent): void {\n this.logger.info(\n \"Message from configured iframe source and origin received\",\n {\n data: event.data,\n iframeSrc: this.iframeElement?.src,\n },\n );\n\n const message = event.data as AuthMessage;\n const messageType = message?.type;\n\n switch (messageType) {\n case \"auth_success\":\n this.handleAuthSuccess(message);\n break;\n case \"auth_error\":\n this.handleAuthError(message);\n break;\n default:\n this.logger.debug(\n \"Message from iframe did not match expected types (auth_success, auth_error)\",\n { data: event.data },\n );\n }\n }\n\n private handleAuthSuccess(data: AuthMessage): void {\n this.config.events?.emit(AuthEvent.SIGN_IN_COMPLETE, {\n detail: \"Success signal received via postMessage\",\n data,\n });\n this.authPromiseResolve?.((data?.data as AuthResult) || {});\n this.cleanup();\n }\n\n private handleAuthError(data: AuthMessage): void {\n this.config.events?.emit(AuthEvent.SIGN_IN_ERROR, {\n detail: \"Error signal received via postMessage\",\n error: data,\n });\n this.authPromiseReject?.(\n new CivicAuthError(\n data?.detail || \"Error signal received via postMessage\",\n CivicAuthErrorCode.INVALID_MESSAGE,\n ),\n );\n this.cleanup();\n }\n\n private setupSignalObserver(iframeDoc: Document): void {\n const signalObserver = new SignalObserver(\n {\n textSignals: this.config.textSignals,\n events: this.config.events,\n logger: this.logger,\n },\n this.authPromiseResolve,\n this.authPromiseReject,\n () => this.cleanup(),\n );\n\n signalObserver.setup(iframeDoc);\n }\n\n private async handleNewTabAuth(\n fullAuthUrl: string,\n reject: (error: Error) => void,\n ): Promise<void> {\n const popupWindow = window.open(fullAuthUrl, \"_blank\");\n if (!popupWindow) {\n const error = new CivicAuthError(\n \"Failed to open popup window. Please check your browser's popup settings.\",\n CivicAuthErrorCode.INIT_FAILED,\n );\n this.config.events?.emit(AuthEvent.SIGN_IN_ERROR, {\n detail: error.message,\n });\n reject(error);\n }\n }\n\n private async handleIframeAuth(\n fullAuthUrl: string,\n reject: (error: Error) => void,\n ): Promise<void> {\n const container = this.getContainerElement();\n if (!container) {\n const error = new CivicAuthError(\n \"Target container element not found.\",\n CivicAuthErrorCode.CONTAINER_NOT_FOUND,\n );\n this.logger.error(error.message);\n reject(error);\n return;\n }\n\n this.logger.debug(\"Creating iframe with modal backdrop\", {\n url: fullAuthUrl,\n containerId: container?.id,\n iframeId: this.config.iframeId,\n origin: window.location.origin,\n });\n\n // Determine the actual display mode for IframeManager\n // For iframe displayMode, we need to decide between modal and embedded based on container\n const iframeDisplayMode = this.determineIframeDisplayMode(container);\n\n this.logger.debug(\n `🎯 CivicAuth: Creating IframeManager with display mode: ${iframeDisplayMode}`,\n );\n\n // Create IframeManager with appropriate display mode\n this.iframeManager = new IframeManager({\n container: container,\n displayMode: iframeDisplayMode,\n iframeId: this.config.iframeId,\n onClose: () => {\n this.logger.debug(\n \"Authentication close requested by user (backdrop click, close button, or Escape key)\",\n );\n this.config.events?.emit(AuthEvent.SIGN_IN_ERROR, {\n detail: \"Authentication cancelled by user\",\n });\n reject(\n new CivicAuthError(\n \"Authentication cancelled by user\",\n CivicAuthErrorCode.AUTH_PROCESS_TIMEOUT,\n ),\n );\n this.cleanup();\n },\n });\n\n // Create the iframe using IframeManager\n this.iframeElement = this.iframeManager.createIframe(fullAuthUrl);\n\n this.config.events?.emit(AuthEvent.SIGN_IN_STARTED, {\n detail: \"Iframe created with modal backdrop\",\n });\n\n this.iframeElement.onload = () => {\n this.logger.info(\"Iframe loaded\", {\n iframeSrc: this.iframeElement?.src,\n currentOrigin: window.location.origin,\n expectedAuthServerOrigin: new URL(this.config.oauthServerBaseUrl)\n .origin,\n });\n\n if (!this.iframeElement?.contentWindow) {\n const errorMsg = \"Iframe content window not available after load.\";\n this.logger.error(errorMsg, {\n iframeSrc: this.iframeElement?.src,\n });\n reject(new Error(errorMsg));\n this.cleanup();\n return;\n }\n\n // Set up postMessage listener for cross-origin communication\n if (this.messageEventHandler) {\n window.addEventListener(\"message\", this.messageEventHandler);\n this.logger.info(\n \"Added cross-origin message event listener for auth server communication\",\n {\n parentOrigin: window.location.origin,\n authServerOrigin: new URL(this.config.oauthServerBaseUrl).origin,\n },\n );\n } else {\n this.logger.error(\n \"messageEventHandler was not defined when trying to add listener.\",\n );\n }\n\n // Try to detect redirect to our domain\n try {\n const currentIframeHref =\n this.iframeElement.contentWindow.location.href;\n\n if (currentIframeHref.startsWith(this.config.redirectUrl)) {\n this.logger.info(\n \"Iframe has navigated to redirectUrl (same-origin). Setting up DOM observer.\",\n );\n\n if (\n this.iframeElement.contentDocument &&\n this.iframeElement.contentDocument.body\n ) {\n this.setupSignalObserver(this.iframeElement.contentDocument);\n }\n }\n } catch (error) {\n this.logger.error(\"Error checking iframe href\", {\n error,\n iframeSrc: this.iframeElement?.src,\n });\n // This is expected when the iframe is on the auth server domain\n this.logger.info(\n \"Iframe is on auth server domain - using postMessage for communication\",\n {\n parentOrigin: window.location.origin,\n authServerOrigin: new URL(this.config.oauthServerBaseUrl).origin,\n },\n );\n }\n };\n\n this.iframeElement.onerror = (event) => {\n this.logger.error(\"Iframe load error\", {\n event,\n iframeSrc: this.iframeElement?.src,\n currentOrigin: window.location.origin,\n });\n this.config.events?.emit(AuthEvent.SIGN_IN_ERROR, {\n detail: \"Iframe load error\",\n error: event,\n });\n reject(new Error(\"Iframe failed to load.\"));\n this.cleanup();\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 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.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\n this.logger.info(\"Starting authentication process\", {\n constructedIframeUrl: 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 // Handle different display modes\n switch (this.config.displayMode) {\n case \"redirect\":\n // For redirect mode, just navigate to the auth URL\n window.location.href = fullAuthUrl;\n break;\n\n case \"new_tab\":\n this.handleNewTabAuth(fullAuthUrl, reject);\n break;\n\n case \"iframe\":\n default:\n this.handleIframeAuth(fullAuthUrl, reject);\n break;\n }\n\n // Set up timeout for all display modes\n if (\n this.config.authProcessTimeout &&\n this.config.authProcessTimeout > 0\n ) {\n this.logger.debug(\"Setting up authentication timeout\", {\n authProcessTimeout: this.config.authProcessTimeout,\n displayMode: this.config.displayMode,\n });\n this.authProcessTimeoutHandle = window.setTimeout(() => {\n this.logger.warn(\"Authentication timed out\", {\n displayMode: this.config.displayMode,\n currentOrigin: window.location.origin,\n });\n this.config.events?.emit(AuthEvent.SIGN_IN_ERROR, {\n detail: \"Authentication timed out\",\n });\n reject(new Error(\"Authentication timed out.\"));\n this.cleanup();\n }, this.config.authProcessTimeout);\n }\n });\n\n return this.authPromise;\n }\n\n /**\n * Cleans up resources and event listeners\n */\n public cleanup(): void {\n this.logger.info(\"Cleaning up iframe authentication client\");\n\n if (this.observer) {\n this.logger.debug(\"Disconnecting mutation observer\");\n this.observer.disconnect();\n this.observer = undefined;\n }\n\n if (this.messageEventHandler) {\n window.removeEventListener(\"message\", this.messageEventHandler);\n this.logger.debug(\"Removed 'message' event listener from window.\");\n }\n\n if (this.iframeManager) {\n this.logger.debug(\"Cleaning up iframe manager\");\n this.iframeManager.cleanup();\n this.iframeManager = undefined;\n }\n\n // Reset iframe element reference (actual removal handled by IframeManager)\n if (this.iframeElement) {\n this.iframeElement = undefined;\n }\n\n if (this.authProcessTimeoutHandle) {\n this.logger.debug(\"Clearing authentication process timeout\");\n window.clearTimeout(this.authProcessTimeoutHandle);\n this.authProcessTimeoutHandle = undefined;\n }\n\n this.logger.debug(\"Resetting promise state\");\n this.authPromise = undefined;\n this.authPromiseResolve = undefined;\n this.authPromiseReject = undefined;\n }\n\n private async handleCallback(): Promise<void> {\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 if (callbackHandled) {\n const successSignal = document.getElementById(\n CONSTANTS.SUCCESS_SIGNAL_ID,\n );\n const errorSignal = document.getElementById(CONSTANTS.ERROR_SIGNAL_ID);\n\n if (successSignal) {\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.config.events?.emit(AuthEvent.SIGN_IN_ERROR, {\n detail: errorSignal.textContent || \"Unknown error during callback\",\n });\n }\n }\n } catch (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 * 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"]}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * OAuth Callback Handler for Vanilla JavaScript Applications
3
+ *
4
+ * This module provides functionality for handling OAuth redirect/callback pages in vanilla JavaScript
5
+ * applications using the Civic Auth system. It processes the OAuth authorization code flow completion
6
+ * by exchanging authorization codes for access tokens and managing the authentication state.
7
+ *
8
+ * Key responsibilities:
9
+ * - Process OAuth callback URL parameters (code, state)
10
+ * - Exchange authorization codes for access tokens using PKCE
11
+ * - Store tokens and user session data using shared utilities
12
+ * - Create DOM signals for iframe-based authentication flows
13
+ * - Handle error states and cleanup during the OAuth flow
14
+ *
15
+ * This module works in conjunction with:
16
+ * - CivicAuth class for initiating OAuth flows
17
+ * - SignalObserver for detecting authentication completion in iframes
18
+ * - Shared token storage utilities for consistent state management
19
+ *
20
+ * @example
21
+ * ```typescript
22
+ * // In an OAuth callback page
23
+ * import { handleOAuthRedirectPage, LocalStorageAdapter } from '@civic/auth/vanillajs';
24
+ *
25
+ * const handled = await handleOAuthRedirectPage({
26
+ * clientId: 'your-client-id',
27
+ * redirectUrl: 'https://your-app.com/callback',
28
+ * oauthServer: 'https://auth.civic.com/oauth/',
29
+ * textSignals: {
30
+ * success: 'Authentication successful!',
31
+ * error: 'Authentication failed!'
32
+ * },
33
+ * storageAdapter: new LocalStorageAdapter()
34
+ * });
35
+ * ```
36
+ */
37
+ import { getCurrentLogger } from "../utils/logger.js";
38
+ import type { AuthStorage, OIDCTokenResponseBody } from "../../types.js";
39
+ /**
40
+ * Store tokens using the shared utilities from /shared/lib
41
+ * This ensures consistency with the React implementation and also handles user session storage
42
+ */
43
+ export declare function storeTokens(tokens: OIDCTokenResponseBody, storageAdapter: AuthStorage, loggerInstance?: {
44
+ debug: (message: string, ...args: unknown[]) => void;
45
+ info: (message: string, ...args: unknown[]) => void;
46
+ warn: (message: string, ...args: unknown[]) => void;
47
+ error: (message: string, ...args: unknown[]) => void;
48
+ }): Promise<object | null>;
49
+ export interface HandleOAuthRedirectConfig {
50
+ clientId: string;
51
+ redirectUrl: string;
52
+ oauthServer: string;
53
+ textSignals: {
54
+ success: string;
55
+ error: string;
56
+ };
57
+ storageAdapter: AuthStorage;
58
+ logger?: ReturnType<typeof getCurrentLogger>;
59
+ }
60
+ /**
61
+ * Handle OAuth redirect page processing for vanilla JavaScript applications.
62
+ * This function processes the OAuth callback URL parameters and exchanges the authorization code for tokens.
63
+ *
64
+ * @param config - Configuration object for handling the OAuth redirect
65
+ * @param config.clientId - OAuth client ID
66
+ * @param config.redirectUrl - URL to redirect to after authentication
67
+ * @param config.oauthServer - OAuth server base URL
68
+ * @param config.textSignals - Text signals for success and error states
69
+ * @param config.storageAdapter - Storage adapter for persisting auth state (required)
70
+ * @param config.logger - Optional logger instance
71
+ * @returns Promise<boolean> - Returns true if callback was handled, false otherwise
72
+ *
73
+ * @example
74
+ * ```typescript
75
+ * import { handleOAuthRedirectPage, LocalStorageAdapter } from '@civic/auth/vanillajs';
76
+ *
77
+ * const handled = await handleOAuthRedirectPage({
78
+ * clientId: 'your-client-id',
79
+ * redirectUrl: 'https://your-app.com/callback',
80
+ * oauthServer: 'https://auth.civic.com/oauth/',
81
+ * textSignals: {
82
+ * success: 'Authentication successful!',
83
+ * error: 'Authentication failed!'
84
+ * },
85
+ * storageAdapter: new LocalStorageAdapter()
86
+ * });
87
+ * ```
88
+ */
89
+ export declare function handleOAuthRedirectPage(config: HandleOAuthRedirectConfig): Promise<boolean>;
90
+ //# sourceMappingURL=OAuthCallbackHandler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OAuthCallbackHandler.d.ts","sourceRoot":"","sources":["../../../src/vanillajs/auth/OAuthCallbackHandler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAWH,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAEzE;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,qBAAqB,EAC7B,cAAc,EAAE,WAAW,EAC3B,cAAc;;;;;CAAqB,GAClC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAyBxB;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE;QACX,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,cAAc,EAAE,WAAW,CAAC;IAC5B,MAAM,CAAC,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;CAC9C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,yBAAyB,GAChC,OAAO,CAAC,OAAO,CAAC,CAmElB"}