diff --git a/lib/msal-browser/src/controllers/StandardController.ts b/lib/msal-browser/src/controllers/StandardController.ts index 7ecb752980..5270c86056 100644 --- a/lib/msal-browser/src/controllers/StandardController.ts +++ b/lib/msal-browser/src/controllers/StandardController.ts @@ -584,19 +584,37 @@ export class StandardController implements IController { scenarioId: request.scenarioId, }); + // Override on request only if set, as onRedirectNavigate field is deprecated const onRedirectNavigateCb = request.onRedirectNavigate; - request.onRedirectNavigate = (url: string) => { - const navigate = - typeof onRedirectNavigateCb === "function" - ? onRedirectNavigateCb(url) - : undefined; - if (navigate !== false) { - atrMeasurement.end({ success: true }); - } else { - atrMeasurement.discard(); - } - return navigate; - }; + if (onRedirectNavigateCb) { + request.onRedirectNavigate = (url: string) => { + const navigate = + typeof onRedirectNavigateCb === "function" + ? onRedirectNavigateCb(url) + : undefined; + if (navigate !== false) { + atrMeasurement.end({ success: true }); + } else { + atrMeasurement.discard(); + } + return navigate; + }; + } else { + const configOnRedirectNavigateCb = + this.config.auth.onRedirectNavigate; + this.config.auth.onRedirectNavigate = (url: string) => { + const navigate = + typeof configOnRedirectNavigateCb === "function" + ? configOnRedirectNavigateCb(url) + : undefined; + if (navigate !== false) { + atrMeasurement.end({ success: true }); + } else { + atrMeasurement.discard(); + } + return navigate; + }; + } // If logged in, emit acquire token events const isLoggedIn = this.getAllAccounts().length > 0; diff --git a/lib/msal-browser/test/app/PublicClientApplication.spec.ts b/lib/msal-browser/test/app/PublicClientApplication.spec.ts index 2bf8b219f7..26b953a040 100644 --- a/lib/msal-browser/test/app/PublicClientApplication.spec.ts +++ b/lib/msal-browser/test/app/PublicClientApplication.spec.ts @@ -1900,6 +1900,52 @@ describe("PublicClientApplication.ts Class Unit Tests", () => { pca.acquireTokenRedirect(loginRequest); }); + it("emits pre-redirect telemetry event when onRedirectNavigate callback is set in configuration", async () => { + const onRedirectNavigate = (url: string) => { + expect(url).toBeDefined(); + }; + + pca = new PublicClientApplication({ + auth: { + clientId: TEST_CONFIG.MSAL_CLIENT_ID, + onRedirectNavigate, + }, + telemetry: { + client: new BrowserPerformanceClient(testAppConfig), + application: { + appName: TEST_CONFIG.applicationName, + appVersion: TEST_CONFIG.applicationVersion, + }, + }, + }); + pca = (pca as any).controller; + await pca.initialize(); + + const callbackId = pca.addPerformanceCallback((events) => { + expect(events[0].success).toBe(true); + expect(events[0].name).toBe( + PerformanceEvents.AcquireTokenPreRedirect + ); + pca.removePerformanceCallback(callbackId); + }); + + jest.spyOn( + NavigationClient.prototype, + "navigateExternal" + ).mockImplementation(() => Promise.resolve(true)); + + jest.spyOn(PkceGenerator, "generatePkceCodes").mockResolvedValue({ + challenge: TEST_CONFIG.TEST_CHALLENGE, + verifier: TEST_CONFIG.TEST_VERIFIER, + }); + const loginRequest: RedirectRequest = { + redirectUri: TEST_URIS.TEST_REDIR_URI, + scopes: ["user.read", "openid", "profile"], + state: TEST_STATE_VALUES.USER_STATE, + }; + await pca.acquireTokenRedirect(loginRequest); + }); + it("discards pre-redirect telemetry event when onRedirectNavigate callback returns false", async () => { const onRedirectNavigate = (url: string) => { return false;