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:",
|
"jszip": "catalog:",
|
||||||
"react": "catalog:",
|
"react": "catalog:",
|
||||||
"react-dom": "catalog:",
|
"react-dom": "catalog:",
|
||||||
|
"systeminformation": "catalog:",
|
||||||
"uuid": "catalog:",
|
"uuid": "catalog:",
|
||||||
"zod": "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 { sha256Hex } from '@furtherverse/crypto'
|
||||||
|
import { system } from 'systeminformation'
|
||||||
|
|
||||||
const readMachineId = (): string => {
|
export const computeDeviceFingerprint = async (): Promise<string> => {
|
||||||
const candidates = ['/etc/machine-id', '/var/lib/dbus/machine-id']
|
const { uuid, serial, model, manufacturer } = await system()
|
||||||
|
const source = [uuid, serial, model, manufacturer].join('|')
|
||||||
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('|')
|
|
||||||
const hash = sha256Hex(source)
|
const hash = sha256Hex(source)
|
||||||
|
|
||||||
return `FP-${hash.slice(0, 16)}`
|
return `FP-${hash.slice(0, 16)}`
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ export const ensureUxConfig = async (db: DB) => {
|
|||||||
return existing
|
return existing
|
||||||
}
|
}
|
||||||
|
|
||||||
const fingerprint = computeDeviceFingerprint()
|
const fingerprint = await computeDeviceFingerprint()
|
||||||
const rows = await db
|
const rows = await db
|
||||||
.insert(uxConfigTable)
|
.insert(uxConfigTable)
|
||||||
.values({
|
.values({
|
||||||
|
|||||||
4
bun.lock
4
bun.lock
@@ -51,6 +51,7 @@
|
|||||||
"jszip": "catalog:",
|
"jszip": "catalog:",
|
||||||
"react": "catalog:",
|
"react": "catalog:",
|
||||||
"react-dom": "catalog:",
|
"react-dom": "catalog:",
|
||||||
|
"systeminformation": "catalog:",
|
||||||
"uuid": "catalog:",
|
"uuid": "catalog:",
|
||||||
"zod": "catalog:",
|
"zod": "catalog:",
|
||||||
},
|
},
|
||||||
@@ -122,6 +123,7 @@
|
|||||||
"openpgp": "^6.0.1",
|
"openpgp": "^6.0.1",
|
||||||
"react": "^19.2.4",
|
"react": "^19.2.4",
|
||||||
"react-dom": "^19.2.4",
|
"react-dom": "^19.2.4",
|
||||||
|
"systeminformation": "^5.31.3",
|
||||||
"tailwindcss": "^4.2.1",
|
"tailwindcss": "^4.2.1",
|
||||||
"tree-kill": "^1.2.2",
|
"tree-kill": "^1.2.2",
|
||||||
"uuid": "^13.0.0",
|
"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=="],
|
"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=="],
|
"tagged-tag": ["tagged-tag@1.0.0", "", {}, "sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng=="],
|
||||||
|
|
||||||
"tailwindcss": ["tailwindcss@4.2.1", "", {}, "sha512-/tBrSQ36vCleJkAOsy9kbNTgaxvGbyOamC30PRePTQe/o1MFwEKHQk4Cn7BNGaPtjp+PuUrByJehM1hgxfq4sw=="],
|
"tailwindcss": ["tailwindcss@4.2.1", "", {}, "sha512-/tBrSQ36vCleJkAOsy9kbNTgaxvGbyOamC30PRePTQe/o1MFwEKHQk4Cn7BNGaPtjp+PuUrByJehM1hgxfq4sw=="],
|
||||||
|
|||||||
@@ -63,6 +63,7 @@
|
|||||||
"uuid": "^13.0.0",
|
"uuid": "^13.0.0",
|
||||||
"vite": "^8.0.0-beta.16",
|
"vite": "^8.0.0-beta.16",
|
||||||
"vite-tsconfig-paths": "^6.1.1",
|
"vite-tsconfig-paths": "^6.1.1",
|
||||||
|
"systeminformation": "^5.31.3",
|
||||||
"zod": "^4.3.6"
|
"zod": "^4.3.6"
|
||||||
},
|
},
|
||||||
"overrides": {
|
"overrides": {
|
||||||
|
|||||||
Reference in New Issue
Block a user