jevb
aa2a1cf025
ci: add GitHub Actions CI and release workflows
...
CI runs build+test+lint for both server and client on push/PR.
Release workflow builds binaries, generates SHA256 checksums,
and creates a GitHub Release with auto-generated notes on tag push.
2026-03-14 21:58:06 +01:00
jevb
5aa216d991
fix: correct embed path (static not admin/static) and simplify audit_log migration
2026-03-14 21:37:47 +01:00
jevb
ab389764b5
feat: implement Phase 5 (voice/WebRTC signaling) and Phase 6 (admin panel)
...
Phase 5 — Voice:
- migrations/002_voice_states.sql: voice_states table with FK + index
- db/voice_queries: JoinVoiceChannel, LeaveVoiceChannel, GetVoiceState,
GetChannelVoiceStates, UpdateVoiceMute, UpdateVoiceDeafen, ClearVoiceState
- ws/voice_handlers: handleVoiceJoin (perm check, DB, broadcast existing
states), handleVoiceLeave, handleVoiceMute, handleVoiceDeafen,
handleVoiceSignal (rate-limited relay, SDP never logged),
handleSoundboard (rate-limited, USE_SOUNDBOARD perm check)
- ws/handlers: dispatch voice_join/leave/mute/deafen/offer/answer/ice/soundboard
- ws/serve: call handleVoiceLeave on disconnect; include voice states in ready payload
- ws/messages: buildVoiceState, buildVoiceLeave, buildVoiceSignalRelay
- api/voice_handler: GET /api/v1/voice/credentials — HMAC-SHA1 TURN creds
- config: VoiceConfig (TURNSecret, STUNPort, TURNPort, TURNEnabled)
Phase 6 — Admin Panel:
- migrations/003_audit_log.sql: audit_log table with indexes
- db/admin_queries: GetServerStats, ListAllUsers, UpdateUserRole,
ForceLogoutUser, AdminCreate/Update/DeleteChannel, LogAudit,
GetAuditLog, GetSetting, SetSetting, GetAllSettings, BackupTo
- admin/api: full REST API — stats, users, channels, audit log, settings,
backup; adminAuthMiddleware (ADMINISTRATOR bit), ownerOnlyMiddleware
- admin/static/index.html: single-page admin panel (dark theme, vanilla JS,
no CDN) — dashboard, users, channels, audit log, settings sections
- admin/admin.go: NewHandler wiring go:embed static files + API
Fixes: Channel struct json tags (was serializing as "ID" not "id"),
duplicate getWithToken helper renamed in voice_handler_test.go
Test coverage: admin 59.1%, api 78.2%, auth 90.9%, db 82.0%, ws 37.9%
2026-03-14 21:31:03 +01:00
jevb
36640e3051
feat: implement Phase 4 real-time chat (WebSocket hub + message REST)
...
- db: channel_queries (ListChannels, GetChannel, CRUD, permissions),
message_queries (CreateMessage, GetMessage, GetMessages paginated,
EditMessage, DeleteMessage soft, AddReaction, RemoveReaction,
GetReactions, SearchMessages FTS5, UpdateReadState)
- db: fix in-memory DB isolation — SetMaxOpenConns(1) for :memory: path
- ws/hub: replace stub with full Hub (register/unregister, broadcast to
channel/all, send to user, thread-safe, buffered broadcast channel)
- ws/client: Client with send channel, NewTestClient helpers for tests
- ws/handlers: dispatch chat_send/edit/delete, reaction_add/remove,
typing_start, presence_update — all with rate limiting and permission checks
- ws/messages: JSON builder helpers for all server→client message types
- ws/serve: ServeWS HTTP handler, WS auth handshake (10s timeout),
ready payload, writePump/readPump goroutines, graceful disconnect
- api: channel_handler — GET /channels, GET /channels/{id}/messages,
GET /search; fixed double-mount of /api/v1 route group
- api/router: mount channel routes, start hub, register /api/v1/ws
Test coverage: api 77.6%, auth 90.9%, db 84.2%, ws 26.7% (serve.go
requires live WS connection; hub/handlers/messages fully covered)
2026-03-14 21:17:09 +01:00
jevb
814653ea08
chore: add Client .gitignore, remove tracked build artifacts
2026-03-14 21:07:25 +01:00
jevb
9707c4d4af
feat: scaffold Phase 3 WPF client shell with MVVM and TDD structure
...
- WPF (.NET 8) project targeting net8.0-windows
- Models: ServerProfile (record), Channel, Message, User, Role
- ViewModels: ViewModelBase (INotifyPropertyChanged), RelayCommand<T>,
ConnectViewModel (profiles, login/register toggle, connect command),
MainViewModel (channels, messages, typing indicator, send command),
SettingsViewModel (dark theme, notifications, PTT key)
- Services: IProfileService + ProfileService (AppData JSON, immutable ops),
ICredentialService + CredentialService (DPAPI via ProtectedData),
IWebSocketService + WebSocketService (ClientWebSocket stub)
- Views: ConnectPage (server address, login/register, profile selector),
MainPage (3-column: channel list, message area, member list),
App.xaml wires converters and startup
- Converters: BoolToVisibilityConverter, IntToVisibilityConverter
- Tests: ConnectViewModelTests (11 cases), MainViewModelTests (11 cases),
ProfileServiceTests (6 cases) — ready to run once NuGet accessible
(run: dotnet restore && dotnet test OwnCord.Client.Tests/)
Build: dotnet build OwnCord.Client/ succeeds with 0 warnings
2026-03-14 21:07:07 +01:00
jevb
b7dd6eabe9
feat: implement Phase 2 auth & security with TDD
...
- auth/session: 256-bit crypto-random tokens, SHA-256 hashing for storage
- auth/password: bcrypt cost 12, strength validation (8-72 chars)
- auth/ratelimit: sliding-window RateLimiter with lockout, thread-safe
- db/models: User, Session, Invite, Role types
- db/auth_queries: full user/session/invite CRUD with in-memory test coverage
- api/middleware: AuthMiddleware (Bearer token), RequirePermission (bitfield),
RateLimitMiddleware (X-Real-IP, Retry-After header)
- api/auth_handler: POST register/login, POST logout, GET me
- Generic errors — username existence never revealed
- Rate limits: 3/min register, 5/min login, lockout after 10 failures
- api/invite_handler: create/list/revoke behind MANAGE_INVITES permission
- bluemonday sanitization on all user-supplied string fields
Test coverage: auth 90.9%, db 84.4%, api 80.9%
2026-03-14 20:52:11 +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
jevb
bcf563f36c
chore: initial commit with project specs and configuration
...
Add all specification files (CHATSERVER, PROTOCOL, SCHEMA, API, SETUP),
Claude Code config, and skill definitions for the OwnCord chat platform.
2026-03-14 19:57:39 +01:00