Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/microsoft-authentication/src/common/telemetryReporter.ts
5237 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { AuthError, ClientAuthError } from '@azure/msal-node';
7
import TelemetryReporter, { TelemetryEventProperties } from '@vscode/extension-telemetry';
8
import { IExperimentationTelemetry } from 'vscode-tas-client';
9
10
export const enum MicrosoftAccountType {
11
AAD = 'aad',
12
MSA = 'msa',
13
Unknown = 'unknown'
14
}
15
16
export class MicrosoftAuthenticationTelemetryReporter implements IExperimentationTelemetry {
17
private sharedProperties: Record<string, string> = {};
18
protected _telemetryReporter: TelemetryReporter;
19
constructor(aiKey: string) {
20
this._telemetryReporter = new TelemetryReporter(aiKey);
21
}
22
23
get telemetryReporter(): TelemetryReporter {
24
return this._telemetryReporter;
25
}
26
27
setSharedProperty(name: string, value: string): void {
28
this.sharedProperties[name] = value;
29
}
30
31
postEvent(eventName: string, props: Map<string, string>): void {
32
const eventProperties: TelemetryEventProperties = { ...this.sharedProperties, ...Object.fromEntries(props) };
33
this._telemetryReporter.sendTelemetryEvent(
34
eventName,
35
eventProperties
36
);
37
}
38
39
sendActivatedWithMsalNoBrokerEvent(): void {
40
/* __GDPR__
41
"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." }
42
*/
43
this._telemetryReporter.sendTelemetryEvent('activatingmsalnobroker');
44
}
45
46
sendLoginEvent(scopes: readonly string[]): void {
47
/* __GDPR__
48
"login" : {
49
"owner": "TylerLeonhardt",
50
"comment": "Used to determine the usage of the Microsoft Auth Provider.",
51
"scopes": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight", "comment": "Used to determine what scope combinations are being requested." }
52
}
53
*/
54
this._telemetryReporter.sendTelemetryEvent('login', {
55
// Get rid of guids from telemetry.
56
scopes: JSON.stringify(this._scrubGuids(scopes)),
57
});
58
}
59
sendLoginFailedEvent(): void {
60
/* __GDPR__
61
"loginFailed" : { "owner": "TylerLeonhardt", "comment": "Used to determine how often users run into issues with the login flow." }
62
*/
63
this._telemetryReporter.sendTelemetryEvent('loginFailed');
64
}
65
sendLogoutEvent(): void {
66
/* __GDPR__
67
"logout" : { "owner": "TylerLeonhardt", "comment": "Used to determine how often users log out." }
68
*/
69
this._telemetryReporter.sendTelemetryEvent('logout');
70
}
71
sendLogoutFailedEvent(): void {
72
/* __GDPR__
73
"logoutFailed" : { "owner": "TylerLeonhardt", "comment": "Used to determine how often fail to log out." }
74
*/
75
this._telemetryReporter.sendTelemetryEvent('logoutFailed');
76
}
77
78
sendTelemetryErrorEvent(error: Error | string): void {
79
let errorMessage: string | undefined;
80
let errorName: string | undefined;
81
let errorCode: string | undefined;
82
let errorCorrelationId: string | undefined;
83
if (typeof error === 'string') {
84
errorMessage = error;
85
} else {
86
const authError: AuthError = error as AuthError;
87
// don't set error message or stack because it contains PII
88
errorCode = authError.errorCode;
89
errorCorrelationId = authError.correlationId;
90
errorName = authError.name;
91
}
92
93
/* __GDPR__
94
"msalError" : {
95
"owner": "TylerLeonhardt",
96
"comment": "Used to determine how often users run into issues with the login flow.",
97
"errorMessage": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The error message." },
98
"errorName": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The name of the error." },
99
"errorCode": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The error code." },
100
"errorCorrelationId": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The error correlation id." }
101
}
102
*/
103
this._telemetryReporter.sendTelemetryErrorEvent('msalError', {
104
errorMessage,
105
errorName,
106
errorCode,
107
errorCorrelationId,
108
});
109
}
110
111
sendTelemetryClientAuthErrorEvent(error: AuthError): void {
112
const errorCode = error.errorCode;
113
const correlationId = error.correlationId;
114
const errorName = error.name;
115
let brokerErrorCode: string | undefined;
116
let brokerStatusCode: string | undefined;
117
let brokerTag: string | undefined;
118
119
// Extract platform broker error information if available
120
if (error.platformBrokerError) {
121
brokerErrorCode = error.platformBrokerError.errorCode;
122
brokerStatusCode = `${error.platformBrokerError.statusCode}`;
123
brokerTag = error.platformBrokerError.tag;
124
}
125
126
/* __GDPR__
127
"msalClientAuthError" : {
128
"owner": "TylerLeonhardt",
129
"comment": "Used to determine how often users run into client auth errors during the login flow.",
130
"errorName": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The name of the client auth error." },
131
"errorCode": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The client auth error code." },
132
"correlationId": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The client auth error correlation id." },
133
"brokerErrorCode": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The broker error code." },
134
"brokerStatusCode": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The broker error status code." },
135
"brokerTag": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The broker error tag." }
136
}
137
*/
138
this._telemetryReporter.sendTelemetryErrorEvent('msalClientAuthError', {
139
errorName,
140
errorCode,
141
correlationId,
142
brokerErrorCode,
143
brokerStatusCode,
144
brokerTag
145
});
146
}
147
148
/**
149
* Sends an event for an account type available at startup.
150
* @param scopes The scopes for the session
151
* @param accountType The account type for the session
152
* @todo Remove the scopes since we really don't care about them.
153
*/
154
sendAccountEvent(scopes: string[], accountType: MicrosoftAccountType): void {
155
/* __GDPR__
156
"account" : {
157
"owner": "TylerLeonhardt",
158
"comment": "Used to determine the usage of the Microsoft Auth Provider.",
159
"scopes": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight", "comment": "Used to determine what scope combinations are being requested." },
160
"accountType": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight", "comment": "Used to determine what account types are being used." }
161
}
162
*/
163
this._telemetryReporter.sendTelemetryEvent('account', {
164
// Get rid of guids from telemetry.
165
scopes: JSON.stringify(this._scrubGuids(scopes)),
166
accountType
167
});
168
}
169
170
protected _scrubGuids(scopes: readonly string[]): string[] {
171
return 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}'));
172
}
173
}
174
175
export class MicrosoftSovereignCloudAuthenticationTelemetryReporter extends MicrosoftAuthenticationTelemetryReporter {
176
override sendLoginEvent(scopes: string[]): void {
177
/* __GDPR__
178
"loginMicrosoftSovereignCloud" : {
179
"owner": "TylerLeonhardt",
180
"comment": "Used to determine the usage of the Microsoft Auth Provider.",
181
"scopes": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight", "comment": "Used to determine what scope combinations are being requested." }
182
}
183
*/
184
this._telemetryReporter.sendTelemetryEvent('loginMicrosoftSovereignCloud', {
185
// Get rid of guids from telemetry.
186
scopes: JSON.stringify(this._scrubGuids(scopes)),
187
});
188
}
189
override sendLoginFailedEvent(): void {
190
/* __GDPR__
191
"loginMicrosoftSovereignCloudFailed" : { "owner": "TylerLeonhardt", "comment": "Used to determine how often users run into issues with the login flow." }
192
*/
193
this._telemetryReporter.sendTelemetryEvent('loginMicrosoftSovereignCloudFailed');
194
}
195
override sendLogoutEvent(): void {
196
/* __GDPR__
197
"logoutMicrosoftSovereignCloud" : { "owner": "TylerLeonhardt", "comment": "Used to determine how often users log out." }
198
*/
199
this._telemetryReporter.sendTelemetryEvent('logoutMicrosoftSovereignCloud');
200
}
201
override sendLogoutFailedEvent(): void {
202
/* __GDPR__
203
"logoutMicrosoftSovereignCloudFailed" : { "owner": "TylerLeonhardt", "comment": "Used to determine how often fail to log out." }
204
*/
205
this._telemetryReporter.sendTelemetryEvent('logoutMicrosoftSovereignCloudFailed');
206
}
207
}
208
209