|
|
188e083719
|
refactor: auth expiry - sync JWT exp check, remove async validation
Previous async validateAuth() approach caused: recursion loop,
wrong /me path (404 -> session cleared), init() fetching auth-required
settings without token (cleared session every load).
New synchronous approach:
- Auth.expired(): decodes JWT payload locally, checks exp timestamp
- Auth.logged(): token+user exist AND not expired; auto-clears stale
session on expiry (no network, no async, no loops)
- route(): simple sync guard - if !Auth.logged() reset + redirect to
#/login; home page stays public (clears stale cookie only)
- API.req: 401 response -> Auth.reset() + redirect to login unless on
public page (fallback for server-side revocation/invalid signature)
- Removed validateAuth/_validating/_doRoute entirely
|
2026-08-21 21:01:30 +08:00 |
|
|
|
559970c5b7
|
feat: one account can bind both netease + skin identities
- db: user_identities table (UNIQUE user_id+source), migrate backfill from users
- auth: GET/POST/DELETE /api/auth/identities - bind/unbind/list identities
(netease requires UID, one per source, name uniqueness, keep >=1)
- register/external/plugin/admin-created users auto-write primary identity
- tickets: submit uses selected identity (validated belongs to user)
- dashboard: 我的身份 card with bind/unbind UI
- ticket-create: identity selector when >1 identity
|
2026-08-17 01:17:09 +08:00 |
|