refactor(server): 使用 systeminformation 替代手动采集生成设备特征码
硬件级 SMBIOS 标识(uuid/serial/model/manufacturer)跨平台稳定, 不再依赖 Linux 独有的 machine-id 和易变的 OS release/内存/MAC 地址。
This commit is contained in:
@@ -39,6 +39,7 @@
|
||||
"jszip": "catalog:",
|
||||
"react": "catalog:",
|
||||
"react-dom": "catalog:",
|
||||
"systeminformation": "catalog:",
|
||||
"uuid": "catalog:",
|
||||
"zod": "catalog:"
|
||||
},
|
||||
|
||||
@@ -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)}`
|
||||
|
||||
@@ -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({
|
||||
|
||||
4
bun.lock
4
bun.lock
@@ -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=="],
|
||||
|
||||
@@ -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": {
|
||||
|
||||
Reference in New Issue
Block a user