{"version":3,"file":"NativeMessageHandler.js","sources":["../../../src/broker/nativeBroker/NativeMessageHandler.ts"],"sourcesContent":["/*\r\n * Copyright (c) Microsoft Corporation. All rights reserved.\r\n * Licensed under the MIT License.\r\n */\r\n\r\nimport { NativeConstants, NativeExtensionMethod } from \"../../utils/BrowserConstants\";\r\nimport {\r\n Logger,\r\n AuthError,\r\n AuthenticationScheme,\r\n InProgressPerformanceEvent,\r\n PerformanceEvents,\r\n IPerformanceClient\r\n} from \"@azure/msal-common\";\r\nimport { NativeExtensionRequest, NativeExtensionRequestBody } from \"./NativeRequest\";\r\nimport { NativeAuthError } from \"../../error/NativeAuthError\";\r\nimport { BrowserAuthError } from \"../../error/BrowserAuthError\";\r\nimport { BrowserConfiguration } from \"../../config/Configuration\";\r\n\r\ntype ResponseResolvers = {\r\n resolve: (value:T|PromiseLike) => void;\r\n reject: (value:AuthError|Error|PromiseLike|PromiseLike) => void;\r\n};\r\n\r\nexport class NativeMessageHandler {\r\n private extensionId: string | undefined;\r\n private extensionVersion: string | undefined;\r\n private logger: Logger;\r\n private readonly handshakeTimeoutMs: number;\r\n private responseId: number;\r\n private timeoutId: number | undefined;\r\n private resolvers: Map>;\r\n private handshakeResolvers: Map>;\r\n private messageChannel: MessageChannel;\r\n private readonly windowListener: (event: MessageEvent) => void;\r\n private readonly performanceClient: IPerformanceClient;\r\n private readonly handshakeEvent: InProgressPerformanceEvent;\r\n\r\n constructor(logger: Logger, handshakeTimeoutMs: number, performanceClient: IPerformanceClient, extensionId?: string) {\r\n this.logger = logger;\r\n this.handshakeTimeoutMs = handshakeTimeoutMs;\r\n this.extensionId = extensionId;\r\n this.resolvers = new Map(); // Used for non-handshake messages\r\n this.handshakeResolvers = new Map(); // Used for handshake messages\r\n this.responseId = 0;\r\n this.messageChannel = new MessageChannel();\r\n this.windowListener = this.onWindowMessage.bind(this); // Window event callback doesn't have access to 'this' unless it's bound\r\n this.performanceClient = performanceClient;\r\n this.handshakeEvent = performanceClient.startMeasurement(PerformanceEvents.NativeMessageHandlerHandshake);\r\n }\r\n\r\n /**\r\n * Sends a given message to the extension and resolves with the extension response\r\n * @param body\r\n */\r\n async sendMessage(body: NativeExtensionRequestBody): Promise {\r\n this.logger.trace(\"NativeMessageHandler - sendMessage called.\");\r\n const req: NativeExtensionRequest = {\r\n channel: NativeConstants.CHANNEL_ID,\r\n extensionId: this.extensionId,\r\n responseId: this.responseId++,\r\n body: body\r\n };\r\n\r\n this.logger.trace(\"NativeMessageHandler - Sending request to browser extension\");\r\n this.logger.tracePii(`NativeMessageHandler - Sending request to browser extension: ${JSON.stringify(req)}`);\r\n this.messageChannel.port1.postMessage(req);\r\n\r\n return new Promise((resolve, reject) => {\r\n this.resolvers.set(req.responseId, {resolve, reject});\r\n });\r\n }\r\n\r\n /**\r\n * Returns an instance of the MessageHandler that has successfully established a connection with an extension\r\n * @param {Logger} logger\r\n * @param {number} handshakeTimeoutMs\r\n * @param {IPerformanceClient} performanceClient\r\n */\r\n static async createProvider(logger: Logger, handshakeTimeoutMs: number, performanceClient: IPerformanceClient): Promise {\r\n logger.trace(\"NativeMessageHandler - createProvider called.\");\r\n try {\r\n const preferredProvider = new NativeMessageHandler(logger, handshakeTimeoutMs, performanceClient, NativeConstants.PREFERRED_EXTENSION_ID);\r\n await preferredProvider.sendHandshakeRequest();\r\n return preferredProvider;\r\n } catch (e) {\r\n // If preferred extension fails for whatever reason, fallback to using any installed extension\r\n const backupProvider = new NativeMessageHandler(logger, handshakeTimeoutMs, performanceClient);\r\n await backupProvider.sendHandshakeRequest();\r\n return backupProvider;\r\n }\r\n }\r\n\r\n /**\r\n * Send handshake request helper.\r\n */\r\n private async sendHandshakeRequest(): Promise {\r\n this.logger.trace(\"NativeMessageHandler - sendHandshakeRequest called.\");\r\n // Register this event listener before sending handshake\r\n window.addEventListener(\"message\", this.windowListener, false); // false is important, because content script message processing should work first\r\n\r\n const req: NativeExtensionRequest = {\r\n channel: NativeConstants.CHANNEL_ID,\r\n extensionId: this.extensionId,\r\n responseId: this.responseId++,\r\n body: {\r\n method: NativeExtensionMethod.HandshakeRequest\r\n }\r\n };\r\n this.handshakeEvent.addStaticFields({\r\n extensionId: this.extensionId,\r\n extensionHandshakeTimeoutMs: this.handshakeTimeoutMs\r\n });\r\n\r\n this.messageChannel.port1.onmessage = (event) => {\r\n this.onChannelMessage(event);\r\n };\r\n\r\n window.postMessage(req, window.origin, [this.messageChannel.port2]);\r\n\r\n return new Promise((resolve, reject) => {\r\n this.handshakeResolvers.set(req.responseId, {resolve, reject});\r\n this.timeoutId = window.setTimeout(() => {\r\n /*\r\n * Throw an error if neither HandshakeResponse nor original Handshake request are received in a reasonable timeframe.\r\n * This typically suggests an event handler stopped propagation of the Handshake request but did not respond to it on the MessageChannel port\r\n */\r\n window.removeEventListener(\"message\", this.windowListener, false);\r\n this.messageChannel.port1.close();\r\n this.messageChannel.port2.close();\r\n this.handshakeEvent.endMeasurement({extensionHandshakeTimedOut: true, success: false});\r\n reject(BrowserAuthError.createNativeHandshakeTimeoutError());\r\n this.handshakeResolvers.delete(req.responseId);\r\n }, this.handshakeTimeoutMs); // Use a reasonable timeout in milliseconds here\r\n });\r\n }\r\n\r\n /**\r\n * Invoked when a message is posted to the window. If a handshake request is received it means the extension is not installed.\r\n * @param event\r\n */\r\n private onWindowMessage(event: MessageEvent): void {\r\n this.logger.trace(\"NativeMessageHandler - onWindowMessage called\");\r\n // We only accept messages from ourselves\r\n if (event.source !== window) {\r\n return;\r\n }\r\n\r\n const request = event.data;\r\n\r\n if (!request.channel || request.channel !== NativeConstants.CHANNEL_ID) {\r\n return;\r\n }\r\n\r\n if (request.extensionId && request.extensionId !== this.extensionId) {\r\n return;\r\n }\r\n\r\n if (request.body.method === NativeExtensionMethod.HandshakeRequest) {\r\n // If we receive this message back it means no extension intercepted the request, meaning no extension supporting handshake protocol is installed\r\n this.logger.verbose(request.extensionId ? `Extension with id: ${request.extensionId} not installed` : \"No extension installed\");\r\n clearTimeout(this.timeoutId);\r\n this.messageChannel.port1.close();\r\n this.messageChannel.port2.close();\r\n window.removeEventListener(\"message\", this.windowListener, false);\r\n const handshakeResolver = this.handshakeResolvers.get(request.responseId);\r\n if (handshakeResolver) {\r\n this.handshakeEvent.endMeasurement({success: false, extensionInstalled: false});\r\n handshakeResolver.reject(BrowserAuthError.createNativeExtensionNotInstalledError());\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Invoked when a message is received from the extension on the MessageChannel port\r\n * @param event\r\n */\r\n private onChannelMessage(event: MessageEvent): void {\r\n this.logger.trace(\"NativeMessageHandler - onChannelMessage called.\");\r\n const request = event.data;\r\n\r\n const resolver = this.resolvers.get(request.responseId);\r\n const handshakeResolver = this.handshakeResolvers.get(request.responseId);\r\n\r\n try {\r\n const method = request.body.method;\r\n\r\n if (method === NativeExtensionMethod.Response) {\r\n if (!resolver) {\r\n return;\r\n }\r\n const response = request.body.response;\r\n this.logger.trace(\"NativeMessageHandler - Received response from browser extension\");\r\n this.logger.tracePii(`NativeMessageHandler - Received response from browser extension: ${JSON.stringify(response)}`);\r\n if (response.status !== \"Success\") {\r\n resolver.reject(NativeAuthError.createError(response.code, response.description, response.ext));\r\n } else if (response.result) {\r\n if (response.result[\"code\"] && response.result[\"description\"]) {\r\n resolver.reject(NativeAuthError.createError(response.result[\"code\"], response.result[\"description\"], response.result[\"ext\"]));\r\n } else {\r\n resolver.resolve(response.result);\r\n }\r\n } else {\r\n throw AuthError.createUnexpectedError(\"Event does not contain result.\");\r\n }\r\n this.resolvers.delete(request.responseId);\r\n } else if (method === NativeExtensionMethod.HandshakeResponse) {\r\n if (!handshakeResolver) {\r\n return;\r\n }\r\n clearTimeout(this.timeoutId); // Clear setTimeout\r\n window.removeEventListener(\"message\", this.windowListener, false); // Remove 'No extension' listener\r\n this.extensionId = request.extensionId;\r\n this.extensionVersion = request.body.version;\r\n this.logger.verbose(`NativeMessageHandler - Received HandshakeResponse from extension: ${this.extensionId}`);\r\n this.handshakeEvent.endMeasurement({extensionInstalled: true, success: true});\r\n\r\n handshakeResolver.resolve();\r\n this.handshakeResolvers.delete(request.responseId);\r\n }\r\n // Do nothing if method is not Response or HandshakeResponse\r\n } catch (err) {\r\n this.logger.error(\"Error parsing response from WAM Extension\");\r\n this.logger.errorPii(`Error parsing response from WAM Extension: ${err.toString()}`);\r\n this.logger.errorPii(`Unable to parse ${event}`);\r\n\r\n if (resolver) {\r\n resolver.reject(err as AuthError);\r\n } else if (handshakeResolver) {\r\n handshakeResolver.reject(err as AuthError);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Returns the Id for the browser extension this handler is communicating with\r\n * @returns\r\n */\r\n getExtensionId(): string | undefined {\r\n return this.extensionId;\r\n }\r\n\r\n /**\r\n * Returns the version for the browser extension this handler is communicating with\r\n * @returns\r\n */\r\n getExtensionVersion(): string | undefined {\r\n return this.extensionVersion;\r\n }\r\n\r\n /**\r\n * Returns boolean indicating whether or not the request should attempt to use native broker\r\n * @param logger\r\n * @param config\r\n * @param nativeExtensionProvider\r\n * @param authenticationScheme\r\n */\r\n static isNativeAvailable(config: BrowserConfiguration, logger: Logger, nativeExtensionProvider?: NativeMessageHandler, authenticationScheme?: AuthenticationScheme): boolean {\r\n logger.trace(\"isNativeAvailable called\");\r\n if (!config.system.allowNativeBroker) {\r\n logger.trace(\"isNativeAvailable: allowNativeBroker is not enabled, returning false\");\r\n // Developer disabled WAM\r\n return false;\r\n }\r\n\r\n if (!nativeExtensionProvider) {\r\n logger.trace(\"isNativeAvailable: WAM extension provider is not initialized, returning false\");\r\n // Extension is not available\r\n return false;\r\n }\r\n\r\n if (authenticationScheme) {\r\n switch(authenticationScheme) {\r\n case AuthenticationScheme.BEARER:\r\n case AuthenticationScheme.POP:\r\n logger.trace(\"isNativeAvailable: authenticationScheme is supported, returning true\");\r\n return true;\r\n default:\r\n logger.trace(\"isNativeAvailable: authenticationScheme is not supported, returning false\");\r\n return false;\r\n }\r\n }\r\n\r\n return true;\r\n }\r\n}\r\n"],"names":[],"mappings":"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"}