diff --git a/src/credential/credentialController.ts b/src/credential/credentialController.ts index 755db83a..16063c25 100644 --- a/src/credential/credentialController.ts +++ b/src/credential/credentialController.ts @@ -151,6 +151,7 @@ export class CredentialController { const query = parseQuery(uri); resolve({ + userId: query.id, userName: query.name, userEmail: query.email, userToken: query['X-OP-BuildUserToken'], diff --git a/src/extension.ts b/src/extension.ts index ffeb7bfc..c07148e5 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -108,9 +108,13 @@ export async function activate(context: vscode.ExtensionContext): Promise { switch (event.type) { + // Sign case EventType.UserSignInTriggered: this.handleUserSignInTriggered(event); break; @@ -23,6 +24,10 @@ export class TelemetryObserver { case EventType.UserSignOutCompleted: this.handleUserSignOutCompleted(event); break; + case EventType.CredentialReset: + this.handleCredentialReset(); + break; + // Build case EventType.BuildTriggered: this.handleBuildTriggered(event); break; @@ -60,7 +65,6 @@ export class TelemetryObserver { private handleUserSignInTriggered(event: UserSignInTriggered) { this.reporter.sendTelemetryEvent( 'SignIn.Triggered', - { CorrelationId: event.correlationId } @@ -68,6 +72,14 @@ export class TelemetryObserver { } private handleUserSignInCompleted(event: UserSignInCompleted) { + // Set telemetry common property + if (event.succeeded) { + this.reporter.setCommonProperty({ + 'common.docsUserId': (event).credential.userInfo.userId + }); + } + + // Send telemetry let signInType: DocsSignInType; let userName: string; let userEmail: string; @@ -94,6 +106,12 @@ export class TelemetryObserver { ); } + private handleCredentialReset() { + this.reporter.setCommonProperty({ + 'common.docsUserId': undefined + }); + } + private handleUserSignOutTriggered(event: UserSignOutTriggered) { this.reporter.sendTelemetryEvent( 'SignOut.Triggered', diff --git a/src/shared.ts b/src/shared.ts index fa0ea4eb..c223beff 100644 --- a/src/shared.ts +++ b/src/shared.ts @@ -30,6 +30,7 @@ export type DocsSignInType = 'GitHub' | 'Azure DevOps'; export interface UserInfo { readonly signType: DocsSignInType; + readonly userId: string; readonly userName: string; readonly userEmail: string; readonly userToken: string; diff --git a/test/unitTests/credential/credentialController.test.ts b/test/unitTests/credential/credentialController.test.ts index 636e2ac0..8f98f923 100644 --- a/test/unitTests/credential/credentialController.test.ts +++ b/test/unitTests/credential/credentialController.test.ts @@ -17,7 +17,7 @@ import { TimeOutError } from '../../../src/error/timeOutError'; const fakedGitHubCallbackURL = { authority: 'ceapex.docs-build', path: '/github-authenticate', - query: 'name=Fake-User&email=fake@microsoft.com&X-OP-BuildUserToken=fake-token' + query: 'id=faked-id&name=Fake-User&email=fake@microsoft.com&X-OP-BuildUserToken=fake-token' }; describe('CredentialController', () => { @@ -170,6 +170,7 @@ describe('CredentialController', () => { let credential = credentialController.credential; let expectedUserInfo = { signType: 'GitHub', + userId: 'faked-id', userEmail: 'fake@microsoft.com', userName: 'Fake-User', userToken: 'fake-token' diff --git a/test/unitTests/observers/telemetryObserver.test.ts b/test/unitTests/observers/telemetryObserver.test.ts index 9fcdfdd7..96f65030 100644 --- a/test/unitTests/observers/telemetryObserver.test.ts +++ b/test/unitTests/observers/telemetryObserver.test.ts @@ -1,5 +1,5 @@ import assert from 'assert'; -import { UserSignInTriggered, UserSignInSucceeded, UserSignInFailed, UserSignOutTriggered, UserSignOutSucceeded, UserSignOutFailed, BuildCanceled, BuildFailed, BuildTriggered, BuildSucceeded, LearnMoreClicked, QuickPickTriggered, QuickPickCommandSelected, DependencyInstallStarted, DependencyInstallCompleted, PackageInstallCompleted, BuildCacheSizeCalculated, PackageInstallAttemptFailed, } from '../../../src/common/loggingEvents'; +import { UserSignInTriggered, UserSignInSucceeded, UserSignInFailed, UserSignOutTriggered, UserSignOutSucceeded, UserSignOutFailed, BuildCanceled, BuildFailed, BuildTriggered, BuildSucceeded, LearnMoreClicked, QuickPickTriggered, QuickPickCommandSelected, DependencyInstallStarted, DependencyInstallCompleted, PackageInstallCompleted, BuildCacheSizeCalculated, PackageInstallAttemptFailed, CredentialReset, } from '../../../src/common/loggingEvents'; import { TelemetryObserver } from '../../../src/observers/telemetryObserver'; import { DocsError } from '../../../src/error/docsError'; import { ErrorCode } from '../../../src/error/errorCode'; @@ -17,8 +17,12 @@ describe('TelemetryObserver', () => { let sentEventName: string; let sentEventProperties: any; let sentEventMeasurements: any; + let commonProperty: { [key: string]: string }; let telemetryReporter = { + setCommonProperty(properties: { [key: string]: string }): void { + commonProperty = properties; + }, sendTelemetryEvent(eventName: string, properties?: { [key: string]: string; }, measurements?: { @@ -50,6 +54,8 @@ describe('TelemetryObserver', () => { sentEventName = undefined; sentEventProperties = undefined; sentEventMeasurements = undefined; + + commonProperty = {}; }); // Sign @@ -76,6 +82,9 @@ describe('TelemetryObserver', () => { UserEmail: 'fake@microsoft.com', ErrorCode: undefined, }); + assert.deepStrictEqual(commonProperty, { + 'common.docsUserId': 'faked-id' + }); }); it('UserSignInFailed', () => { @@ -106,6 +115,20 @@ describe('TelemetryObserver', () => { UserEmail: 'fake@microsoft.com', ErrorCode: undefined }); + assert.deepStrictEqual(commonProperty, { + 'common.docsUserId': 'faked-id' + }); + }); + }); + + it(`UserSignOutTriggered: 'SignOut.Triggered' event should be sent`, () => { + let event = new CredentialReset(); + commonProperty = { + 'common.docsUserId': 'faked-id' + }; + observer.eventHandler(event); + assert.deepStrictEqual(commonProperty, { + 'common.docsUserId': undefined }); }); diff --git a/test/utils/faker.ts b/test/utils/faker.ts index 7fe701ee..1cf39ff2 100644 --- a/test/utils/faker.ts +++ b/test/utils/faker.ts @@ -37,6 +37,7 @@ export const fakedCredential = { signInStatus: 'SignedIn', userInfo: { signType: 'GitHub', + userId: 'faked-id', userEmail: 'fake@microsoft.com', userName: 'Faked User', userToken: 'faked-token'