Commit Graph
9 Commits
Author SHA1 Message Date
Claude 46aeccc49b fix(phase-bc): address review findings — auth, SSRF, seq alignment
Phase B + C review pass: critical security and correctness fixes.

Security
- S1: plugin admin endpoints now require admin.RequireAdminAuth in addition
  to AdminIPRestrict. Previously a LAN attacker on the allowed CIDR could
  list/enable/disable/uninstall plugins without a session.
- S2: rewrite plugin HTTPDo allowlist with proper net/url parsing. Empty
  entries are ignored, suffix matches require a dot boundary, and a custom
  Dialer rejects loopback / RFC1918 / link-local addresses to close the
  DNS-rebinding TOCTOU window. Redirects re-validated.
- S3 + #9: manifest Name pinned to ^[a-z0-9][a-z0-9_-]{0,63}$, Entrypoint
  and UI tab assets validated against absolute / "..", NUL byte, backslash
  and non-canonical paths. Asset handler hardened with filepath.Rel check
  for symlink and prefix-without-separator escapes.
- S5: pluginBridge postMessage handler ignores the pluginId in the message
  body and uses an e.source -> contentWindow lookup instead, defeating
  spoofed messages from same-origin scripts.
- S8: HTTPDo body capped at 5 MiB via io.LimitReader, redirects bounded
  to 5 hops.

Correctness
- Critical seq alignment: PersistEvent now takes the hub-assigned seq as a
  required parameter so the events table row seq always matches the wrapped
  payload seq. Hub seeds its in-memory atomic counter from MAX(events.seq)
  on startup. Drops in the persister queue no longer mis-align row vs
  payload seq.
- #1: live plugin.Registry constructed in main.go BEFORE NewRouter and
  threaded through; admin handler is no longer wired with nil.
- #3: EventPersister.Stop is now safe to call without a prior Start by
  tracking a started flag — previously deadlocked waiting on done.

Wiring
- NewRouter signature gains *plugin.Registry; two test callers updated.
- admin.RequireAdminAuth exported as a thin wrapper over the existing
  package-private adminAuthMiddleware.
- sqlc query templates updated for the new PersistEvent + GetMaxEventSeq
  contracts (sqlite + postgres).

https://claude.ai/code/session_01UsBsQW2YiA2usk9pnJjAWk
2026-04-06 09:29:29 +00:00
Claude 1d8bfe2d6a fix: revert breaking security changes and update tests for version removal
Restores dangerous-settings and allowSelfSigned which are required for
self-hosted servers with self-signed certificates. Makes HealthResponse.version
optional to match server-side removal, and updates router tests to assert
version is correctly omitted from unauthenticated endpoints.

https://claude.ai/code/session_01KKo3RwjdmcNzkgXNfUkgNT
2026-04-04 18:02:26 +00:00
jevb 2976863ad0 fix: atomic invite registration, fail-closed search, proxy-aware rate limiting
- Atomic CreateUserWithInvite prevents invite burn on failed registration
- Channel search fails closed on channel-type and override lookup errors
- Malformed FTS input returns 400 instead of 500
- Search rate limiting uses own namespace, respects trusted proxy IPs
- Login lockout keyed by forwarded client IP behind reverse proxy
- Trusted same-server OG previews re-enabled with self-signed cert support
- Normalized host matching for embeds/attachments
- Regression tests for all changes (auth, channel, embeds)
2026-03-29 19:39:22 +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 65a8403a92 fix: resolve 1 critical and 5 high security/reliability issues from go-review
- CRIT-2: Prevent HTTP header injection in Content-Disposition via mime.FormatMediaType
- HIGH-1: Call hub.GracefulStop() on server shutdown to clean up WebSocket/voice state
- HIGH-2: Remove double send on serveErr channel that caused goroutine leak
- HIGH-3: Handle GetUserByID error after registration to prevent nil panic
- HIGH-4: Return nil,nil on sql.ErrNoRows in GetAttachmentByID (matching codebase convention)
- HIGH-5: Add voiceDone channel to bound RTP goroutine lifetime on voice teardown
- Fix handleVoiceICE to return VOICE_ERROR when no PC (consistent with other voice handlers)
- Update tests to match corrected behavior
2026-03-19 03:53:40 +01:00
jevb ce4326766a fix: resolve all golangci-lint issues blocking CI server build
Fix 70+ errcheck violations by adding explicit error discards (`_ =`)
for unchecked return values across test helpers and deferred Close()
calls. Remove unused `senderID` field from broadcastMsg and unused
`defaultCleanupMaxWindow` const. Apply De Morgan's law, remove empty
branch, and simplify redundant type declaration per staticcheck.
2026-03-17 08:09:52 +01:00
jevb 9c1d99683c fix: address PR review findings (issues #9-#14)
- Fix capacity over-allocation and use strings.Builder in getReactionsBatch (#9)
- Replace `any` types and cache Tauri invoke in window-state.ts (#10)
- Remove custom `contains` helper, fix NilHub tests to pass nil (#11)
- Add nil guards before hub method calls in admin handlers (#12)
- Run golangci-lint v2: modernize interface{}/any, range-over-int loops,
  remove dead code, fix errcheck, add .golangci.yml config (#13)
- Add 23 client unit test suites (694 tests), exclude Tauri-coupled
  files from coverage, achieve 80%+ threshold (#14)

Closes #9, closes #10, closes #11, closes #12, closes #13, closes #14
2026-03-17 04:11:04 +01:00
jevb 73a621ef0f feat: implement server auto-update API endpoints with download, verify, and restart 2026-03-14 22:05:13 +01:00
jevb a1434ad07f feat: implement Phase 1 server skeleton with TDD
- Scaffold Go module (github.com/owncord/server) with all package dirs
- config: koanf-based YAML loader with env var overrides, default generation
- db: pure-Go SQLite (modernc, no CGO), WAL mode, FK enforcement, full
  15-table schema from SCHEMA.md including FTS5 and idempotent migrations
- auth/tls: ECDSA P-256 self-signed cert generation, LoadOrGenerate for
  all 4 TLS modes (self_signed, acme, manual, off)
- api: chi router with request ID middleware, /health and /api/v1/info
- main: graceful shutdown (30s timeout), structured slog JSON logging
- Stubs for ws, storage, admin packages ready for Phase 2+

Test coverage: api 100%, auth 85.7%, db 82.4%, config 80.6%
Binary: chatserver.exe 12MB, GOOS=windows GOARCH=amd64
2026-03-14 20:34:37 +01:00