The token-hashing commit (57aec2c) never updated ServeWS to hash tokens
before querying the sessions table. Cookie and message-frame auth both
compared raw tokens against stored hashes, so every WS connection failed.
Also moved reconnectDelay to module scope so the exponential backoff
survives across connect() calls, and resets on successful open.
- --safe-top: 1.5rem → 2rem for extra status bar clearance
- Formatting toolbar: w-3→w-4, p-1→p-1.5 for better touch targets
- Login form: increased vertical spacing between buttons, text-xs on passkey
Scroll handler now checks !hasMore to avoid calling fetchOlderMessages
when all messages are loaded. Previously the handler would fire on every
scroll event (since scrollTop stayed < 100), creating a .then() callback
loop that adjusted scroll position repeatedly, causing 'stuck' scrolling.
- fetchMe() no longer surfaces 401 as a user-facing error (it just
means 'no session', not a failure)
- API client auto-clears auth state on 401 mid-session so the user
gets redirected to login instead of seeing 'ERR: Request failed: 401'
- Session middleware now accepts Authorization: Bearer <token> header
as fallback when no cookie is present (for Tauri/native clients)
- Login, register, and WebAuthn endpoints expose X-Session-Token header
so non-browser clients can capture the token
- usePermissions ORs current user roles + @everyone only (not all server roles)
- cache myRolesByServer; load on active server; refresh after self role edit
- gate/notify @everyone and @channel; plain @username push; special mention UI
- refresh FEATURE_PARITY (DMs exist; drop stale critical gaps)
- README production deploy notes dumpster.service
- unit tests for permission bits and broadcast mention tokens
Members API appends server bots (is_bot). Sidebar groups ONLINE / OFFLINE / BOTS.
Bots get green BOT badge, no kick menu or profile. Mentions and DMs skip bots.
Root cause of "not anonymous":
1. Confess deleted via raw SQL with no MESSAGE_DELETE broadcast
2. Frontend extractIds only accepted message_id, but deletes send id
so live clients never removed deleted messages without refresh
Fix:
- Intercept /confess at message create: never store or broadcast the
original; post only the anonymous bot message
- Accept both id and message_id on MESSAGE_DELETE in the WS store
- Include both fields on delete broadcasts
- MobileBottomNav: [SERVERS] [CHAT] [MEMBERS] tab bar, always visible
- Servers tab opens sidebar overlay, chat/members switch views
- Removed hamburger + members toggle from mobile top bar
- Top bar compact on mobile (no redundant buttons)
- safe-area-inset-bottom on nav, clean inset on frame
- Desktop status bar hidden on mobile, preserved on desktop
- Dead MobileNav/MobileDrawer left in place (unused, can prune later)
Moved thread and forum-tag routes from nested /servers/{sid}/channels/ to
top-level /channels/{id}/... to match frontend API calls. Forum posts were
getting SPA HTML fallback instead of JSON.
Added orange notification dots to DM and server buttons in ServerBar.