POST /api/devices/protected/handshake — server-to-server endpoint called by
the AdGuard log-watcher whenever a Mac with our DNS-profile makes a DoH query
with its dnsToken embedded in the path (/dns-query/<token>).
- Idempotent: pending → active on first hit, lastDnsQueryAt always updated
- Auth: shared secret via x-handshake-secret (Infisical: HANDSHAKE_SECRET,
must be set before enabling the watcher)
- Revoked tokens are silently ignored (no info leak to potential attackers)
- Realtime publication added so the native app auto-advances the AddMacSheet
flow when status flips (no "I've installed it" button needed anymore)
Backend:
- ProtectedDevice prisma model + migration add_protected_devices
- DB helpers: list/count/get/create/confirm/revoke
- mobileconfig.ts utility — XML-escape, unique UUIDs per request
- 5 endpoints under /api/devices/* (avoid /api/devices conflict with existing
Capacitor UserDevice route by using /api/devices/protected for list)
Phase 1: backend ready. DoH-server token-routing comes in phase 2.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>