Skip to content

Normalizes machineId across VS Code clones #4391

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions src/env/browser/machine.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// This is intentional as the browser environment doesn't have access to MAC addresses
export function getMac(): string | undefined {
return undefined;
}
50 changes: 50 additions & 0 deletions src/env/node/machine.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { createHash } from 'crypto';
import { networkInterfaces } from 'os';

// Sourced from GKD
const knownBadAppIds = [
// this appId corresponds to the 'iBridge Adapter for the Touchbar' on macbooks
// https://github.com/bevry/getmac/issues/42
// https://discussions.apple.com/thread/7763102
// discovered 3/21/23 with ~28,000 unique users
'8149453d12fde3c987f5ceb011360abe56307d17', // sha1('ac:de:48:00:11:22')

// these appIds correspond to the default VMWARE vnet1 and vmnet8 interface mac address
// https://communities.vmware.com/t5/VMware-Workstation-Pro/Why-are-MAC-addresses-for-vmnet1-and-vmnet8-hardcoded/td-p/1580213
// discovered 3/21/23 with 10250 unique users
'a76a6cbfb93cbb6daa4c4836544564fb777a0803', // sha1('00-50-56-C0-00-01')
// discovered 3/22/23 with 3473 unique users
'4433e1caaca0b97ba94ef3e0772e5931f792fa9b', // sha1('00-50-56-C0-00-08')

// this appId corresponds to the "Forticlient VPN client" adapter mac address
// https://community.fortinet.com/t5/Support-Forum/FortiClient-MAC-Address/m-p/60724
// discovered 3/21/23 with 5655 unique users
'b14e824ad9cd8a3e95493d48e6132ecce40e0e47', // sha1('00-09-0F-FE-00-01')
];

// Sourced from https://github.com/bevry/getmac/blob/master/source/index.ts
// There's issues with importing 'getmac' directly, so we referenced the relevant code here

const zeroRegex = /(?:[0]{1,2}[:-]){5}[0]{1,2}/;
export function getMac(): string | undefined {
const list = networkInterfaces();

for (const parts of Object.values(list)) {
// for some reason beyond me, this is needed to satisfy typescript
// fix https://github.com/bevry/getmac/issues/100
if (!parts) continue;
for (const part of parts) {
if (zeroRegex.test(part.mac) === false) {
const appId = sha1(part.mac);
if (appId != null && !knownBadAppIds.includes(appId)) {
return appId;
}
}
}
}
return undefined;
}

function sha1(data: string): string | undefined {
return createHash('sha1').update(data, 'utf8').digest('hex');
}
5 changes: 3 additions & 2 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { registerPartnerActionRunners } from './partners';
import { executeCommand, registerCommands } from './system/-webview/command';
import { configuration, Configuration } from './system/-webview/configuration';
import { setContext } from './system/-webview/context';
import { getMachineId } from './system/-webview/machine';
import { Storage } from './system/-webview/storage';
import { deviceCohortGroup } from './system/-webview/vscode';
import { isTextDocument } from './system/-webview/vscode/documents';
Expand Down Expand Up @@ -56,7 +57,7 @@ export async function activate(context: ExtensionContext): Promise<GitLensApi |
env.appName
} (${codeVersion}) on the ${isWeb ? 'web' : 'desktop'}; language='${
env.language
}', logLevel='${logLevel}', defaultDateLocale='${defaultDateLocale}' (${env.machineId}|${
}', logLevel='${logLevel}', defaultDateLocale='${defaultDateLocale}' (${getMachineId()}|${
env.sessionId
})`,
);
Expand Down Expand Up @@ -110,7 +111,7 @@ export async function activate(context: ExtensionContext): Promise<GitLensApi |
log: {
message: ` activating in ${env.appName} (${codeVersion}) on the ${isWeb ? 'web' : 'desktop'}; language='${
env.language
}', logLevel='${logLevel}', defaultDateLocale='${defaultDateLocale}' (${env.uriScheme}|${env.machineId}|${
}', logLevel='${logLevel}', defaultDateLocale='${defaultDateLocale}' (${env.uriScheme}|${getMachineId()}|${
env.sessionId
})`,
//${context.extensionRuntime !== ExtensionRuntime.Node ? ' in a webworker' : ''}
Expand Down
3 changes: 2 additions & 1 deletion src/plus/gk/subscriptionService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import type { RepositoriesChangeEvent } from '../../git/gitProviderService';
import { executeCommand, registerCommand } from '../../system/-webview/command';
import { configuration } from '../../system/-webview/configuration';
import { setContext } from '../../system/-webview/context';
import { getMachineId } from '../../system/-webview/machine';
import { openUrl } from '../../system/-webview/vscode/uris';
import { createFromDateDelta, fromNow } from '../../system/date';
import { gate } from '../../system/decorators/-webview/gate';
Expand Down Expand Up @@ -1025,7 +1026,7 @@ export class SubscriptionService implements Disposable {
id: session.account.id,
platform: getPlatform(),
gitlensVersion: this.container.version,
machineId: env.machineId,
machineId: getMachineId(),
sessionId: env.sessionId,
vscodeEdition: env.appName,
vscodeHost: env.appHost,
Expand Down
10 changes: 10 additions & 0 deletions src/system/-webview/machine.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { env } from 'vscode';
import { getMac } from '@env/machine';
import { isWeb } from '@env/platform';

export function getMachineId(): string {
if (isWeb) {
return env.machineId;
}
return getMac() ?? env.machineId;
}
3 changes: 2 additions & 1 deletion src/system/-webview/vscode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ import { getDistributionGroup } from '../string';
import { satisfies } from '../version';
import { executeCoreCommand } from './command';
import { configuration } from './configuration';
import { getMachineId } from './machine';
import { exists } from './vscode/uris';

export const deviceCohortGroup = getDistributionGroup(env.machineId);
export const deviceCohortGroup = getDistributionGroup(getMachineId());

let _hostExecutablePath: string | undefined;
export async function getHostExecutablePath(): Promise<string> {
Expand Down
3 changes: 2 additions & 1 deletion src/telemetry/telemetry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { getPlatform } from '@env/platform';
import type { Source, TelemetryEventData, TelemetryEvents, TelemetryGlobalContext } from '../constants.telemetry';
import type { Container } from '../container';
import { configuration } from '../system/-webview/configuration';
import { getMachineId } from '../system/-webview/machine';

export interface TelemetryContext {
env: string;
Expand Down Expand Up @@ -99,7 +100,7 @@ export class TelemetryService implements Disposable {
env: container.env,
extensionId: container.id,
extensionVersion: container.version,
machineId: env.machineId,
machineId: getMachineId(),
sessionId: env.sessionId,
language: env.language,
platform: getPlatform(),
Expand Down