Commit Graph
11 Commits
Author SHA1 Message Date
tajniak81andClaude Opus 5.5 0fc8ee809d Mobile: QR-code verification
When both sides support it, a verification offers QR codes first: this
device shows its code (in a white quiet zone, whatever the theme) and can
scan the other's with the camera (mobile_scanner; only codes that start
with MATRIX count). The side whose code was scanned confirms the other
saw it succeed. Compare emoji stays available, and is used directly when
either side has no QR support.

Adds the CAMERA permission (camera hardware not required).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 23:16:27 +02:00
tajniak81andClaude Opus 5.5 879e22141b Mobile: spaces; /hierarchy always sends children_state
Mobile:
- The room list's title picks a space: All chats, or one space, which
  narrows the list to its rooms (and its subspaces' rooms).
- A space browser over /hierarchy: the rooms of a space and of its
  subspaces, joined or joinable, with Join; for those who may, adding an
  existing room or a new one to the space.
- New space in the new-chat sheet; invites to spaces show with the other
  invites and open the space when joined.
- Fixes several setState calls that were handed a Future (reloading the
  members, sessions, push distributor, threads), which Flutter rejects.

Server: /hierarchy left out children_state for a room without children.
The spec requires it on every room (an empty list), and SpaceRoom's
omitempty dropped empty lists too, despite its comment. The famedly Dart
SDK fails to parse such a response. The client API now wraps each room so
the field is always written; the federation response, which wants it left
out of the children it lists, is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 23:14:40 +02:00
tajniak81andClaude Opus 5.5 4271d2ab17 Mobile: replies, reactions and threads
- Replies: Reply on a message's long press puts it above the composer;
  sent replies quote the message they answer (sender and first line),
  with the reply fallback left out of the body.
- Reactions: six quick ones and any other on long press, chips under the
  message with counts, the user's own highlighted; tapping a chip adds or
  takes back a reaction, a long press lists who reacted.
- Threads: Reply in thread opens a thread view (the root, then its
  replies, older ones fetched from /relations, new ones live from the room
  timeline) with a composer that sends into the thread. Thread replies
  are hidden from the main timeline; the root shows "N replies". Room info
  lists the room's threads (/threads).

The composer moved out of the room screen into widgets/composer.dart so
the room and thread views share it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 23:00:57 +02:00
tajniak81andClaude Opus 5.5 3356089c13 Android app (apps/mobile) with Flutter
apps/mobile is a Matrix client for Android on the famedly Matrix Dart SDK,
with vodozemac (compiled from Rust during the build) for end-to-end
encryption. It speaks the plain Client-Server API and uses the web
client's design tokens, fonts and symbol.

- Sign in by server name (.well-known), homeserver address or full user ID;
  sign up with the dummy and registration token stages. Sessions survive
  restarts: SQLite in private storage, credentials also in the Keystore,
  both excluded from backups and device transfers.
- Room list with unread and mention counts, invites, search and filters.
  Timeline with grouping, day separators, notices, history on scroll,
  links, images and files (authenticated media). Sending text, photos,
  camera shots and files, with Sending/Sent/Read/Not sent and Retry.
  Typing, receipts, deleting. New rooms and DMs, encrypted by default;
  joining by address; room info with members, invite, rename, topic,
  notification level, leave.
- Encryption: one-step setup behind a recovery key, verifying a new session
  with the recovery key (restoring the backup) or another session, emoji
  verification of people and sessions, reset. Undecryptable messages say
  why. Session list with verify and sign out.
- Notifications while running, and push through UnifiedPush (no Firebase):
  the distributor's endpoint becomes an event_id_only pusher, the gateway
  is discovered, and a push starts the app headless to fetch, decrypt and
  show the event.

Make targets: mobile (release APKs per ABI into bin/), mobile-run,
mobile-test. Kotlin incremental compilation is off (Windows, project and
pub cache on different drives), and Tink's JVM artifact is excluded in
favour of tink-android.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 22:45:06 +02:00
tajniak81andClaude Opus 5.5 b6bf3ce741 Desktop client (warp-desktop) with Wails v3
CI / Test (ubuntu-latest) (push) Canceled after 0s
CI / Test (windows-latest) (push) Canceled after 0s
CI / Storage tests on PostgreSQL (push) Canceled after 0s
CI / Complement (federation off) (push) Canceled after 0s
CI / golangci-lint (push) Canceled after 0s
CI / Smoke test the binary (push) Canceled after 0s
CI / Admin panel (push) Canceled after 0s
CI / Web client (push) Canceled after 0s
apps/desktop is the web client in a native window. It embeds the same
build warp-web does and serves it through the same Go package, so every
screen is shared. Unlike warp-web it proxies nothing: the client calls the
homeserver directly, and the CSP allows the homeserver plus any https:
and wss: origin for the call backend.

- First run asks for the homeserver: a server name or address, with
  .well-known discovery and a /versions check; File > Change homeserver
  asks again. Signed-in sessions keep their own base URL, so a change
  never sends one server's token to another.
- Links to other sites open in the system browser (/_desktop/links.js,
  added to index.html); only http, https and mailto are opened.
- One instance at a time, since sessions and keys live in the webview's
  storage.
- Dev builds open the DevTools Protocol on Windows when
  WARP_DESKTOP_REMOTE_DEBUGGING_PORT is set, for scripted testing.
- Packaging: icon, version info and manifest in the Windows exe, a macOS
  .app with camera and microphone descriptions, Linux packages via nfpm.
  Make targets: desktop, desktop-run, desktop-test, desktop-resources,
  desktop-macos, desktop-linux.

Web client: host and client move out of internal/ so the desktop app can
import them, and host gains AnyCallOrigin. The Dockerfile, .dockerignore
and the vite output path follow the move.

Pinned to Wails v3.0.0-beta.27.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 21:43:54 +02:00
tajniak81andClaude Opus 5.5 76dfc98a86 Group voice and video calls with MatrixRTC and LiveKit
CI / Test (ubuntu-latest) (push) Canceled after 0s
CI / Test (windows-latest) (push) Canceled after 0s
CI / Storage tests on PostgreSQL (push) Canceled after 0s
CI / Complement (federation off) (push) Canceled after 0s
CI / golangci-lint (push) Canceled after 0s
CI / Smoke test the binary (push) Canceled after 0s
CI / Admin panel (push) Canceled after 0s
CI / Web client (push) Canceled after 0s
Every call in the web client now goes through MatrixRTC with a LiveKit
SFU, the model Element Call and Element X use; the legacy 1:1 m.call.*
calls are gone. In a room of two the other person is rung and can answer
or decline; in a bigger room a banner offers to join the call. Calls show
a grid of participant tiles with mute, camera, screen sharing and leave,
and media is end-to-end encrypted in encrypted rooms.

Server:
- MSC4140 delayed events (send/state with a delay, plus the
  delayed_events list/restart/cancel/send API), stored and scheduled, so
  a member whose client drops off is taken out of the call.
- POST /user/{userId}/openid/request_token, which lk-jwt-service uses to
  hand out LiveKit tokens.
- org.matrix.msc4143.rtc_foci in /.well-known/matrix/client, configured
  under client_api.rtc.
- Room presets let members send call membership state.
- Migration 0014 for both SQL dialects.

Deploy: LiveKit and lk-jwt-service in compose (calls.yml) and the helm
chart. Docs: docs/calls.md, configuration and deployment.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 19:33:29 +02:00
tajniak81andClaude Opus 5.5 325431a5be Voice and video calls: TURN endpoint and web client calls
Server: GET /voip/turnServer, configured under client_api.turn. A shared
secret (coturn use-auth-secret) gives each user expiring TURN REST API
credentials; static credentials are the fallback; with nothing configured
it answers {} so clients still try a direct connection.

Web client: 1:1 calls (Matrix VoIP via matrix-js-sdk) in rooms with one
other person. Voice and video buttons in the room header, a ringing card
with answer, answer without video and decline, and a call panel that
stays up across rooms: mute, camera, screen sharing, expand, hang up,
ring tones. Call events show in the timeline and room list. Works around
the SDK keeping a failed microphone request forever.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 18:04:02 +02:00
tajniak81andClaude Opus 5.5 69ce927b6d Web client: E2EE on by default, trust shields, identity verification, QR
CI / Test (ubuntu-latest) (push) Canceled after 0s
CI / Test (windows-latest) (push) Canceled after 0s
CI / Storage tests on PostgreSQL (push) Canceled after 0s
CI / Complement (federation off) (push) Canceled after 0s
CI / golangci-lint (push) Canceled after 0s
CI / Smoke test the binary (push) Canceled after 0s
CI / Admin panel (push) Canceled after 0s
CI / Web client (push) Canceled after 0s
- New rooms (public too) and direct messages are end-to-end encrypted by
  default.
- Per-message trust: "Not verified" for sessions you haven't verified,
  and what is wrong for unsigned sessions, mismatched keys or plain text
  in an encrypted room (src/matrix/trust.ts).
- Verify a person's identity in a room you share (your DM first), and
  QR-code verification both ways: show ours, scan theirs with the camera
  (qrcode-generator, jsqr).
- Warnings when someone's identity changes, with acknowledge, verify
  again or withdraw verification.
- Encrypted thumbnails for large images.
- A tab-only session encrypts its crypto store with a key kept in
  sessionStorage; stores unused for two weeks are deleted.
- Reset encryption fixed: new secret storage first, so the new
  cross-signing keys survive a stale /keys/query answer; status checks
  no longer query our own keys mid-setup.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 16:56:28 +02:00
tajniak81andClaude Opus 5.5 b6f3be6ac4 Web client (warp-web) with E2EE, and two sync fixes
CI / Test (ubuntu-latest) (push) Canceled after 0s
CI / Test (windows-latest) (push) Canceled after 0s
CI / Storage tests on PostgreSQL (push) Canceled after 0s
CI / Complement (federation off) (push) Canceled after 0s
CI / golangci-lint (push) Canceled after 0s
CI / Smoke test the binary (push) Canceled after 0s
CI / Admin panel (push) Canceled after 0s
CI / Web client (push) Canceled after 0s
apps/web: a Matrix client for the browser on Vue 3, Tailwind and
matrix-js-sdk, built on @warp/ui. Like the admin panel it is an optional,
separate service: warp-web embeds the built app, serves /config.json and
proxies only /_matrix/client and /_matrix/media to the homeserver (or,
with -public-homeserver, lets the browser call it directly).
Sign-in and sign-up with registration tokens, room list, timeline with
back-pagination, text, images, video and files over authenticated media,
local echo with sent/read/failed states, receipts, typing, invites,
creating, joining and leaving rooms, room info, settings, phone layout.
End-to-end encryption through the Rust crypto: encrypted messages and
files, emoji verification, key backup setup and restore.

apps/ui: WRoomItem, WMessageBubble and WComposer from the brand package,
and the icons the client needs.

syncapi fixes found with the client:
- A room joined inside the sync window was sent as the join alone with
  limited: false, so clients thought they had the whole room. It is now
  read like an initial sync; a profile change is not mistaken for a join.
- A live typing notification was reported on every sync, so every long
  poll returned at once while anybody typed. Typing now has a position
  in the sync token and is reported when it changes, including the empty
  list when the last person stops.

Also: Dockerfile, a `web` compose profile, Makefile targets, a CI job
with a proxy smoke test, docs. PLAN.md moves out of the repository.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 16:22:11 +02:00
tajniak81andClaude Opus 5.5 7e5e38c921 Admin panel (warp-admin) and the apps/ui design system
apps/ui: Warp's design system for Vue 3 + Tailwind v4. Tokens, fonts,
icons and logo come from the brand package, with a Tailwind theme on the
tokens and Vue components on the brand component styles.

apps/admin: the admin panel as a separate, optional service. warp-admin
embeds the built Vue app and proxies only the login endpoints and
/_warp/admin/v1 to the homeserver. Pages: dashboard, users, rooms,
federation, registration and tokens, server notices, application
services, audit log.

Also: pnpm workspace, go.work entry, Dockerfile, an `admin` compose
profile, Makefile targets, a CI job with a proxy smoke test, and docs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 15:05:16 +02:00
tajniak81andClaude Opus 5 b4fb60a8ab Phase 0: bootstrap the Warp homeserver
CI / Test (ubuntu-latest) (push) Canceled after 0s
CI / Test (windows-latest) (push) Canceled after 0s
CI / Storage tests on PostgreSQL (push) Canceled after 0s
CI / golangci-lint (push) Canceled after 0s
CI / Smoke test the binary (push) Canceled after 0s
Scaffolds the server module and everything Phase 0 of PLAN.md calls for:
a binary that boots, serves its discovery endpoints and nothing else yet.

- config: one YAML file plus per-field WARP_* environment overrides,
  unknown fields rejected, validation that reports every problem at once
- logging and metrics: slog, a Prometheus registry, per-route HTTP
  instrumentation labelled by pattern rather than path
- httputil: the Matrix error envelope, error-returning handlers, CORS,
  request logging, panic recovery, and a router over http.ServeMux
- endpoints: /_matrix/client/versions, /.well-known/matrix/client,
  /.well-known/matrix/server (gated), /healthz, /metrics, and
  M_UNRECOGNIZED for everything else
- storage: driver registry, shared database/sql base, checksummed
  migration runner, sqlite and postgres drivers, pocketbase stub
- settings: server_settings table behind a cached service, so the
  federation and registration switches change without a restart
- federation: the gate that makes federation a runtime mode
- cmd/warp: serve, migrate, generate-keys, version
- Makefile, golangci-lint v2, GitHub Actions CI (Linux and Windows tests,
  race on Linux, storage tests against PostgreSQL, lint, boot smoke test),
  Dockerfile, example config and docs

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-15 17:01:13 +02:00