Skip to content

Commit

Permalink
Add correlation id param to initialize and clearTokensAndKeysWithClai…
Browse files Browse the repository at this point in the history
…ms APIs to streamline telemetry data analysis (#7190)

- Add correlation id param to initialize and
clearTokensAndKeysWithClaims APIs to streamline telemetry data analysis
  • Loading branch information
konstantin-msft committed Jul 9, 2024
1 parent be05b05 commit 6339ce7
Show file tree
Hide file tree
Showing 11 changed files with 101 additions and 19 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "minor",
"comment": "Add correlation id param to initialize and clearTokensAndKeysWithClaims APIs to streamline telemetry data analysis #7190",
"packageName": "@azure/msal-browser",
"email": "kshabelko@microsoft.com",
"dependentChangeType": "patch"
}
16 changes: 13 additions & 3 deletions lib/msal-browser/apiReview/msal-browser.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -916,7 +916,7 @@ export interface IController {
// (undocumented)
hydrateCache(result: AuthenticationResult, request: SilentRequest | SsoSilentRequest | RedirectRequest | PopupRequest): Promise<void>;
// (undocumented)
initialize(): Promise<void>;
initialize(request?: InitializeApplicationRequest): Promise<void>;
// (undocumented)
initializeWrapperLibrary(sku: WrapperSKU, version: string): void;
// @internal (undocumented)
Expand Down Expand Up @@ -968,6 +968,13 @@ export interface INavigationClient {

export { INetworkModule }

// Warning: (ae-missing-release-tag) "InitializeApplicationRequest" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export type InitializeApplicationRequest = {
correlationId?: string;
};

// Warning: (ae-missing-release-tag) "inMemRedirectUnavailable" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
Expand Down Expand Up @@ -1358,7 +1365,8 @@ export class PublicClientApplication implements IPublicClientApplication {
clearCache(logoutRequest?: ClearCacheRequest): Promise<void>;
// (undocumented)
protected controller: IController;
// (undocumented)
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (tsdoc-param-tag-with-invalid-type) The @param block should not include a JSDoc-style '{type}'
static createPublicClientApplication(configuration: Configuration): Promise<IPublicClientApplication>;
disableAccountStorageEvents(): void;
enableAccountStorageEvents(): void;
Expand Down Expand Up @@ -1386,7 +1394,9 @@ export class PublicClientApplication implements IPublicClientApplication {
handleRedirectPromise(hash?: string | undefined): Promise<AuthenticationResult | null>;
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
hydrateCache(result: AuthenticationResult, request: SilentRequest | SsoSilentRequest | RedirectRequest | PopupRequest): Promise<void>;
initialize(): Promise<void>;
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (tsdoc-param-tag-with-invalid-type) The @param block should not include a JSDoc-style '{type}'
initialize(request?: InitializeApplicationRequest): Promise<void>;
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
initializeWrapperLibrary(sku: WrapperSKU, version: string): void;
Expand Down
12 changes: 9 additions & 3 deletions lib/msal-browser/src/app/PublicClientApplication.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { ClearCacheRequest } from "../request/ClearCacheRequest";
import { EndSessionPopupRequest } from "../request/EndSessionPopupRequest";
import { NestedAppAuthController } from "../controllers/NestedAppAuthController";
import { NestedAppOperatingContext } from "../operatingcontext/NestedAppOperatingContext";
import { InitializeApplicationRequest } from "../request/InitializeApplicationRequest";

/**
* The PublicClientApplication class is the object exposed by the library to perform authentication and authorization functions in Single Page Applications
Expand All @@ -38,7 +39,11 @@ import { NestedAppOperatingContext } from "../operatingcontext/NestedAppOperatin
export class PublicClientApplication implements IPublicClientApplication {
protected controller: IController;

// creates StandardController and passes it to the PublicClientApplication
/**
* Creates StandardController and passes it to the PublicClientApplication
*
* @param configuration {Configuration}
*/
public static async createPublicClientApplication(
configuration: Configuration
): Promise<IPublicClientApplication> {
Expand Down Expand Up @@ -80,9 +85,10 @@ export class PublicClientApplication implements IPublicClientApplication {

/**
* Initializer function to perform async startup tasks such as connecting to WAM extension
* @param request {?InitializeApplicationRequest}
*/
async initialize(): Promise<void> {
return this.controller.initialize();
async initialize(request?: InitializeApplicationRequest): Promise<void> {
return this.controller.initialize(request);
}

/**
Expand Down
7 changes: 5 additions & 2 deletions lib/msal-browser/src/cache/BrowserCacheManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1266,13 +1266,16 @@ export class BrowserCacheManager extends CacheManager {
/**
* Clears all access tokes that have claims prior to saving the current one
* @param performanceClient {IPerformanceClient}
* @param correlationId {string} correlation id
* @returns
*/
async clearTokensAndKeysWithClaims(
performanceClient: IPerformanceClient
performanceClient: IPerformanceClient,
correlationId: string
): Promise<void> {
performanceClient.addQueueMeasurement(
PerformanceEvents.ClearTokensAndKeysWithClaims
PerformanceEvents.ClearTokensAndKeysWithClaims,
correlationId
);

const tokenKeys = this.getTokenKeys();
Expand Down
6 changes: 4 additions & 2 deletions lib/msal-browser/src/controllers/ControllerFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@ import { IController } from "./IController";
import { Configuration } from "../config/Configuration";
import { StandardController } from "./StandardController";
import { NestedAppAuthController } from "./NestedAppAuthController";
import { InitializeApplicationRequest } from "../request/InitializeApplicationRequest";

export async function createV3Controller(
config: Configuration
config: Configuration,
request?: InitializeApplicationRequest
): Promise<IController> {
const standard = new StandardOperatingContext(config);

await standard.initialize();
return StandardController.createController(standard);
return StandardController.createController(standard, request);
}

export async function createController(
Expand Down
4 changes: 3 additions & 1 deletion lib/msal-browser/src/controllers/IController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@ import { EventHandler } from "../event/EventHandler";
import { AuthenticationResult } from "../response/AuthenticationResult";
import { EventCallbackFunction } from "../event/EventMessage";
import { ClearCacheRequest } from "../request/ClearCacheRequest";
import { InitializeApplicationRequest } from "../request/InitializeApplicationRequest";

export interface IController {
initialize(): Promise<void>;
// TODO: Make request mandatory in the next major version?
initialize(request?: InitializeApplicationRequest): Promise<void>;

acquireTokenPopup(request: PopupRequest): Promise<AuthenticationResult>;

Expand Down
19 changes: 13 additions & 6 deletions lib/msal-browser/src/controllers/StandardController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ import { AuthenticationResult } from "../response/AuthenticationResult";
import { ClearCacheRequest } from "../request/ClearCacheRequest";
import { createNewGuid } from "../crypto/BrowserCrypto";
import { initializeSilentRequest } from "../request/RequestHelpers";
import { InitializeApplicationRequest } from "../request/InitializeApplicationRequest";

function getAccountType(
account?: AccountInfo
Expand Down Expand Up @@ -281,10 +282,11 @@ export class StandardController implements IController {
}

static async createController(
operatingContext: BaseOperatingContext
operatingContext: BaseOperatingContext,
request?: InitializeApplicationRequest
): Promise<IController> {
const controller = new StandardController(operatingContext);
await controller.initialize();
await controller.initialize(request);
return controller;
}

Expand All @@ -301,8 +303,9 @@ export class StandardController implements IController {

/**
* Initializer function to perform async startup tasks such as connecting to WAM extension
* @param request {?InitializeApplicationRequest} correlation id
*/
async initialize(): Promise<void> {
async initialize(request?: InitializeApplicationRequest): Promise<void> {
this.logger.trace("initialize called");
if (this.initialized) {
this.logger.info(
Expand All @@ -311,9 +314,12 @@ export class StandardController implements IController {
return;
}

const initCorrelationId =
request?.correlationId || this.getRequestCorrelationId();
const allowNativeBroker = this.config.system.allowNativeBroker;
const initMeasurement = this.performanceClient.startMeasurement(
PerformanceEvents.InitializeClientApplication
PerformanceEvents.InitializeClientApplication,
initCorrelationId
);
this.eventHandler.emitEvent(EventType.INITIALIZE_START);

Expand Down Expand Up @@ -341,8 +347,9 @@ export class StandardController implements IController {
),
PerformanceEvents.ClearTokensAndKeysWithClaims,
this.logger,
this.performanceClient
)(this.performanceClient);
this.performanceClient,
initCorrelationId
)(this.performanceClient, initCorrelationId);
}

this.initialized = true;
Expand Down
1 change: 1 addition & 0 deletions lib/msal-browser/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ export { AuthorizationUrlRequest } from "./request/AuthorizationUrlRequest";
export { AuthorizationCodeRequest } from "./request/AuthorizationCodeRequest";
export { AuthenticationResult } from "./response/AuthenticationResult";
export { ClearCacheRequest } from "./request/ClearCacheRequest";
export { InitializeApplicationRequest } from "./request/InitializeApplicationRequest";

// Cache
export { LoadTokenOptions } from "./cache/TokenCache";
Expand Down
13 changes: 13 additions & 0 deletions lib/msal-browser/src/request/InitializeApplicationRequest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/

/**
* InitializeApplicationRequest: Request object passed by user to initialize application
*
* - correlationId - Unique GUID set per request to trace a request end-to-end for telemetry purposes.
*/
export type InitializeApplicationRequest = {
correlationId?: string;
};
29 changes: 29 additions & 0 deletions lib/msal-browser/test/app/PublicClientApplication.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,35 @@ describe("PublicClientApplication.ts Class Unit Tests", () => {
// @ts-ignore
expect(pca.nativeExtensionProvider).toBeUndefined();
});

it("reports telemetry event using provided correlation id", (done) => {
pca = new PublicClientApplication({
auth: {
clientId: TEST_CONFIG.MSAL_CLIENT_ID,
},
telemetry: {
client: new BrowserPerformanceClient(testAppConfig),
application: {
appName: TEST_CONFIG.applicationName,
appVersion: TEST_CONFIG.applicationVersion,
},
},
});

const callbackId = pca.addPerformanceCallback((events) => {
expect(events[0].name).toEqual(
PerformanceEvents.InitializeClientApplication
);
expect(events[0].correlationId).toEqual("test-correlation-id");
expect(
events[0]["clearTokensAndKeysWithClaimsDurationMs"]
).toBeGreaterThanOrEqual(0);
pca.removePerformanceCallback(callbackId);
done();
});

pca.initialize({ correlationId: "test-correlation-id" });
});
});

describe("handleRedirectPromise", () => {
Expand Down
6 changes: 4 additions & 2 deletions lib/msal-browser/test/cache/BrowserCacheManager.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1105,10 +1105,12 @@ describe("BrowserCacheManager tests", () => {
).toEqual(testAT4);

browserSessionStorage.clearTokensAndKeysWithClaims(
getDefaultPerformanceClient()
getDefaultPerformanceClient(),
"test-correlation-id"
);
browserLocalStorage.clearTokensAndKeysWithClaims(
getDefaultPerformanceClient()
getDefaultPerformanceClient(),
"test-correlation-id"
);

expect(
Expand Down

0 comments on commit 6339ce7

Please sign in to comment.