# Movim (Rust edition) A rewrite of the [Movim](https://movim.eu) XMPP web client backend in Rust, keeping Movim's frontend (CSS/JS/theme, in `frontend/`). The PHP daemon, widgets and templates were replaced by a single Rust server (tokio, axum, tokio-xmpp, sqlx with SQLite or PostgreSQL, minijinja). Scope: a Conversations-like chat client. ## Features 1:1 chat, group chats (MUC, bookmarks, invitations, moderation, configuration), MAM history, carbons, receipts and chat markers, typing states, corrections, retractions, reactions, replies, link previews (OpenGraph cards, picture links shown inline), HTTP file upload, avatars and vCards, OMEMO (in-browser libsignal), 1:1 audio/video calls (Jingle + JMI), group audio/video calls in group chats (Muji, XEP-0272: a mesh of Jingle sessions), blocking, contact requests, search, account registration (XEP-0077), settings, Web Push, last seen (XEP-0319 idle), Client State Indication when no tab is open, and automatic XMPP reconnection (backoff up to 60s, rooms rejoined). ## Run cargo build --release MOVIM_BIND=0.0.0.0:8080 MOVIM_DOMAIN=example.org ./target/release/movim Put it behind a TLS reverse proxy (WebSocket on `/ws/`, same host). Link previews are fetched by the server (only public addresses, every redirect checked) and cached for 30 days. Group calls are a mesh: every participant sends its streams to every other one, fine for a handful of people. They need a non-anonymous room (the default for group chats created by Movim). Environment: `MOVIM_BIND`, `MOVIM_ROOT`, `MOVIM_DATA_DIR`, `MOVIM_DATABASE_URL`, `MOVIM_DOMAIN`, `MOVIM_XMPP_WHITELIST`, `MOVIM_MAX_SESSIONS`, `MOVIM_DISABLE_REGISTRATION`, `MOVIM_LOCALE`, `MOVIM_SESSION_TIMEOUT_HOURS`, `MOVIM_MESSAGE_RETENTION_DAYS` (delete cached messages older than this, e.g. the XMPP server's archive expiry), dev only: `MOVIM_XMPP_PLAINTEXT=host:port`, `MOVIM_ALLOW_PRIVATE_URLS=1`, `MOVIM_DEBUG_XMPP=1`. ## Database SQLite by default (`data/movim.sqlite`). For PostgreSQL, set `MOVIM_DATABASE_URL=postgres://user:password@host/database`; the tables are created at startup. To move an existing SQLite database, stop Movim, create an empty PostgreSQL database and run: movim migrate-to-postgres postgres://user:password@host/database [--from sqlite:///path/movim.sqlite] Without `--from` it copies the SQLite database Movim would use (`MOVIM_DATABASE_URL` or the one in `MOVIM_DATA_DIR`). Everything is copied in one transaction, ids included, and the command refuses a database that already has data. The SQLite file is left untouched. ## Tests `cargo test` runs the unit tests (`MOVIM_TEST_POSTGRES_URL=postgres://…` also runs them against PostgreSQL, in throwaway databases). `tests/e2e/` holds end-to-end scripts that drive the server (and the real frontend in headless Chromium) against a local Prosody; see `tests/e2e/README.md`. ## Frontend patches (vs upstream Movim) - `widgets/Notif/notif.js`: guard missing service worker registration. - `widgets/ChatOmemo/chatomemo_storage.js`: blind trust before verification (upstream trust check crashes: `libsignal.util` is undefined). - `scripts/movim_jingles.js`: the signaling of each call session runs through a promise queue (a content-add could arrive before the remote description was applied, early ICE candidates were dropped). ## Not implemented Movim social features (blogs, communities, stories), SFU conference calls (Movim's own extension; Muji group calls work), sticker packs/GIFs, ad-hoc commands, XEP-0198 stream resumption. Web Push has only been tested without a real HTTPS push service; Dictaphone/Snap/Draw go through the upload path but are untested. License: AGPL-3.0 (same as Movim).