d9fbecf5a7
Move audio scrub/volume and brush drafts off root React ticks, coalesce overlay layout IPC, cache machine fingerprint and asset URLs, share one scene overlay host, and stop idle Pixi ticker. Also harden console against EPIPE on window load failures. Co-authored-by: Cursor <cursoragent@cursor.com>
152 lines
4.9 KiB
TypeScript
152 lines
4.9 KiB
TypeScript
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 {
|
|
clearMachineFingerprintMemoryCache,
|
|
hashMachineRawId,
|
|
machineWideIdPath,
|
|
parseMacIOPlatformUUID,
|
|
parseWindowsMachineGuid,
|
|
parseWmicUuid,
|
|
resolveMachineFingerprint,
|
|
} from './machineFingerprint';
|
|
import { machineFingerprintCachePath } from './paths';
|
|
|
|
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 <class IOPlatformExpertDevice, id 0x1000001ea, registered, matched>
|
|
{
|
|
"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', () => {
|
|
clearMachineFingerprintMemoryCache();
|
|
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', () => {
|
|
clearMachineFingerprintMemoryCache();
|
|
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,
|
|
});
|
|
clearMachineFingerprintMemoryCache();
|
|
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', () => {
|
|
clearMachineFingerprintMemoryCache();
|
|
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 путь', () => {
|
|
clearMachineFingerprintMemoryCache();
|
|
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');
|
|
},
|
|
});
|
|
clearMachineFingerprintMemoryCache();
|
|
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 });
|
|
});
|
|
|
|
void test('resolveMachineFingerprint: disk cache — без повторного exec', () => {
|
|
clearMachineFingerprintMemoryCache();
|
|
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'machine-fp-cache-'));
|
|
const expected = hashMachineRawId('win32', 'A1B2C3D4-E5F6-7890-ABCD-EF1234567890');
|
|
let execCalls = 0;
|
|
const exec = () => {
|
|
execCalls += 1;
|
|
return `
|
|
HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography
|
|
MachineGuid REG_SZ A1B2C3D4-E5F6-7890-ABCD-EF1234567890
|
|
`;
|
|
};
|
|
const a = resolveMachineFingerprint({
|
|
platform: 'win32',
|
|
env: {},
|
|
userData: tmp,
|
|
execFileSync: exec as never,
|
|
});
|
|
assert.equal(a, expected);
|
|
assert.equal(execCalls, 1);
|
|
assert.ok(fs.existsSync(machineFingerprintCachePath(tmp)));
|
|
|
|
clearMachineFingerprintMemoryCache();
|
|
const b = resolveMachineFingerprint({
|
|
platform: 'win32',
|
|
env: {},
|
|
userData: tmp,
|
|
execFileSync: exec as never,
|
|
});
|
|
assert.equal(b, expected);
|
|
assert.equal(execCalls, 1, 'второй вызов читает disk cache, без reg/wmic');
|
|
fs.rmSync(tmp, { recursive: true, force: true });
|
|
});
|