Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Discard empty redirect telemetry events with no error codes #7058

Merged
merged 5 commits into from
Apr 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "minor",
"comment": "Discard empty redirect telemetry events with no error codes #7058",
"packageName": "@azure/msal-browser",
"email": "[email protected]",
"dependentChangeType": "patch"
}
18 changes: 12 additions & 6 deletions lib/msal-browser/src/controllers/StandardController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -455,11 +455,7 @@ export class StandardController implements IController {
this.logger,
this.performanceClient,
rootMeasurement.event.correlationId
)(
hash,
this.performanceClient,
rootMeasurement.event.correlationId
);
)(hash, rootMeasurement);
}

return redirectResponse
Expand Down Expand Up @@ -492,12 +488,22 @@ export class StandardController implements IController {
success: true,
accountType: getAccountType(result.account),
});
} else {
/*
* Instrument an event only if an error code is set. Otherwise, discard it when the redirect response
* is empty and the error code is missing.
*/
if (rootMeasurement.event.errorCode) {
rootMeasurement.end({ success: false });
} else {
rootMeasurement.discard();
}
}

this.eventHandler.emitEvent(
EventType.HANDLE_REDIRECT_END,
InteractionType.Redirect
);
rootMeasurement.end({ success: false });

return result;
})
Expand Down
18 changes: 6 additions & 12 deletions lib/msal-browser/src/interaction_client/RedirectClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
invokeAsync,
ServerResponseType,
UrlUtils,
InProgressPerformanceEvent,
} from "@azure/msal-common";
import { StandardInteractionClient } from "./StandardInteractionClient";
import {
Expand Down Expand Up @@ -190,14 +191,12 @@ export class RedirectClient extends StandardInteractionClient {
* Checks if navigateToLoginRequestUrl is set, and:
* - if true, performs logic to cache and navigate
* - if false, handles hash string and parses response
* @param hash {string?} url hash
* @param performanceClient {IPerformanceClient?}
* @param correlationId {string?} correlation identifier
* @param hash {string} url hash
* @param parentMeasurement {InProgressPerformanceEvent} parent measurement
*/
async handleRedirectPromise(
hash?: string,
performanceClient?: IPerformanceClient,
correlationId?: string
hash: string = "",
parentMeasurement: InProgressPerformanceEvent
): Promise<AuthenticationResult | null> {
const serverTelemetryManager = this.initializeServerTelemetryManager(
ApiId.handleRedirectPromise
Expand All @@ -220,12 +219,7 @@ export class RedirectClient extends StandardInteractionClient {
this.browserStorage.cleanRequestByInteractionType(
InteractionType.Redirect
);
if (performanceClient && correlationId) {
performanceClient?.addFields(
{ errorCode: "no_server_response" },
correlationId
);
}
parentMeasurement.event.errorCode = "no_server_response";
return null;
}

Expand Down
61 changes: 61 additions & 0 deletions lib/msal-browser/test/app/PublicClientApplication.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import {
InteractionRequiredAuthErrorCodes,
Logger,
LogLevel,
PerformanceClient,
PerformanceEvent,
PerformanceEvents,
PersistentCacheKeys,
Expand Down Expand Up @@ -1020,6 +1021,66 @@ describe("PublicClientApplication.ts Class Unit Tests", () => {
expect(tokenResponse1).toEqual(tokenResponse2);
expect(tokenResponse4).toEqual(tokenResponse1);
});

it("Emits performance event with error code if no response is provided", (done) => {
const testAccount: AccountInfo = {
homeAccountId: TEST_DATA_CLIENT_INFO.TEST_HOME_ACCOUNT_ID,
localAccountId: TEST_DATA_CLIENT_INFO.TEST_UID,
environment: "login.windows.net",
tenantId: "3338040d-6c67-4c5b-b112-36a304b66dad",
username: "[email protected]",
};
sinon
.stub(StandardController.prototype, "getAllAccounts")
.returns([testAccount]);
sinon
// @ts-ignore
.stub(RedirectClient.prototype, "getRedirectResponse")
// @ts-ignore
.returns([null, ""]);

const callbackId = pca.addPerformanceCallback((events) => {
expect(events.length).toEqual(1);
expect(events[0].success).toBe(false);
expect(events[0].errorCode).toBe("no_server_response");
pca.removePerformanceCallback(callbackId);
done();
});

window.sessionStorage.setItem(
`${Constants.CACHE_PREFIX}.${TEST_CONFIG.MSAL_CLIENT_ID}.${TemporaryCacheKeys.CORRELATION_ID}`,
RANDOM_TEST_GUID
);
window.sessionStorage.setItem(
`${Constants.CACHE_PREFIX}.${TemporaryCacheKeys.INTERACTION_STATUS_KEY}`,
TEST_CONFIG.MSAL_CLIENT_ID
);
pca.handleRedirectPromise();
});

it("Discards performance event if handleRedirectPromise returns null and no error code is set", async () => {
const testAccount: AccountInfo = {
homeAccountId: TEST_DATA_CLIENT_INFO.TEST_HOME_ACCOUNT_ID,
localAccountId: TEST_DATA_CLIENT_INFO.TEST_UID,
environment: "login.windows.net",
tenantId: "3338040d-6c67-4c5b-b112-36a304b66dad",
username: "[email protected]",
};
sinon
.stub(StandardController.prototype, "getAllAccounts")
.returns([testAccount]);
sinon
.stub(RedirectClient.prototype, "handleRedirectPromise")
.resolves(null);

const emitSpy = jest.spyOn(
PerformanceClient.prototype,
"emitEvents"
);

await pca.handleRedirectPromise();
expect(emitSpy).toHaveBeenCalledTimes(0);
});
});
describe("OIDC Protocol Mode tests", () => {
beforeEach(async () => {
Expand Down
Loading
Loading