Skip to content
Open
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
749f002
Initial plan
Copilot Dec 3, 2025
2ec6f71
Add telemetry performance event fields for platform broker integration
Copilot Dec 3, 2025
d1ba090
Update PlatformAuthInteractionClient telemetry instrumentation
Copilot Dec 3, 2025
26b4174
Add StandardController telemetry for acquireToken methods (partial)
Copilot Dec 3, 2025
445e38f
Complete StandardController telemetry instrumentation
Copilot Dec 3, 2025
b988285
Add beachball change files for msal-v5 branch
Copilot Dec 3, 2025
5d2209e
Remove getAccountType function and restore original telemetry fields
Copilot Dec 3, 2025
67af560
Update lib/msal-browser/src/controllers/StandardController.ts
sameerag Dec 3, 2025
10bc6e7
Update NativeAuthError test for PERSISTENT_ERROR behavior
Copilot Dec 3, 2025
92d5766
Update lib/msal-common/src/telemetry/performance/PerformanceEvent.ts
sameerag Dec 3, 2025
9f988d6
Update change/@azure-msal-browser-v5-telemetry-cherry-pick.json
sameerag Dec 3, 2025
2e190fe
Update change/@azure-msal-common-v5-telemetry-cherry-pick.json
sameerag Dec 3, 2025
1d8f086
Update lib/msal-browser/src/interaction_client/PlatformAuthInteractio…
sameerag Dec 3, 2025
9e82d1b
Remove misleading brokerErrorCode for cache miss scenario
Copilot Dec 3, 2025
58cd7a2
Add performance event validation tests to PlatformAuthInteractionClient
Copilot Dec 3, 2025
ebd6f93
Update change/@azure-msal-browser-v5-telemetry-cherry-pick.json
sameerag Dec 3, 2025
a7e8b69
Update change/@azure-msal-browser-v5-telemetry-cherry-pick.json
sameerag Dec 3, 2025
56cd917
Update change/@azure-msal-common-v5-telemetry-cherry-pick.json
sameerag Dec 3, 2025
b889f1b
Update changefile format to reference PR #7991
Copilot Dec 3, 2025
7331407
Add telemetry validation to acquireTokenRedirect platform broker test
Copilot Dec 3, 2025
3e06f5a
Merge branch 'msal-v5' into copilot/cherry-pick-js-telemetry-params
sameerag Dec 4, 2025
22ff8b6
Update apiReview for common
sameerag Dec 4, 2025
f04ba36
Update change/@azure-msal-common-v5-telemetry-cherry-pick.json
sameerag Dec 4, 2025
fe9508d
Update change/@azure-msal-common-v5-telemetry-cherry-pick.json
sameerag Dec 4, 2025
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
7 changes: 7 additions & 0 deletions change/@azure-msal-browser-v5-telemetry-cherry-pick.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "minor",
"comment": "Cherry-pick: Add Platform Telemetry (PR #7991) [#7991](https://github.com/AzureAD/microsoft-authentication-library-for-js/pull/7991)",
"packageName": "@azure/msal-browser",
"email": "[email protected]",
"dependentChangeType": "patch"
}
7 changes: 7 additions & 0 deletions change/@azure-msal-common-v5-telemetry-cherry-pick.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "minor",
"comment": "Cherry-pick: Add Platform Telemetry [#7991](https://github.com/AzureAD/microsoft-authentication-library-for-js/pull/7991)",
"packageName": "@azure/msal-common",
"email": "[email protected]",
"dependentChangeType": "patch"
}
50 changes: 45 additions & 5 deletions lib/msal-browser/src/controllers/StandardController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,9 @@ export class StandardController implements IController {
"handleRedirectPromise - acquiring token from native platform",
correlationId
);
rootMeasurement.add({
isPlatformBrokerRequest: true,
});
const nativeClient = new PlatformAuthInteractionClient(
this.config,
this.browserStorage,
Expand Down Expand Up @@ -650,6 +653,9 @@ export class StandardController implements IController {
this.platformAuthProvider &&
this.canUsePlatformBroker(request)
) {
atrMeasurement.add({
isPlatformBrokerRequest: true,
});
const nativeClient = new PlatformAuthInteractionClient(
this.config,
this.browserStorage,
Expand All @@ -664,14 +670,19 @@ export class StandardController implements IController {
this.nativeInternalStorage,
correlationId
);

result = nativeClient
.acquireTokenRedirect(request, atrMeasurement)
.catch((e: AuthError) => {
atrMeasurement.add({
brokerErrorName: e.name,
brokerErrorCode: e.errorCode,
});
if (
e instanceof NativeAuthError &&
isFatalNativeAuthError(e)
) {
this.platformAuthProvider = undefined; // If extension gets uninstalled during session prevent future requests from continuing to attempt
this.platformAuthProvider = undefined; // If extension gets uninstalled during session prevent future requests from continuing to attempt platform broker calls
const redirectClient =
this.createRedirectClient(correlationId);
return redirectClient.acquireToken(request);
Expand Down Expand Up @@ -771,6 +782,9 @@ export class StandardController implements IController {
const pkce = this.getPreGeneratedPkceCodes(correlationId);

if (this.canUsePlatformBroker(request)) {
atPopupMeasurement.add({
isPlatformBrokerRequest: true,
});
result = this.acquireTokenNative(
{
...request,
Expand All @@ -790,11 +804,15 @@ export class StandardController implements IController {
return response;
})
.catch((e: AuthError) => {
atPopupMeasurement.add({
brokerErrorName: e.name,
brokerErrorCode: e.errorCode,
});
if (
e instanceof NativeAuthError &&
isFatalNativeAuthError(e)
) {
this.platformAuthProvider = undefined; // If extension gets uninstalled during session prevent future requests from continuing to attempt
this.platformAuthProvider = undefined; // If extension gets uninstalled during session prevent future requests from continuing to attempt platform broker calls
const popupClient =
this.createPopupClient(correlationId);
return popupClient.acquireToken(request, pkce);
Expand Down Expand Up @@ -942,10 +960,17 @@ export class StandardController implements IController {
let result: Promise<AuthenticationResult>;

if (this.canUsePlatformBroker(validRequest)) {
this.ssoSilentMeasurement?.add({
isPlatformBrokerRequest: true,
});
result = this.acquireTokenNative(
validRequest,
ApiId.ssoSilent
).catch((e: AuthError) => {
this.ssoSilentMeasurement?.add({
brokerErrorName: e.name,
brokerErrorCode: e.errorCode,
});
// If native token acquisition fails for availability reasons fallback to standard flow
if (e instanceof NativeAuthError && isFatalNativeAuthError(e)) {
this.platformAuthProvider = undefined; // If extension gets uninstalled during session prevent future requests from continuing to attempt
Expand Down Expand Up @@ -1108,6 +1133,9 @@ export class StandardController implements IController {
if (
this.canUsePlatformBroker(request, request.nativeAccountId)
) {
atbcMeasurement.add({
isPlatformBrokerRequest: true,
});
const result = await this.acquireTokenNative(
{
...request,
Expand All @@ -1123,6 +1151,10 @@ export class StandardController implements IController {
) {
this.platformAuthProvider = undefined; // If extension gets uninstalled during session prevent future requests from continuing to attempt
}
atbcMeasurement.add({
brokerErrorName: e.name,
brokerErrorCode: e.errorCode,
});
throw e;
});
atbcMeasurement.end(
Expand Down Expand Up @@ -1190,7 +1222,6 @@ export class StandardController implements IController {
this.acquireTokenByCodeAsyncMeasurement?.end({
success: true,
fromCache: response.fromCache,
isNativeBroker: response.fromPlatformBroker,
});
return response;
})
Expand Down Expand Up @@ -1878,7 +1909,6 @@ export class StandardController implements IController {
{
success: true,
fromCache: result.fromCache,
isNativeBroker: result.fromPlatformBroker,
accessTokenSize: result.accessToken.length,
idTokenSize: result.idToken.length,
},
Expand Down Expand Up @@ -2117,7 +2147,6 @@ export class StandardController implements IController {
this.performanceClient.addFields(
{
fromCache: response.fromCache,
isNativeBroker: response.fromPlatformBroker,
},
request.correlationId
);
Expand Down Expand Up @@ -2167,12 +2196,23 @@ export class StandardController implements IController {
"acquireTokenSilent - attempting to acquire token from native platform",
silentRequest.correlationId
);
this.performanceClient.addFields(
{ isPlatformBrokerRequest: true },
silentRequest.correlationId
);
return this.acquireTokenNative(
silentRequest,
ApiId.acquireTokenSilent_silentFlow,
silentRequest.account.nativeAccountId,
cacheLookupPolicy
).catch(async (e: AuthError) => {
this.performanceClient.addFields(
{
brokerErrorName: e.name,
brokerErrorCode: e.errorCode,
},
silentRequest.correlationId
);
// If native token acquisition fails for availability reasons fallback to web flow
if (e instanceof NativeAuthError && isFatalNativeAuthError(e)) {
this.logger.verbose(
Expand Down
3 changes: 1 addition & 2 deletions lib/msal-browser/src/error/NativeAuthError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,7 @@ export function isFatalNativeAuthError(error: NativeAuthError): boolean {
if (
error.ext &&
error.ext.status &&
(error.ext.status === NativeStatusCodes.PERSISTENT_ERROR ||
error.ext.status === NativeStatusCodes.DISABLED)
error.ext.status === NativeStatusCodes.DISABLED
) {
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ export class PlatformAuthInteractionClient extends BaseInteractionClient {
// start the perf measurement
const nativeATMeasurement = this.performanceClient.startMeasurement(
BrowserPerformanceEvents.NativeInteractionClientAcquireToken,
request.correlationId
this.correlationId
);
const reqTimestamp = TimeUtils.nowSeconds();

Expand Down Expand Up @@ -200,6 +200,9 @@ export class PlatformAuthInteractionClient extends BaseInteractionClient {
"MSAL internal Cache does not contain tokens, return error as per cache policy",
this.correlationId
);
nativeATMeasurement.end({
success: false,
});
throw e;
}
// continue with a native call for any and all errors
Expand All @@ -220,25 +223,36 @@ export class PlatformAuthInteractionClient extends BaseInteractionClient {
.then((result: AuthenticationResult) => {
nativeATMeasurement.end({
success: true,
isNativeBroker: true,
requestId: result.requestId,
});
serverTelemetryManager.clearNativeBrokerErrorCode();
if (this.performanceClient && this.correlationId) {
this.performanceClient.addFields(
{ isNativeBroker: true },
this.correlationId
);
}
return result;
})
.catch((error: AuthError) => {
nativeATMeasurement.end({
success: false,
errorCode: error.errorCode,
subErrorCode: error.subError,
isNativeBroker: true,
});
throw error;
});
} catch (e) {
if (e instanceof NativeAuthError) {
serverTelemetryManager.setNativeBrokerErrorCode(e.errorCode);
}
nativeATMeasurement.end({
success: false,
...(e instanceof NativeAuthError && {
brokerErrorName: e.name,
brokerErrorCode: e.errorCode,
}),
});
throw e;
}
}
Expand Down Expand Up @@ -284,7 +298,7 @@ export class PlatformAuthInteractionClient extends BaseInteractionClient {
{
nativeAccountId,
},
request.correlationId
this.correlationId
);

if (!account) {
Expand Down Expand Up @@ -1144,7 +1158,7 @@ export class PlatformAuthInteractionClient extends BaseInteractionClient {
embeddedClientId: child_client_id,
embeddedRedirectUri: child_redirect_uri,
},
request.correlationId
this.correlationId
);
}
}
8 changes: 8 additions & 0 deletions lib/msal-browser/src/protocol/Authorize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,14 @@ async function getStandardParameters(
// signal ests that this is a WAM call
RequestParameterBuilder.addNativeBroker(parameters);

// instrument JS-platform bridge specific fields
performanceClient.addFields(
{
isPlatformAuthorizeRequest: true,
},
request.correlationId
);

// pass the req_cnf for POP
if (
request.authenticationScheme === Constants.AuthenticationScheme.POP
Expand Down
8 changes: 4 additions & 4 deletions lib/msal-browser/test/error/NativeAuthError.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import {
NativeAuthErrorCodes,
createNativeAuthError,
isFatalNativeAuthError,
} from "../../src/error/NativeAuthError";
} from "../../src/error/NativeAuthError.js";
import {
InteractionRequiredAuthError,
InteractionRequiredAuthErrorCodes,
} from "@azure/msal-common";
import * as NativeStatusCode from "../../src/broker/nativeBroker/NativeStatusCodes";
import * as NativeStatusCode from "../../src/broker/nativeBroker/NativeStatusCodes.js";
import {
BrowserAuthErrorCodes,
BrowserAuthError,
Expand All @@ -17,7 +17,7 @@ import {
describe("NativeAuthError Unit Tests", () => {
describe("NativeAuthError", () => {
describe("isFatal tests", () => {
it("should return true for isFatal when WAM status is PERSISTENT_ERROR", () => {
it("should return false for isFatal when WAM status is PERSISTENT_ERROR", () => {
const error = new NativeAuthError(
"testError",
"testErrorDescription",
Expand All @@ -28,7 +28,7 @@ describe("NativeAuthError Unit Tests", () => {
status: NativeStatusCode.PERSISTENT_ERROR,
}
);
expect(isFatalNativeAuthError(error)).toBe(true);
expect(isFatalNativeAuthError(error)).toBe(false);
});

it("should return true for isFatal when WAM status is DISABLED", () => {
Expand Down
Loading
Loading