diff --git a/change/@azure-msal-common-36ee3c61-5054-4e0a-8614-47950e257505.json b/change/@azure-msal-common-36ee3c61-5054-4e0a-8614-47950e257505.json new file mode 100644 index 0000000000..9202951f3a --- /dev/null +++ b/change/@azure-msal-common-36ee3c61-5054-4e0a-8614-47950e257505.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "Move correlationId to query string on /token calls", + "packageName": "@azure/msal-common", + "email": "thomas.norling@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/lib/msal-common/apiReview/msal-common.api.md b/lib/msal-common/apiReview/msal-common.api.md index 9acc6cd260..c80577cf7f 100644 --- a/lib/msal-common/apiReview/msal-common.api.md +++ b/lib/msal-common/apiReview/msal-common.api.md @@ -4284,9 +4284,9 @@ const X_MS_LIB_CAPABILITY = "x-ms-lib-capability"; // src/client/AuthorizationCodeClient.ts:228:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // src/client/AuthorizationCodeClient.ts:229:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // src/client/AuthorizationCodeClient.ts:307:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// src/client/AuthorizationCodeClient.ts:512:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// src/client/AuthorizationCodeClient.ts:735:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// src/client/AuthorizationCodeClient.ts:795:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// src/client/AuthorizationCodeClient.ts:507:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// src/client/AuthorizationCodeClient.ts:730:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// src/client/AuthorizationCodeClient.ts:790:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // src/client/RefreshTokenClient.ts:193:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // src/client/RefreshTokenClient.ts:277:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // src/client/RefreshTokenClient.ts:278:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen diff --git a/lib/msal-common/src/client/AuthorizationCodeClient.ts b/lib/msal-common/src/client/AuthorizationCodeClient.ts index a520e9c1ef..fd58ce6098 100644 --- a/lib/msal-common/src/client/AuthorizationCodeClient.ts +++ b/lib/msal-common/src/client/AuthorizationCodeClient.ts @@ -420,11 +420,6 @@ export class AuthorizationCodeClient extends BaseClient { } } - const correlationId = - request.correlationId || - this.config.cryptoInterface.createNewGuid(); - parameterBuilder.addCorrelationId(correlationId); - if ( !StringUtils.isEmptyObj(request.claims) || (this.config.authOptions.clientCapabilities && diff --git a/lib/msal-common/src/client/BaseClient.ts b/lib/msal-common/src/client/BaseClient.ts index cdebaaab10..820243cfb3 100644 --- a/lib/msal-common/src/client/BaseClient.ts +++ b/lib/msal-common/src/client/BaseClient.ts @@ -226,6 +226,8 @@ export abstract class BaseClient { ); } + parameterBuilder.addCorrelationId(request.correlationId); + return parameterBuilder.createQueryString(); } } diff --git a/lib/msal-common/src/client/RefreshTokenClient.ts b/lib/msal-common/src/client/RefreshTokenClient.ts index 59310be645..7dbb2347c2 100644 --- a/lib/msal-common/src/client/RefreshTokenClient.ts +++ b/lib/msal-common/src/client/RefreshTokenClient.ts @@ -380,8 +380,6 @@ export class RefreshTokenClient extends BaseClient { parameterBuilder.addServerTelemetry(this.serverTelemetryManager); } - parameterBuilder.addCorrelationId(correlationId); - parameterBuilder.addRefreshToken(request.refreshToken); if (this.config.clientCredentials.clientSecret) { diff --git a/lib/msal-common/test/client/AuthorizationCodeClient.spec.ts b/lib/msal-common/test/client/AuthorizationCodeClient.spec.ts index 546ece6092..ef5429c0c1 100644 --- a/lib/msal-common/test/client/AuthorizationCodeClient.spec.ts +++ b/lib/msal-common/test/client/AuthorizationCodeClient.spec.ts @@ -2327,6 +2327,46 @@ describe("AuthorizationCodeClient unit tests", () => { ).toBe(true); }); + it("Adds correlationId to the /token query string", (done) => { + jest.spyOn( + Authority.prototype, + "getEndpointMetadataFromNetwork" + ).mockResolvedValue(DEFAULT_OPENID_CONFIG_RESPONSE.body); + jest.spyOn( + AuthorizationCodeClient.prototype, + "executePostToTokenEndpoint" + // @ts-expect-error + ).mockImplementation((url: string) => { + try { + expect(url).toContain( + `client-request-id=${RANDOM_TEST_GUID}` + ); + done(); + } catch (error) { + done(error); + } + }); + + const client = new AuthorizationCodeClient(config); + const authorizationCodeRequest: CommonAuthorizationCodeRequest = { + authority: Constants.DEFAULT_AUTHORITY, + scopes: [ + ...TEST_CONFIG.DEFAULT_GRAPH_SCOPE, + ...TEST_CONFIG.DEFAULT_SCOPES, + ], + redirectUri: TEST_URIS.TEST_REDIRECT_URI_LOCALHOST, + code: TEST_TOKENS.AUTHORIZATION_CODE, + codeVerifier: TEST_CONFIG.TEST_VERIFIER, + claims: TEST_CONFIG.CLAIMS, + correlationId: RANDOM_TEST_GUID, + authenticationScheme: AuthenticationScheme.BEARER, + }; + + client.acquireToken(authorizationCodeRequest).catch((error) => { + // Catch errors thrown after the function call this test is testing + }); + }); + it("Adds tokenQueryParameters to the /token request", (done) => { jest.spyOn( Authority.prototype, diff --git a/lib/msal-common/test/client/RefreshTokenClient.spec.ts b/lib/msal-common/test/client/RefreshTokenClient.spec.ts index d746e43787..328c1d88d0 100644 --- a/lib/msal-common/test/client/RefreshTokenClient.spec.ts +++ b/lib/msal-common/test/client/RefreshTokenClient.spec.ts @@ -144,6 +144,44 @@ describe("RefreshTokenClient unit tests", () => { config = await ClientTestUtils.createTestClientConfiguration(); }); + it("Adds correlationId to the /token query string", (done) => { + jest.spyOn( + RefreshTokenClient.prototype, + "executePostToTokenEndpoint" + // @ts-expect-error + ).mockImplementation((url: string) => { + try { + expect(url).toContain( + `client-request-id=${TEST_CONFIG.CORRELATION_ID}` + ); + done(); + } catch (error) { + done(error); + } + }); + + const client = new RefreshTokenClient( + config, + stubPerformanceClient + ); + const refreshTokenRequest: CommonRefreshTokenRequest = { + scopes: TEST_CONFIG.DEFAULT_GRAPH_SCOPE, + refreshToken: TEST_TOKENS.REFRESH_TOKEN, + claims: TEST_CONFIG.CLAIMS, + authority: TEST_CONFIG.validAuthority, + correlationId: TEST_CONFIG.CORRELATION_ID, + authenticationScheme: + TEST_CONFIG.TOKEN_TYPE_BEARER as AuthenticationScheme, + tokenQueryParameters: { + testParam: "testValue", + }, + }; + + client.acquireToken(refreshTokenRequest).catch((e) => { + // Catch errors thrown after the function call this test is testing + }); + }); + it("Adds tokenQueryParameters to the /token request", (done) => { jest.spyOn( RefreshTokenClient.prototype, diff --git a/lib/msal-node/test/config/ClientConfiguration.spec.ts b/lib/msal-node/test/config/ClientConfiguration.spec.ts index 42722ce5fa..a2bdd85d69 100644 --- a/lib/msal-node/test/config/ClientConfiguration.spec.ts +++ b/lib/msal-node/test/config/ClientConfiguration.spec.ts @@ -18,6 +18,7 @@ import { ConfidentialClientApplication, } from "../../src"; import { OnBehalfOfRequest } from "../../src/request/OnBehalfOfRequest"; +import { RANDOM_TEST_GUID } from "../test_kit/StringConstants.js"; describe("ClientConfiguration tests", () => { test("builds configuration and assigns default functions", () => { @@ -203,6 +204,7 @@ describe("ClientConfiguration tests", () => { const request: ClientCredentialRequest = { scopes: TEST_CONSTANTS.DEFAULT_GRAPH_SCOPE, skipCache: true, + correlationId: RANDOM_TEST_GUID, }; await new ConfidentialClientApplication( @@ -215,7 +217,7 @@ describe("ClientConfiguration tests", () => { DEFAULT_OPENID_CONFIG_RESPONSE.body.token_endpoint.replace( "{tenant}", "tenantid" - ), + ) + `?client-request-id=${RANDOM_TEST_GUID}`, expect.objectContaining({ body: expect.stringContaining("TEST-CAPABILITY"), }) @@ -227,6 +229,7 @@ describe("ClientConfiguration tests", () => { scopes: TEST_CONSTANTS.DEFAULT_GRAPH_SCOPE, oboAssertion: "user_assertion_hash", skipCache: true, + correlationId: RANDOM_TEST_GUID, }; const appConfig: Configuration = { @@ -258,7 +261,7 @@ describe("ClientConfiguration tests", () => { DEFAULT_OPENID_CONFIG_RESPONSE.body.token_endpoint.replace( "{tenant}", "tenantid" - ), + ) + `?client-request-id=${RANDOM_TEST_GUID}`, expect.objectContaining({ body: expect.stringContaining("TEST-CAPABILITY"), })