Path: blob/main/extensions/microsoft-authentication/src/common/telemetryReporter.ts
3320 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { AuthError } from '@azure/msal-node';6import TelemetryReporter, { TelemetryEventProperties } from '@vscode/extension-telemetry';7import { IExperimentationTelemetry } from 'vscode-tas-client';89export const enum MicrosoftAccountType {10AAD = 'aad',11MSA = 'msa',12Unknown = 'unknown'13}1415export class MicrosoftAuthenticationTelemetryReporter implements IExperimentationTelemetry {16private sharedProperties: Record<string, string> = {};17protected _telemetryReporter: TelemetryReporter;18constructor(aiKey: string) {19this._telemetryReporter = new TelemetryReporter(aiKey);20}2122get telemetryReporter(): TelemetryReporter {23return this._telemetryReporter;24}2526setSharedProperty(name: string, value: string): void {27this.sharedProperties[name] = value;28}2930postEvent(eventName: string, props: Map<string, string>): void {31const eventProperties: TelemetryEventProperties = { ...this.sharedProperties, ...Object.fromEntries(props) };32this._telemetryReporter.sendTelemetryEvent(33eventName,34eventProperties35);36}3738sendActivatedWithMsalNoBrokerEvent(): void {39/* __GDPR__40"activatingMsalNoBroker" : { "owner": "TylerLeonhardt", "comment": "Used to determine how often users use the msal-no-broker login flow. This only fires if the user explictly opts in to this." }41*/42this._telemetryReporter.sendTelemetryEvent('activatingmsalnobroker');43}4445sendActivatedWithClassicImplementationEvent(reason: 'setting' | 'web'): void {46/* __GDPR__47"activatingClassic" : {48"owner": "TylerLeonhardt",49"comment": "Used to determine how often users use the classic login flow.",50"reason": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "Why classic was used" }51}52*/53this._telemetryReporter.sendTelemetryEvent('activatingClassic', { reason });54}5556sendLoginEvent(scopes: readonly string[]): void {57/* __GDPR__58"login" : {59"owner": "TylerLeonhardt",60"comment": "Used to determine the usage of the Microsoft Auth Provider.",61"scopes": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight", "comment": "Used to determine what scope combinations are being requested." }62}63*/64this._telemetryReporter.sendTelemetryEvent('login', {65// Get rid of guids from telemetry.66scopes: JSON.stringify(this._scrubGuids(scopes)),67});68}69sendLoginFailedEvent(): void {70/* __GDPR__71"loginFailed" : { "owner": "TylerLeonhardt", "comment": "Used to determine how often users run into issues with the login flow." }72*/73this._telemetryReporter.sendTelemetryEvent('loginFailed');74}75sendLogoutEvent(): void {76/* __GDPR__77"logout" : { "owner": "TylerLeonhardt", "comment": "Used to determine how often users log out." }78*/79this._telemetryReporter.sendTelemetryEvent('logout');80}81sendLogoutFailedEvent(): void {82/* __GDPR__83"logoutFailed" : { "owner": "TylerLeonhardt", "comment": "Used to determine how often fail to log out." }84*/85this._telemetryReporter.sendTelemetryEvent('logoutFailed');86}8788sendTelemetryErrorEvent(error: unknown): void {89let errorMessage: string | undefined;90let errorName: string | undefined;91let errorCode: string | undefined;92let errorCorrelationId: string | undefined;93if (typeof error === 'string') {94errorMessage = error;95} else {96const authError: AuthError = error as any;97// don't set error message or stack because it contains PII98errorCode = authError.errorCode;99errorCorrelationId = authError.correlationId;100errorName = authError.name;101}102103/* __GDPR__104"msalError" : {105"owner": "TylerLeonhardt",106"comment": "Used to determine how often users run into issues with the login flow.",107"errorMessage": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The error message." },108"errorName": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The name of the error." },109"errorCode": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The error code." },110"errorCorrelationId": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The error correlation id." }111}112*/113this._telemetryReporter.sendTelemetryErrorEvent('msalError', {114errorMessage,115errorName,116errorCode,117errorCorrelationId,118});119}120121/**122* Sends an event for an account type available at startup.123* @param scopes The scopes for the session124* @param accountType The account type for the session125* @todo Remove the scopes since we really don't care about them.126*/127sendAccountEvent(scopes: string[], accountType: MicrosoftAccountType): void {128/* __GDPR__129"account" : {130"owner": "TylerLeonhardt",131"comment": "Used to determine the usage of the Microsoft Auth Provider.",132"scopes": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight", "comment": "Used to determine what scope combinations are being requested." },133"accountType": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight", "comment": "Used to determine what account types are being used." }134}135*/136this._telemetryReporter.sendTelemetryEvent('account', {137// Get rid of guids from telemetry.138scopes: JSON.stringify(this._scrubGuids(scopes)),139accountType140});141}142143protected _scrubGuids(scopes: readonly string[]): string[] {144return scopes.map(s => s.replace(/[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}/i, '{guid}'));145}146}147148export class MicrosoftSovereignCloudAuthenticationTelemetryReporter extends MicrosoftAuthenticationTelemetryReporter {149override sendLoginEvent(scopes: string[]): void {150/* __GDPR__151"loginMicrosoftSovereignCloud" : {152"owner": "TylerLeonhardt",153"comment": "Used to determine the usage of the Microsoft Auth Provider.",154"scopes": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight", "comment": "Used to determine what scope combinations are being requested." }155}156*/157this._telemetryReporter.sendTelemetryEvent('loginMicrosoftSovereignCloud', {158// Get rid of guids from telemetry.159scopes: JSON.stringify(this._scrubGuids(scopes)),160});161}162override sendLoginFailedEvent(): void {163/* __GDPR__164"loginMicrosoftSovereignCloudFailed" : { "owner": "TylerLeonhardt", "comment": "Used to determine how often users run into issues with the login flow." }165*/166this._telemetryReporter.sendTelemetryEvent('loginMicrosoftSovereignCloudFailed');167}168override sendLogoutEvent(): void {169/* __GDPR__170"logoutMicrosoftSovereignCloud" : { "owner": "TylerLeonhardt", "comment": "Used to determine how often users log out." }171*/172this._telemetryReporter.sendTelemetryEvent('logoutMicrosoftSovereignCloud');173}174override sendLogoutFailedEvent(): void {175/* __GDPR__176"logoutMicrosoftSovereignCloudFailed" : { "owner": "TylerLeonhardt", "comment": "Used to determine how often fail to log out." }177*/178this._telemetryReporter.sendTelemetryEvent('logoutMicrosoftSovereignCloudFailed');179}180}181182183