Commit Graph
8 Commits
Author SHA1 Message Date
J3vbandClaude Fable 5 94d8c2f827 test(admin): cover ban authorization matrix (W1-4)
Service level: BAN_MEMBERS refusal (Forbidden even for nonexistent targets
— no id enumeration), equal-rank and owner-target hierarchy refusals,
authorized ban/unban round-trip, self-ban rejection. Admin API level:
equal-rank owner ban 403s, a lower-positioned ADMINISTRATOR cannot ban the
owner, downward bans still work. All existing NewAdminAPI/NewHandler test
callsites now inject a real ModerationService so the production
authorization runs in every PATCH-user test.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 08:41:12 +02:00
Claude c9099f04e7 fix compile errors and wire permission cache invalidation
Critical fixes:
- Move svc creation in router.go above MountInviteRoutes/MountChannelRoutes
  (was used before definition — compile error)
- Restore hasChannelPermREST in channel_handler.go for upload_handler.go
  (was removed but still referenced — compile error)

Permission cache invalidation:
- Add PermissionInvalidator interface to admin package
- Wire through NewHandler → NewAdminAPI → handlePatchUser
- Call InvalidateUser(userID) after role changes in admin panel
- Update all admin test files to pass nil as new parameter

Also clarifies WithTx documentation for SQLite single-writer semantics.

https://claude.ai/code/session_01CBFF3r84ywkJRWwuqw8zD8
2026-04-05 21:25:35 +00:00
J3vb 77c440c4ae fix: atomic setup prevents TOCTOU race creating multiple owners (BUG-119)
Replace separate UserCount() + CreateUser() with atomic
CreateOwnerIfEmpty() that checks and inserts in a single SQLite
transaction. Concurrent race test validates exactly 1 owner under
20 parallel requests.
2026-04-02 12:09:27 +02:00
J3vb 098eebe674 fix: add CSRF Origin check to setup endpoint (BUG-097)
The first-run setup POST was vulnerable to cross-site request forgery
because it had no Origin validation. Added isSetupOriginAllowed check
that validates the Origin header against configured allowed_origins.
Requests with a mismatched Origin are rejected with 403. Requests
without an Origin header (same-origin or curl) are allowed through.
2026-04-02 11:54:56 +02:00
jevb 28f33644de fix: address remaining code review findings (C-3, H-5, H-6, M-1 through M-16)
- C-3: inject setupLimiter into NewAdminAPI instead of package-level global
- H-5: generateRandomKey returns error instead of panicking
- H-6: replace init() bcrypt with sync.Once lazy initialization
- M-2: remove unsafe-inline from admin CSP script-src and style-src
- M-3: sanitize upload filenames (strip control chars, truncate to 255)
- M-5: truncate User-Agent to 512 bytes before storing as device
- M-10: MaxBodySizeUnless uses prefix matching instead of exact path
- M-12: wrap seedExistingDatabase in a single transaction
- M-13: use errors.Is for EOF check in upload handler
- M-14: log writeJSON encoding errors instead of discarding
- M-16: standardize error codes to INTERNAL_ERROR across all handlers
2026-03-31 19:00:17 +02:00
jevb 4c4526e539 fix: security hardening — 45 issues from full-project Copilot audit
Critical (6):
- C1: SQL injection in VACUUM INTO backup path — strict character allowlist
- C2: Unlimited binary download in updater — 500MB LimitReader
- C3: JSON injection in SSE log stream — json.Marshal instead of concat
- C4: CSS injection via custom themes — reject () and {} in values
- C5: Silent DM message loss — error response on participant lookup failure
- C6: LiveKit URL credential leak — strip creds from diagnostics endpoint

High (11):
- H1: DB errors no longer trigger login rate-limit lockout
- H2: Permission fetch failure returns 500, not empty channel list
- H3: TOCTOU race on duplicate WS — atomic check-and-register in hub
- H5: LiveKit webhook verifies voice channel match (already implemented)
- H7: Server host address validated before storage (hostname regex)
- H8: WS message deduplication on reconnect replay (1000-entry Set)
- H9: Admin setup endpoint rate limited (5/min/IP)
- H10: Backup responses return filename only, not full path
- H11: Update binary recovery failure now alerts admin

Medium (17):
- M1: MIME type from magic bytes, not client header
- M3: Nil guard on DM broadcast recipient
- M5: LiveKit process run-done channel race fixed
- M6: Backup restore calls fsync before close
- M7: Partial download file cleaned up on error
- M8: Admin CSP uses nonce instead of unsafe-inline
- M9: Client rate limiter enforced for presence_update
- M10: Voice joinedAt not reset on double-join
- M11: Unread count skips increment during reconnect replay
- M13: Category type uses exact match, not substring
- M14: Storage LimitReader off-by-one fixed
- M15: GitHub token only sent to GitHub hosts
- M16: Content-parser ReDoS regex replaced with split approach
- M17: Audio device switch error handling added

Low (11):
- L1: CORS uses configured origins instead of wildcard
- L2: HSTS header added when TLS enabled
- L3: Consistent JSON error responses across all endpoints
- L4: File modtime from stat, not time.Now()
- L5: Malformed invite JSON returns 400
- L6: TouchSession failure logged at warn
- L8: MessageInput timers cleared on destroy
- L9: Log persistence flush errors caught
- L10: Credential save failure surfaced to user
- L11: Case-insensitive asset name matching in updater

Found by GitHub Copilot full-project review (claude-sonnet-4.6 + claude-haiku-4.5).
2026-03-29 12:35:04 +02:00
jevb df998386d9 feat: redesign admin panel, add live server logs and audit log filters
Admin panel redesign:
- Rebuild frontend from mockup with Discord-style dark theme
- Stat cards, section cards, role badges, modal system, toast notifications
- All 7 sections: Dashboard, Users, Channels, Audit Log, Settings, Backups, Updates
- Modals replace confirm()/prompt() for all destructive actions

Live server logs (new):
- RingBuffer + MultiHandler tees slog to stdout AND in-memory buffer
- SSE endpoint at /admin/api/logs/stream streams logs in real-time
- Log viewer with level filters (DEBUG/INFO/WARN/ERROR), search,
  auto-scroll, pause/resume, copy all, clear
- Color-coded lines by level, source categorization from file paths

Audit log improvements:
- Search filter (actor, action, target, detail)
- Action type dropdown filter
- Copy All and Export CSV buttons
- Instant client-side re-filtering

Console output:
- Switch from JSON to human-readable text format (slog.TextHandler)
- Move startup banner before init logs so it appears first
2026-03-19 05:32:40 +01:00
jevb d425dc5553 feat: add setup wizard for initial owner account creation
When no users exist, the admin panel shows a setup wizard instead of the
login form. Creates the first Owner account with a session token and
generates an unlimited invite code for onboarding other users. The setup
endpoint is locked out after the first user is created.

Also fixes the admin panel 404 by serving index.html directly for the
root path instead of delegating to http.FileServer.
2026-03-14 22:36:35 +01:00