import assert from 'node:assert/strict'; import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; import test from 'node:test'; import { hashMachineRawId, machineWideIdPath, parseMacIOPlatformUUID, parseWindowsMachineGuid, parseWmicUuid, resolveMachineFingerprint, } from './machineFingerprint'; void test('hashMachineRawId: стабилен и не зависит от регистра GUID', () => { const a = hashMachineRawId('win32', 'ABCDEF00-1111-2222-3333-444455556666'); const b = hashMachineRawId('win32', 'abcdef00-1111-2222-3333-444455556666'); assert.equal(a, b); assert.equal(a.length, 64); assert.notEqual(a, hashMachineRawId('linux', 'abcdef00-1111-2222-3333-444455556666')); }); void test('parseWindowsMachineGuid', () => { const out = ` HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography MachineGuid REG_SZ A1B2C3D4-E5F6-7890-ABCD-EF1234567890 `; assert.equal(parseWindowsMachineGuid(out), 'A1B2C3D4-E5F6-7890-ABCD-EF1234567890'); assert.equal(parseWindowsMachineGuid('nope'), null); }); void test('parseMacIOPlatformUUID', () => { const out = ` +-o IOPlatformExpertDevice { "IOPlatformUUID" = "A1B2C3D4-E5F6-7890-ABCD-EF1234567890" } `; assert.equal(parseMacIOPlatformUUID(out), 'A1B2C3D4-E5F6-7890-ABCD-EF1234567890'); }); void test('parseWmicUuid', () => { assert.equal(parseWmicUuid('UUID\nA1B2C3D4-E5F6-7890-ABCD-EF1234567890\n'), 'A1B2C3D4-E5F6-7890-ABCD-EF1234567890'); assert.equal(parseWmicUuid('UUID\n00000000-0000-0000-0000-000000000000\n'), null); }); void test('resolveMachineFingerprint: override через DND_LICENSE_DEVICE_ID', () => { const id = resolveMachineFingerprint({ platform: 'linux', env: { DND_LICENSE_DEVICE_ID: 'override-device-id-12345' }, }); assert.equal(id, 'override-device-id-12345'); }); void test('resolveMachineFingerprint: Windows MachineGuid → одинаковый hash', () => { const exec = () => ` HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography MachineGuid REG_SZ A1B2C3D4-E5F6-7890-ABCD-EF1234567890 `; const a = resolveMachineFingerprint({ platform: 'win32', env: {}, execFileSync: exec as never, }); const b = resolveMachineFingerprint({ platform: 'win32', env: {}, execFileSync: exec as never, }); assert.equal(a, b); assert.equal(a, hashMachineRawId('win32', 'A1B2C3D4-E5F6-7890-ABCD-EF1234567890')); }); void test('resolveMachineFingerprint: Linux /etc/machine-id', () => { const id = resolveMachineFingerprint({ platform: 'linux', env: {}, readFileSync: (p) => { if (p === '/etc/machine-id') return '0123456789abcdef0123456789abcdef\n'; throw new Error('enoent'); }, }); assert.equal(id, hashMachineRawId('linux', '0123456789abcdef0123456789abcdef')); }); void test('resolveMachineFingerprint: fallback в machine-wide путь', () => { const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'machine-fp-')); const env = { PROGRAMDATA: tmp }; const p = machineWideIdPath('win32', env); const id1 = resolveMachineFingerprint({ platform: 'win32', env, execFileSync: () => { throw new Error('no reg'); }, }); const id2 = resolveMachineFingerprint({ platform: 'win32', env, execFileSync: () => { throw new Error('no reg'); }, }); assert.equal(id1, id2); assert.ok(fs.existsSync(p)); fs.rmSync(tmp, { recursive: true, force: true }); });