From 31a7001dc11e9ab9302d8500e8e96779801aad32 Mon Sep 17 00:00:00 2001 From: Konstantin Date: Fri, 26 Apr 2024 14:52:34 -0400 Subject: [PATCH 1/6] Make performanceClient.discardMeasurements() flush aux cache data in addition to measurements (#7061) - Make `performanceClient.discardMeasurements()` flush aux cache data in addition to measurements. --- ...-e0ac26de-f149-4faf-adef-154f60c566b8.json | 7 ++ .../performance/PerformanceClient.ts | 13 +--- .../test/telemetry/PerformanceClient.spec.ts | 76 ++++++++++++++++++- 3 files changed, 84 insertions(+), 12 deletions(-) create mode 100644 change/@azure-msal-common-e0ac26de-f149-4faf-adef-154f60c566b8.json diff --git a/change/@azure-msal-common-e0ac26de-f149-4faf-adef-154f60c566b8.json b/change/@azure-msal-common-e0ac26de-f149-4faf-adef-154f60c566b8.json new file mode 100644 index 0000000000..c6e509982a --- /dev/null +++ b/change/@azure-msal-common-e0ac26de-f149-4faf-adef-154f60c566b8.json @@ -0,0 +1,7 @@ +{ + "type": "minor", + "comment": "Make performanceClient.discardMeasurements() flush aux cache data in addition to measurements #7061", + "packageName": "@azure/msal-common", + "email": "kshabelko@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/lib/msal-common/src/telemetry/performance/PerformanceClient.ts b/lib/msal-common/src/telemetry/performance/PerformanceClient.ts index 532cbb86fa..02edc27b5c 100644 --- a/lib/msal-common/src/telemetry/performance/PerformanceClient.ts +++ b/lib/msal-common/src/telemetry/performance/PerformanceClient.ts @@ -620,7 +620,7 @@ export abstract class PerformanceClient implements IPerformanceClient { if (isRoot) { queueInfo = this.getQueueInfo(event.correlationId); - this.discardCache(rootEvent.correlationId); + this.discardMeasurements(rootEvent.correlationId); } else { rootEvent.incompleteSubMeasurements?.delete(event.eventId); } @@ -781,7 +781,7 @@ export abstract class PerformanceClient implements IPerformanceClient { } /** - * Removes measurements for a given correlation id. + * Removes measurements and aux data for a given correlation id. * * @param {string} correlationId */ @@ -791,15 +791,6 @@ export abstract class PerformanceClient implements IPerformanceClient { correlationId ); this.eventsByCorrelationId.delete(correlationId); - } - - /** - * Removes cache for a given correlation id. - * - * @param {string} correlationId correlation identifier - */ - private discardCache(correlationId: string): void { - this.discardMeasurements(correlationId); this.logger.trace( "PerformanceClient: QueueMeasurements discarded", diff --git a/lib/msal-common/test/telemetry/PerformanceClient.spec.ts b/lib/msal-common/test/telemetry/PerformanceClient.spec.ts index 1d9444aaf6..e640b2622c 100644 --- a/lib/msal-common/test/telemetry/PerformanceClient.spec.ts +++ b/lib/msal-common/test/telemetry/PerformanceClient.spec.ts @@ -72,7 +72,10 @@ export class MockPerformanceClient eventName: PerformanceEvents, correlationId?: string | undefined ): void { - return; + this.preQueueTimeByCorrelationId.set(correlationId || "", { + name: eventName, + time: 12345, + }); } getDurationMs(startTimeMs: number): number { @@ -1122,4 +1125,75 @@ describe("PerformanceClient.spec.ts", () => { rootEvent.end({ success: true }); }); }); + + describe("discard", () => { + it("discards cache data", () => { + const mockPerfClient = new MockPerformanceClient(); + const correlationId = "test-correlation-id"; + const dummyCorrelationId = "dummy-correlation-id"; + + const rootEvent = mockPerfClient.startMeasurement( + PerformanceEvents.AcquireTokenSilent, + correlationId + ); + const firstEvent = mockPerfClient.startMeasurement( + PerformanceEvents.AcquireTokenSilentAsync, + correlationId + ); + mockPerfClient.setPreQueueTime( + PerformanceEvents.AcquireTokenSilentAsync, + correlationId + ); + const secondEvent = mockPerfClient.startMeasurement( + PerformanceEvents.AcquireTokenFromCache, + correlationId + ); + mockPerfClient.setPreQueueTime( + PerformanceEvents.AcquireTokenFromCache, + correlationId + ); + secondEvent.end({ success: true }); + firstEvent.end({ success: true }); + rootEvent.discard(); + + mockPerfClient.startMeasurement( + PerformanceEvents.AcquireTokenSilent, + dummyCorrelationId + ); + mockPerfClient.setPreQueueTime( + PerformanceEvents.AcquireTokenSilent, + dummyCorrelationId + ); + + expect( + // @ts-ignore + mockPerfClient.eventsByCorrelationId.has(correlationId) + ).toBeFalsy(); + expect( + // @ts-ignore + mockPerfClient.preQueueTimeByCorrelationId.has(correlationId) + ).toBeFalsy(); + expect( + // @ts-ignore + mockPerfClient.queueMeasurements.has(correlationId) + ).toBeFalsy(); + // @ts-ignore + expect(mockPerfClient.eventStack.has(correlationId)).toBeFalsy(); + + expect( + // @ts-ignore + mockPerfClient.eventsByCorrelationId.has(dummyCorrelationId) + ).toBeTruthy(); + expect( + // @ts-ignore + mockPerfClient.preQueueTimeByCorrelationId.has( + dummyCorrelationId + ) + ).toBeTruthy(); + expect( + // @ts-ignore + mockPerfClient.eventStack.has(dummyCorrelationId) + ).toBeTruthy(); + }); + }); }); From 869336ff5f3890fba8563dfa981d87f583c6cd17 Mon Sep 17 00:00:00 2001 From: Konstantin Date: Fri, 26 Apr 2024 17:12:42 -0400 Subject: [PATCH 2/6] Add cache_quota_exceeded error info to errors.md (#7062) Add cache_quota_exceeded error info to errors.md --- lib/msal-browser/docs/errors.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/msal-browser/docs/errors.md b/lib/msal-browser/docs/errors.md index cfe55940b3..dea8855245 100644 --- a/lib/msal-browser/docs/errors.md +++ b/lib/msal-browser/docs/errors.md @@ -409,7 +409,7 @@ msalInstance.acquireTokenSilent(); // This will also no longer throw this error ## Other -Errors not thrown by MSAL, such as server errors. +Errors not thrown by MSAL, such as server or cache errors. ### Access to fetch at [url] has been blocked by CORS policy @@ -418,3 +418,16 @@ This error occurs with MSAL.js v2.x and is due to improper configuration during > Your Redirect URI is eligible for the Authorization Code Flow with PKCE. ![image](https://user-images.githubusercontent.com/5307810/110390912-922fa380-801b-11eb-9e2b-d7aa88ca0687.png) + +### cache_quota_exceeded + +**Error messages**: + +- Exceeded cache storage capacity + +This error occurs when MSAL.js surpasses the allotted storage limit when attempting to save token information in the [configured cache storage](./caching.md#cache-storage). See [here](https://developer.mozilla.org/en-US/docs/Web/API/Storage_API/Storage_quotas_and_eviction_criteria#web_storage) for web storage limits. + +**Mitigation**: + +1. Make sure the configured cache storage has enough capacity to allow MSAL.js to persist token payload. The amount of cache storage required depends on the number of [cached artifacts](./caching.md#cached-artifacts). +2. Disable [claimsBasedCachingEnabled](./configuration.md#cache-config-options) cache config option. When enabled, it caches access tokens under a key containing the hash of the requested claims. Depending on the MSAL.js API usage, it may result in the vast number of access tokens persisted in the cache storage. From 8242d67cec8499154bf94a13926b285e495e6752 Mon Sep 17 00:00:00 2001 From: Dan Saunders Date: Fri, 26 Apr 2024 14:51:36 -0700 Subject: [PATCH 3/6] Add getAccount API to IPublicClientApplication (#7019) Add getAccount(accountFilter: AccountFilter) API to IPublicClientApplication so that it can be called by the PCA returned from PublicClientNext.createPublicClientApplication. --- ...-msal-browser-7b8679dc-1a5c-44b1-8f0a-bb52821145a9.json | 7 +++++++ lib/msal-browser/src/app/IPublicClientApplication.ts | 5 +++++ 2 files changed, 12 insertions(+) create mode 100644 change/@azure-msal-browser-7b8679dc-1a5c-44b1-8f0a-bb52821145a9.json diff --git a/change/@azure-msal-browser-7b8679dc-1a5c-44b1-8f0a-bb52821145a9.json b/change/@azure-msal-browser-7b8679dc-1a5c-44b1-8f0a-bb52821145a9.json new file mode 100644 index 0000000000..90f8d583ec --- /dev/null +++ b/change/@azure-msal-browser-7b8679dc-1a5c-44b1-8f0a-bb52821145a9.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "Add getAccount API to IPublicClientApplication (#7019)", + "packageName": "@azure/msal-browser", + "email": "dasau@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/lib/msal-browser/src/app/IPublicClientApplication.ts b/lib/msal-browser/src/app/IPublicClientApplication.ts index 0185d65878..21a4cf6671 100644 --- a/lib/msal-browser/src/app/IPublicClientApplication.ts +++ b/lib/msal-browser/src/app/IPublicClientApplication.ts @@ -4,6 +4,7 @@ */ import { + AccountFilter, AccountInfo, Logger, PerformanceCallbackFunction, @@ -43,6 +44,7 @@ export interface IPublicClientApplication { removePerformanceCallback(callbackId: string): boolean; enableAccountStorageEvents(): void; disableAccountStorageEvents(): void; + getAccount(accountFilter: AccountFilter): AccountInfo | null; getAccountByHomeId(homeAccountId: string): AccountInfo | null; getAccountByLocalId(localId: string): AccountInfo | null; getAccountByUsername(userName: string): AccountInfo | null; @@ -113,6 +115,9 @@ export const stubbedPublicClientApplication: IPublicClientApplication = { getAllAccounts: () => { return []; }, + getAccount: () => { + return null; + }, getAccountByHomeId: () => { return null; }, From c244947a022c90fbc055b5d1c9c5a98aea181110 Mon Sep 17 00:00:00 2001 From: Kade Keith <91503387+hatched-kade@users.noreply.github.com> Date: Fri, 26 Apr 2024 17:32:09 -0500 Subject: [PATCH 4/6] Fix `useIsAuthenticated` hook briefly returning false even though the user is authenticated (#7057) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addresses https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/6918 The current `useIsAuthenticated` has an unnecessary `useEffect`, which causes it to briefly return `false` in some cases even when an account is present. See https://react.dev/learn/you-might-not-need-an-effect#updating-state-based-on-props-or-state and https://react.dev/learn/you-might-not-need-an-effect#caching-expensive-calculations This PR switches to use the `useMemo` recommendation I added a unit test that passes now, but fails with the old implementation: ``` FAIL test/hooks/useIsAuthenticated.spec.tsx ● withMsal tests › useAuthenticated always returns true if user has an account expect(jest.fn()).toHaveBeenCalledTimes(expected) Expected number of calls: 0 Received number of calls: 1 78 | expect(await screen.findByText("Has accounts")).toBeInTheDocument(); 79 | expect(await screen.findByText("Is authed")).toBeInTheDocument(); > 80 | expect(invalidAuthStateCallback).toHaveBeenCalledTimes(0); | ^ 81 | }); 82 | }); 83 | at Object. (test/hooks/useIsAuthenticated.spec.tsx:80:42) ``` I also had to tweak some act / await / async code in other tests, presumably because now it takes fewer renders for the hook to start returning the correct value. Without the tweaks a couple tests were failing, and others printed warning about updating state outside of an `act(...)`. --------- Co-authored-by: Thomas Norling Co-authored-by: Jo Arroyo --- ...-5355b5e3-0c1c-4e23-ae9d-a6d96ef4285d.json | 7 ++ .../src/hooks/useIsAuthenticated.ts | 12 +-- .../MsalAuthenticationTemplate.spec.tsx | 32 ++++---- .../test/hooks/useIsAuthenticated.spec.tsx | 82 +++++++++++++++++++ 4 files changed, 111 insertions(+), 22 deletions(-) create mode 100644 change/@azure-msal-react-5355b5e3-0c1c-4e23-ae9d-a6d96ef4285d.json create mode 100644 lib/msal-react/test/hooks/useIsAuthenticated.spec.tsx diff --git a/change/@azure-msal-react-5355b5e3-0c1c-4e23-ae9d-a6d96ef4285d.json b/change/@azure-msal-react-5355b5e3-0c1c-4e23-ae9d-a6d96ef4285d.json new file mode 100644 index 0000000000..cde9c32890 --- /dev/null +++ b/change/@azure-msal-react-5355b5e3-0c1c-4e23-ae9d-a6d96ef4285d.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "Fix useIsAuthenticated returning incorrect value during useEffect update #7057", + "packageName": "@azure/msal-react", + "email": "kade@hatchedlabs.com", + "dependentChangeType": "patch" +} diff --git a/lib/msal-react/src/hooks/useIsAuthenticated.ts b/lib/msal-react/src/hooks/useIsAuthenticated.ts index 509cb1435b..aa5963f449 100644 --- a/lib/msal-react/src/hooks/useIsAuthenticated.ts +++ b/lib/msal-react/src/hooks/useIsAuthenticated.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. */ -import { useState, useEffect } from "react"; +import { useMemo } from "react"; import { useMsal } from "./useMsal"; import { AccountIdentifiers } from "../types/AccountIdentifiers"; import { AccountInfo, InteractionStatus } from "@azure/msal-browser"; @@ -32,16 +32,12 @@ function isAuthenticated( export function useIsAuthenticated(matchAccount?: AccountIdentifiers): boolean { const { accounts: allAccounts, inProgress } = useMsal(); - const [hasAuthenticated, setHasAuthenticated] = useState(() => { + const isUserAuthenticated = useMemo(() => { if (inProgress === InteractionStatus.Startup) { return false; } return isAuthenticated(allAccounts, matchAccount); - }); + }, [allAccounts, inProgress, matchAccount]); - useEffect(() => { - setHasAuthenticated(isAuthenticated(allAccounts, matchAccount)); - }, [allAccounts, matchAccount]); - - return hasAuthenticated; + return isUserAuthenticated; } diff --git a/lib/msal-react/test/components/MsalAuthenticationTemplate.spec.tsx b/lib/msal-react/test/components/MsalAuthenticationTemplate.spec.tsx index 7968d09f3d..9ad6a16ee1 100644 --- a/lib/msal-react/test/components/MsalAuthenticationTemplate.spec.tsx +++ b/lib/msal-react/test/components/MsalAuthenticationTemplate.spec.tsx @@ -665,7 +665,7 @@ describe("MsalAuthenticationTemplate tests", () => { expect(acquireTokenPopupSpy).toHaveBeenCalledTimes(1) ); expect( - screen.queryByText("This text will always display.") + await screen.findByText("This text will always display.") ).toBeInTheDocument(); expect( screen.queryByText("A user is authenticated!") @@ -697,16 +697,18 @@ describe("MsalAuthenticationTemplate tests", () => { return Promise.resolve(); }); - render( - -

This text will always display.

- - A user is authenticated! - -
- ); + await act(async () => { + render( + +

This text will always display.

+ + A user is authenticated! + +
+ ); + }); await waitFor(() => expect(handleRedirectSpy).toHaveBeenCalledTimes(1) @@ -765,7 +767,7 @@ describe("MsalAuthenticationTemplate tests", () => { ); await waitFor(() => expect(ssoSilentSpy).toHaveBeenCalledTimes(1)); expect( - screen.queryByText("This text will always display.") + await screen.findByText("This text will always display.") ).toBeInTheDocument(); expect( screen.queryByText("A user is authenticated!") @@ -863,7 +865,7 @@ describe("MsalAuthenticationTemplate tests", () => { await waitFor(() => expect(acquireTokenSilentSpy).toHaveBeenCalledTimes(1) ); - act(() => { + await act(async () => { const eventMessage: EventMessage = { eventType: EventType.ACQUIRE_TOKEN_SUCCESS, interactionType: InteractionType.Redirect, @@ -923,7 +925,9 @@ describe("MsalAuthenticationTemplate tests", () => { await waitFor(() => expect(acquireTokenSilentSpy).toHaveBeenCalledTimes(1) ); - expect(screen.queryByText("Error Occurred")).toBeInTheDocument(); + expect( + await screen.findByText("Error Occurred") + ).toBeInTheDocument(); expect( screen.queryByText("This text will always display.") ).toBeInTheDocument(); diff --git a/lib/msal-react/test/hooks/useIsAuthenticated.spec.tsx b/lib/msal-react/test/hooks/useIsAuthenticated.spec.tsx new file mode 100644 index 0000000000..4630529509 --- /dev/null +++ b/lib/msal-react/test/hooks/useIsAuthenticated.spec.tsx @@ -0,0 +1,82 @@ +import React from "react"; +import { render, screen, waitFor, act } from "@testing-library/react"; +import "@testing-library/jest-dom"; +import { Configuration, PublicClientApplication } from "@azure/msal-browser"; +import { TEST_CONFIG, testAccount } from "../TestConstants"; +import { MsalProvider, useIsAuthenticated, withMsal } from "../../src/index"; + +describe("useIsAuthenticated tests", () => { + let pca: PublicClientApplication; + const msalConfig: Configuration = { + auth: { + clientId: TEST_CONFIG.MSAL_CLIENT_ID, + }, + system: { + allowNativeBroker: false, + }, + }; + + let handleRedirectSpy: jest.SpyInstance; + + beforeEach(() => { + pca = new PublicClientApplication(msalConfig); + handleRedirectSpy = jest.spyOn(pca, "handleRedirectPromise"); + jest.spyOn(pca, "getAllAccounts").mockImplementation(() => []); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + test("useAuthenticated always returns true if user has an account", async () => { + const invalidAuthStateCallback = jest.fn(); + + const testComponent = ({ ...props }) => { + const isAuth = useIsAuthenticated(); + const accounts = props.msalContext.accounts; + + if (accounts.length > 0 && !isAuth) { + invalidAuthStateCallback(); + } + + return ( + <> +

This component has been wrapped by msal

+ {accounts.length === 0 &&

No accounts

} + {accounts.length > 0 &&

Has accounts

} + {isAuth &&

Is authed

} + {!isAuth &&

Not authed

} + + ); + }; + + const WrappedComponent = withMsal(testComponent); + const { rerender } = render( + + + + ); + + await waitFor(() => expect(handleRedirectSpy).toHaveBeenCalledTimes(1)); + + expect(await screen.findByText("No accounts")).toBeInTheDocument(); + expect(await screen.findByText("Not authed")).toBeInTheDocument(); + + const pcaWithAccounts = new PublicClientApplication(msalConfig); + jest.spyOn(pcaWithAccounts, "getAllAccounts").mockImplementation(() => [ + testAccount, + ]); + + await act(async () => + rerender( + + + + ) + ); + + expect(await screen.findByText("Has accounts")).toBeInTheDocument(); + expect(await screen.findByText("Is authed")).toBeInTheDocument(); + expect(invalidAuthStateCallback).toHaveBeenCalledTimes(0); + }); +}); From b2bd5ce0ec4545663d93d3083ad284228dd711d3 Mon Sep 17 00:00:00 2001 From: alexqbm <51962150+alexqbm@users.noreply.github.com> Date: Sat, 27 Apr 2024 00:33:26 +0200 Subject: [PATCH 5/6] Add the protocolMode property to the configuration.md code example. (#7053) It was missing from the code example. --------- Co-authored-by: Thomas Norling --- lib/msal-browser/docs/configuration.md | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/msal-browser/docs/configuration.md b/lib/msal-browser/docs/configuration.md index c891e4de6c..f6b1a54c2c 100644 --- a/lib/msal-browser/docs/configuration.md +++ b/lib/msal-browser/docs/configuration.md @@ -19,6 +19,7 @@ const msalConfig = { postLogoutRedirectUri: "enter_postlogout_uri_here", navigateToLoginRequestUrl: true, clientCapabilities: ["CP1"], + protocolMode: "AAD" }, cache: { cacheLocation: "sessionStorage", From b4736b139d70b0b030a0c6b18f78dea4bbbaf2ab Mon Sep 17 00:00:00 2001 From: Robbie-Microsoft <87724641+Robbie-Microsoft@users.noreply.github.com> Date: Mon, 29 Apr 2024 12:04:50 -0400 Subject: [PATCH 6/6] MSAL-Node NetworkModule: Fixed inconsistencies with cancellationToken (timeout) (#7001) - renamed cancellationToken to timeout - it can only be used in get requests (region discovery, for example) - it's not part of the public api --- ...-36d2e3a5-a377-457a-8f44-de8b7cfa68c2.json | 7 + ...-09eb19fc-c2da-4430-8f1e-37987728ea16.json | 7 + lib/msal-common/src/network/INetworkModule.ts | 2 +- lib/msal-common/src/utils/Constants.ts | 6 +- lib/msal-node/src/network/HttpClient.ts | 53 ++-- lib/msal-node/src/utils/Constants.ts | 9 +- lib/msal-node/test/network/HttpClient.spec.ts | 235 +++++++++--------- .../test/test_kit/ManagedIdentityTestUtils.ts | 6 +- lib/msal-node/test/utils/MockNetworkClient.ts | 2 +- 9 files changed, 164 insertions(+), 163 deletions(-) create mode 100644 change/@azure-msal-common-36d2e3a5-a377-457a-8f44-de8b7cfa68c2.json create mode 100644 change/@azure-msal-node-09eb19fc-c2da-4430-8f1e-37987728ea16.json diff --git a/change/@azure-msal-common-36d2e3a5-a377-457a-8f44-de8b7cfa68c2.json b/change/@azure-msal-common-36d2e3a5-a377-457a-8f44-de8b7cfa68c2.json new file mode 100644 index 0000000000..81f1babad3 --- /dev/null +++ b/change/@azure-msal-common-36d2e3a5-a377-457a-8f44-de8b7cfa68c2.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": " Fixed inconsistencies with cancellationToken (timeout)", + "packageName": "@azure/msal-common", + "email": "rginsburg@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/change/@azure-msal-node-09eb19fc-c2da-4430-8f1e-37987728ea16.json b/change/@azure-msal-node-09eb19fc-c2da-4430-8f1e-37987728ea16.json new file mode 100644 index 0000000000..bd4fa67688 --- /dev/null +++ b/change/@azure-msal-node-09eb19fc-c2da-4430-8f1e-37987728ea16.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": " Fixed inconsistencies with cancellationToken (timeout)", + "packageName": "@azure/msal-node", + "email": "rginsburg@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/lib/msal-common/src/network/INetworkModule.ts b/lib/msal-common/src/network/INetworkModule.ts index 3c9afe4dd6..15254ade3f 100644 --- a/lib/msal-common/src/network/INetworkModule.ts +++ b/lib/msal-common/src/network/INetworkModule.ts @@ -31,7 +31,7 @@ export interface INetworkModule { sendGetRequestAsync( url: string, options?: NetworkRequestOptions, - cancellationToken?: number + timeout?: number ): Promise>; /** diff --git a/lib/msal-common/src/utils/Constants.ts b/lib/msal-common/src/utils/Constants.ts index 627baa97f3..8b5a35e1a1 100644 --- a/lib/msal-common/src/utils/Constants.ts +++ b/lib/msal-common/src/utils/Constants.ts @@ -64,10 +64,11 @@ export const Constants = { }; export const HttpStatus = { - SUCCESS_RANGE_START: 200, SUCCESS: 200, + SUCCESS_RANGE_START: 200, SUCCESS_RANGE_END: 299, REDIRECT: 302, + CLIENT_ERROR: 400, CLIENT_ERROR_RANGE_START: 400, BAD_REQUEST: 400, UNAUTHORIZED: 401, @@ -75,11 +76,12 @@ export const HttpStatus = { REQUEST_TIMEOUT: 408, TOO_MANY_REQUESTS: 429, CLIENT_ERROR_RANGE_END: 499, + SERVER_ERROR: 500, SERVER_ERROR_RANGE_START: 500, - INTERNAL_SERVER_ERROR: 500, SERVICE_UNAVAILABLE: 503, GATEWAY_TIMEOUT: 504, SERVER_ERROR_RANGE_END: 599, + MULTI_SIDED_ERROR: 600, } as const; export type HttpStatus = (typeof HttpStatus)[keyof typeof HttpStatus]; diff --git a/lib/msal-node/src/network/HttpClient.ts b/lib/msal-node/src/network/HttpClient.ts index f383663299..3da5a15895 100644 --- a/lib/msal-node/src/network/HttpClient.ts +++ b/lib/msal-node/src/network/HttpClient.ts @@ -36,7 +36,8 @@ export class HttpClient implements INetworkModule { */ async sendGetRequestAsync( url: string, - options?: NetworkRequestOptions + options?: NetworkRequestOptions, + timeout?: number ): Promise> { if (this.proxyUrl) { return networkRequestViaProxy( @@ -44,7 +45,8 @@ export class HttpClient implements INetworkModule { this.proxyUrl, HttpMethod.GET, options, - this.customAgentOptions as http.AgentOptions + this.customAgentOptions as http.AgentOptions, + timeout ); } else { return networkRequestViaHttps( @@ -52,7 +54,7 @@ export class HttpClient implements INetworkModule { HttpMethod.GET, options, this.customAgentOptions as https.AgentOptions, - undefined + timeout ); } } @@ -64,8 +66,7 @@ export class HttpClient implements INetworkModule { */ async sendPostRequestAsync( url: string, - options?: NetworkRequestOptions, - cancellationToken?: number + options?: NetworkRequestOptions ): Promise> { if (this.proxyUrl) { return networkRequestViaProxy( @@ -73,16 +74,14 @@ export class HttpClient implements INetworkModule { this.proxyUrl, HttpMethod.POST, options, - this.customAgentOptions as http.AgentOptions, - cancellationToken + this.customAgentOptions as http.AgentOptions ); } else { return networkRequestViaHttps( url, HttpMethod.POST, options, - this.customAgentOptions as https.AgentOptions, - cancellationToken + this.customAgentOptions as https.AgentOptions ); } } @@ -109,10 +108,6 @@ const networkRequestViaProxy = ( headers: headers, }; - if (timeout) { - tunnelRequestOptions.timeout = timeout; - } - if (agentOptions && Object.keys(agentOptions).length) { tunnelRequestOptions.agent = new http.Agent(agentOptions); } @@ -125,6 +120,11 @@ const networkRequestViaProxy = ( "Content-Type: application/x-www-form-urlencoded\r\n" + `Content-Length: ${body.length}\r\n` + `\r\n${body}`; + } else { + // optional timeout is only for get requests (regionDiscovery, for example) + if (timeout) { + tunnelRequestOptions.timeout = timeout; + } } const outgoingRequestString = `${httpMethod.toUpperCase()} ${destinationUrl.href} HTTP/1.1\r\n` + @@ -136,7 +136,7 @@ const networkRequestViaProxy = ( return new Promise>((resolve, reject) => { const request = http.request(tunnelRequestOptions); - if (tunnelRequestOptions.timeout) { + if (timeout) { request.on("timeout", () => { request.destroy(); reject(new Error("Request time out")); @@ -165,14 +165,6 @@ const networkRequestViaProxy = ( ) ); } - if (tunnelRequestOptions.timeout) { - socket.setTimeout(tunnelRequestOptions.timeout); - socket.on("timeout", () => { - request.destroy(); - socket.destroy(); - reject(new Error("Request time out")); - }); - } // make a request over an HTTP tunnel socket.write(outgoingRequestString); @@ -291,10 +283,6 @@ const networkRequestViaHttps = ( ...NetworkUtils.urlToHttpOptions(url), }; - if (timeout) { - customOptions.timeout = timeout; - } - if (agentOptions && Object.keys(agentOptions).length) { customOptions.agent = new https.Agent(agentOptions); } @@ -305,6 +293,11 @@ const networkRequestViaHttps = ( ...customOptions.headers, "Content-Length": body.length, }; + } else { + // optional timeout is only for get requests (regionDiscovery, for example) + if (timeout) { + customOptions.timeout = timeout; + } } return new Promise>((resolve, reject) => { @@ -316,6 +309,10 @@ const networkRequestViaHttps = ( request = https.request(customOptions); } + if (isPostRequest) { + request.write(body); + } + if (timeout) { request.on("timeout", () => { request.destroy(); @@ -323,10 +320,6 @@ const networkRequestViaHttps = ( }); } - if (isPostRequest) { - request.write(body); - } - request.end(); request.on("response", (response) => { diff --git a/lib/msal-node/src/utils/Constants.ts b/lib/msal-node/src/utils/Constants.ts index d840cc2208..ebb9328c77 100644 --- a/lib/msal-node/src/utils/Constants.ts +++ b/lib/msal-node/src/utils/Constants.ts @@ -65,9 +65,10 @@ export const HttpMethod = { export type HttpMethod = (typeof HttpMethod)[keyof typeof HttpMethod]; export const ProxyStatus = { - SUCCESS_RANGE_START: 200, - SUCCESS_RANGE_END: 299, - SERVER_ERROR: 500, + SUCCESS: HttpStatus.SUCCESS, + SUCCESS_RANGE_START: HttpStatus.SUCCESS_RANGE_START, + SUCCESS_RANGE_END: HttpStatus.SUCCESS_RANGE_END, + SERVER_ERROR: HttpStatus.SERVER_ERROR, } as const; export type ProxyStatus = (typeof ProxyStatus)[keyof typeof ProxyStatus]; @@ -160,7 +161,7 @@ export const MANAGED_IDENTITY_HTTP_STATUS_CODES_TO_RETRY_ON = [ HttpStatus.NOT_FOUND, HttpStatus.REQUEST_TIMEOUT, HttpStatus.TOO_MANY_REQUESTS, - HttpStatus.INTERNAL_SERVER_ERROR, + HttpStatus.SERVER_ERROR, HttpStatus.SERVICE_UNAVAILABLE, HttpStatus.GATEWAY_TIMEOUT, ]; diff --git a/lib/msal-node/test/network/HttpClient.spec.ts b/lib/msal-node/test/network/HttpClient.spec.ts index 48bda31fc1..87f7fff445 100644 --- a/lib/msal-node/test/network/HttpClient.spec.ts +++ b/lib/msal-node/test/network/HttpClient.spec.ts @@ -3,8 +3,10 @@ import { NetworkResponse, NetworkRequestOptions, UrlToHttpRequestOptions, + HttpStatus, } from "@azure/msal-common"; import { MockedMetadataResponse } from "../utils/TestConstants"; +import { ProxyStatus } from "../../src/utils/Constants"; import http from "http"; jest.mock("http", () => ({ @@ -18,20 +20,18 @@ jest.mock("https", () => ({ request: jest.fn(), })); -const httpsStatusCode200 = 200; -const httpsStatusCode400 = 400; -const httpsStatusCode500 = 500; -const httpsStatusCode600 = 600; -const httpsStatusMessage200 = "OK"; -const httpsStatusMessage400 = "Bad Request"; -const httpsStatusMessage500 = "Internal Server Error"; -const httpsStatusMessage600 = "Unknown Error"; -const proxyStatusCode200 = 200; -const proxyStatusCode500 = 500; -const socketStatusCode200 = 200; -const socketStatusCode400 = 400; -const socketStatusCode500 = 500; -const socketStatusCode600 = 600; +const httpsStatusSuccessMessage = "OK"; +const httpsStatusClientErrorMessage = "Bad Request"; +const httpsStatusServerErrorMessage = "Internal Server Error"; +const httpsStatusMultiSidedErrorMessage = "Unknown Error"; + +const SocketStatus = { + SUCCESS: HttpStatus.SUCCESS, + CLIENT_ERROR: HttpStatus.CLIENT_ERROR, + SERVER_ERROR: HttpStatus.SERVER_ERROR, + MULTI_SIDED_ERROR: HttpStatus.MULTI_SIDED_ERROR, +} as const; +type SocketStatus = (typeof SocketStatus)[keyof typeof SocketStatus]; const url: string = "https://www.url.com"; @@ -94,15 +94,15 @@ const mockPostResponseBodyBuffer: Buffer = Buffer.from( JSON.stringify(mockPostResponseBody) ); -const mockServer400ErrorResponseBody = httpsStatusMessage400; +const mockServer400ErrorResponseBody = httpsStatusClientErrorMessage; const mockServer400ErrorResponseBodyBuffer: Buffer = Buffer.from( mockServer400ErrorResponseBody ); -const mockServer500ErrorResponseBody = httpsStatusMessage500; +const mockServer500ErrorResponseBody = httpsStatusServerErrorMessage; const mockServer500ErrorResponseBodyBuffer: Buffer = Buffer.from( mockServer500ErrorResponseBody ); -const mockServer600ErrorResponseBody = httpsStatusMessage600; +const mockServer600ErrorResponseBody = httpsStatusMultiSidedErrorMessage; const mockServer600ErrorResponseBodyBuffer: Buffer = Buffer.from( mockServer600ErrorResponseBody ); @@ -119,15 +119,15 @@ const getMockServerErrorResponse = ( if (statusCode >= 400 && statusCode <= 499) { errorType = "client_error"; errorDescriptionHelper = "A client"; - statusMessage = httpsStatusMessage400; + statusMessage = httpsStatusClientErrorMessage; } else if (statusCode >= 500 && statusCode <= 599) { errorType = "server_error"; errorDescriptionHelper = "A server"; - statusMessage = httpsStatusMessage500; + statusMessage = httpsStatusServerErrorMessage; } else { errorType = "unknown_error"; errorDescriptionHelper = "An unknown"; - statusMessage = httpsStatusMessage600; + statusMessage = httpsStatusMultiSidedErrorMessage; } return { @@ -218,19 +218,19 @@ const mockHttpRequest = ( socketRequestStatusCode: number ) => { const bodyString = - socketRequestStatusCode !== socketStatusCode200 + socketRequestStatusCode !== SocketStatus.SUCCESS ? body : JSON.stringify(body); let statusMessage; - if (socketRequestStatusCode === socketStatusCode200) { - statusMessage = httpsStatusMessage200; - } else if (socketRequestStatusCode === socketStatusCode400) { - statusMessage = httpsStatusMessage400; - } else if (socketRequestStatusCode === socketStatusCode500) { - statusMessage = httpsStatusMessage500; + if (socketRequestStatusCode === SocketStatus.SUCCESS) { + statusMessage = httpsStatusSuccessMessage; + } else if (socketRequestStatusCode === SocketStatus.CLIENT_ERROR) { + statusMessage = httpsStatusClientErrorMessage; + } else if (socketRequestStatusCode === SocketStatus.SERVER_ERROR) { + statusMessage = httpsStatusServerErrorMessage; } else { - statusMessage = httpsStatusMessage600; + statusMessage = httpsStatusMultiSidedErrorMessage; } const mockSocketResponse = `HTTP/1.1 ${socketRequestStatusCode} ${statusMessage}${headersString}${bodyString}`; @@ -238,13 +238,11 @@ const mockHttpRequest = ( // sample socket object const mockSocket: { - setTimeout: jest.Mock; on: jest.Mock; destroy: jest.Mock; write: jest.Mock; error: jest.Mock; } = { - setTimeout: jest.fn(), on: jest.fn((_socketEvent: string, cb: any) => cb(mockSocketResponseBuffer) ), @@ -301,13 +299,13 @@ describe("HttpClient", () => { test("Via Https", async () => { const httpsNetworkResponse: NetworkResponse = getNetworkResponse( mockGetResponseBody, - httpsStatusCode200 + HttpStatus.SUCCESS ); (https.request as jest.Mock).mockImplementationOnce( mockHttpsRequest( mockGetResponseBodyBuffer, - httpsStatusCode200, - httpsStatusMessage200 + HttpStatus.SUCCESS, + httpsStatusSuccessMessage ) ); await expect( @@ -317,12 +315,12 @@ describe("HttpClient", () => { test("Via Proxy", async () => { const proxyThenSocketNetworkResponse: NetworkResponse = - getNetworkResponse(mockGetResponseBody, httpsStatusCode200); + getNetworkResponse(mockGetResponseBody, HttpStatus.SUCCESS); (http.request as jest.Mock).mockImplementationOnce( mockHttpRequest( mockGetResponseBody, - proxyStatusCode200, - socketStatusCode200 + ProxyStatus.SUCCESS, + SocketStatus.SUCCESS ) ); await expect( @@ -335,13 +333,13 @@ describe("HttpClient", () => { test("Via Https", async () => { const httpsNetworkResponse: NetworkResponse = getNetworkResponse( mockPostResponseBody, - httpsStatusCode200 + HttpStatus.SUCCESS ); (https.request as jest.Mock).mockImplementationOnce( mockHttpsRequest( mockPostResponseBodyBuffer, - httpsStatusCode200, - httpsStatusMessage200 + HttpStatus.SUCCESS, + httpsStatusSuccessMessage ) ); await expect( @@ -354,12 +352,12 @@ describe("HttpClient", () => { test("Via Proxy", async () => { const proxyThenSocketNetworkResponse: NetworkResponse = - getNetworkResponse(mockPostResponseBody, httpsStatusCode200); + getNetworkResponse(mockPostResponseBody, HttpStatus.SUCCESS); (http.request as jest.Mock).mockImplementationOnce( mockHttpRequest( mockPostResponseBody, - proxyStatusCode200, - socketStatusCode200 + ProxyStatus.SUCCESS, + SocketStatus.SUCCESS ) ); await expect( @@ -378,38 +376,15 @@ describe("HttpClient", () => { test("Via Https", async () => { (https.request as jest.Mock).mockImplementationOnce( mockHttpsRequest( - mockPostResponseBodyBuffer, - httpsStatusCode200, - httpsStatusMessage200 - ) - ); - await expect( - httpClientWithoutProxyUrl.sendPostRequestAsync( - url, - postNetworkRequestOptions, - timeoutInMilliseconds - ) - ).rejects.toEqual(error); - }); - - /** - * can only test http timeout, not socket timeout inside of the socket - * - * future work: add another timeout parameter to sendPostRequestAsync so it accepts two different timeouts: - * one for http timeout and one for the socket timeout inside of the socket - */ - test("Via Proxy", async () => { - (http.request as jest.Mock).mockImplementationOnce( - mockHttpRequest( - mockPostResponseBody, - proxyStatusCode200, - socketStatusCode200 + mockGetResponseBodyBuffer, + HttpStatus.SUCCESS, + httpsStatusSuccessMessage ) ); await expect( - httpClientWithProxyUrl.sendPostRequestAsync( + httpClientWithoutProxyUrl.sendGetRequestAsync( url, - postNetworkRequestOptions, + undefined, timeoutInMilliseconds ) ).rejects.toEqual(error); @@ -426,14 +401,14 @@ describe("HttpClient", () => { test("Client Error 400", async () => { const serverErrorNetworkResponse: NetworkResponse = getNetworkResponse( - getMockServerErrorResponse(httpsStatusCode400), - httpsStatusCode400 + getMockServerErrorResponse(HttpStatus.CLIENT_ERROR), + HttpStatus.CLIENT_ERROR ); (https.request as jest.Mock).mockImplementationOnce( mockHttpsRequest( mockServer400ErrorResponseBodyBuffer, - httpsStatusCode400, - httpsStatusMessage400 + HttpStatus.CLIENT_ERROR, + httpsStatusClientErrorMessage ) ); await expect( @@ -444,14 +419,14 @@ describe("HttpClient", () => { test("Server Error 500", async () => { const serverErrorNetworkResponse: NetworkResponse = getNetworkResponse( - getMockServerErrorResponse(httpsStatusCode500), - httpsStatusCode500 + getMockServerErrorResponse(HttpStatus.SERVER_ERROR), + HttpStatus.SERVER_ERROR ); (https.request as jest.Mock).mockImplementationOnce( mockHttpsRequest( mockServer500ErrorResponseBodyBuffer, - httpsStatusCode500, - httpsStatusMessage500 + HttpStatus.SERVER_ERROR, + httpsStatusServerErrorMessage ) ); await expect( @@ -462,14 +437,16 @@ describe("HttpClient", () => { test("Unknown Error 600", async () => { const serverErrorNetworkResponse: NetworkResponse = getNetworkResponse( - getMockServerErrorResponse(httpsStatusCode600), - httpsStatusCode600 + getMockServerErrorResponse( + HttpStatus.MULTI_SIDED_ERROR + ), + HttpStatus.MULTI_SIDED_ERROR ); (https.request as jest.Mock).mockImplementationOnce( mockHttpsRequest( mockServer600ErrorResponseBodyBuffer, - httpsStatusCode600, - httpsStatusMessage600 + HttpStatus.MULTI_SIDED_ERROR, + httpsStatusMultiSidedErrorMessage ) ); await expect( @@ -483,8 +460,8 @@ describe("HttpClient", () => { (http.request as jest.Mock).mockImplementationOnce( mockHttpRequest( mockGetResponseBody, - proxyStatusCode500, - httpsStatusCode500 + ProxyStatus.SERVER_ERROR, + HttpStatus.SERVER_ERROR ) ); await expect( @@ -496,14 +473,16 @@ describe("HttpClient", () => { test("Client Error 400", async () => { const serverErrorNetworkResponse: NetworkResponse = getNetworkResponse( - getMockServerErrorResponse(socketStatusCode400), - socketStatusCode400 + getMockServerErrorResponse( + SocketStatus.CLIENT_ERROR + ), + SocketStatus.CLIENT_ERROR ); (http.request as jest.Mock).mockImplementationOnce( mockHttpRequest( mockServer400ErrorResponseBody, - proxyStatusCode200, - socketStatusCode400 + ProxyStatus.SUCCESS, + SocketStatus.CLIENT_ERROR ) ); await expect( @@ -514,14 +493,16 @@ describe("HttpClient", () => { test("Server Error 500", async () => { const serverErrorNetworkResponse: NetworkResponse = getNetworkResponse( - getMockServerErrorResponse(socketStatusCode500), - socketStatusCode500 + getMockServerErrorResponse( + SocketStatus.SERVER_ERROR + ), + SocketStatus.SERVER_ERROR ); (http.request as jest.Mock).mockImplementationOnce( mockHttpRequest( mockServer500ErrorResponseBody, - proxyStatusCode200, - socketStatusCode500 + ProxyStatus.SUCCESS, + SocketStatus.SERVER_ERROR ) ); await expect( @@ -532,14 +513,16 @@ describe("HttpClient", () => { test("Unknown Error 600", async () => { const serverErrorNetworkResponse: NetworkResponse = getNetworkResponse( - getMockServerErrorResponse(socketStatusCode600), - socketStatusCode600 + getMockServerErrorResponse( + SocketStatus.MULTI_SIDED_ERROR + ), + SocketStatus.MULTI_SIDED_ERROR ); (http.request as jest.Mock).mockImplementationOnce( mockHttpRequest( mockServer600ErrorResponseBody, - proxyStatusCode200, - socketStatusCode600 + ProxyStatus.SUCCESS, + SocketStatus.MULTI_SIDED_ERROR ) ); await expect( @@ -555,14 +538,14 @@ describe("HttpClient", () => { test("Client Error 400", async () => { const serverErrorNetworkResponse: NetworkResponse = getNetworkResponse( - getMockServerErrorResponse(httpsStatusCode400), - httpsStatusCode400 + getMockServerErrorResponse(HttpStatus.CLIENT_ERROR), + HttpStatus.CLIENT_ERROR ); (https.request as jest.Mock).mockImplementationOnce( mockHttpsRequest( mockServer400ErrorResponseBodyBuffer, - httpsStatusCode400, - httpsStatusMessage400 + HttpStatus.CLIENT_ERROR, + httpsStatusClientErrorMessage ) ); await expect( @@ -576,14 +559,14 @@ describe("HttpClient", () => { test("Server Error 500", async () => { const serverErrorNetworkResponse: NetworkResponse = getNetworkResponse( - getMockServerErrorResponse(httpsStatusCode500), - httpsStatusCode500 + getMockServerErrorResponse(HttpStatus.SERVER_ERROR), + HttpStatus.SERVER_ERROR ); (https.request as jest.Mock).mockImplementationOnce( mockHttpsRequest( mockServer500ErrorResponseBodyBuffer, - httpsStatusCode500, - httpsStatusMessage500 + HttpStatus.SERVER_ERROR, + httpsStatusServerErrorMessage ) ); await expect( @@ -597,14 +580,16 @@ describe("HttpClient", () => { test("Unknown Error 600", async () => { const serverErrorNetworkResponse: NetworkResponse = getNetworkResponse( - getMockServerErrorResponse(httpsStatusCode600), - httpsStatusCode600 + getMockServerErrorResponse( + HttpStatus.MULTI_SIDED_ERROR + ), + HttpStatus.MULTI_SIDED_ERROR ); (https.request as jest.Mock).mockImplementationOnce( mockHttpsRequest( mockServer600ErrorResponseBodyBuffer, - httpsStatusCode600, - httpsStatusMessage600 + HttpStatus.MULTI_SIDED_ERROR, + httpsStatusMultiSidedErrorMessage ) ); await expect( @@ -621,8 +606,8 @@ describe("HttpClient", () => { (http.request as jest.Mock).mockImplementationOnce( mockHttpRequest( mockPostResponseBody, - proxyStatusCode500, - httpsStatusCode500 + ProxyStatus.SERVER_ERROR, + HttpStatus.SERVER_ERROR ) ); await expect( @@ -637,14 +622,16 @@ describe("HttpClient", () => { test("Client Error 400", async () => { const serverErrorNetworkResponse: NetworkResponse = getNetworkResponse( - getMockServerErrorResponse(socketStatusCode400), - socketStatusCode400 + getMockServerErrorResponse( + SocketStatus.CLIENT_ERROR + ), + SocketStatus.CLIENT_ERROR ); (http.request as jest.Mock).mockImplementationOnce( mockHttpRequest( mockServer400ErrorResponseBody, - proxyStatusCode200, - socketStatusCode400 + ProxyStatus.SUCCESS, + SocketStatus.CLIENT_ERROR ) ); await expect( @@ -658,14 +645,16 @@ describe("HttpClient", () => { test("Server Error 500", async () => { const serverErrorNetworkResponse: NetworkResponse = getNetworkResponse( - getMockServerErrorResponse(socketStatusCode500), - socketStatusCode500 + getMockServerErrorResponse( + SocketStatus.SERVER_ERROR + ), + SocketStatus.SERVER_ERROR ); (http.request as jest.Mock).mockImplementationOnce( mockHttpRequest( mockServer500ErrorResponseBody, - proxyStatusCode200, - socketStatusCode500 + ProxyStatus.SUCCESS, + SocketStatus.SERVER_ERROR ) ); await expect( @@ -679,14 +668,16 @@ describe("HttpClient", () => { test("Unknown Error 600", async () => { const serverErrorNetworkResponse: NetworkResponse = getNetworkResponse( - getMockServerErrorResponse(socketStatusCode600), - socketStatusCode600 + getMockServerErrorResponse( + SocketStatus.MULTI_SIDED_ERROR + ), + SocketStatus.MULTI_SIDED_ERROR ); (http.request as jest.Mock).mockImplementationOnce( mockHttpRequest( mockServer600ErrorResponseBody, - proxyStatusCode200, - socketStatusCode600 + ProxyStatus.SUCCESS, + SocketStatus.MULTI_SIDED_ERROR ) ); await expect( diff --git a/lib/msal-node/test/test_kit/ManagedIdentityTestUtils.ts b/lib/msal-node/test/test_kit/ManagedIdentityTestUtils.ts index da72c8db63..949a42ec1d 100644 --- a/lib/msal-node/test/test_kit/ManagedIdentityTestUtils.ts +++ b/lib/msal-node/test/test_kit/ManagedIdentityTestUtils.ts @@ -92,7 +92,7 @@ export class ManagedIdentityNetworkClient implements INetworkModule { sendGetRequestAsync( _url: string, _options?: NetworkRequestOptions, - _cancellationToken?: number + _timeout?: number ): Promise> { return new Promise>((resolve, _reject) => { resolve({ @@ -169,7 +169,7 @@ export class ManagedIdentityNetworkErrorClient implements INetworkModule { sendGetRequestAsync( _url: string, _options?: NetworkRequestOptions, - _cancellationToken?: number + _timeout?: number ): Promise> { return new Promise>((resolve, _reject) => { resolve( @@ -188,7 +188,7 @@ export class ManagedIdentityNetworkErrorClient implements INetworkModule { ): Promise> { return new Promise>((resolve, _reject) => { resolve({ - status: httpStatusCode || HttpStatus.INTERNAL_SERVER_ERROR, + status: httpStatusCode || HttpStatus.SERVER_ERROR, body: { message: MANAGED_IDENTITY_TOKEN_RETRIEVAL_ERROR, correlationId: mockAuthenticationResult.correlationId, diff --git a/lib/msal-node/test/utils/MockNetworkClient.ts b/lib/msal-node/test/utils/MockNetworkClient.ts index b523078165..9540ead950 100644 --- a/lib/msal-node/test/utils/MockNetworkClient.ts +++ b/lib/msal-node/test/utils/MockNetworkClient.ts @@ -17,7 +17,7 @@ export const mockNetworkClient = ( sendGetRequestAsync( _url: string, _options?: NetworkRequestOptions, - _cancellationToken?: number + _timeout?: number ): Promise> { return new Promise>((resolve, _reject) => { resolve(getRequestResult as NetworkResponse);