v1.1.0-beta.039 - feat(permissions): request gate, per-library access, themed tiers, default-access
π‘οΈ Per-library access control
- library-access chokepoint enforced across every read surface (library/{route,series,issue,recent,check,ids}, discover, calendar, recommendations, reader/image, opds/, reading-lists/) β non-admins see only granted libraries (fresh DB lookup, not JWT)
- New UserLibraryAccess grants; admin/users gains per-library checkboxes; new admin/libraries route backs the picker
- reader/image hardened against path traversal via shared isPathWithinRoots() (utils/paths)
π¦Έ Themed tiers + request gate
- canRequest gate on request/route, request/manual, reading-lists import/fallback β Civilian β 403, admins bypass
- Tiers (Civilian/Sidekick/Vigilante/Hero) via tier-badge in admin/users, site-header, profile; Apply-Tier + per-library grants in users admin
- Auth seeding: register + SSO users get default-library access + canRequest; flows through JWT/session (next-auth.d.ts)
π Per-library default access
- Library.defaultAccess "Auto-grant to all users" toggle in Settings; admin/config grants newly-default libraries to all users on falseβtrue
- db-init one-time sentinel-guarded backfills: canRequest for existing users, all-library access for existing users, Comics flagged default-access
π§ SQLite adaptation
- Replaced createMany skipDuplicates (Postgres-only) with existing-pair filtering in the default-access grant + library backfill
β Verification
- tsc --noEmit clean; vitest 210/210 across 63 files (8 permission suites updated)