From 9cd82bea82a75a2b633a1edfd403325229b3f192 Mon Sep 17 00:00:00 2001 From: Viktoria Zlatinova Date: Thu, 7 Nov 2024 09:49:37 -0800 Subject: [PATCH 1/4] Update PopupClient.ts --- .../src/interaction_client/PopupClient.ts | 112 ++++++++++-------- 1 file changed, 65 insertions(+), 47 deletions(-) diff --git a/lib/msal-browser/src/interaction_client/PopupClient.ts b/lib/msal-browser/src/interaction_client/PopupClient.ts index 2fd05de3c5..98597ed108 100644 --- a/lib/msal-browser/src/interaction_client/PopupClient.ts +++ b/lib/msal-browser/src/interaction_client/PopupClient.ts @@ -58,6 +58,7 @@ export type PopupParams = { export class PopupClient extends StandardInteractionClient { private currentWindow: Window | undefined; protected nativeStorage: BrowserCacheManager; + private authChannel: BroadcastChannel; constructor( config: BrowserConfiguration, @@ -85,6 +86,7 @@ export class PopupClient extends StandardInteractionClient { // Properly sets this reference for the unload event. this.unloadWindow = this.unloadWindow.bind(this); this.nativeStorage = nativeStorageImpl; + this.authChannel = new BroadcastChannel('auth'); } /** @@ -546,58 +548,71 @@ export class PopupClient extends StandardInteractionClient { popupWindowParent: Window ): Promise { return new Promise((resolve, reject) => { - this.logger.verbose( - "PopupHandler.monitorPopupForHash - polling started" - ); - - const intervalId = setInterval(() => { - // Window is closed - if (popupWindow.closed) { - this.logger.error( - "PopupHandler.monitorPopupForHash - window closed" - ); - clearInterval(intervalId); + setTimeout(() => { + this.logger.verbose( + "PopupHandler.monitorPopupForHash - polling started" + ); + this.authChannel.onmessage = function (event) { + resolve(event.data); + } + this.authChannel.onmessageerror = function (event) { + console.log('BroadcastChannel error', event.data); reject( createBrowserAuthError( - BrowserAuthErrorCodes.userCancelled + BrowserAuthErrorCodes.popupWindowError ) ); - return; - } - - let href = ""; - try { - /* - * Will throw if cross origin, - * which should be caught and ignored - * since we need the interval to keep running while on STS UI. - */ - href = popupWindow.location.href; - } catch (e) {} - - // Don't process blank pages or cross domain - if (!href || href === "about:blank") { - return; - } - clearInterval(intervalId); - - let responseString = ""; - const responseType = - this.config.auth.OIDCOptions.serverResponseType; - if (popupWindow) { - if (responseType === ServerResponseType.QUERY) { - responseString = popupWindow.location.search; - } else { - responseString = popupWindow.location.hash; - } - } - - this.logger.verbose( - "PopupHandler.monitorPopupForHash - popup window is on same origin as caller" - ); - - resolve(responseString); + } }, this.config.system.pollIntervalMilliseconds); + + // const intervalId = setInterval(() => { + // // Window is closed + // if (popupWindow.closed) { + // this.logger.error( + // "PopupHandler.monitorPopupForHash - window closed" + // ); + // clearInterval(intervalId); + // reject( + // createBrowserAuthError( + // BrowserAuthErrorCodes.userCancelled + // ) + // ); + // return; + // } + + // let href = ""; + // try { + // /* + // * Will throw if cross origin, + // * which should be caught and ignored + // * since we need the interval to keep running while on STS UI. + // */ + // href = popupWindow.location.href; + // } catch (e) {} + + // // Don't process blank pages or cross domain + // if (!href || href === "about:blank") { + // return; + // } + // clearInterval(intervalId); + + // let responseString = ""; + // const responseType = + // this.config.auth.OIDCOptions.serverResponseType; + // if (popupWindow) { + // if (responseType === ServerResponseType.QUERY) { + // responseString = popupWindow.location.search; + // } else { + // responseString = popupWindow.location.hash; + // } + // } + + // this.logger.verbose( + // "PopupHandler.monitorPopupForHash - popup window is on same origin as caller" + // ); + + // resolve(responseString); + // }, this.config.system.pollIntervalMilliseconds); }).finally(() => { this.cleanPopup(popupWindow, popupWindowParent); }); @@ -763,6 +778,9 @@ export class PopupClient extends StandardInteractionClient { // Close window. popupWindow.close(); + // Close the broadcast channel + this.authChannel.close(); + // Remove window unload function popupWindowParent.removeEventListener( "beforeunload", From 5aa33f122a2819986be9e3b0e501d71d0186ae76 Mon Sep 17 00:00:00 2001 From: Viktoria Zlatinova Date: Thu, 7 Nov 2024 09:50:56 -0800 Subject: [PATCH 2/4] Update RedirectClient.ts --- .../src/interaction_client/RedirectClient.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/msal-browser/src/interaction_client/RedirectClient.ts b/lib/msal-browser/src/interaction_client/RedirectClient.ts index abd01a3615..ce86f2c973 100644 --- a/lib/msal-browser/src/interaction_client/RedirectClient.ts +++ b/lib/msal-browser/src/interaction_client/RedirectClient.ts @@ -67,6 +67,7 @@ function getNavigationType(): NavigationTimingType | undefined { export class RedirectClient extends StandardInteractionClient { protected nativeStorage: BrowserCacheManager; + private authChannel = new BroadcastChannel('auth'); constructor( config: BrowserConfiguration, @@ -248,6 +249,9 @@ export class RedirectClient extends StandardInteractionClient { "Back navigation event detected. Muting no_server_response error" ); } + // Logout with popup case + this.authChannel.postMessage(""); + window.close(); return null; } @@ -394,7 +398,8 @@ export class RedirectClient extends StandardInteractionClient { ResponseHandler.validateInteractionType( response, this.browserCrypto, - InteractionType.Redirect + // TODO: Use correct type depending on the situation + InteractionType.Popup ); } catch (e) { if (e instanceof AuthError) { @@ -422,6 +427,11 @@ export class RedirectClient extends StandardInteractionClient { if (cachedHash) { response = UrlUtils.getDeserializedResponse(cachedHash); + + // Login with popup case + this.authChannel.postMessage(cachedHash); + window.close(); + if (response) { this.logger.verbose( "Hash does not contain known properties, returning cached hash" From 6585340b7a380189d0c1ef41eba914ba0420daef Mon Sep 17 00:00:00 2001 From: Viktoria Zlatinova Date: Thu, 7 Nov 2024 10:37:14 -0800 Subject: [PATCH 3/4] Delete commented out code in PopupClient.ts --- .../src/interaction_client/PopupClient.ts | 49 ------------------- 1 file changed, 49 deletions(-) diff --git a/lib/msal-browser/src/interaction_client/PopupClient.ts b/lib/msal-browser/src/interaction_client/PopupClient.ts index 98597ed108..c337f50d57 100644 --- a/lib/msal-browser/src/interaction_client/PopupClient.ts +++ b/lib/msal-browser/src/interaction_client/PopupClient.ts @@ -564,55 +564,6 @@ export class PopupClient extends StandardInteractionClient { ); } }, this.config.system.pollIntervalMilliseconds); - - // const intervalId = setInterval(() => { - // // Window is closed - // if (popupWindow.closed) { - // this.logger.error( - // "PopupHandler.monitorPopupForHash - window closed" - // ); - // clearInterval(intervalId); - // reject( - // createBrowserAuthError( - // BrowserAuthErrorCodes.userCancelled - // ) - // ); - // return; - // } - - // let href = ""; - // try { - // /* - // * Will throw if cross origin, - // * which should be caught and ignored - // * since we need the interval to keep running while on STS UI. - // */ - // href = popupWindow.location.href; - // } catch (e) {} - - // // Don't process blank pages or cross domain - // if (!href || href === "about:blank") { - // return; - // } - // clearInterval(intervalId); - - // let responseString = ""; - // const responseType = - // this.config.auth.OIDCOptions.serverResponseType; - // if (popupWindow) { - // if (responseType === ServerResponseType.QUERY) { - // responseString = popupWindow.location.search; - // } else { - // responseString = popupWindow.location.hash; - // } - // } - - // this.logger.verbose( - // "PopupHandler.monitorPopupForHash - popup window is on same origin as caller" - // ); - - // resolve(responseString); - // }, this.config.system.pollIntervalMilliseconds); }).finally(() => { this.cleanPopup(popupWindow, popupWindowParent); }); From d26982931abc2f2069b7a0db5daba8e5bc3f16a7 Mon Sep 17 00:00:00 2001 From: Viktoria Zlatinova Date: Thu, 7 Nov 2024 11:19:34 -0800 Subject: [PATCH 4/4] Remove timeout in PopupClient.ts --- .../src/interaction_client/PopupClient.ts | 28 +++++++++---------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/lib/msal-browser/src/interaction_client/PopupClient.ts b/lib/msal-browser/src/interaction_client/PopupClient.ts index c337f50d57..92010c882a 100644 --- a/lib/msal-browser/src/interaction_client/PopupClient.ts +++ b/lib/msal-browser/src/interaction_client/PopupClient.ts @@ -548,22 +548,20 @@ export class PopupClient extends StandardInteractionClient { popupWindowParent: Window ): Promise { return new Promise((resolve, reject) => { - setTimeout(() => { - this.logger.verbose( - "PopupHandler.monitorPopupForHash - polling started" + this.logger.verbose( + "PopupHandler.monitorPopupForHash" + ); + this.authChannel.onmessage = function (event) { + resolve(event.data); + } + this.authChannel.onmessageerror = function (event) { + console.log('BroadcastChannel error', event.data); + reject( + createBrowserAuthError( + BrowserAuthErrorCodes.popupWindowError + ) ); - this.authChannel.onmessage = function (event) { - resolve(event.data); - } - this.authChannel.onmessageerror = function (event) { - console.log('BroadcastChannel error', event.data); - reject( - createBrowserAuthError( - BrowserAuthErrorCodes.popupWindowError - ) - ); - } - }, this.config.system.pollIntervalMilliseconds); + } }).finally(() => { this.cleanPopup(popupWindow, popupWindowParent); });