Commit Graph

100 Commits

Author SHA1 Message Date
hobokenchicken 7f2a58599d fix: invisible notification/settings icons were eating channel clicks
The notification bell and settings gear spans had opacity-0 but
pointer-events were still active. Their stopPropagation handlers
prevented the parent button's onClick from firing when clicking
in the icon area. Added pointer-events-none to the container,
re-enabled on group-hover.
2026-07-02 09:06:04 -04:00
hobokenchicken 67ce6bbfd9 refactor: remove redundant far-left [S][@] selector
ServerBar already has [@] at the top and server icons below.
The far-left w-16 div was a duplicate layer. ServerBar now
navigates on server/DM clicks.
2026-07-02 09:02:40 -04:00
hobokenchicken c0686d4ca3 fix: nested button inside button broke channel clicks
Invalid HTML: <button> inside <button> causes the browser to close
the outer button prematurely, so clicking the channel name never
fires setActiveChannel. Changed inner elements to <span role=button>.
2026-07-02 08:52:26 -04:00
hobokenchicken 74a1db8392 fix: nav buttons now navigate, not just toggle store state
The [S] button only called setDM(false) without navigating away from
/chat area. Since the notes-to-self feature now calls navigate('/dm/:id'),
the URL stayed at /dm/... and ChatArea never re-mounted.

[S] now navigates to /, [@] navigates to /dm.
2026-07-02 08:49:47 -04:00
hobokenchicken 3aa1ca3ead fix: clicking DM entries actually navigates to conversation
ConversationList was only setting activeConversationId in the store
but never navigating. If the Outlet was still showing ChatArea from
a server channel route, DMChat never mounted. Now every click
navigates to /dm/:conversationId so the router mounts DMChat.
2026-07-02 08:43:57 -04:00
hobokenchicken 3ed66f3d43 debug: add error surfacing for notes-to-self creation 2026-07-02 08:40:07 -04:00
hobokenchicken a5c3b25cc0 feat: notes to self via self-DM
Backend:
- Removed self-DM restriction in conversation Create
- Added duplicate check for self-DMs (returns existing one)

Frontend:
- ConversationList: [📝] button creates/opens notes to self
- Self-DMs show as 'Notes' with 📝 icon in sidebar
- DMChat header shows 'Notes' for self-DMs
2026-07-02 08:33:57 -04:00
hobokenchicken d0da35e816 fix: channel/group rename now works
- Input field no longer nested inside a button/clickable div
- Snapshot state before clearing editing mode to avoid stale closures
- Log errors instead of silently swallowing them
2026-07-02 08:25:11 -04:00
hobokenchicken 31cb295a24 feat: right-click context menus for channels, groups, and servers
ContextMenu: reusable hook-based component that positions a menu at
the cursor and auto-closes on outside click or Escape.

ChannelList:
- Right-click channel -> Edit Name, Permissions, Delete Channel
- Right-click group header -> Edit Name, Create Channel Here, Delete Group
- Inline rename: replacing name text with an input, commits on Enter/blur
- CreateChannelModal now accepts defaultGroupId to pre-select a group

ServerBar:
- Right-click server icon -> Server Settings, Invite People, Leave Server
- Leave calls DELETE /servers/{id}/members/me

Backend:
- Added LeaveServer handler (DELETE /servers/{serverID}/members/me)
- Server owner cannot leave; must transfer or delete
2026-07-02 08:18:12 -04:00
hobokenchicken ecb26cb731 fix: use gif image URL instead of giphy page URL in messages
gif.url is the giphy.com page link, gif.images.fixed_height.url is
the actual media CDN URL. react-markdown was rendering a dead link
instead of an embedded image.
2026-07-02 08:06:31 -04:00
hobokenchicken 33dc63b94c fix: stop double-posting messages (WS + HTTP both appended) 2026-07-01 15:59:31 -04:00
hobokenchicken c80a36bacb fix: move DUMPSTER banner back inside login card, centered 2026-06-30 15:56:45 -04:00
hobokenchicken 65de4efb0d fix: span DUMPSTER banner full-width above login card 2026-06-30 15:55:14 -04:00
hobokenchicken b8ae43e250 fix: center DUMPSTER and LOGIN headings on login screen 2026-06-30 15:53:04 -04:00
hobokenchicken 82ddf914e4 feat: add forgot password UI flow
- ForgotPasswordPage: email input, sends reset request, shows success
- ResetPasswordPage: reads token from ?token= query param, password
  + confirm inputs, validates min length, shows success with login link
- LoginForm: added [FORGOT PASSWORD?] link below the form
- App.tsx: /forgot-password and /reset-password routes (public, no auth)
- auth store: requestPasswordReset + resetPassword actions
- Backend routes already existed at POST /auth/request-password-reset
  and POST /auth/reset-password
2026-06-30 15:49:23 -04:00
root f4437c5e1d feat: add SMTP email support and fix profile/permissions bugs 2026-06-30 19:29:08 +00:00
hobokenchicken 215f931311 fix: wire permission checks into message/channel handlers
- Add CheckChannelPermission to permissions.Checker (layers channel overrides on top of role permissions)
- Refactor requireChannelAccess to accept required permission bitmap
- Message Create checks SEND_MESSAGES; List/Search check VIEW_CHANNEL
- BulkDelete uses Checker.CheckPermission for MANAGE_MESSAGES
- Channel handler List filters out channels user cannot view
- Remove dead checkPermission method from message handler
- Fix frontend avatar upload: parse response URL, call updateProfile
2026-06-30 13:47:08 -04:00
hobokenchicken a13546bdf6 fix: timestamp format to [dd.mm.yyyy @ hh:mm] 2026-06-30 13:12:06 -04:00
hobokenchicken d663638387 feat(phase8.1): server groups — table, CRUD handler, collapsible channel sections 2026-06-30 12:50:53 -04:00
hobokenchicken cc6ed741f0 feat(phase7): per-channel notification settings and read receipts
Phase 7.1 — Per-channel notification settings
- New notification_settings table (user_id, channel_id, level)
- GET/PUT/DELETE handlers under /channels/{channelID}/notifications
- Push dispatch and @mention loops filtered by notification level
- Frontend: bell icon per channel cycling all/mentions/none

Phase 7.4 — Read receipts
- New read_states table (user_id, channel_id, last_read_message_id)
- PUT /channels/{channelID}/read and GET /users/me/read-states
- Auto-mark-read when messages load in ChatArea
- Unread dot for channels never opened

Also: favicon/icon refresh in index.html
2026-06-30 12:39:14 -04:00
hobokenchicken 775bd953b0 feat(phase6): video grid, noise suppression, whisper system
- New VideoGrid component: live camera feeds (local + remote) in VoicePanel
- Camera toggle in VoiceControls: enable/disable video per participant
- Noise suppression toggle in VoiceControls + voice store
- VOICE_WHISPER WS event: backend routes whisper to target user only
- Whisper UI: per-participant whisper button, notification toasts with dismiss
- Fix circular import between voice.ts and ws.ts (use lazy accessor)
2026-06-30 12:21:53 -04:00
hobokenchicken 6db4e3cc2d feat(phase5): scheduling/availability - DB, API, UI in server settings 2026-06-30 11:29:43 -04:00
hobokenchicken 74d2153ffa feat(phase5): list channels - todo/in_progress/done columns, CRUD 2026-06-30 11:26:15 -04:00
hobokenchicken dbebc1f381 feat(phase5): docs channels - CRUD, wiki sidebar, markdown editor 2026-06-30 11:19:32 -04:00
hobokenchicken e65ce54e36 feat(phase5): calendar channels - events, RSVPs, calendar view 2026-06-30 11:15:40 -04:00
hobokenchicken 58ce09cc18 feat(phase4): rich profiles, badges DB, block list 2026-06-30 11:04:32 -04:00
hobokenchicken 368172e3d6 feat(phase3): forum channels + tags + card UI 2026-06-30 10:44:52 -04:00
hobokenchicken f3f03df710 feat(phase3): threads backend + thread panel UI 2026-06-30 10:36:18 -04:00
hobokenchicken bd260183ef feat(phase2): channel permission overrides + expanded role UI + audit log cleanup 2026-06-30 10:28:03 -04:00
hobokenchicken d7c84647e5 feat(phase2): bulk delete + audit log; update roadmap/parity docs 2026-06-30 10:20:57 -04:00
hobokenchicken 30e159cbdb sync: phase 1 backend + frontend from server 2026-06-30 09:26:03 -04:00
hobokenchicken 6c8defb6fd feat: realtime status, mentions, push notifications 2026-06-29 15:52:34 -04:00
hobokenchicken 282a436995 fix: construct invite URL from code on frontend 2026-06-29 15:35:22 -04:00
hobokenchicken 2d3bf48e66 fix: add invite button, voice join dedup, voice panel immediate render 2026-06-29 15:28:05 -04:00
hobokenchicken 369737565e fix: WebSocket cookie auth + connect on layout mount 2026-06-29 14:30:29 -04:00
hobokenchicken 90289fede1 sync: all server-side fixes and features 2026-06-29 14:24:45 -04:00
hobokenchicken 175ec90705 fix: blank page on channel click + logout issue 2026-06-29 14:16:32 -04:00
hobokenchicken 9f138deb9d feat: login with username or email + change password
Backend:
- Login handler accepts username OR email via the same field
- New PUT /auth/me/password endpoint (verifies current password,
  requires min 8 chars for new password)

Frontend:
- Login form shows EMAIL OR USERNAME field (single field for both)
- Auth store updated with changePassword function
- UserSettings has new CHANGE PASSWORD section
2026-06-29 14:00:19 -04:00
root 23902de912 feat: server members API + member list in sidebar + fix chat input
Backend:
- Add GET /api/v1/servers/{serverID}/members endpoint
- Wire MemberHandler routes in main.go

Frontend:
- Create member store (fetchMembers by server ID)
- MemberList now fetches members from API instead of empty props
- ChatArea: show channel name instead of ID, add error display,
  add flex-1 + min-w-0 to input for proper sizing, error handling
  on sendMessage
2026-06-29 17:51:32 +00:00
hobokenchicken 3f33859f4a feat: UI for server/channel creation, settings link, role management backend
Frontend:
- Settings link in header next to logout
- [+] button to create server (name + optional icon)
- [#] button to join server via invite code
- [+] button to create channel (name, type, category)
- Server name shown instead of UUID in channel list header
- /invites/:code route wired for JoinServer component

Backend:
- Wire role CRUD + member-role assignment routes (MANAGE_SERVER gated)
- Seed @everyone default role on server creation
2026-06-29 12:50:46 -04:00
hobokenchicken d25763cc84 feat(voice): add AudioPresets and publish defaults for voice quality 2026-06-29 09:37:25 -04:00
hobokenchicken 130187c7be security: remediate all P0-P2 audit findings (12 tasks)
P0 fixes:
- WebSocket origin checking (reject untrusted origins)
- WS session token moved from URL query param to first message frame
- WebAuthn login cookie now uses Secure flag via shared SetSessionCookie
- PostgreSQL sslmode configurable via POSTGRES_SSLMODE env (default: require)
- Fixed DatabaseDSN to use real password instead of masked placeholder

P1 fixes:
- Per-IP rate limiting middleware (auth: 5 req/s, invites: 2 req/s)
- Security headers on all responses (CSP, X-Frame-Options, nosniff, etc.)
- WS broadcasts scoped to server members (prevents cross-server data leak)
- Webhook tokens stored as SHA-256 hashes (not plaintext)

P2 fixes:
- CSRF protection via Origin header validation on state-changing requests
- MANAGE_CHANNELS permission enforced on channel update/delete
- Upload validation: 25MB limit, extension allowlist, server-side MIME check
- File serve: path traversal protection + Content-Disposition: attachment

Files: 23 changed, +499/-100. Builds clean (go build, go vet, npm build).
Zero CVEs (govulncheck, npm audit).
2026-06-29 09:30:50 -04:00
hobokenchicken bb0540b70c Finish Phase 6: Push frontend, WebAuthn frontend, OpenAPI/Swagger
Frontend:
- stores/push.ts: fixed VAPID key endpoint, added checkSubscription, proper subscription format
- UserSettings.tsx: added [ENABLE PUSH] toggle and [REGISTER PASSKEY] button
- LoginForm.tsx: added [SIGN IN WITH PASSKEY] button

Backend:
- cmd/server/main.go: added Swagger annotations, /docs/* route
- docs/: generated swagger.json, swagger.yaml, docs.go
- Makefile: added docs target for swag init
2026-06-28 18:53:05 -04:00
hobokenchicken af1de3d140 Phase 6: Permissions, Push, WebAuthn scaffolding
Backend:
- internal/permissions/permissions.go: permission bitflags (VIEW_CHANNEL through SHARE_SCREEN)
- internal/permissions/checker.go: permission checker with role aggregation
- internal/middleware/permission.go: RequirePermission middleware
- internal/push/handlers.go: push subscription CRUD, VAPID key endpoint, SendPush
- internal/auth/webauthn.go: WebAuthn passkey scaffolding (begin/finish endpoints)
- internal/db/db.go: is_default on roles, push_subscriptions table, webauthn_credentials table
- go.mod: added webpush-go, go-webauthn dependencies

Frontend:
- stores/role.ts: Zustand store for role management
- RoleManager.tsx: role CRUD with permission checkboxes
- MemberRoleAssign.tsx: assign roles to members
- App.tsx: /servers/:serverId/roles route
2026-06-28 17:53:44 -04:00
hobokenchicken 000ce85816 Phase 4: Bots & Extensibility
Backend:
- internal/bot/auth.go: bot token generation and verification
- internal/bot/handlers.go: bot CRUD (create, list, get, update, delete, server management, token regen)
- internal/bot/commands.go: slash command registration and management
- internal/webhook/handlers.go: webhook CRUD and execution endpoint
- internal/webhook/token.go: webhook token generation
- internal/db/db.go: bots, bot_servers, slash_commands, webhooks tables
- internal/gateway/events.go: BOT_JOIN, BOT_LEAVE event constants
- cmd/server/main.go: wired bot, webhook, invite routes

Frontend:
- stores/bot.ts: Zustand store for bot management
- BotManager.tsx: bot list, create, edit, delete, add to server, token display
- CommandManager.tsx: slash command CRUD per bot
- SlashCommandPopup.tsx: / command autocomplete popup
- App.tsx: /bots and /bots/:id/commands routes

Examples:
- examples/modbot/: auto-delete banned words, /kick, /ban, /purge commands
- examples/welcome/: welcome message on member join
2026-06-28 17:00:37 -04:00
hobokenchicken bb650ac2a0 Phase 3: Polish & PWA
Backend:
- DB: reactions table, invites table, reply_to column on messages
- gateway/events.go: added REACTION_ADD, REACTION_REMOVE events
- internal/reaction/handlers.go: reaction CRUD with WebSocket broadcast
- internal/invite/handlers.go: invite creation, info, join with code
- gateway/hub.go: presence tracking with idle detection
- gateway/client.go: idle timeout support

Frontend - Social:
- TypingIndicator: real-time 'user is typing...' display
- ReactionBar: emoji reactions on messages with counts
- EmojiPicker: searchable emoji grid for reactions
- ReplyBar: quoted reply display above messages
- MentionPopup: @mention autocomplete with user list

Frontend - PWA:
- manifest.json: PWA manifest with theme color and icons
- sw.js: service worker with cache-first strategy and push support
- stores/push.ts: push notification subscription management
- InstallPrompt: 'Add to Home Screen' banner

Frontend - Mobile:
- MobileNav: bottom nav bar for mobile (servers/channels/chat/members)
- MobileDrawer: slide-out drawer with server bar + channel list
- index.html: PWA meta tags, safe area viewport

Frontend - Polish:
- ThemeToggle: dark/light mode switch with localStorage persistence
- InviteModal: generate invite links with expiry and max uses
- JoinServer: /invite/:code join flow
- stores/typing.ts: typing indicator state management
- stores/presence.ts: real-time presence tracking
- tailwind.config.js: darkMode: 'class', light mode color tokens
- styles/index.css: light mode CSS variable overrides
2026-06-28 16:44:39 -04:00
hobokenchicken f694301ca7 Phase 2 frontend: voice store, VoiceChannel, VoicePanel, VoiceControls
Frontend:
- stores/voice.ts: Zustand store for voice state (join, leave, mute, deafen, video, screen share)
- VoiceChannel.tsx: sidebar item showing 🔊 channel name with participant count
- VoicePanel.tsx: box-drawn frame with participant list and controls
- VoiceControls.tsx: [m] mute, [d] deafen, [cam] video, [share] screen, [x] disconnect
- ChannelList.tsx: integrated VoiceChannel for voice-type channels
- Layout.tsx: added VoicePanel above chat area

Deps:
- Added livekit-client, @livekit/components-react
- NODE_ENV fix for dev deps installation
2026-06-28 16:26:19 -04:00
hobokenchicken e69553af02 Profiles, Giphy, uploads, settings UI
Backend:
- Auth: split routes into RegisterPublicRoutes + RegisterProtectedRoutes
- Auth: PATCH /me for profile updates (display_name, bio, accent_color, status_text)
- Auth: Gravatar fallback for avatars on register
- DB: users table now has bio, accent_color, status_text columns
- giphy/client.go: Search() and GetTrending() against Giphy API
- upload/handlers.go: MinIO file upload + serve
- config: added GiphyConfig and MinIO config
- cmd/server: wired giphy (/gifs/search, /gifs/trending), upload (/upload), files (/files/*) routes

Frontend:
- auth store: updated User interface with new profile fields, added updateProfile()
- UserSettings.tsx: terminal-styled profile editor (display_name, bio, accent_color, status_text, avatar upload)
- GiphyPicker.tsx: terminal-styled GIF picker with search + trending
- ChatArea.tsx: integrated [GIF] button into message input
- App.tsx: imports UserSettings, added /settings route
2026-06-28 16:06:08 -04:00
hobokenchicken bb5a56816b Phase 1 MVP: gateway, CRUD handlers, frontend components
Backend:
- WebSocket gateway (hub, client, events) with fanout broadcast
- Server CRUD handlers (create, list, get, update, delete)
- Channel CRUD handlers (create, list, get, update, delete)
- Message CRUD handlers (list with cursor pagination, create, update, delete)
- cmd/migrate standalone migration CLI (up/down)
- cmd/server wired to all handlers + WebSocket + static file serving

Frontend:
- Zustand stores: auth, server, channel, message, websocket
- API client with fetch wrapper
- Terminal-styled components: Layout, LoginForm, ChatArea, ChannelList, ServerBar, MemberList
- React Router with login and main routes
- Gruvbox dark palette throughout

Ops:
- Docker Compose with app service (multi-stage build)
- Caddyfile with WebSocket upgrade support
- Makefile for common tasks
2026-06-26 14:47:29 -04:00
hobokenchicken e499ce884d Initial scaffold: Go backend, React frontend, Docker Compose
- Go backend: config, db (PostgreSQL migrations), auth (argon2id + sessions),
  middleware (cookie sessions, RequireAuth), chi router, cmd/server
- React frontend: Vite + React 18 + TS + Tailwind + Gruvbox palette + terminal CSS
- Docker: compose.yml (Postgres, Valkey, minio, LiveKit, coturn, Caddy),
  livekit.yaml, Caddyfile, Dockerfile (multi-stage Go+Node+Alpine)
- .env.example, .gitignore, README.md
2026-06-26 14:41:10 -04:00