Authentication
Anonymous-first: try without signup, link email later to sync. Same model powers web + Android.
Device model
Prisma DeviceToken: deviceFingerprint (unique), refreshTokenHash, accessTokenJti, email (unique), passwordHash. Anonymous rows have no email; linking email merges bookmarks/folders.
Flow
bash
# 1) anonymous — create or resume device (200 existing, 201 new)
curl -X POST https://api.reqistry.dev/v1/auth/anonymous \
-H "Content-Type: application/json" -d '{"deviceFingerprint":"abc","deviceInfo":{}}'
# → { accessToken (15m), refreshToken (30d, single-use), deviceFingerprint }
# 2) use
curl https://api.reqistry.dev/v1/auth/me -H "Authorization: Bearer <accessToken>"
# 3) refresh (rotates; old refresh invalidated)
curl -X POST https://api.reqistry.dev/v1/auth/refresh -d '{"refreshToken":"..."}'
# 4) link email to sync (merges if email exists on another device → old device deactivated)
curl -X POST https://api.reqistry.dev/v1/auth/link-email \
-H "Authorization: Bearer <accessToken>" -d '{"email":"you@example.com","password":"..."}'
# 5) later, login from any device
curl -X POST https://api.reqistry.dev/v1/auth/login-email -d '{"email":"you@example.com","password":"..."}'
# 6) revoke
curl -X POST https://api.reqistry.dev/v1/auth/revoke -d '{"deviceFingerprint":"abc"}'What needs auth
Public reads: categories, search, APIs, compare, trust-scores, change-feed, recently-added, recommend (no token). Auth required: /v1/stack, bookmarks/folders, reports, health-check trigger, notifications preferences/events, PUT /v1/auth/me, DELETE /v1/auth/me. Health check: per-device cooldown + per-API rate limit.Token lifecycle
Access 15m · Refresh 30d · single-use rotation. Store refresh securely; on 401, refresh then retry. Revoke deactivates all tokens for that device.