Frederic Cabassut 27c3e7dccd fix(editor): render the table-with-list HTML fallback safely instead of escaping it
The table markdown fallback (previous commit) embeds raw HTML in saved
markdown when a cell holds a bullet list, since GFM can't express block
content in a table cell. But the read-only renderer (note-card preview,
public share page) ran with html:false, so that HTML rendered as
escaped literal text instead of a table - moving the bug rather than
fixing it.

Enable html mode and sanitize the rendered output with sanitize-html.
Sanitizing matters beyond this one fallback: note content isn't only
ever written through the editor - the MCP server and notes API accept
a raw markdown string directly, bypassing the editor's schema, so any
HTML this renders has to be treated as untrusted regardless of source.

Also make the table's HTML fallback respect the editor's own `html`
option (falls back to a `[table]` placeholder when disabled), matching
every other node type's markdown storage in tiptap-markdown.

Found via a 3-agent adversarial review of the previous fix.
2026-09-01 12:00:36 +02:00
2026-08-19 13:15:42 +00:00
2026-03-20 22:58:39 +01:00

CI License: MIT Version Docker

Crumbs logo

Crumbs by Bretzel

A self-hostable, offline-first note-taking app that respects your privacy. Part of the Bretzel app universe.

Crumbs notes grid view

Install

docker compose up -d

Open http://localhost:3000 and create your admin account on first visit.

With SSO (optional)

# docker-compose.yml
services:
  crumbs:
    image: ghcr.io/bretzel-app/crumbs:latest
    ports:
      - "3000:3000"
    volumes:
      - crumbs-data:/data
    environment:
      - ORIGIN=https://notes.example.com
      - AUTH_OIDC_ISSUER=https://authentik.example.com/application/o/crumbs/
      - AUTH_OIDC_CLIENT_ID=your-client-id
      - AUTH_OIDC_CLIENT_SECRET=your-client-secret
      - AUTH_OIDC_DISPLAY_NAME=Authentik
    restart: unless-stopped

volumes:
  crumbs-data:

Google and GitHub OAuth are also supported. See docs/AUTH.md for all providers and setup guides.

With Email Notifications (optional)

Add SMTP settings to enable email notifications (share alerts, welcome emails, security alerts):

environment:
  - SMTP_HOST=smtp.example.com
  - SMTP_PORT=587
  - SMTP_USER=your-username
  - SMTP_PASS=your-password
  - SMTP_FROM=Crumbs <noreply@example.com>

Auto-enabled when SMTP_HOST is set. Users can opt out in Settings > Preferences. See docs/DEPLOYMENT.md for details.

Manual (Node.js)

git clone <repo-url> crumbs && cd crumbs
pnpm install
pnpm build
DATABASE_URL=./data/crumbs.db ORIGIN=http://localhost:3000 node build

Development

pnpm install
pnpm dev

Run make help to see all available commands, or use pnpm directly:

pnpm test          # Unit + E2E tests
pnpm check         # Type checking
pnpm build         # Production build

Features

  • Rich notes with Markdown, checklists, image attachments, and 12 color themes
  • Organize with #tags, pinning, archive, and trash
  • Full-text search across titles, content, and tags
  • Note version history — browse and restore previous versions
  • Share notes with other users on the same instance
  • Email notifications for shares, security alerts, and account events (optional SMTP)
  • PWA — installable, works offline via IndexedDB + LWW CRDT sync
  • MCP server — let AI assistants (Claude Code, etc.) manage your notes
  • Multi-user auth (Argon2) with optional OAuth/SSO (Google, GitHub, OIDC)
  • Docker deployment with a single command

See docs/FEATURES.md for detailed feature documentation.

Tech Stack

Layer Technology
Framework SvelteKit 2 (Svelte 5 runes)
Language TypeScript (strict)
UI Tailwind CSS 4
Database SQLite (better-sqlite3) + Drizzle ORM
Client DB IndexedDB (idb)
Sync LWW CRDTs
Auth Argon2 + session cookies
Testing Vitest + Playwright
Container Docker (multi-stage)
CI/CD GitHub Actions

Documentation

Document Description
Features Detailed feature list and behavior
Architecture Local-first sync design, tech rationale, DB schema
Auth Password auth, OAuth/SSO setup (Authentik, Keycloak, etc.)
Deployment Docker, Node.js, reverse proxy, backups, env vars
API REST API reference (auto-generated)
Contributing How to contribute
Security Vulnerability reporting policy
Changelog Release history

CI/CD

  • CI — lint, type check, unit tests, E2E tests, Docker build on every push/PR
  • Release — builds and pushes Docker image on v* tags

Configure registry via GitHub Secrets: REGISTRY_URL, REGISTRY_USER, REGISTRY_TOKEN.

License

MIT

Languages
TypeScript 68.5%
Svelte 25.1%
HTML 2.7%
CSS 2.7%
Shell 0.5%
Other 0.5%