89be497fdbb24ee452ea98c08710cd0ae1b4eb01
Renders message content with markdown-to-jsx: bold/italic/strikethrough, inline code, fenced code blocks, blockquotes, lists (incl. nested and task lists), tables, footnotes, headings, and highlight (==text==). Raw HTML in message content is parsed to escaped literal text rather than rendered (disableParsingRawHTML), which is the XSS mitigation for this being user-generated content -- verified against both <img onerror> and <script> probes. Markdown image embeds degrade to a link instead of an <img>, since the app already has a first-class image upload and a second silent remote-image-embed path would duplicate it and leak the viewer's IP to arbitrary URLs. The inline message-edit control is upgraded from a single-line <input> to a <textarea> so multi-line markdown can actually be edited without losing newlines, mirroring the Composer's Enter-sends/Shift+Enter- newlines convention. Since CommonMark treats a single newline as a soft break (collapses to a space) rather than a visible line break, added a small code-fence- aware preprocessor that converts single newlines to hard breaks -- without it, existing multi-line messages sent via the Composer's Shift+Enter would silently collapse onto one line. Also fixes heading levels rendering at an identical capped size (should still step down by level, just capped lower than default), and adds CSS for markdown constructs the library already parsed but hadn't been styled for the dark theme: table borders, highlight/mark color, task-list checkbox accent, and footnote divider.
KeepItTalking
A web-based team chat service (Mattermost-style, no threaded conversations), invite-only. See ARCHITECTURE.md for the full system design and phased build plan.
Phase 1: auth, open-room CRUD, and single-instance WebSocket chat, backend
- a minimal frontend. Phase 2: private rooms, room roles (owner/admin/ member), and room invites — backend only, see below. Later phases (push notifications, Redis fan-out, the admin portal, the bot/extension system, and production deployment) are tracked as issues in the repo's issue tracker, prioritized.
Structure
backend/— FastAPI + SQLAlchemy 2.0 (async) + PostgreSQL. Seebackend/README.mdfor local setup, migrations, how to create a user (site registration is invite-only — no public sign-up endpoint), and the Phase 2 room-roles/invites API.frontend/— React + Vite PWA (login, room list, chat view). Still Phase-1-only: it doesn't yet call any of the Phase 2 endpoints. A UI redesign is happening separately; frontend work resumes once that lands.
Quickstart
# 1. Postgres (see backend/README.md for details)
docker run -d --name chatapp-postgres \
-e POSTGRES_USER=chatapp -e POSTGRES_PASSWORD=chatapp -e POSTGRES_DB=chatapp \
-p 5432:5432 postgres:16-alpine
# 2. Backend
cd backend
python3 -m venv .venv
.venv/bin/pip install -e ".[dev]"
cp .env.example .env # then set SESSION_SECRET
.venv/bin/alembic upgrade head
.venv/bin/python -m app.cli create-user alice alice@example.com "some-password"
.venv/bin/uvicorn app.main:app --reload &
# 3. Frontend (in another shell)
cd frontend
npm install
npm run dev
Then open http://localhost:5173 and log in with the account created above.
The Vite dev server proxies /api and /ws to the backend on :8000, so no
CORS configuration is needed in development.
Deployment
See DEPLOYMENT.md for the full production runbook — two Debian 13 servers, no containers, matching ARCHITECTURE.md §9.