Skip to content

Commit 6b78af8

Browse files
committed
node: fix machine id not being a UUID in some cases
1 parent f4b76ae commit 6b78af8

File tree

2 files changed

+55
-4
lines changed

2 files changed

+55
-4
lines changed

packages/node/src/attributes/MachineIdentitfierAttributeProvider.ts

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
import { BacktraceAttributeProvider, IdGenerator } from '@backtrace/sdk-core';
22
import { execSync } from 'child_process';
3+
import crypto from 'crypto';
4+
5+
const UUID_REGEX = /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/i;
6+
const DASHLESS_UUID_REGEX = /^[a-f0-9]{32}$/i;
37

48
export class MachineIdentitfierAttributeProvider implements BacktraceAttributeProvider {
59
public static readonly SUPPORTED_PLATFORMS = ['win32', 'darwin', 'linux', 'freebsd'];
@@ -15,15 +19,21 @@ export class MachineIdentitfierAttributeProvider implements BacktraceAttributePr
1519
public get type(): 'scoped' | 'dynamic' {
1620
return 'scoped';
1721
}
22+
1823
public get(): Record<string, unknown> {
19-
const guid = this.generateGuid() ?? IdGenerator.uuid();
24+
let machineId = this.getMachineId();
25+
if (machineId) {
26+
machineId = this.getValidGuid(machineId);
27+
} else {
28+
machineId = IdGenerator.uuid();
29+
}
2030

2131
return {
22-
[this.MACHINE_ID_ATTRIBUTE]: guid,
32+
[this.MACHINE_ID_ATTRIBUTE]: machineId,
2333
};
2434
}
2535

26-
public generateGuid() {
36+
public getMachineId() {
2737
switch (process.platform) {
2838
case 'win32': {
2939
return execSync(this.COMMANDS['win32'])
@@ -51,4 +61,21 @@ export class MachineIdentitfierAttributeProvider implements BacktraceAttributePr
5161
}
5262
}
5363
}
64+
65+
private getValidGuid(input: string) {
66+
if (input.length === 36 && UUID_REGEX.test(input)) {
67+
return input;
68+
}
69+
70+
if (input.length === 32 && DASHLESS_UUID_REGEX.test(input)) {
71+
return this.addDashesToUuid(input);
72+
}
73+
74+
const sha = crypto.createHash('sha1').update(input).digest('hex').substring(0, 32);
75+
return this.addDashesToUuid(sha);
76+
}
77+
78+
private addDashesToUuid(uuid: string) {
79+
return `${uuid.substring(0, 8)}-${uuid.substring(8, 12)}-${uuid.substring(12, 16)}-${uuid.substring(16, 20)}-${uuid.substring(20, 32)}`;
80+
}
5481
}

packages/node/tests/attributes/machineIdAttributeProviderTests.spec.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import crypto from 'crypto';
12
import { MachineIdentitfierAttributeProvider } from '../../src/attributes/MachineIdentitfierAttributeProvider.js';
23

34
describe('Machine id attribute provider test', () => {
@@ -6,7 +7,7 @@ describe('Machine id attribute provider test', () => {
67
const machineIdentifier1 = new MachineIdentitfierAttributeProvider();
78
const machineIdentifier2 = new MachineIdentitfierAttributeProvider();
89

9-
expect(machineIdentifier1.generateGuid()).toBe(machineIdentifier2.generateGuid());
10+
expect(machineIdentifier1.getMachineId()).toBe(machineIdentifier2.getMachineId());
1011
});
1112
}
1213

@@ -15,4 +16,27 @@ describe('Machine id attribute provider test', () => {
1516

1617
expect(machineIdentifier.get()['guid']).toBeDefined();
1718
});
19+
20+
it(`Should convert guid to a guid with dashes`, () => {
21+
const machineIdentifier = new MachineIdentitfierAttributeProvider();
22+
const uuid = crypto.randomUUID();
23+
24+
jest.spyOn(machineIdentifier, 'getMachineId').mockReturnValue(uuid.replace(/-/g, ''));
25+
26+
expect(machineIdentifier.get()['guid']).toEqual(uuid);
27+
});
28+
29+
it(`Should create a hash of guid if it is not a proper guid`, () => {
30+
const machineIdentifier = new MachineIdentitfierAttributeProvider();
31+
const guidResult = 'foo';
32+
const sha = crypto.createHash('sha1').update(guidResult).digest('hex').substring(0, 32);
33+
const expected = `${sha.substring(0, 8)}-${sha.substring(8, 12)}-${sha.substring(12, 16)}-${sha.substring(16, 20)}-${sha.substring(20, 32)}`;
34+
35+
// Sanity check for creating a dashed guid
36+
expect(expected.replace(/-/g, '')).toEqual(sha);
37+
38+
jest.spyOn(machineIdentifier, 'getMachineId').mockReturnValue(guidResult);
39+
40+
expect(machineIdentifier.get()['guid']).toEqual(expected);
41+
});
1842
});

0 commit comments

Comments
 (0)