feat(dcauth): 移除机器码,改用纯设备码认证

- DCAuth 协议升级到 v2,签名原文只含设备码;客户端 2.0.0,旧版本返回 426
- 删除客户端机器码采集、后端 machine_code_* 字段与日志、后台机器码展示
- 102 迁移在生产执行前直接改为无机器码结构;SQL 守卫仅放行该文件
- Mock 短信不启用每日限额;修复慢电脑首次启动的协议转发竞态
- 新增 macOS DCAuth.app 打包脚本,注册 dcauth:// 协议,浏览器可直接唤起
This commit is contained in:
yml2213
2026-10-21 20:46:25 +08:00
parent cb916d7750
commit ef36453694
28 changed files with 355 additions and 326 deletions
@@ -11,8 +11,6 @@ export type AdminDeviceChallengeRow = {
user_id: number | null
device_id: string
public_key: string
machine_code_hash: string
machine_code_mask: string
client_version: string
device_ticket_hash: string
expires_at: string
@@ -28,8 +26,6 @@ export type AdminUserDeviceRow = {
user_id: number
device_id: string
public_key: string
machine_code_hash: string
machine_code_mask: string
client_version: string
status: string
bound_at: string
@@ -87,8 +83,6 @@ export async function authorizeAdminDeviceChallenge(input: {
app: string
deviceId: string
publicKey: string
machineCodeHash: string
machineCodeMask: string
clientVersion: string
now: string
}): Promise<AdminDeviceChallengeRow | null> {
@@ -99,27 +93,16 @@ export async function authorizeAdminDeviceChallenge(input: {
status = 'authorized',
device_id = $3,
public_key = $4,
machine_code_hash = $5,
machine_code_mask = $6,
client_version = $7,
authorized_at = $8,
updated_at = $8
client_version = $5,
authorized_at = $6,
updated_at = $6
WHERE challenge_id = $1
AND app = $2
AND status = 'pending'
AND expires_at > $8
AND expires_at > $6
RETURNING *
`,
[
input.challengeId,
input.app,
input.deviceId,
input.publicKey,
input.machineCodeHash,
input.machineCodeMask,
input.clientVersion,
input.now,
],
[input.challengeId, input.app, input.deviceId, input.publicKey, input.clientVersion, input.now],
)
return result.rows[0] || null
}
@@ -188,38 +171,26 @@ export async function bindAdminUserDevice(input: {
userId: number
deviceId: string
publicKey: string
machineCodeHash: string
machineCodeMask: string
clientVersion: string
now: string
}): Promise<AdminUserDeviceRow | null> {
const result = await query<AdminUserDeviceRow>(
`
INSERT INTO admin_user_devices (
user_id, device_id, public_key, machine_code_hash, machine_code_mask,
client_version, status, bound_at, last_used_at, created_at, updated_at
) VALUES ($1, $2, $3, $4, $5, $6, 'active', $7, $7, $7, $7)
user_id, device_id, public_key, client_version, status,
bound_at, last_used_at, created_at, updated_at
) VALUES ($1, $2, $3, $4, 'active', $5, $5, $5, $5)
ON CONFLICT (user_id) WHERE status = 'active'
DO UPDATE SET
device_id = EXCLUDED.device_id,
public_key = EXCLUDED.public_key,
machine_code_hash = EXCLUDED.machine_code_hash,
machine_code_mask = EXCLUDED.machine_code_mask,
client_version = EXCLUDED.client_version,
bound_at = EXCLUDED.bound_at,
last_used_at = EXCLUDED.last_used_at,
updated_at = EXCLUDED.updated_at
RETURNING *
`,
[
input.userId,
input.deviceId,
input.publicKey,
input.machineCodeHash,
input.machineCodeMask,
input.clientVersion,
input.now,
],
[input.userId, input.deviceId, input.publicKey, input.clientVersion, input.now],
)
return result.rows[0] || null
}
@@ -13,7 +13,6 @@ export type AdminLoginLogRow = {
success: boolean
failure_reason: string
login_method: string
machine_code_mask: string
created_at: string
}
@@ -27,7 +26,6 @@ type AdminLoginLogCreateInput = {
success?: boolean
failureReason?: string
loginMethod?: string
machineCodeMask?: string
createdAt: string
}
@@ -54,9 +52,8 @@ export async function createAdminLoginLog(
success,
failure_reason,
login_method,
machine_code_mask,
created_at
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
RETURNING *
`,
[
@@ -69,7 +66,6 @@ export async function createAdminLoginLog(
input.success !== false,
String(input.failureReason || '').trim(),
String(input.loginMethod || 'password').trim() || 'password',
String(input.machineCodeMask || '').trim(),
input.createdAt,
],
)
@@ -15,7 +15,6 @@ type AdminUserRow = {
created_at: string
updated_at: string
device_id?: string | null
machine_code_mask?: string | null
device_bound_at?: string | null
device_last_used_at?: string | null
}
@@ -68,7 +67,6 @@ const ADMIN_USER_SELECT = `
SELECT
au.*,
d.device_id AS device_id,
d.machine_code_mask AS machine_code_mask,
d.bound_at AS device_bound_at,
d.last_used_at AS device_last_used_at
FROM admin_users au