No description
  • Rust 56.6%
  • TypeScript 40.9%
  • Kotlin 0.9%
  • Python 0.7%
  • Shell 0.3%
  • Other 0.5%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Ivan Pavlina e50ce3b172
All checks were successful
image / image (push) Successful in 1m3s
image / notify (push) Successful in 2s
Queue a mail action with one INSERT: reading UIDVALIDITY first made quick successive actions fail with 'database is locked'
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-10 19:56:57 +01:00
.forgejo/workflows Pin ci-notify to a commit in both workflows 2026-11-10 12:15:26 +01:00
android Android: relock after the file picker/settings too, no mail notifications suppressed while locked, FLAG_SECURE below API 33, download cookie only to our origin, probe WebView timeout, Back falls back to history on a dead page 2026-11-10 12:15:25 +01:00
backend Queue a mail action with one INSERT: reading UIDVALIDITY first made quick successive actions fail with 'database is locked' 2026-11-10 19:56:57 +01:00
e2e Add end-to-end test harness (Dovecot, GreenMail, Radicale) with run.sh 2026-10-17 08:48:43 +02:00
frontend PGP sign covers the whole MIME entity the server sends; design log for the FB audit fixes 2026-11-10 12:44:27 +01:00
mikrotik Queue a mail action with one INSERT: reading UIDVALIDITY first made quick successive actions fail with 'database is locked' 2026-11-10 19:56:57 +01:00
.dockerignore New icons, remove what was left of the upstream code 2026-10-12 12:59:23 +02:00
.gitignore New icons, remove what was left of the upstream code 2026-10-12 12:59:23 +02:00
CLAUDE.md Docs: rev is LAN-only (live Caddyfile, owner decision 2026-11-10), not public 2026-11-10 13:27:41 +01:00
FABLE_AUDIT.md Rename to rev, split from rav, add the Android app 2026-10-12 11:41:12 +02:00
LICENSE Rename to rev, split from rav, add the Android app 2026-10-12 11:41:12 +02:00
README.md ci: drop the repull job, the router repulls on its own 2026-10-20 11:07:07 +02:00

rev

A personal webmail with contacts, calendars, notes and full-text search over the whole mailbox (message bodies and PDF/Office attachments). Rust/Axum backend, Next.js frontend, one SQLite database and one Tantivy index per user, in front of Purelymail (IMAP/SMTP, CalDAV/CardDAV). It also has an Android app (WebView, biometric unlock, notifications without Google).

Quick start

There is no local toolchain requirement; everything builds in Docker.

# Backend: build and test
docker run --rm -v "$PWD":/src -v rev-cargo-registry:/usr/local/cargo/registry \
  -v rev-cargo-target:/src/backend/target -w /src/backend rust:1-bookworm cargo test

# Frontend: typecheck and test
cd frontend && docker run --rm -v "$PWD":/app -v rev-frontend-nm:/app/node_modules \
  -w /app node:24-bookworm-slim sh -c 'npm i -g bun@1.4.3 && bun install --frozen-lockfile && npx tsc --noEmit -p . && npx vitest run'

To run the whole app, build the frontend (bun run build → frontend/out), build the backend (cargo build --release) and start the binary with STATIC_DIR, DATA_DIR, IMAP_HOST, SMTP_HOST and DAV_URL set; it listens on port 3001. All settings are environment variables, listed in backend/src/config.rs.

Build and deploy

Pushing to main makes Forgejo Actions build the arm64 image (mikrotik/Dockerfile), push it to git.exithub.net/ivan.pavlina/rev and the MikroTik RB5009 repulls it by itself (scheduler repull-tick). A change under android/ also builds a signed APK and publishes it as a release for Obtainium. Details are in CLAUDE.md.

More

License

MIT, see LICENSE. rev started as a fork of rav (itself a fork of oxi); their copyright notices stay in it, as the MIT license requires.