refactor(server): 使用 systeminformation 替代手动采集生成设备特征码

硬件级 SMBIOS 标识(uuid/serial/model/manufacturer)跨平台稳定,
不再依赖 Linux 独有的 machine-id 和易变的 OS release/内存/MAC 地址。
This commit is contained in:
2026-03-06 11:16:17 +08:00
parent cdb3298f6d
commit aabd60e619
5 changed files with 11 additions and 34 deletions

View File

@@ -39,6 +39,7 @@
"jszip": "catalog:",
"react": "catalog:",
"react-dom": "catalog:",
"systeminformation": "catalog:",
"uuid": "catalog:",
"zod": "catalog:"
},

View File

@@ -1,38 +1,9 @@
import { readFileSync } from 'node:fs'
import { arch, cpus, networkInterfaces, platform, release, totalmem } from 'node:os'
import { sha256Hex } from '@furtherverse/crypto'
import { system } from 'systeminformation'
const readMachineId = (): string => {
const candidates = ['/etc/machine-id', '/var/lib/dbus/machine-id']
for (const path of candidates) {
try {
const value = readFileSync(path, 'utf-8').trim()
if (value.length > 0) {
return value
}
} catch {}
}
return ''
}
const collectMacAddresses = (): string[] => {
const interfaces = networkInterfaces()
return Object.values(interfaces)
.flatMap((group) => group ?? [])
.filter((item) => item.mac && item.mac !== '00:00:00:00:00:00' && !item.internal)
.map((item) => item.mac)
.sort()
}
export const computeDeviceFingerprint = (): string => {
const machineId = readMachineId()
const firstCpuModel = cpus()[0]?.model ?? 'unknown'
const macs = collectMacAddresses().join(',')
const source = [machineId, platform(), release(), arch(), String(totalmem()), firstCpuModel, macs].join('|')
export const computeDeviceFingerprint = async (): Promise<string> => {
const { uuid, serial, model, manufacturer } = await system()
const source = [uuid, serial, model, manufacturer].join('|')
const hash = sha256Hex(source)
return `FP-${hash.slice(0, 16)}`

View File

@@ -18,7 +18,7 @@ export const ensureUxConfig = async (db: DB) => {
return existing
}
const fingerprint = computeDeviceFingerprint()
const fingerprint = await computeDeviceFingerprint()
const rows = await db
.insert(uxConfigTable)
.values({

View File

@@ -51,6 +51,7 @@
"jszip": "catalog:",
"react": "catalog:",
"react-dom": "catalog:",
"systeminformation": "catalog:",
"uuid": "catalog:",
"zod": "catalog:",
},
@@ -122,6 +123,7 @@
"openpgp": "^6.0.1",
"react": "^19.2.4",
"react-dom": "^19.2.4",
"systeminformation": "^5.31.3",
"tailwindcss": "^4.2.1",
"tree-kill": "^1.2.2",
"uuid": "^13.0.0",
@@ -1342,6 +1344,8 @@
"supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
"systeminformation": ["systeminformation@5.31.3", "", { "os": "!aix", "bin": { "systeminformation": "lib/cli.js" } }, "sha512-vX0eeI7oGIr79NLiJRWnK8SyxDjyiNOEanaQnHRNyb5ep8QcpD8QMDvrukdrxV4pV4AKjwUDfaypXnWHMC/65A=="],
"tagged-tag": ["tagged-tag@1.0.0", "", {}, "sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng=="],
"tailwindcss": ["tailwindcss@4.2.1", "", {}, "sha512-/tBrSQ36vCleJkAOsy9kbNTgaxvGbyOamC30PRePTQe/o1MFwEKHQk4Cn7BNGaPtjp+PuUrByJehM1hgxfq4sw=="],

View File

@@ -63,6 +63,7 @@
"uuid": "^13.0.0",
"vite": "^8.0.0-beta.16",
"vite-tsconfig-paths": "^6.1.1",
"systeminformation": "^5.31.3",
"zod": "^4.3.6"
},
"overrides": {