feat(desktop): isolate platform accounts per desktop client
Frontend CI / Frontend (push) Successful in 3m4s
Backend CI / Backend (push) Successful in 14m24s

Scope desktop media accounts by the authenticated desktop client_id so
the same user logging in from Mac and Windows no longer sees a shared
account list. The list, identity lookup, upsert, patch, tombstone and
async health sink paths now all require matching client_id, and the
active uniqueness index moves from (workspace, platform, uid) to
(workspace, client, platform, uid).

Also strengthen the desktop client_id seed: when the OS machine id is
unavailable, fall back to a hashed fingerprint of stable hardware MAC
addresses before the random installation id, so the same hardware
keeps the same client across reinstalls.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-06 13:13:11 +08:00
parent f6aed87e44
commit 1ba29b9a09
14 changed files with 378 additions and 24 deletions
+8
View File
@@ -271,3 +271,11 @@
- Desktop publish management now surfaces scheduled-publish compliance recheck blocks through publish job metadata: `publish_job_status`, `compliance_blocked_record_id`, `compliance_blocked_at`, and summarized `compliance_blocked_reason`.
- Verification passed on 2026-05-05: targeted compliance Go tests, full `go test ./...`, admin-web typecheck/build, ops-web typecheck/build, desktop-client typecheck/build, and `git diff --check`.
- Residual risk: build output still reports large Ant Design / Milkdown chunks, but this is an existing bundle-size warning rather than a functional failure.
## Desktop Client Account Isolation - 2026-05-06
- Root cause: `/api/desktop/accounts` was calling `ListByUser`, so it returned all active platform accounts for `workspace_id + user_id`. The same user logging in on Mac and Windows therefore saw the same bound media accounts.
- Second root cause: desktop account upsert used `ON CONFLICT (workspace_id, platform_id, platform_uid)`, so the same third-party UID on another machine could update the existing row and move its `client_id`.
- Fix: desktop account listing, identity lookup, upsert, patch, delete, and async health sink paths are now scoped by the current desktop token's `client_id`.
- Migration `20260506120000_scope_platform_accounts_to_desktop_client` replaces the active platform-account uniqueness index with `(workspace_id, client_id, platform_id, platform_uid)`.
- Desktop client IDs are still stable hardware-derived UUIDs, but the seed intentionally includes tenant/workspace/user scope so two users on the same physical computer do not share one client record/token.
- Device fingerprinting now prefers OS-level machine IDs and uses a filtered MAC-address fingerprint only when OS machine IDs are unavailable; raw hardware identifiers are hashed locally and are not sent to the server.