diff --git a/change/@azure-msal-browser-f27b9a8d-ad98-44f7-8af5-f0ece472b848.json b/change/@azure-msal-browser-f27b9a8d-ad98-44f7-8af5-f0ece472b848.json new file mode 100644 index 0000000000..d10cf502d3 --- /dev/null +++ b/change/@azure-msal-browser-f27b9a8d-ad98-44f7-8af5-f0ece472b848.json @@ -0,0 +1,7 @@ +{ + "type": "minor", + "comment": "Mute no_server_response error when back navigation is detected #7342", + "packageName": "@azure/msal-browser", + "email": "kshabelko@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/lib/msal-browser/src/interaction_client/RedirectClient.ts b/lib/msal-browser/src/interaction_client/RedirectClient.ts index 79efd2d5c1..abd01a3615 100644 --- a/lib/msal-browser/src/interaction_client/RedirectClient.ts +++ b/lib/msal-browser/src/interaction_client/RedirectClient.ts @@ -49,6 +49,22 @@ import { EventError } from "../event/EventMessage.js"; import { AuthenticationResult } from "../response/AuthenticationResult.js"; import * as ResponseHandler from "../response/ResponseHandler.js"; +function getNavigationType(): NavigationTimingType | undefined { + if ( + typeof window === "undefined" || + typeof window.performance === "undefined" || + typeof window.performance.getEntriesByType !== "function" + ) { + return undefined; + } + + const navigationEntries = window.performance.getEntriesByType("navigation"); + const navigation = navigationEntries.length + ? (navigationEntries[0] as PerformanceNavigationTiming) + : undefined; + return navigation?.type; +} + export class RedirectClient extends StandardInteractionClient { protected nativeStorage: BrowserCacheManager; @@ -223,7 +239,15 @@ export class RedirectClient extends StandardInteractionClient { this.browserStorage.cleanRequestByInteractionType( InteractionType.Redirect ); - parentMeasurement.event.errorCode = "no_server_response"; + + // Do not instrument "no_server_response" if user clicked back button + if (getNavigationType() !== "back_forward") { + parentMeasurement.event.errorCode = "no_server_response"; + } else { + this.logger.verbose( + "Back navigation event detected. Muting no_server_response error" + ); + } return null; } diff --git a/lib/msal-browser/test/interaction_client/RedirectClient.spec.ts b/lib/msal-browser/test/interaction_client/RedirectClient.spec.ts index e6933b8b26..5326ca801b 100644 --- a/lib/msal-browser/test/interaction_client/RedirectClient.spec.ts +++ b/lib/msal-browser/test/interaction_client/RedirectClient.spec.ts @@ -1827,6 +1827,50 @@ describe("RedirectClient", () => { }); redirectClient.handleRedirectPromise("", rootMeasurement); }); + + it("mutes no_server_response error when back navigation is detected", async () => { + // @ts-ignore + window.performance.getEntriesByType = () => { + return [{ type: "back_forward" }]; + }; + + browserStorage.setInteractionInProgress(true); + const loginRequestUrl = window.location.href; + window.location.hash = ""; + window.sessionStorage.setItem( + `${Constants.CACHE_PREFIX}.${TEST_CONFIG.MSAL_CLIENT_ID}.${TemporaryCacheKeys.ORIGIN_URI}`, + loginRequestUrl + ); + const res = await redirectClient.handleRedirectPromise( + "", + rootMeasurement + ); + expect(res).toBeNull(); + expect(rootMeasurement.event.errorCode).toBeUndefined(); + }); + + it("does not mute no_server_response error when back navigation is not detected", async () => { + // @ts-ignore + window.performance.getEntriesByType = () => { + return []; + }; + + browserStorage.setInteractionInProgress(true); + const loginRequestUrl = window.location.href; + window.location.hash = ""; + window.sessionStorage.setItem( + `${Constants.CACHE_PREFIX}.${TEST_CONFIG.MSAL_CLIENT_ID}.${TemporaryCacheKeys.ORIGIN_URI}`, + loginRequestUrl + ); + const res = await redirectClient.handleRedirectPromise( + "", + rootMeasurement + ); + expect(res).toBeNull(); + expect(rootMeasurement.event.errorCode).toEqual( + "no_server_response" + ); + }); }); describe("acquireToken", () => {