@civic/auth 0.8.2-beta.1 → 0.8.3-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 +5 -0
- package/README.md +6 -0
- package/dist/lib/oauth.d.ts +4 -2
- package/dist/lib/oauth.d.ts.map +1 -1
- package/dist/lib/oauth.js +4 -2
- package/dist/lib/oauth.js.map +1 -1
- package/dist/nextjs/NextClientAuthenticationRefresher.d.ts +1 -1
- package/dist/nextjs/NextClientAuthenticationRefresher.d.ts.map +1 -1
- package/dist/nextjs/NextClientAuthenticationRefresher.js.map +1 -1
- package/dist/nextjs/NextServerAuthenticationRefresherImpl.d.ts +1 -1
- package/dist/nextjs/NextServerAuthenticationRefresherImpl.d.ts.map +1 -1
- package/dist/nextjs/NextServerAuthenticationRefresherImpl.js +3 -0
- package/dist/nextjs/NextServerAuthenticationRefresherImpl.js.map +1 -1
- package/dist/nextjs/routeHandler.d.ts.map +1 -1
- package/dist/nextjs/routeHandler.js +2 -1
- package/dist/nextjs/routeHandler.js.map +1 -1
- package/dist/reactjs/core/GlobalAuthManager.d.ts +15 -0
- package/dist/reactjs/core/GlobalAuthManager.d.ts.map +1 -1
- package/dist/reactjs/core/GlobalAuthManager.js +26 -1
- package/dist/reactjs/core/GlobalAuthManager.js.map +1 -1
- package/dist/reactjs/hooks/useUser.d.ts +3 -0
- package/dist/reactjs/hooks/useUser.d.ts.map +1 -1
- package/dist/reactjs/hooks/useUser.js +32 -0
- package/dist/reactjs/hooks/useUser.js.map +1 -1
- package/dist/reactjs/providers/CivicAuthContext.d.ts +4 -0
- package/dist/reactjs/providers/CivicAuthContext.d.ts.map +1 -1
- package/dist/reactjs/providers/CivicAuthContext.js +22 -13
- package/dist/reactjs/providers/CivicAuthContext.js.map +1 -1
- package/dist/reactjs/providers/CivicAuthProvider.d.ts +1 -0
- package/dist/reactjs/providers/CivicAuthProvider.d.ts.map +1 -1
- package/dist/reactjs/providers/CivicAuthProvider.js +3 -1
- package/dist/reactjs/providers/CivicAuthProvider.js.map +1 -1
- package/dist/server/config.d.ts +47 -0
- package/dist/server/config.d.ts.map +1 -1
- package/dist/server/config.js.map +1 -1
- package/dist/server/index.d.ts +8 -2
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +5 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server/login.d.ts +9 -0
- package/dist/server/login.d.ts.map +1 -1
- package/dist/server/login.js +4 -2
- package/dist/server/login.js.map +1 -1
- package/dist/server/refresh.d.ts +1 -1
- package/dist/server/refresh.d.ts.map +1 -1
- package/dist/server/refresh.js.map +1 -1
- package/dist/server/session.d.ts +60 -2
- package/dist/server/session.d.ts.map +1 -1
- package/dist/server/session.js +216 -5
- package/dist/server/session.js.map +1 -1
- package/dist/server/types/express.d.ts +97 -0
- package/dist/server/types/express.d.ts.map +1 -0
- package/dist/server/types/express.js +2 -0
- package/dist/server/types/express.js.map +1 -0
- package/dist/services/AuthenticationService.d.ts +6 -0
- package/dist/services/AuthenticationService.d.ts.map +1 -1
- package/dist/services/AuthenticationService.js +48 -6
- package/dist/services/AuthenticationService.js.map +1 -1
- package/dist/services/types.d.ts +1 -1
- package/dist/services/types.d.ts.map +1 -1
- package/dist/services/types.js.map +1 -1
- package/dist/shared/components/CivicAuthIframe.d.ts +1 -0
- package/dist/shared/components/CivicAuthIframe.d.ts.map +1 -1
- package/dist/shared/components/CivicAuthIframe.js +4 -4
- package/dist/shared/components/CivicAuthIframe.js.map +1 -1
- package/dist/shared/components/CivicAuthIframeContainer.d.ts +2 -1
- package/dist/shared/components/CivicAuthIframeContainer.d.ts.map +1 -1
- package/dist/shared/components/CivicAuthIframeContainer.js +10 -3
- package/dist/shared/components/CivicAuthIframeContainer.js.map +1 -1
- package/dist/shared/hooks/useSignIn.d.ts.map +1 -1
- package/dist/shared/hooks/useSignIn.js +2 -1
- package/dist/shared/hooks/useSignIn.js.map +1 -1
- package/dist/shared/lib/AuthenticationRefresherImpl.d.ts +2 -2
- package/dist/shared/lib/AuthenticationRefresherImpl.d.ts.map +1 -1
- package/dist/shared/lib/AuthenticationRefresherImpl.js +3 -0
- package/dist/shared/lib/AuthenticationRefresherImpl.js.map +1 -1
- package/dist/shared/lib/GenericAuthenticationRefresher.d.ts +2 -2
- package/dist/shared/lib/GenericAuthenticationRefresher.d.ts.map +1 -1
- package/dist/shared/lib/GenericAuthenticationRefresher.js.map +1 -1
- package/dist/shared/lib/iframeUtils.d.ts +1 -0
- package/dist/shared/lib/iframeUtils.d.ts.map +1 -1
- package/dist/shared/lib/iframeUtils.js +3 -0
- package/dist/shared/lib/iframeUtils.js.map +1 -1
- package/dist/shared/lib/util.d.ts +7 -0
- package/dist/shared/lib/util.d.ts.map +1 -1
- package/dist/shared/lib/util.js +12 -0
- package/dist/shared/lib/util.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/BackendAuthenticationRefresher.d.ts +41 -0
- package/dist/vanillajs/auth/BackendAuthenticationRefresher.d.ts.map +1 -0
- package/dist/vanillajs/auth/BackendAuthenticationRefresher.js +125 -0
- package/dist/vanillajs/auth/BackendAuthenticationRefresher.js.map +1 -0
- package/dist/vanillajs/auth/CivicAuth.d.ts +66 -0
- package/dist/vanillajs/auth/CivicAuth.d.ts.map +1 -1
- package/dist/vanillajs/auth/CivicAuth.js +296 -10
- package/dist/vanillajs/auth/CivicAuth.js.map +1 -1
- package/dist/vanillajs/auth/SessionManager.d.ts +31 -3
- package/dist/vanillajs/auth/SessionManager.d.ts.map +1 -1
- package/dist/vanillajs/auth/SessionManager.js +253 -22
- package/dist/vanillajs/auth/SessionManager.js.map +1 -1
- package/dist/vanillajs/auth/TokenRefresher.d.ts.map +1 -1
- package/dist/vanillajs/auth/TokenRefresher.js +31 -18
- package/dist/vanillajs/auth/TokenRefresher.js.map +1 -1
- package/dist/vanillajs/auth/config/ConfigProcessor.d.ts.map +1 -1
- package/dist/vanillajs/auth/config/ConfigProcessor.js +14 -8
- package/dist/vanillajs/auth/config/ConfigProcessor.js.map +1 -1
- package/dist/vanillajs/auth/handlers/IframeAuthHandler.d.ts +34 -0
- package/dist/vanillajs/auth/handlers/IframeAuthHandler.d.ts.map +1 -1
- package/dist/vanillajs/auth/handlers/IframeAuthHandler.js +139 -0
- package/dist/vanillajs/auth/handlers/IframeAuthHandler.js.map +1 -1
- package/dist/vanillajs/auth/handlers/MessageHandler.d.ts +21 -0
- package/dist/vanillajs/auth/handlers/MessageHandler.d.ts.map +1 -1
- package/dist/vanillajs/auth/handlers/MessageHandler.js +52 -2
- package/dist/vanillajs/auth/handlers/MessageHandler.js.map +1 -1
- package/dist/vanillajs/auth/types/AuthTypes.d.ts +17 -0
- package/dist/vanillajs/auth/types/AuthTypes.d.ts.map +1 -1
- package/dist/vanillajs/auth/types/AuthTypes.js +1 -0
- package/dist/vanillajs/auth/types/AuthTypes.js.map +1 -1
- package/dist/vanillajs/iframe/IframeManager.d.ts +36 -0
- package/dist/vanillajs/iframe/IframeManager.d.ts.map +1 -1
- package/dist/vanillajs/iframe/IframeManager.js +205 -18
- package/dist/vanillajs/iframe/IframeManager.js.map +1 -1
- package/dist/vanillajs/index.d.ts +2 -0
- package/dist/vanillajs/index.d.ts.map +1 -1
- package/dist/vanillajs/index.js +4 -0
- package/dist/vanillajs/index.js.map +1 -1
- package/dist/vanillajs/ui/LoadingComponents.d.ts.map +1 -1
- package/dist/vanillajs/ui/LoadingComponents.js +1 -1
- package/dist/vanillajs/ui/LoadingComponents.js.map +1 -1
- package/package.json +7 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MessageHandler.js","sourceRoot":"","sources":["../../../../src/vanillajs/auth/handlers/MessageHandler.ts"],"names":[],"mappings":"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","sourcesContent":["import { AuthEvent } from \"../../types/index.js\";\nimport type { AuthResult } from \"../../types/index.js\";\nimport type {\n IframeMessage,\n AuthMessage,\n LoginAppMessage,\n ProcessedCivicAuthConfig,\n} from \"../types/AuthTypes.js\";\nimport { CivicAuthError, CivicAuthErrorCode } from \"../types/AuthTypes.js\";\nimport type { createLogger } from \"../../utils/logger.js\";\nimport { createLogger as createLoggerFn } from \"../../utils/logger.js\";\n\nexport interface MessageHandlerConfig {\n config: ProcessedCivicAuthConfig;\n logger: ReturnType<typeof createLogger>;\n iframeElement?: HTMLIFrameElement;\n onAuthSuccess: (result: AuthResult) => void;\n onAuthError: (error: Error) => void;\n onPopupFailure: (failedUrl?: string) => void;\n cleanup: () => void;\n}\n\n/**\n * MessageHandler - Handles postMessage communication and authentication flow logic\n * Processes messages from iframe, validates origins, and manages auth state transitions\n */\nexport class MessageHandler {\n private config: ProcessedCivicAuthConfig;\n private logger = createLoggerFn(\"message-handler\");\n private iframeElement?: HTMLIFrameElement;\n private onAuthSuccess: (result: AuthResult) => void;\n private onAuthError: (error: Error) => void;\n private onPopupFailure: (failedUrl?: string) => void;\n private cleanup: () => void;\n\n constructor(handlerConfig: MessageHandlerConfig) {\n this.config = handlerConfig.config;\n this.iframeElement = handlerConfig.iframeElement;\n this.onAuthSuccess = handlerConfig.onAuthSuccess;\n this.onAuthError = handlerConfig.onAuthError;\n this.onPopupFailure = handlerConfig.onPopupFailure;\n this.cleanup = handlerConfig.cleanup;\n }\n\n /**\n * Updates the iframe element reference used for message validation.\n *\n * This method allows updating the iframe element after the MessageHandler\n * has been instantiated, which is useful when the iframe is created\n * dynamically after the handler setup.\n *\n * @param iframeElement - The new iframe element to associate with this handler\n */\n public updateIframeElement(iframeElement: HTMLIFrameElement): void {\n this.iframeElement = iframeElement;\n }\n\n /**\n * Main message handler for processing postMessage events.\n *\n * Validates message origin and source, then routes valid messages to\n * appropriate handlers. This is the entry point for all iframe communication.\n *\n * @param event - The MessageEvent received from the iframe or other sources\n */\n public handleMessage = (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 /**\n * Logs incoming message details for debugging purposes.\n *\n * Provides comprehensive logging of message properties including origin,\n * source validation, and iframe state for troubleshooting communication issues.\n *\n * @param event - The MessageEvent to log\n * @param expectedOrigin - The expected origin for comparison\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 /**\n * Validates that a message comes from the expected origin and source.\n *\n * Performs security checks to ensure messages are only processed from\n * the configured OAuth server origin and the designated iframe element.\n *\n * @param event - The MessageEvent to validate\n * @param expectedOrigin - The expected origin URL for the message\n * @returns True if the message source and origin are valid, false otherwise\n */\n private isValidMessageSource(\n event: MessageEvent,\n expectedOrigin: string,\n ): boolean {\n // Check if message is from the iframe source\n const isValidSource = event.source === this.iframeElement?.contentWindow;\n\n // Build list of allowed origins\n const allowedOrigins = [expectedOrigin];\n\n // Add the actual iframe origin (to handle redirects)\n if (this.iframeElement?.src) {\n try {\n const actualIframeOrigin = new URL(this.iframeElement.src).origin;\n allowedOrigins.push(actualIframeOrigin);\n } catch {\n // ignore URL parsing errors\n }\n }\n\n // Add the client app's own origin (same-origin) for messages sent after token exchange\n // This is needed when the iframe navigates to the client app's callback URL\n const clientOrigin = window.location.origin;\n if (!allowedOrigins.includes(clientOrigin)) {\n allowedOrigins.push(clientOrigin);\n }\n\n // Add common development login app origins for localhost\n const expectedUrl = new URL(expectedOrigin);\n if (expectedUrl.hostname === \"localhost\") {\n // For localhost, also allow common development ports\n allowedOrigins.push(\"http://localhost:3004\"); // default login-app port\n allowedOrigins.push(\"http://localhost:3001\"); // auth server port\n }\n\n const isValidOrigin = allowedOrigins.includes(event.origin);\n\n if (!isValidOrigin) {\n this.logger.warn(\"Ignored message from unexpected origin.\", {\n receivedOrigin: event.origin,\n expectedOrigin,\n allowedOrigins,\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 /**\n * Processes messages that have passed origin and source validation.\n *\n * Routes validated messages to specific handlers based on message type,\n * including civicloginApp messages, iframe resizer messages, and standard auth messages.\n *\n * @param event - The validated MessageEvent to process\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 IframeMessage;\n\n this.logger.debug(\"Processing iframe message\", {\n messageType: typeof message,\n hasType: message && typeof message === \"object\" && \"type\" in message,\n hasSource: message && typeof message === \"object\" && \"source\" in message,\n messageKeys:\n message && typeof message === \"object\" ? Object.keys(message) : [],\n rawData: message,\n });\n\n // Handle civicloginApp messages\n if (this.isCivicLoginAppMessage(message)) {\n this.handleCivicLoginAppMessage(message);\n return;\n }\n\n // Handle iframe resizer messages\n if (this.isIframeResizerMessage(message)) {\n this.handleIframeResizerMessage(message);\n return;\n }\n\n // Handle standard auth messages\n this.handleStandardAuthMessage(message);\n }\n\n /**\n * Type guard to identify civicloginApp messages.\n *\n * Checks if a message object has the structure and source property\n * that identifies it as coming from the civicloginApp.\n *\n * @param message - The message object to check\n * @returns True if the message is a LoginAppMessage, false otherwise\n */\n private isCivicLoginAppMessage(message: unknown): message is LoginAppMessage {\n return (\n message !== null &&\n typeof message === \"object\" &&\n \"source\" in message &&\n (message as Record<string, unknown>).source === \"civicloginApp\"\n );\n }\n\n /**\n * Handles messages originating from the civicloginApp.\n *\n * Processes various civicloginApp message types including authentication errors,\n * popup failures, design updates, and other app-specific communications.\n * Validates client ID matches before processing.\n *\n * @param message - The validated civicloginApp message to process\n */\n private handleCivicLoginAppMessage(message: LoginAppMessage): void {\n this.logger.info(\"Received civicloginApp message\", {\n type: message.type,\n clientId: message.clientId,\n data: message.data,\n });\n\n // Validate clientId matches our config\n if (message.clientId !== this.config.clientId) {\n this.logger.warn(\"civicloginApp message clientId mismatch\", {\n received: message.clientId,\n expected: this.config.clientId,\n });\n return;\n }\n\n switch (message.type) {\n case \"auth_error\":\n case \"auth_error_try_again\":\n this.handleCivicLoginAppError(message);\n break;\n case \"generatePopupFailed\":\n this.handlePopupFailure(message);\n break;\n case \"design\":\n this.logger.debug(\"civicloginApp design message\", {\n data: message.data,\n });\n break;\n case \"auth_success_early\":\n this.logger.info(\"civicloginApp auth success early message\", {\n data: message.data,\n });\n this.handleAuthSuccessEarly(message);\n break;\n case \"auth_success\":\n this.logger.info(\"civicloginApp auth success message\", {\n data: message.data,\n });\n\n // Dispatch early auth success event for immediate modal closing\n\n // Still handle auth success normally (for callback processing)\n this.handleAuthSuccess({\n type: \"auth_success\",\n detail: \"Authentication successful\",\n data: message.data,\n });\n break;\n default:\n this.handleUnknownCivicLoginAppMessage(message);\n break;\n }\n }\n\n /**\n * Handles auth success early messages from civicloginApp.\n *\n * Processes auth_success_early messages, emits success events,\n * and triggers the success callback with authentication results.\n *\n * @param message - The civicloginApp auth success early message to process\n */\n\n private handleAuthSuccessEarly(message: LoginAppMessage): void {\n this.logger.info(\"civicloginApp auth success early message\", {\n data: message.data,\n });\n\n const earlySuccessEvent = new CustomEvent(\"civic-auth-success-early\", {\n detail: {\n clientId: message.clientId,\n data: message.data,\n },\n });\n window.dispatchEvent(earlySuccessEvent);\n }\n\n /**\n * Handles authentication error messages from civicloginApp.\n *\n * Processes auth_error and auth_error_try_again messages, creates\n * appropriate error objects, emits error events, and triggers cleanup.\n *\n * @param message - The civicloginApp error message to process\n */\n private handleCivicLoginAppError(message: LoginAppMessage): void {\n this.logger.error(\"civicloginApp authentication error\", {\n type: message.type,\n data: message.data,\n });\n\n const error = new CivicAuthError(\n `Login app error: ${message.type}`,\n CivicAuthErrorCode.INVALID_MESSAGE,\n );\n\n this.config.events?.emit(AuthEvent.SIGN_IN_ERROR, {\n detail: error.message,\n error: message.data,\n });\n\n this.onAuthError(error);\n this.cleanup();\n }\n\n /**\n * Handles popup generation failure messages from civicloginApp.\n *\n * Processes generatePopupFailed messages, extracts the failed URL,\n * emits appropriate events, and triggers the popup failure callback\n * to enable fallback authentication methods.\n *\n * @param message - The civicloginApp popup failure message to process\n */\n private handlePopupFailure(message: LoginAppMessage): void {\n this.logger.warn(\"civicloginApp popup generation failed\", {\n data: message.data,\n });\n\n const failedUrl = (message.data as Record<string, unknown> | undefined)\n ?.url as string | undefined;\n if (failedUrl) {\n this.logger.info(\"Popup failed for URL, considering fallback options\", {\n failedUrl,\n displayMode: this.config.displayMode,\n });\n\n this.config.events?.emit(AuthEvent.SIGN_IN_ERROR, {\n detail: \"Popup blocked by browser - switching to redirect mode\",\n error: {\n type: \"popup_blocked\",\n failedUrl,\n suggestion:\n \"The browser blocked a popup window. Redirecting to complete authentication in a new page.\",\n },\n });\n }\n\n this.onPopupFailure(failedUrl);\n }\n\n /**\n * Handles unknown or unrecognized civicloginApp message types.\n *\n * Provides fallback handling for unexpected message types, with special\n * logic to detect potential success messages that don't match standard types.\n *\n * @param message - The unrecognized civicloginApp message to process\n */\n private handleUnknownCivicLoginAppMessage(message: LoginAppMessage): void {\n this.logger.debug(\"Unhandled civicloginApp message type\", {\n type: message.type,\n data: message.data,\n });\n\n // Check if this might be a success message with a different type\n if (message.type && message.type.toLowerCase().includes(\"success\")) {\n this.logger.info(\"Potential success message from civicloginApp\", {\n type: message.type,\n data: message.data,\n });\n\n this.handleAuthSuccess({\n type: \"auth_success\",\n detail: `civicloginApp success: ${message.type}`,\n data: message.data,\n });\n }\n }\n\n /**\n * Type guard to identify iframe resizer messages.\n *\n * Checks if a message is related to iframe resizing functionality,\n * including both civic-specific resize messages and iFrameResizerChild messages.\n *\n * @param message - The message object to check\n * @returns True if the message is an iframe resizer message, false otherwise\n */\n private isIframeResizerMessage(message: unknown): boolean {\n return (\n (message !== null &&\n typeof message === \"object\" &&\n \"type\" in message &&\n ((message as Record<string, unknown>).type === \"civic-iframe-resize\" ||\n (message as Record<string, unknown>).type ===\n \"civic-iframe-ready\")) ||\n (typeof message === \"string\" && message.includes(\"iFrameResizerChild\"))\n );\n }\n\n /**\n * Handles iframe resizer messages for dynamic iframe sizing.\n *\n * Processes messages related to iframe resizing, including height adjustments\n * and ready state notifications from the iframe resizer library.\n *\n * @param message - The iframe resizer message to process\n */\n private handleIframeResizerMessage(message: unknown): void {\n if (typeof message === \"string\") {\n this.logger.debug(\"Received iframe resizer child message\", { message });\n } else if (message && typeof message === \"object\" && message !== null) {\n const messageObj = message as Record<string, unknown>;\n this.logger.debug(\"Received iframe resizer message\", {\n type: messageObj.type,\n height: messageObj.height,\n });\n }\n }\n\n /**\n * Handles standard authentication messages.\n *\n * Processes auth_success and auth_error messages that follow the standard\n * authentication message format, routing them to appropriate success or error handlers.\n *\n * @param message - The standard auth message to process\n */\n private handleStandardAuthMessage(message: unknown): void {\n const messageObj =\n message && typeof message === \"object\" && message !== null\n ? (message as Record<string, unknown>)\n : null;\n const messageType = messageObj?.type;\n\n switch (messageType) {\n case \"auth_success\":\n this.handleAuthSuccess(message as AuthMessage);\n break;\n case \"auth_error\":\n this.handleAuthError(message as AuthMessage);\n break;\n default:\n // Check if this is a calculateSubFramePositioning message (expected and harmless)\n if (messageObj?.command === \"calculateSubFramePositioning\") {\n this.logger.debug(\"Received iframe positioning message (expected)\", {\n command: messageObj.command,\n hasSubFrameData: !!messageObj.subFrameData,\n });\n } else {\n this.logger.debug(\n \"Message from iframe did not match expected types (auth_success, auth_error, civicloginApp, iframe-resizer)\",\n {\n data: message,\n messageType: typeof message,\n hasType: messageObj?.type ?? \"none\",\n messageKeys: messageObj ? Object.keys(messageObj) : [],\n },\n );\n }\n }\n }\n\n /**\n * Handles successful authentication completion.\n *\n * Processes authentication success messages, emits success events,\n * triggers the success callback with authentication results, and performs cleanup.\n *\n * @param data - The authentication success message containing result data\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.onAuthSuccess((data?.data as AuthResult) || {});\n this.cleanup();\n }\n\n /**\n * Handles authentication errors.\n *\n * Processes authentication error messages, creates appropriate error objects,\n * emits error events, triggers the error callback, and performs cleanup.\n *\n * @param data - The authentication error message containing error details\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\n const error = new CivicAuthError(\n data?.detail || \"Error signal received via postMessage\",\n CivicAuthErrorCode.INVALID_MESSAGE,\n );\n\n this.onAuthError(error);\n this.cleanup();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"MessageHandler.js","sourceRoot":"","sources":["../../../../src/vanillajs/auth/handlers/MessageHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAQjD,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAE3E,OAAO,EAAE,YAAY,IAAI,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AAYpE;;;GAGG;AACH,MAAM,OAAO,cAAc;IACjB,MAAM,CAA2B;IACjC,MAAM,GAAG,cAAc,CAAC,iBAAiB,CAAC,CAAC;IAC3C,aAAa,CAAqB;IAClC,aAAa,CAA+B;IAC5C,WAAW,CAAyB;IACpC,cAAc,CAA+B;IAC7C,OAAO,CAAa;IAE5B,+CAA+C;IACvC,oBAAoB,CAAU;IAEtC,YAAY,aAAmC;QAC7C,IAAI,CAAC,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC;QACnC,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC,aAAa,CAAC;QACjD,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC,aAAa,CAAC;QACjD,IAAI,CAAC,WAAW,GAAG,aAAa,CAAC,WAAW,CAAC;QAC7C,IAAI,CAAC,cAAc,GAAG,aAAa,CAAC,cAAc,CAAC;QACnD,IAAI,CAAC,OAAO,GAAG,aAAa,CAAC,OAAO,CAAC;IACvC,CAAC;IAED;;;;;;;;OAQG;IACI,mBAAmB,CAAC,aAAgC;QACzD,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;IACrC,CAAC;IAED;;;;;;;OAOG;IACI,uBAAuB,CAAC,cAAsB;QACnD,IAAI,CAAC,oBAAoB,GAAG,IAAI,GAAG,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC;QAC3D,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,uDAAuD,EAAE;YACxE,oBAAoB,EAAE,IAAI,CAAC,oBAAoB;YAC/C,cAAc;SACf,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACI,yBAAyB;QAC9B,IAAI,CAAC,oBAAoB,GAAG,SAAS,CAAC;QACtC,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,qEAAqE,CACtE,CAAC;IACJ,CAAC;IAED;;;;;;;OAOG;IACI,aAAa,GAAG,CAAC,KAAmB,EAAQ,EAAE;QACnD,wFAAwF;QACxF,MAAM,cAAc,GAClB,IAAI,CAAC,oBAAoB;YACzB,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,MAAM,CAAC;QACjD,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;QAE/C,IAAI,CAAC,IAAI,CAAC,oBAAoB,CAAC,KAAK,EAAE,cAAc,CAAC,EAAE,CAAC;YACtD,OAAO;QACT,CAAC;QAED,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC,CAAC;IAEF;;;;;;;;OAQG;IACK,kBAAkB,CACxB,KAAmB,EACnB,cAAsB;QAEtB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,iCAAiC,EAAE;YACnD,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,cAAc,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM;YAC9B,mBAAmB,EAAE,IAAI,CAAC,aAAa,EAAE,aAAa;YACtD,oBAAoB,EAAE,cAAc;SACrC,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;;OASG;IACK,oBAAoB,CAC1B,KAAmB,EACnB,cAAsB;QAEtB,6CAA6C;QAC7C,MAAM,aAAa,GAAG,KAAK,CAAC,MAAM,KAAK,IAAI,CAAC,aAAa,EAAE,aAAa,CAAC;QAEzE,gCAAgC;QAChC,MAAM,cAAc,GAAG,CAAC,cAAc,CAAC,CAAC;QAExC,qDAAqD;QACrD,IAAI,IAAI,CAAC,aAAa,EAAE,GAAG,EAAE,CAAC;YAC5B,IAAI,CAAC;gBACH,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;gBAClE,cAAc,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;YAC1C,CAAC;YAAC,MAAM,CAAC;gBACP,4BAA4B;YAC9B,CAAC;QACH,CAAC;QAED,uFAAuF;QACvF,4EAA4E;QAC5E,MAAM,YAAY,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;QAC5C,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;YAC3C,cAAc,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACpC,CAAC;QAED,yDAAyD;QACzD,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,cAAc,CAAC,CAAC;QAC5C,IAAI,WAAW,CAAC,QAAQ,KAAK,WAAW,EAAE,CAAC;YACzC,qDAAqD;YACrD,cAAc,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC,CAAC,yBAAyB;YACvE,cAAc,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC,CAAC,mBAAmB;QACnE,CAAC;QAED,MAAM,aAAa,GAAG,cAAc,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAE5D,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,yCAAyC,EAAE;gBAC1D,cAAc,EAAE,KAAK,CAAC,MAAM;gBAC5B,cAAc;gBACd,cAAc;gBACd,SAAS,EAAE,IAAI,CAAC,aAAa,EAAE,GAAG;aACnC,CAAC,CAAC;QACL,CAAC;QAED,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,yCAAyC,EAAE;gBAC1D,gBAAgB,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM;gBAChC,8BAA8B,EAAE,CAAC,CAAC,IAAI,CAAC,aAAa,EAAE,aAAa;gBACnE,SAAS,EAAE,IAAI,CAAC,aAAa,EAAE,GAAG;aACnC,CAAC,CAAC;QACL,CAAC;QAED,OAAO,aAAa,IAAI,aAAa,CAAC;IACxC,CAAC;IAED;;;;;;;OAOG;IACK,kBAAkB,CAAC,KAAmB;QAC5C,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,2DAA2D,EAC3D;YACE,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,SAAS,EAAE,IAAI,CAAC,aAAa,EAAE,GAAG;SACnC,CACF,CAAC;QAEF,MAAM,OAAO,GAAG,KAAK,CAAC,IAAqB,CAAC;QAE5C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,2BAA2B,EAAE;YAC7C,WAAW,EAAE,OAAO,OAAO;YAC3B,OAAO,EAAE,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,MAAM,IAAI,OAAO;YACpE,SAAS,EAAE,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,QAAQ,IAAI,OAAO;YACxE,WAAW,EACT,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE;YACpE,OAAO,EAAE,OAAO;SACjB,CAAC,CAAC;QAEH,gCAAgC;QAChC,IAAI,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC,EAAE,CAAC;YACzC,IAAI,CAAC,0BAA0B,CAAC,OAAO,CAAC,CAAC;YACzC,OAAO;QACT,CAAC;QAED,iCAAiC;QACjC,IAAI,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC,EAAE,CAAC;YACzC,IAAI,CAAC,0BAA0B,CAAC,OAAO,CAAC,CAAC;YACzC,OAAO;QACT,CAAC;QAED,gCAAgC;QAChC,IAAI,CAAC,yBAAyB,CAAC,OAAO,CAAC,CAAC;IAC1C,CAAC;IAED;;;;;;;;OAQG;IACK,sBAAsB,CAAC,OAAgB;QAC7C,OAAO,CACL,OAAO,KAAK,IAAI;YAChB,OAAO,OAAO,KAAK,QAAQ;YAC3B,QAAQ,IAAI,OAAO;YAClB,OAAmC,CAAC,MAAM,KAAK,eAAe,CAChE,CAAC;IACJ,CAAC;IAED;;;;;;;;OAQG;IACK,0BAA0B,CAAC,OAAwB;QACzD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,gCAAgC,EAAE;YACjD,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,IAAI,EAAE,OAAO,CAAC,IAAI;SACnB,CAAC,CAAC;QAEH,uCAAuC;QACvC,IACE,OAAO,CAAC,QAAQ,KAAK,IAAI,CAAC,MAAM,CAAC,QAAQ;YACzC,IAAI,CAAC,MAAM,CAAC,QAAQ,KAAK,SAAS,EAClC,CAAC;YACD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,yCAAyC,EAAE;gBAC1D,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ;aAC/B,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;YACrB,KAAK,YAAY,CAAC;YAClB,KAAK,sBAAsB;gBACzB,IAAI,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC;gBACvC,MAAM;YACR,KAAK,qBAAqB;gBACxB,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;gBACjC,MAAM;YACR,KAAK,0BAA0B;gBAC7B,IAAI,CAAC,8BAA8B,CAAC,OAAO,CAAC,CAAC;gBAC7C,MAAM;YACR,KAAK,QAAQ;gBACX,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,8BAA8B,EAAE;oBAChD,IAAI,EAAE,OAAO,CAAC,IAAI;iBACnB,CAAC,CAAC;gBACH,MAAM;YACR,KAAK,oBAAoB;gBACvB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,0CAA0C,EAAE;oBAC3D,IAAI,EAAE,OAAO,CAAC,IAAI;iBACnB,CAAC,CAAC;gBACH,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC;gBACrC,MAAM;YACR,KAAK,cAAc;gBACjB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,oCAAoC,EAAE;oBACrD,IAAI,EAAE,OAAO,CAAC,IAAI;iBACnB,CAAC,CAAC;gBAEH,gEAAgE;gBAEhE,+DAA+D;gBAC/D,IAAI,CAAC,iBAAiB,CAAC;oBACrB,IAAI,EAAE,cAAc;oBACpB,MAAM,EAAE,2BAA2B;oBACnC,IAAI,EAAE,OAAO,CAAC,IAAI;iBACnB,CAAC,CAAC;gBACH,MAAM;YACR;gBACE,IAAI,CAAC,iCAAiC,CAAC,OAAO,CAAC,CAAC;gBAChD,MAAM;QACV,CAAC;IACH,CAAC;IAED;;;;;;;OAOG;IAEK,sBAAsB,CAAC,OAAwB;QACrD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,0CAA0C,EAAE;YAC3D,IAAI,EAAE,OAAO,CAAC,IAAI;SACnB,CAAC,CAAC;QAEH,MAAM,iBAAiB,GAAG,IAAI,WAAW,CAAC,0BAA0B,EAAE;YACpE,MAAM,EAAE;gBACN,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,IAAI,EAAE,OAAO,CAAC,IAAI;aACnB;SACF,CAAC,CAAC;QACH,MAAM,CAAC,aAAa,CAAC,iBAAiB,CAAC,CAAC;IAC1C,CAAC;IAED;;;;;;;OAOG;IACK,wBAAwB,CAAC,OAAwB;QACvD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,oCAAoC,EAAE;YACtD,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,IAAI,EAAE,OAAO,CAAC,IAAI;SACnB,CAAC,CAAC;QAEH,MAAM,KAAK,GAAG,IAAI,cAAc,CAC9B,oBAAoB,OAAO,CAAC,IAAI,EAAE,EAClC,kBAAkB,CAAC,eAAe,CACnC,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,aAAa,EAAE;YAChD,MAAM,EAAE,KAAK,CAAC,OAAO;YACrB,KAAK,EAAE,OAAO,CAAC,IAAI;SACpB,CAAC,CAAC;QAEH,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QACxB,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;IAED;;;;;OAKG;IACK,8BAA8B,CAAC,OAAwB;QAC7D,MAAM,SAAS,GAAI,OAAO,CAAC,IAA4C;YACrE,EAAE,GAAyB,CAAC;QAC9B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,0CAA0C,EAAE;YAC3D,SAAS;YACT,MAAM,EAAE,IAAI,CAAC,MAAM;SACpB,CAAC,CAAC;QACH,IACE,IAAI,CAAC,MAAM,CAAC,WAAW,KAAK,QAAQ;YACpC,IAAI,CAAC,MAAM,CAAC,iBAAiB,KAAK,OAAO;YACzC,SAAS,EACT,CAAC;YACD,aAAa,CAAC,8BAA8B,CAAC,SAAS,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IACD;;;;;;;;OAQG;IACK,kBAAkB,CAAC,OAAwB;QACjD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,uCAAuC,EAAE;YACxD,IAAI,EAAE,OAAO,CAAC,IAAI;SACnB,CAAC,CAAC;QAEH,MAAM,SAAS,GAAI,OAAO,CAAC,IAA4C;YACrE,EAAE,GAAyB,CAAC;QAC9B,IAAI,SAAS,EAAE,CAAC;YACd,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,oDAAoD,EAAE;gBACrE,SAAS;gBACT,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW;aACrC,CAAC,CAAC;YAEH,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,aAAa,EAAE;gBAChD,MAAM,EAAE,uDAAuD;gBAC/D,KAAK,EAAE;oBACL,IAAI,EAAE,eAAe;oBACrB,SAAS;oBACT,UAAU,EACR,2FAA2F;iBAC9F;aACF,CAAC,CAAC;QACL,CAAC;QAED,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;IACjC,CAAC;IAED;;;;;;;OAOG;IACK,iCAAiC,CAAC,OAAwB;QAChE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,sCAAsC,EAAE;YACxD,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,IAAI,EAAE,OAAO,CAAC,IAAI;SACnB,CAAC,CAAC;QAEH,iEAAiE;QACjE,IAAI,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YACnE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,8CAA8C,EAAE;gBAC/D,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,IAAI,EAAE,OAAO,CAAC,IAAI;aACnB,CAAC,CAAC;YAEH,IAAI,CAAC,iBAAiB,CAAC;gBACrB,IAAI,EAAE,cAAc;gBACpB,MAAM,EAAE,0BAA0B,OAAO,CAAC,IAAI,EAAE;gBAChD,IAAI,EAAE,OAAO,CAAC,IAAI;aACnB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED;;;;;;;;OAQG;IACK,sBAAsB,CAAC,OAAgB;QAC7C,OAAO,CACL,CAAC,OAAO,KAAK,IAAI;YACf,OAAO,OAAO,KAAK,QAAQ;YAC3B,MAAM,IAAI,OAAO;YACjB,CAAE,OAAmC,CAAC,IAAI,KAAK,qBAAqB;gBACjE,OAAmC,CAAC,IAAI;oBACvC,oBAAoB,CAAC,CAAC;YAC5B,CAAC,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC,CACxE,CAAC;IACJ,CAAC;IAED;;;;;;;OAOG;IACK,0BAA0B,CAAC,OAAgB;QACjD,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YAChC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,uCAAuC,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAC1E,CAAC;aAAM,IAAI,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACtE,MAAM,UAAU,GAAG,OAAkC,CAAC;YACtD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,iCAAiC,EAAE;gBACnD,IAAI,EAAE,UAAU,CAAC,IAAI;gBACrB,MAAM,EAAE,UAAU,CAAC,MAAM;aAC1B,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED;;;;;;;OAOG;IACK,yBAAyB,CAAC,OAAgB;QAChD,MAAM,UAAU,GACd,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI;YACxD,CAAC,CAAE,OAAmC;YACtC,CAAC,CAAC,IAAI,CAAC;QACX,MAAM,WAAW,GAAG,UAAU,EAAE,IAAI,CAAC;QAErC,QAAQ,WAAW,EAAE,CAAC;YACpB,KAAK,cAAc;gBACjB,IAAI,CAAC,iBAAiB,CAAC,OAAsB,CAAC,CAAC;gBAC/C,MAAM;YACR,KAAK,YAAY;gBACf,IAAI,CAAC,eAAe,CAAC,OAAsB,CAAC,CAAC;gBAC7C,MAAM;YACR;gBACE,kFAAkF;gBAClF,IAAI,UAAU,EAAE,OAAO,KAAK,8BAA8B,EAAE,CAAC;oBAC3D,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gDAAgD,EAAE;wBAClE,OAAO,EAAE,UAAU,CAAC,OAAO;wBAC3B,eAAe,EAAE,CAAC,CAAC,UAAU,CAAC,YAAY;qBAC3C,CAAC,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,4GAA4G,EAC5G;wBACE,IAAI,EAAE,OAAO;wBACb,WAAW,EAAE,OAAO,OAAO;wBAC3B,OAAO,EAAE,UAAU,EAAE,IAAI,IAAI,MAAM;wBACnC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE;qBACvD,CACF,CAAC;gBACJ,CAAC;QACL,CAAC;IACH,CAAC;IAED;;;;;;;OAOG;IACK,iBAAiB,CAAC,IAAiB;QACzC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,gBAAgB,EAAE;YACnD,MAAM,EAAE,yCAAyC;YACjD,IAAI;SACL,CAAC,CAAC;QACH,IAAI,CAAC,aAAa,CAAE,IAAI,EAAE,IAAmB,IAAI,EAAE,CAAC,CAAC;QACrD,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;IAED;;;;;;;OAOG;IACK,eAAe,CAAC,IAAiB;QACvC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,aAAa,EAAE;YAChD,MAAM,EAAE,uCAAuC;YAC/C,KAAK,EAAE,IAAI;SACZ,CAAC,CAAC;QAEH,MAAM,KAAK,GAAG,IAAI,cAAc,CAC9B,IAAI,EAAE,MAAM,IAAI,uCAAuC,EACvD,kBAAkB,CAAC,eAAe,CACnC,CAAC;QAEF,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QACxB,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;CACF","sourcesContent":["import { AuthEvent } from \"../../types/index.js\";\nimport type { AuthResult } from \"../../types/index.js\";\nimport type {\n IframeMessage,\n AuthMessage,\n LoginAppMessage,\n ProcessedCivicAuthConfig,\n} from \"../types/AuthTypes.js\";\nimport { CivicAuthError, CivicAuthErrorCode } from \"../types/AuthTypes.js\";\nimport type { createLogger } from \"../../utils/logger.js\";\nimport { createLogger as createLoggerFn } from \"../../utils/logger.js\";\nimport { IframeManager } from \"@/vanillajs/iframe/IframeManager.js\";\n\nexport interface MessageHandlerConfig {\n config: ProcessedCivicAuthConfig;\n logger: ReturnType<typeof createLogger>;\n iframeElement?: HTMLIFrameElement;\n onAuthSuccess: (result: AuthResult) => void;\n onAuthError: (error: Error) => void;\n onPopupFailure: (failedUrl?: string) => void;\n cleanup: () => void;\n}\n\n/**\n * MessageHandler - Handles postMessage communication and authentication flow logic\n * Processes messages from iframe, validates origins, and manages auth state transitions\n */\nexport class MessageHandler {\n private config: ProcessedCivicAuthConfig;\n private logger = createLoggerFn(\"message-handler\");\n private iframeElement?: HTMLIFrameElement;\n private onAuthSuccess: (result: AuthResult) => void;\n private onAuthError: (error: Error) => void;\n private onPopupFailure: (failedUrl?: string) => void;\n private cleanup: () => void;\n\n // Backend integration - custom expected origin\n private customExpectedOrigin?: string;\n\n constructor(handlerConfig: MessageHandlerConfig) {\n this.config = handlerConfig.config;\n this.iframeElement = handlerConfig.iframeElement;\n this.onAuthSuccess = handlerConfig.onAuthSuccess;\n this.onAuthError = handlerConfig.onAuthError;\n this.onPopupFailure = handlerConfig.onPopupFailure;\n this.cleanup = handlerConfig.cleanup;\n }\n\n /**\n * Updates the iframe element reference used for message validation.\n *\n * This method allows updating the iframe element after the MessageHandler\n * has been instantiated, which is useful when the iframe is created\n * dynamically after the handler setup.\n *\n * @param iframeElement - The new iframe element to associate with this handler\n */\n public updateIframeElement(iframeElement: HTMLIFrameElement): void {\n this.iframeElement = iframeElement;\n }\n\n /**\n * Sets a custom expected origin for backend integration.\n *\n * This allows the MessageHandler to accept messages from a custom backend\n * origin instead of the default OAuth server origin.\n *\n * @param customLoginUrl - The custom login URL to derive the origin from\n */\n public setCustomExpectedOrigin(customLoginUrl: string): void {\n this.customExpectedOrigin = new URL(customLoginUrl).origin;\n this.logger.info(\"🔗 Custom expected origin set for backend integration\", {\n customExpectedOrigin: this.customExpectedOrigin,\n customLoginUrl,\n });\n }\n\n /**\n * Clears the custom expected origin and returns to OAuth server origin.\n */\n public clearCustomExpectedOrigin(): void {\n this.customExpectedOrigin = undefined;\n this.logger.info(\n \"🔗 Custom expected origin cleared, returning to OAuth server origin\",\n );\n }\n\n /**\n * Main message handler for processing postMessage events.\n *\n * Validates message origin and source, then routes valid messages to\n * appropriate handlers. This is the entry point for all iframe communication.\n *\n * @param event - The MessageEvent received from the iframe or other sources\n */\n public handleMessage = (event: MessageEvent): void => {\n // Use custom origin if set (for backend integration), otherwise use OAuth server origin\n const expectedOrigin =\n this.customExpectedOrigin ||\n 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 /**\n * Logs incoming message details for debugging purposes.\n *\n * Provides comprehensive logging of message properties including origin,\n * source validation, and iframe state for troubleshooting communication issues.\n *\n * @param event - The MessageEvent to log\n * @param expectedOrigin - The expected origin for comparison\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 /**\n * Validates that a message comes from the expected origin and source.\n *\n * Performs security checks to ensure messages are only processed from\n * the configured OAuth server origin and the designated iframe element.\n *\n * @param event - The MessageEvent to validate\n * @param expectedOrigin - The expected origin URL for the message\n * @returns True if the message source and origin are valid, false otherwise\n */\n private isValidMessageSource(\n event: MessageEvent,\n expectedOrigin: string,\n ): boolean {\n // Check if message is from the iframe source\n const isValidSource = event.source === this.iframeElement?.contentWindow;\n\n // Build list of allowed origins\n const allowedOrigins = [expectedOrigin];\n\n // Add the actual iframe origin (to handle redirects)\n if (this.iframeElement?.src) {\n try {\n const actualIframeOrigin = new URL(this.iframeElement.src).origin;\n allowedOrigins.push(actualIframeOrigin);\n } catch {\n // ignore URL parsing errors\n }\n }\n\n // Add the client app's own origin (same-origin) for messages sent after token exchange\n // This is needed when the iframe navigates to the client app's callback URL\n const clientOrigin = window.location.origin;\n if (!allowedOrigins.includes(clientOrigin)) {\n allowedOrigins.push(clientOrigin);\n }\n\n // Add common development login app origins for localhost\n const expectedUrl = new URL(expectedOrigin);\n if (expectedUrl.hostname === \"localhost\") {\n // For localhost, also allow common development ports\n allowedOrigins.push(\"http://localhost:3004\"); // default login-app port\n allowedOrigins.push(\"http://localhost:3001\"); // auth server port\n }\n\n const isValidOrigin = allowedOrigins.includes(event.origin);\n\n if (!isValidOrigin) {\n this.logger.warn(\"Ignored message from unexpected origin.\", {\n receivedOrigin: event.origin,\n expectedOrigin,\n allowedOrigins,\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 /**\n * Processes messages that have passed origin and source validation.\n *\n * Routes validated messages to specific handlers based on message type,\n * including civicloginApp messages, iframe resizer messages, and standard auth messages.\n *\n * @param event - The validated MessageEvent to process\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 IframeMessage;\n\n this.logger.debug(\"Processing iframe message\", {\n messageType: typeof message,\n hasType: message && typeof message === \"object\" && \"type\" in message,\n hasSource: message && typeof message === \"object\" && \"source\" in message,\n messageKeys:\n message && typeof message === \"object\" ? Object.keys(message) : [],\n rawData: message,\n });\n\n // Handle civicloginApp messages\n if (this.isCivicLoginAppMessage(message)) {\n this.handleCivicLoginAppMessage(message);\n return;\n }\n\n // Handle iframe resizer messages\n if (this.isIframeResizerMessage(message)) {\n this.handleIframeResizerMessage(message);\n return;\n }\n\n // Handle standard auth messages\n this.handleStandardAuthMessage(message);\n }\n\n /**\n * Type guard to identify civicloginApp messages.\n *\n * Checks if a message object has the structure and source property\n * that identifies it as coming from the civicloginApp.\n *\n * @param message - The message object to check\n * @returns True if the message is a LoginAppMessage, false otherwise\n */\n private isCivicLoginAppMessage(message: unknown): message is LoginAppMessage {\n return (\n message !== null &&\n typeof message === \"object\" &&\n \"source\" in message &&\n (message as Record<string, unknown>).source === \"civicloginApp\"\n );\n }\n\n /**\n * Handles messages originating from the civicloginApp.\n *\n * Processes various civicloginApp message types including authentication errors,\n * popup failures, design updates, and other app-specific communications.\n * Validates client ID matches before processing.\n *\n * @param message - The validated civicloginApp message to process\n */\n private handleCivicLoginAppMessage(message: LoginAppMessage): void {\n this.logger.info(\"Received civicloginApp message\", {\n type: message.type,\n clientId: message.clientId,\n data: message.data,\n });\n\n // Validate clientId matches our config\n if (\n message.clientId !== this.config.clientId &&\n this.config.loginUrl === undefined\n ) {\n this.logger.warn(\"civicloginApp message clientId mismatch\", {\n received: message.clientId,\n expected: this.config.clientId,\n });\n return;\n }\n\n switch (message.type) {\n case \"auth_error\":\n case \"auth_error_try_again\":\n this.handleCivicLoginAppError(message);\n break;\n case \"generatePopupFailed\":\n this.handlePopupFailure(message);\n break;\n case \"browserCorsFailsSilently\":\n this.handleBrowserCorsFailsSilently(message);\n break;\n case \"design\":\n this.logger.debug(\"civicloginApp design message\", {\n data: message.data,\n });\n break;\n case \"auth_success_early\":\n this.logger.info(\"civicloginApp auth success early message\", {\n data: message.data,\n });\n this.handleAuthSuccessEarly(message);\n break;\n case \"auth_success\":\n this.logger.info(\"civicloginApp auth success message\", {\n data: message.data,\n });\n\n // Dispatch early auth success event for immediate modal closing\n\n // Still handle auth success normally (for callback processing)\n this.handleAuthSuccess({\n type: \"auth_success\",\n detail: \"Authentication successful\",\n data: message.data,\n });\n break;\n default:\n this.handleUnknownCivicLoginAppMessage(message);\n break;\n }\n }\n\n /**\n * Handles auth success early messages from civicloginApp.\n *\n * Processes auth_success_early messages, emits success events,\n * and triggers the success callback with authentication results.\n *\n * @param message - The civicloginApp auth success early message to process\n */\n\n private handleAuthSuccessEarly(message: LoginAppMessage): void {\n this.logger.info(\"civicloginApp auth success early message\", {\n data: message.data,\n });\n\n const earlySuccessEvent = new CustomEvent(\"civic-auth-success-early\", {\n detail: {\n clientId: message.clientId,\n data: message.data,\n },\n });\n window.dispatchEvent(earlySuccessEvent);\n }\n\n /**\n * Handles authentication error messages from civicloginApp.\n *\n * Processes auth_error and auth_error_try_again messages, creates\n * appropriate error objects, emits error events, and triggers cleanup.\n *\n * @param message - The civicloginApp error message to process\n */\n private handleCivicLoginAppError(message: LoginAppMessage): void {\n this.logger.error(\"civicloginApp authentication error\", {\n type: message.type,\n data: message.data,\n });\n\n const error = new CivicAuthError(\n `Login app error: ${message.type}`,\n CivicAuthErrorCode.INVALID_MESSAGE,\n );\n\n this.config.events?.emit(AuthEvent.SIGN_IN_ERROR, {\n detail: error.message,\n error: message.data,\n });\n\n this.onAuthError(error);\n this.cleanup();\n }\n\n /**\n * Handle the case where we know in advance that the browser will not prompt the user to open\n * a popup and will fail silently instead. We want to handle this case gracefully by switching to redirect\n * mode if the iframe is in modal display mode. This will be done when the auth flow actually starts\n * @param message\n */\n private handleBrowserCorsFailsSilently(message: LoginAppMessage): void {\n const failedUrl = (message.data as Record<string, unknown> | undefined)\n ?.url as string | undefined;\n this.logger.warn(\"civicloginApp browser CORS fail silently\", {\n failedUrl,\n config: this.config,\n });\n if (\n this.config.displayMode === \"iframe\" &&\n this.config.iframeDisplayMode === \"modal\" &&\n failedUrl\n ) {\n IframeManager.handleBrowserCorsFailsSilently(failedUrl);\n }\n }\n /**\n * Handles popup generation failure messages from civicloginApp.\n *\n * Processes generatePopupFailed messages, extracts the failed URL,\n * emits appropriate events, and triggers the popup failure callback\n * to enable fallback authentication methods.\n *\n * @param message - The civicloginApp popup failure message to process\n */\n private handlePopupFailure(message: LoginAppMessage): void {\n this.logger.warn(\"civicloginApp popup generation failed\", {\n data: message.data,\n });\n\n const failedUrl = (message.data as Record<string, unknown> | undefined)\n ?.url as string | undefined;\n if (failedUrl) {\n this.logger.info(\"Popup failed for URL, considering fallback options\", {\n failedUrl,\n displayMode: this.config.displayMode,\n });\n\n this.config.events?.emit(AuthEvent.SIGN_IN_ERROR, {\n detail: \"Popup blocked by browser - switching to redirect mode\",\n error: {\n type: \"popup_blocked\",\n failedUrl,\n suggestion:\n \"The browser blocked a popup window. Redirecting to complete authentication in a new page.\",\n },\n });\n }\n\n this.onPopupFailure(failedUrl);\n }\n\n /**\n * Handles unknown or unrecognized civicloginApp message types.\n *\n * Provides fallback handling for unexpected message types, with special\n * logic to detect potential success messages that don't match standard types.\n *\n * @param message - The unrecognized civicloginApp message to process\n */\n private handleUnknownCivicLoginAppMessage(message: LoginAppMessage): void {\n this.logger.debug(\"Unhandled civicloginApp message type\", {\n type: message.type,\n data: message.data,\n });\n\n // Check if this might be a success message with a different type\n if (message.type && message.type.toLowerCase().includes(\"success\")) {\n this.logger.info(\"Potential success message from civicloginApp\", {\n type: message.type,\n data: message.data,\n });\n\n this.handleAuthSuccess({\n type: \"auth_success\",\n detail: `civicloginApp success: ${message.type}`,\n data: message.data,\n });\n }\n }\n\n /**\n * Type guard to identify iframe resizer messages.\n *\n * Checks if a message is related to iframe resizing functionality,\n * including both civic-specific resize messages and iFrameResizerChild messages.\n *\n * @param message - The message object to check\n * @returns True if the message is an iframe resizer message, false otherwise\n */\n private isIframeResizerMessage(message: unknown): boolean {\n return (\n (message !== null &&\n typeof message === \"object\" &&\n \"type\" in message &&\n ((message as Record<string, unknown>).type === \"civic-iframe-resize\" ||\n (message as Record<string, unknown>).type ===\n \"civic-iframe-ready\")) ||\n (typeof message === \"string\" && message.includes(\"iFrameResizerChild\"))\n );\n }\n\n /**\n * Handles iframe resizer messages for dynamic iframe sizing.\n *\n * Processes messages related to iframe resizing, including height adjustments\n * and ready state notifications from the iframe resizer library.\n *\n * @param message - The iframe resizer message to process\n */\n private handleIframeResizerMessage(message: unknown): void {\n if (typeof message === \"string\") {\n this.logger.debug(\"Received iframe resizer child message\", { message });\n } else if (message && typeof message === \"object\" && message !== null) {\n const messageObj = message as Record<string, unknown>;\n this.logger.debug(\"Received iframe resizer message\", {\n type: messageObj.type,\n height: messageObj.height,\n });\n }\n }\n\n /**\n * Handles standard authentication messages.\n *\n * Processes auth_success and auth_error messages that follow the standard\n * authentication message format, routing them to appropriate success or error handlers.\n *\n * @param message - The standard auth message to process\n */\n private handleStandardAuthMessage(message: unknown): void {\n const messageObj =\n message && typeof message === \"object\" && message !== null\n ? (message as Record<string, unknown>)\n : null;\n const messageType = messageObj?.type;\n\n switch (messageType) {\n case \"auth_success\":\n this.handleAuthSuccess(message as AuthMessage);\n break;\n case \"auth_error\":\n this.handleAuthError(message as AuthMessage);\n break;\n default:\n // Check if this is a calculateSubFramePositioning message (expected and harmless)\n if (messageObj?.command === \"calculateSubFramePositioning\") {\n this.logger.debug(\"Received iframe positioning message (expected)\", {\n command: messageObj.command,\n hasSubFrameData: !!messageObj.subFrameData,\n });\n } else {\n this.logger.debug(\n \"Message from iframe did not match expected types (auth_success, auth_error, civicloginApp, iframe-resizer)\",\n {\n data: message,\n messageType: typeof message,\n hasType: messageObj?.type ?? \"none\",\n messageKeys: messageObj ? Object.keys(messageObj) : [],\n },\n );\n }\n }\n }\n\n /**\n * Handles successful authentication completion.\n *\n * Processes authentication success messages, emits success events,\n * triggers the success callback with authentication results, and performs cleanup.\n *\n * @param data - The authentication success message containing result data\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.onAuthSuccess((data?.data as AuthResult) || {});\n this.cleanup();\n }\n\n /**\n * Handles authentication errors.\n *\n * Processes authentication error messages, creates appropriate error objects,\n * emits error events, triggers the error callback, and performs cleanup.\n *\n * @param data - The authentication error message containing error details\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\n const error = new CivicAuthError(\n data?.detail || \"Error signal received via postMessage\",\n CivicAuthErrorCode.INVALID_MESSAGE,\n );\n\n this.onAuthError(error);\n this.cleanup();\n }\n}\n"]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { AuthenticationEvents } from "../AuthenticationEvents.js";
|
|
2
2
|
import type { DisplayMode as BaseDisplayMode, AuthStorage, FrameworkType } from "../../../types.js";
|
|
3
|
+
import type { BackendEndpoints } from "../../../server/config.js";
|
|
3
4
|
/**
|
|
4
5
|
* Extended DisplayMode for VanillaJS that includes "embedded" option
|
|
5
6
|
* This provides a cleaner API where users can simply use displayMode: "embedded"
|
|
@@ -16,6 +17,7 @@ export declare enum CivicAuthErrorCode {
|
|
|
16
17
|
CONTAINER_NOT_FOUND = "CONTAINER_NOT_FOUND",
|
|
17
18
|
AUTH_PROCESS_TIMEOUT = "AUTH_PROCESS_TIMEOUT",
|
|
18
19
|
IFRAME_LOAD_ERROR = "IFRAME_LOAD_ERROR",
|
|
20
|
+
IFRAME_PRELOAD_FAILED = "IFRAME_PRELOAD_FAILED",
|
|
19
21
|
INVALID_MESSAGE = "INVALID_MESSAGE",
|
|
20
22
|
LOGOUT_FAILED = "LOGOUT_FAILED",
|
|
21
23
|
POPUP_BLOCKED = "popup_blocked",
|
|
@@ -109,8 +111,20 @@ export interface CivicAuthClientConfig {
|
|
|
109
111
|
initialState?: string;
|
|
110
112
|
/** Logging configuration */
|
|
111
113
|
logging?: LoggingConfig;
|
|
114
|
+
/**
|
|
115
|
+
* Custom login URL for backend integration (e.g., "http://example.com/custom-backendurl")
|
|
116
|
+
* When provided, automatically uses BrowserCookieStorage for session sharing with backend
|
|
117
|
+
*/
|
|
118
|
+
loginUrl?: string;
|
|
119
|
+
/**
|
|
120
|
+
* Custom backend endpoints configuration for backend integration
|
|
121
|
+
* Only used when loginUrl is provided. Allows overriding default endpoints.
|
|
122
|
+
*/
|
|
123
|
+
backendEndpoints?: BackendEndpoints;
|
|
112
124
|
/** Framework being used (for analytics) - internal use only */
|
|
113
125
|
framework?: FrameworkType;
|
|
126
|
+
/** Whether to automatically preload the iframe for instant sign-in (defaults to true) */
|
|
127
|
+
preloadIframe?: boolean;
|
|
114
128
|
}
|
|
115
129
|
export interface LoggingConfig {
|
|
116
130
|
enabled: boolean;
|
|
@@ -136,5 +150,8 @@ export type ProcessedCivicAuthConfig = CivicAuthClientConfig & {
|
|
|
136
150
|
iframeId: string;
|
|
137
151
|
prompt: string;
|
|
138
152
|
nonce?: string;
|
|
153
|
+
loginUrl?: string;
|
|
154
|
+
backendEndpoints?: BackendEndpoints;
|
|
155
|
+
preloadIframe: boolean;
|
|
139
156
|
};
|
|
140
157
|
//# sourceMappingURL=AuthTypes.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthTypes.d.ts","sourceRoot":"","sources":["../../../../src/vanillajs/auth/types/AuthTypes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,KAAK,EACV,WAAW,IAAI,eAAe,EAC9B,WAAW,EACX,aAAa,EACd,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"AuthTypes.d.ts","sourceRoot":"","sources":["../../../../src/vanillajs/auth/types/AuthTypes.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,6 +9,7 @@ export var CivicAuthErrorCode;
|
|
|
9
9
|
CivicAuthErrorCode["CONTAINER_NOT_FOUND"] = "CONTAINER_NOT_FOUND";
|
|
10
10
|
CivicAuthErrorCode["AUTH_PROCESS_TIMEOUT"] = "AUTH_PROCESS_TIMEOUT";
|
|
11
11
|
CivicAuthErrorCode["IFRAME_LOAD_ERROR"] = "IFRAME_LOAD_ERROR";
|
|
12
|
+
CivicAuthErrorCode["IFRAME_PRELOAD_FAILED"] = "IFRAME_PRELOAD_FAILED";
|
|
12
13
|
CivicAuthErrorCode["INVALID_MESSAGE"] = "INVALID_MESSAGE";
|
|
13
14
|
CivicAuthErrorCode["LOGOUT_FAILED"] = "LOGOUT_FAILED";
|
|
14
15
|
CivicAuthErrorCode["POPUP_BLOCKED"] = "popup_blocked";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthTypes.js","sourceRoot":"","sources":["../../../../src/vanillajs/auth/types/AuthTypes.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AuthTypes.js","sourceRoot":"","sources":["../../../../src/vanillajs/auth/types/AuthTypes.ts"],"names":[],"mappings":"AAeA;;GAEG;AACH,MAAM,CAAN,IAAY,kBAkBX;AAlBD,WAAY,kBAAkB;IAC5B,yDAAmC,CAAA;IACnC,iDAA2B,CAAA;IAC3B,6EAAuD,CAAA;IACvD,iEAA2C,CAAA;IAC3C,mEAA6C,CAAA;IAC7C,6DAAuC,CAAA;IACvC,qEAA+C,CAAA;IAC/C,yDAAmC,CAAA;IACnC,qDAA+B,CAAA;IAC/B,qDAA+B,CAAA;IAC/B,uDAAiC,CAAA;IACjC,iEAA2C,CAAA;IAC3C,mEAA6C,CAAA;IAC7C,6DAAuC,CAAA;IACvC,qDAA+B,CAAA;IAC/B,2DAAqC,CAAA;IACrC,uDAAiC,CAAA;AACnC,CAAC,EAlBW,kBAAkB,KAAlB,kBAAkB,QAkB7B;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,iBAAiB,EAAE,mBAAmB;IACtC,4BAA4B,EAAE,KAAK,EAAE,aAAa;IAClD,iBAAiB,EAAE,2BAA2B;IAC9C,eAAe,EAAE,yBAAyB;CAClC,CAAC;AAgCX,MAAM,OAAO,cAAe,SAAQ,KAAK;IAGrB;IAFlB,YACE,OAAe,EACC,IAAwB;QAExC,KAAK,CAAC,OAAO,CAAC,CAAC;QAFC,SAAI,GAAJ,IAAI,CAAoB;QAGxC,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF","sourcesContent":["import type { AuthenticationEvents } from \"../AuthenticationEvents.js\";\nimport type {\n DisplayMode as BaseDisplayMode,\n AuthStorage,\n FrameworkType,\n} from \"../../../types.js\";\nimport type { BackendEndpoints } from \"../../../server/config.js\";\n\n/**\n * Extended DisplayMode for VanillaJS that includes \"embedded\" option\n * This provides a cleaner API where users can simply use displayMode: \"embedded\"\n * instead of displayMode: \"iframe\" + iframeDisplayMode: \"embedded\"\n */\nexport type VanillaJSDisplayMode = BaseDisplayMode | \"embedded\";\n\n/**\n * Error codes for CivicAuth errors\n */\nexport enum CivicAuthErrorCode {\n CONFIG_REQUIRED = \"CONFIG_REQUIRED\",\n INIT_FAILED = \"INIT_FAILED\",\n ENDPOINTS_NOT_INITIALIZED = \"ENDPOINTS_NOT_INITIALIZED\",\n CONTAINER_NOT_FOUND = \"CONTAINER_NOT_FOUND\",\n AUTH_PROCESS_TIMEOUT = \"AUTH_PROCESS_TIMEOUT\",\n IFRAME_LOAD_ERROR = \"IFRAME_LOAD_ERROR\",\n IFRAME_PRELOAD_FAILED = \"IFRAME_PRELOAD_FAILED\",\n INVALID_MESSAGE = \"INVALID_MESSAGE\",\n LOGOUT_FAILED = \"LOGOUT_FAILED\",\n POPUP_BLOCKED = \"popup_blocked\",\n USER_CANCELLED = \"user_cancelled\",\n CONFIGURATION_ERROR = \"configuration_error\",\n TOKEN_REFRESH_FAILED = \"token_refresh_failed\",\n SESSION_NOT_FOUND = \"session_not_found\",\n STORAGE_ERROR = \"storage_error\",\n IFRAME_NOT_FOUND = \"iframe_not_found\",\n INTERNAL_ERROR = \"internal_error\",\n}\n\n/**\n * Constants for the auth client\n */\nexport const CIVIC_AUTH_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 */\nexport type AuthMessageType = \"auth_success\" | \"auth_error\";\n\nexport interface AuthMessage {\n type: AuthMessageType;\n detail?: string;\n data?: unknown;\n error?: unknown;\n}\n\n/**\n * Login app message types for postMessage communication\n */\nexport interface LoginAppMessage {\n source: \"civicloginApp\";\n type: \"design\" | \"generatePopupFailed\" | \"auth_success\" | string;\n clientId: string;\n data?: unknown;\n}\n\n/**\n * Combined message type for all iframe communications\n */\nexport type IframeMessage =\n | AuthMessage\n | LoginAppMessage\n | Record<string, unknown>;\n\nexport class CivicAuthError extends Error {\n constructor(\n message: string,\n public readonly code: CivicAuthErrorCode,\n ) {\n super(message);\n this.name = \"CivicAuthError\";\n }\n}\n\n/**\n * Configuration options for the CivicAuth client\n */\nexport interface CivicAuthClientConfig {\n /** OAuth client ID */\n clientId: string;\n /** URL to redirect to after authentication */\n redirectUrl?: string;\n /** URL to redirect to after logout - if not provided, will use redirectUrl */\n logoutRedirectUrl?: string;\n /** Base URL of the OAuth server */\n oauthServerBaseUrl?: string;\n /** Array of OAuth scopes to request */\n scopes?: string[];\n /** HTML element or element ID where the auth iframe will be mounted (required for embedded iframe mode) */\n targetContainerElement?: HTMLElement | string;\n /** Text signals for success and error states */\n textSignals?: {\n /** Text to display on successful authentication */\n success: string;\n /** Optional text to display on authentication error */\n error?: string;\n };\n /** Display mode for the authentication UI - VanillaJS supports \"embedded\" for simplified API */\n displayMode?: VanillaJSDisplayMode;\n /** Display mode for iframe rendering - modal (full-screen overlay) or embedded (within container) */\n iframeDisplayMode?: \"modal\" | \"embedded\";\n /**\n * Timeout duration in milliseconds for the entire authentication process.\n * If the authentication process takes longer than this duration, it will be cancelled\n * and an error will be thrown.\n * Note: This timeout is not applied to embedded iframe mode, where the iframe remains persistent.\n */\n authProcessTimeout?: number;\n /** Event handlers for authentication events */\n events?: AuthenticationEvents;\n /** Custom ID for the auth iframe */\n iframeId?: string;\n /** Custom storage adapter for auth state - uses shared AuthStorage interface */\n storageAdapter?: AuthStorage;\n /** OAuth nonce parameter for security */\n nonce?: string;\n /** Initial state for OAuth flow */\n initialState?: string;\n /** Logging configuration */\n logging?: LoggingConfig;\n /**\n * Custom login URL for backend integration (e.g., \"http://example.com/custom-backendurl\")\n * When provided, automatically uses BrowserCookieStorage for session sharing with backend\n */\n loginUrl?: string;\n /**\n * Custom backend endpoints configuration for backend integration\n * Only used when loginUrl is provided. Allows overriding default endpoints.\n */\n backendEndpoints?: BackendEndpoints;\n /** Framework being used (for analytics) - internal use only */\n framework?: FrameworkType;\n /** Whether to automatically preload the iframe for instant sign-in (defaults to true) */\n preloadIframe?: boolean;\n}\n\nexport interface LoggingConfig {\n enabled: boolean;\n namespace?: string;\n level?: \"debug\" | \"info\" | \"warn\" | \"error\";\n}\n\n/**\n * Internal configuration with all optional properties resolved to required ones.\n */\nexport type ProcessedCivicAuthConfig = CivicAuthClientConfig & {\n redirectUrl: string;\n logoutRedirectUrl: string;\n oauthServerBaseUrl: string;\n scopes: string[];\n textSignals: {\n success: string;\n error?: string;\n };\n storageAdapter: AuthStorage;\n logging: LoggingConfig;\n displayMode: BaseDisplayMode; // Internal config uses base DisplayMode after processing\n authProcessTimeout: number;\n iframeId: string;\n prompt: string;\n nonce?: string;\n loginUrl?: string;\n backendEndpoints?: BackendEndpoints;\n preloadIframe: boolean;\n // targetContainerElement remains optional as it's not needed for all display modes\n};\n"]}
|
|
@@ -35,6 +35,10 @@ export declare class IframeManager {
|
|
|
35
35
|
private logger;
|
|
36
36
|
private contentWrapper;
|
|
37
37
|
private iframeWrapper;
|
|
38
|
+
private isPreloaded;
|
|
39
|
+
private preloadUrl;
|
|
40
|
+
static browserCorsFailsSilentlyUrl: string | null;
|
|
41
|
+
static handleBrowserCorsFailsSilently(url: string): void;
|
|
38
42
|
constructor(config: IframeConfig);
|
|
39
43
|
private initializeContainer;
|
|
40
44
|
/**
|
|
@@ -43,6 +47,11 @@ export declare class IframeManager {
|
|
|
43
47
|
*/
|
|
44
48
|
private applyModalStyles;
|
|
45
49
|
private setupKeyboardHandlers;
|
|
50
|
+
/**
|
|
51
|
+
* Preloads an iframe in the background for instant display later
|
|
52
|
+
* The iframe is created but kept completely hidden and non-interactable
|
|
53
|
+
*/
|
|
54
|
+
preloadIframe(url: string): HTMLIFrameElement;
|
|
46
55
|
createIframe(url: string): HTMLIFrameElement;
|
|
47
56
|
/**
|
|
48
57
|
* Applies base styles to the iframe element
|
|
@@ -64,10 +73,24 @@ export declare class IframeManager {
|
|
|
64
73
|
* Sets up the iframe onload handler with CSS injection
|
|
65
74
|
*/
|
|
66
75
|
private setupIframeOnloadHandler;
|
|
76
|
+
/**
|
|
77
|
+
* Sets up the iframe for modal display mode during preload
|
|
78
|
+
* Creates the structure but keeps everything hidden
|
|
79
|
+
*/
|
|
80
|
+
private setupModalIframeForPreload;
|
|
81
|
+
/**
|
|
82
|
+
* Sets up the iframe for embedded display mode during preload
|
|
83
|
+
* Creates the structure but keeps everything hidden
|
|
84
|
+
*/
|
|
85
|
+
private setupEmbeddedIframeForPreload;
|
|
67
86
|
/**
|
|
68
87
|
* Sets up the iframe for modal display mode
|
|
69
88
|
*/
|
|
70
89
|
private setupModalIframe;
|
|
90
|
+
/**
|
|
91
|
+
* Sets up modal-specific behaviors like click handlers and close button
|
|
92
|
+
*/
|
|
93
|
+
private setupModalBehaviors;
|
|
71
94
|
/**
|
|
72
95
|
* Sets up the iframe for embedded display mode
|
|
73
96
|
*/
|
|
@@ -111,6 +134,19 @@ export declare class IframeManager {
|
|
|
111
134
|
* Removes visual styling (borders) from iframe wrapper
|
|
112
135
|
*/
|
|
113
136
|
private removeIframeWrapperStyling;
|
|
137
|
+
/**
|
|
138
|
+
* Check if an iframe is currently preloaded
|
|
139
|
+
*/
|
|
140
|
+
isIframePreloaded(): boolean;
|
|
141
|
+
/**
|
|
142
|
+
* Get the URL of the preloaded iframe
|
|
143
|
+
*/
|
|
144
|
+
getPreloadedUrl(): string | null;
|
|
145
|
+
/**
|
|
146
|
+
* Update the onClose handler for the iframe manager
|
|
147
|
+
* This is useful when transitioning from preload to active authentication
|
|
148
|
+
*/
|
|
149
|
+
updateOnCloseHandler(onClose: () => void): void;
|
|
114
150
|
showSubtlePopupFallbackIndicator(): void;
|
|
115
151
|
}
|
|
116
152
|
//# sourceMappingURL=IframeManager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IframeManager.d.ts","sourceRoot":"","sources":["../../../src/vanillajs/iframe/IframeManager.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,WAAW,CAAC;IACvB,WAAW,EAAE,UAAU,GAAG,OAAO,CAAC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAED;;;GAGG;AACH,qBAAa,aAAa;IAExB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAU;IAC/C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAW;IAC9C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,oBAAoB,CAA2B;IACvE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAe;IAC1D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAU;IAC/C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAW;IACtD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAU;IAClD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAW;IACtD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAO;IAEjD,OAAO,CAAC,MAAM,CAAkC;IAChD,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,OAAO,CAAmC;IAClD,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,cAAc,CAAC,CAAiC;IACxD,OAAO,CAAC,YAAY,CAAC,CAA8B;IACnD,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,OAAO,CAAC,CAAa;IAC7B,OAAO,CAAC,aAAa,CAA4B;IACjD,OAAO,CAAC,WAAW,CAAkC;IACrD,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,0BAA0B,CAAC,CAAgC;IACnE,OAAO,CAAC,MAAM,CAAkC;IAEhD,OAAO,CAAC,cAAc,CAA4B;IAClD,OAAO,CAAC,aAAa,CAA4B;
|
|
1
|
+
{"version":3,"file":"IframeManager.d.ts","sourceRoot":"","sources":["../../../src/vanillajs/iframe/IframeManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -32,6 +32,14 @@ export class IframeManager {
|
|
|
32
32
|
// Store references to wrapper elements for styling control
|
|
33
33
|
contentWrapper = null;
|
|
34
34
|
iframeWrapper = null;
|
|
35
|
+
// Preloading support
|
|
36
|
+
isPreloaded = false;
|
|
37
|
+
preloadUrl = null;
|
|
38
|
+
static browserCorsFailsSilentlyUrl = null;
|
|
39
|
+
static handleBrowserCorsFailsSilently(url) {
|
|
40
|
+
// Store the URL that caused CORS failure for later reference
|
|
41
|
+
IframeManager.browserCorsFailsSilentlyUrl = url;
|
|
42
|
+
}
|
|
35
43
|
constructor(config) {
|
|
36
44
|
this.container = config.container;
|
|
37
45
|
this.displayMode = config.displayMode;
|
|
@@ -95,7 +103,101 @@ export class IframeManager {
|
|
|
95
103
|
window.addEventListener("keydown", this.keydownHandler);
|
|
96
104
|
}
|
|
97
105
|
}
|
|
106
|
+
/**
|
|
107
|
+
* Preloads an iframe in the background for instant display later
|
|
108
|
+
* The iframe is created but kept completely hidden and non-interactable
|
|
109
|
+
*/
|
|
110
|
+
preloadIframe(url) {
|
|
111
|
+
this.logger.debug("Preloading iframe in background", { url });
|
|
112
|
+
// Clean up any existing iframe content, but preserve container styles for modal mode
|
|
113
|
+
this.cleanupIframeOnly();
|
|
114
|
+
// Create new iframe for preloading
|
|
115
|
+
this.iframe = document.createElement("iframe");
|
|
116
|
+
this.iframe.id = this.iframeId;
|
|
117
|
+
this.iframe.src = url;
|
|
118
|
+
this.iframe.setAttribute("data-testid", "civic-auth-iframe-with-resizer");
|
|
119
|
+
// Apply base iframe styles but keep it completely hidden for preloading
|
|
120
|
+
this.applyIframeStyles();
|
|
121
|
+
// Make iframe completely invisible and non-interactable during preload
|
|
122
|
+
this.iframe.style.display = "none";
|
|
123
|
+
this.iframe.style.visibility = "hidden";
|
|
124
|
+
this.iframe.style.pointerEvents = "none";
|
|
125
|
+
this.iframe.style.position = "absolute";
|
|
126
|
+
this.iframe.style.left = "-9999px";
|
|
127
|
+
this.iframe.style.top = "-9999px";
|
|
128
|
+
// Add attributes that prevent scrollbars
|
|
129
|
+
this.setIframeAttributes();
|
|
130
|
+
// Add CSS to prevent scrollbars
|
|
131
|
+
this.addScrollbarHidingStyles();
|
|
132
|
+
// Set up message listener for iframe ready events (more reliable than onload)
|
|
133
|
+
this.setupIframeMessageListener();
|
|
134
|
+
// Set up iframe onload handler
|
|
135
|
+
this.setupIframeOnloadHandler();
|
|
136
|
+
// For preloading, we need to add the iframe to the DOM but keep it hidden
|
|
137
|
+
// Create a minimal container structure without showing it
|
|
138
|
+
if (this.displayMode === "modal") {
|
|
139
|
+
this.setupModalIframeForPreload();
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
this.setupEmbeddedIframeForPreload();
|
|
143
|
+
}
|
|
144
|
+
// Initialize resizer - this will handle all the message-based resizing
|
|
145
|
+
this.resizer = new CivicIframeResizer(this.iframe, this.container);
|
|
146
|
+
// Mark as preloaded
|
|
147
|
+
this.isPreloaded = true;
|
|
148
|
+
this.preloadUrl = url;
|
|
149
|
+
// Keep the container hidden during preload
|
|
150
|
+
this.hide();
|
|
151
|
+
this.logger.debug("Iframe preloaded successfully", { url });
|
|
152
|
+
return this.iframe;
|
|
153
|
+
}
|
|
98
154
|
createIframe(url) {
|
|
155
|
+
// If we have a preloaded iframe, show it instantly (even if URL differs)
|
|
156
|
+
// URLs may differ due to fresh PKCE challenges and other dynamic parameters
|
|
157
|
+
if (this.isPreloaded && this.iframe) {
|
|
158
|
+
this.logger.debug("Using preloaded iframe for instant display", {
|
|
159
|
+
preloadedUrl: this.preloadUrl,
|
|
160
|
+
requestedUrl: url,
|
|
161
|
+
urlsMatch: this.preloadUrl === url,
|
|
162
|
+
});
|
|
163
|
+
// Don't change iframe.src for preloaded iframes - use them as-is to avoid reload
|
|
164
|
+
// The preloaded authentication flow will work perfectly without URL changes
|
|
165
|
+
this.logger.debug("Using preloaded iframe without reload", {
|
|
166
|
+
preloadedUrl: this.preloadUrl,
|
|
167
|
+
requestedUrl: url,
|
|
168
|
+
action: "skipping_url_change_to_prevent_reload",
|
|
169
|
+
});
|
|
170
|
+
// Make the preloaded iframe visible and interactable
|
|
171
|
+
this.iframe.style.display = "block";
|
|
172
|
+
this.iframe.style.visibility = "visible";
|
|
173
|
+
this.iframe.style.pointerEvents = "auto";
|
|
174
|
+
this.iframe.style.position = "relative";
|
|
175
|
+
this.iframe.style.left = "0";
|
|
176
|
+
this.iframe.style.top = "0";
|
|
177
|
+
// Show the wrappers that were hidden during preload
|
|
178
|
+
if (this.displayMode === "modal") {
|
|
179
|
+
if (this.contentWrapper) {
|
|
180
|
+
this.contentWrapper.style.display = "block";
|
|
181
|
+
// Apply modal visual styling that was skipped during preload
|
|
182
|
+
this.applyModalVisualStyling();
|
|
183
|
+
// Set up modal behaviors (backdrop click, etc.)
|
|
184
|
+
this.setupModalBehaviors();
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
if (this.iframeWrapper) {
|
|
189
|
+
this.iframeWrapper.style.display = "block";
|
|
190
|
+
// Apply wrapper styling that was skipped during preload
|
|
191
|
+
this.applyIframeWrapperStyling();
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
// Show the container
|
|
195
|
+
this.show();
|
|
196
|
+
// Reset preload state since we're now showing the iframe
|
|
197
|
+
this.isPreloaded = false;
|
|
198
|
+
this.preloadUrl = null;
|
|
199
|
+
return this.iframe;
|
|
200
|
+
}
|
|
99
201
|
// Clean up any existing iframe content, but preserve container styles for modal mode
|
|
100
202
|
this.cleanupIframeOnly();
|
|
101
203
|
// Create new iframe
|
|
@@ -254,6 +356,56 @@ export class IframeManager {
|
|
|
254
356
|
}
|
|
255
357
|
};
|
|
256
358
|
}
|
|
359
|
+
/**
|
|
360
|
+
* Sets up the iframe for modal display mode during preload
|
|
361
|
+
* Creates the structure but keeps everything hidden
|
|
362
|
+
*/
|
|
363
|
+
setupModalIframeForPreload() {
|
|
364
|
+
if (!this.iframe)
|
|
365
|
+
return;
|
|
366
|
+
// Create content wrapper for modal but keep it hidden
|
|
367
|
+
this.contentWrapper = document.createElement("div");
|
|
368
|
+
this.contentWrapper.style.position = "relative";
|
|
369
|
+
this.contentWrapper.style.overflow = "hidden";
|
|
370
|
+
this.contentWrapper.style.width = IframeManager.MODAL_WIDTH;
|
|
371
|
+
this.contentWrapper.style.display = "none"; // Keep hidden during preload
|
|
372
|
+
// Create inner iframe wrapper
|
|
373
|
+
this.iframeWrapper = document.createElement("div");
|
|
374
|
+
this.iframeWrapper.style.position = "relative";
|
|
375
|
+
this.iframeWrapper.style.overflow = "hidden";
|
|
376
|
+
this.iframeWrapper.style.overflowX = "hidden";
|
|
377
|
+
this.iframeWrapper.style.overflowY = "hidden";
|
|
378
|
+
this.iframeWrapper.style.transition = `all ${IframeManager.TRANSITION_DURATION} ease`;
|
|
379
|
+
this.iframeWrapper.style.width = "100%";
|
|
380
|
+
this.iframeWrapper.style.height = "auto";
|
|
381
|
+
this.iframeWrapper.style.minHeight = IframeManager.MODAL_MIN_HEIGHT;
|
|
382
|
+
// Add iframe to wrapper, then wrapper to content, then content to container
|
|
383
|
+
this.iframeWrapper.appendChild(this.iframe);
|
|
384
|
+
this.contentWrapper.appendChild(this.iframeWrapper);
|
|
385
|
+
this.container.appendChild(this.contentWrapper);
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Sets up the iframe for embedded display mode during preload
|
|
389
|
+
* Creates the structure but keeps everything hidden
|
|
390
|
+
*/
|
|
391
|
+
setupEmbeddedIframeForPreload() {
|
|
392
|
+
if (!this.iframe)
|
|
393
|
+
return;
|
|
394
|
+
// Create wrapper but keep it hidden
|
|
395
|
+
this.iframeWrapper = document.createElement("div");
|
|
396
|
+
this.iframeWrapper.style.position = "relative";
|
|
397
|
+
this.iframeWrapper.style.overflow = "hidden";
|
|
398
|
+
this.iframeWrapper.style.overflowX = "hidden";
|
|
399
|
+
this.iframeWrapper.style.overflowY = "hidden";
|
|
400
|
+
this.iframeWrapper.style.transition = "all 0.5s ease-in-out";
|
|
401
|
+
this.iframeWrapper.style.width = "100%";
|
|
402
|
+
this.iframeWrapper.style.height = "auto";
|
|
403
|
+
this.iframeWrapper.style.minHeight = IframeManager.EMBEDDED_MIN_HEIGHT;
|
|
404
|
+
this.iframeWrapper.style.display = "none"; // Keep hidden during preload
|
|
405
|
+
// Add iframe to wrapper, then wrapper to container
|
|
406
|
+
this.iframeWrapper.appendChild(this.iframe);
|
|
407
|
+
this.container.appendChild(this.iframeWrapper);
|
|
408
|
+
}
|
|
257
409
|
/**
|
|
258
410
|
* Sets up the iframe for modal display mode
|
|
259
411
|
*/
|
|
@@ -269,10 +421,6 @@ export class IframeManager {
|
|
|
269
421
|
this.contentWrapper.style.width = IframeManager.MODAL_WIDTH; // 320px like React version
|
|
270
422
|
// Apply initial visual styling
|
|
271
423
|
this.applyModalVisualStyling();
|
|
272
|
-
// Stop propagation on content wrapper to prevent backdrop clicks
|
|
273
|
-
this.contentWrapper.addEventListener("click", (e) => {
|
|
274
|
-
e.stopPropagation();
|
|
275
|
-
});
|
|
276
424
|
// Create inner iframe wrapper to match React structure
|
|
277
425
|
this.iframeWrapper = document.createElement("div");
|
|
278
426
|
this.iframeWrapper.style.position = "relative";
|
|
@@ -287,25 +435,39 @@ export class IframeManager {
|
|
|
287
435
|
this.applyIframeWrapperStyling();
|
|
288
436
|
// Add shimmer loader for modal mode
|
|
289
437
|
this.showShimmerLoader(this.iframeWrapper, "white");
|
|
290
|
-
// Add close button for modal mode (initially hidden)
|
|
291
|
-
if (this.onClose) {
|
|
292
|
-
this.closeButton = createCloseButton(this.onClose);
|
|
293
|
-
// Initially hide close button - it will be shown when content loads
|
|
294
|
-
this.closeButton.style.opacity = "0";
|
|
295
|
-
this.contentWrapper.appendChild(this.closeButton);
|
|
296
|
-
}
|
|
297
438
|
// Add iframe to wrapper, then wrapper to content, then content to container
|
|
298
439
|
this.iframeWrapper.appendChild(this.iframe);
|
|
299
440
|
this.contentWrapper.appendChild(this.iframeWrapper);
|
|
300
441
|
this.container.appendChild(this.contentWrapper);
|
|
442
|
+
this.setupModalBehaviors();
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* Sets up modal-specific behaviors like click handlers and close button
|
|
446
|
+
*/
|
|
447
|
+
setupModalBehaviors() {
|
|
448
|
+
if (!this.contentWrapper)
|
|
449
|
+
return;
|
|
450
|
+
// Stop propagation on content wrapper to prevent backdrop clicks
|
|
451
|
+
this.contentWrapper.addEventListener("click", (e) => {
|
|
452
|
+
e.stopPropagation();
|
|
453
|
+
});
|
|
454
|
+
// Add close button for modal mode (initially hidden if not loaded)
|
|
455
|
+
if (this.onClose && !this.closeButton) {
|
|
456
|
+
this.closeButton = createCloseButton(this.onClose);
|
|
457
|
+
// Show close button immediately if iframe is already loaded, otherwise keep hidden
|
|
458
|
+
this.closeButton.style.opacity = this.isIframeLoaded ? "1" : "0";
|
|
459
|
+
this.contentWrapper.appendChild(this.closeButton);
|
|
460
|
+
}
|
|
301
461
|
// Add click-to-close functionality after content is added
|
|
302
|
-
this.clickHandler
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
462
|
+
if (!this.clickHandler) {
|
|
463
|
+
this.clickHandler = (e) => {
|
|
464
|
+
if (e.target === this.container) {
|
|
465
|
+
// Only close if clicking the backdrop, not the iframe content
|
|
466
|
+
this.onClose?.();
|
|
467
|
+
}
|
|
468
|
+
};
|
|
469
|
+
this.container.addEventListener("click", this.clickHandler);
|
|
470
|
+
}
|
|
309
471
|
}
|
|
310
472
|
/**
|
|
311
473
|
* Sets up the iframe for embedded display mode
|
|
@@ -434,6 +596,9 @@ export class IframeManager {
|
|
|
434
596
|
}
|
|
435
597
|
// Reset loading state
|
|
436
598
|
this.isIframeLoaded = false;
|
|
599
|
+
// Reset preload state
|
|
600
|
+
this.isPreloaded = false;
|
|
601
|
+
this.preloadUrl = null;
|
|
437
602
|
// Clear wrapper references
|
|
438
603
|
this.contentWrapper = null;
|
|
439
604
|
this.iframeWrapper = null;
|
|
@@ -463,6 +628,9 @@ export class IframeManager {
|
|
|
463
628
|
}
|
|
464
629
|
// Reset loading state
|
|
465
630
|
this.isIframeLoaded = false;
|
|
631
|
+
// Reset preload state
|
|
632
|
+
this.isPreloaded = false;
|
|
633
|
+
this.preloadUrl = null;
|
|
466
634
|
// Remove keyboard event listener
|
|
467
635
|
if (this.keydownHandler) {
|
|
468
636
|
window.removeEventListener("keydown", this.keydownHandler);
|
|
@@ -588,6 +756,25 @@ export class IframeManager {
|
|
|
588
756
|
return;
|
|
589
757
|
this.iframeWrapper.style.borderRadius = "0";
|
|
590
758
|
}
|
|
759
|
+
/**
|
|
760
|
+
* Check if an iframe is currently preloaded
|
|
761
|
+
*/
|
|
762
|
+
isIframePreloaded() {
|
|
763
|
+
return this.isPreloaded;
|
|
764
|
+
}
|
|
765
|
+
/**
|
|
766
|
+
* Get the URL of the preloaded iframe
|
|
767
|
+
*/
|
|
768
|
+
getPreloadedUrl() {
|
|
769
|
+
return this.preloadUrl;
|
|
770
|
+
}
|
|
771
|
+
/**
|
|
772
|
+
* Update the onClose handler for the iframe manager
|
|
773
|
+
* This is useful when transitioning from preload to active authentication
|
|
774
|
+
*/
|
|
775
|
+
updateOnCloseHandler(onClose) {
|
|
776
|
+
this.onClose = onClose;
|
|
777
|
+
}
|
|
591
778
|
showSubtlePopupFallbackIndicator() {
|
|
592
779
|
if (!this.iframeWrapper && !this.contentWrapper) {
|
|
593
780
|
this.logger.warn("Cannot show popup fallback indicator, no iframe wrapper or content wrapper found.");
|