first commit
This commit is contained in:
commit
19dfc51360
85 files changed
+25504
No files matched your search
@@ -0,0 +1,78 @@
|
||||
# Development
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
src/
|
||||
main.rs CLI (serve, admin, config, device, probe)
|
||||
lib.rs public router (ActiveSync, Autodiscover, /, /healthz)
|
||||
app.rs application state: settings (ArcSwap), IMAP pool, metrics, lockouts
|
||||
config.rs settings model (serde, validation, merging, secrets)
|
||||
db.rs SQLite (sqlx, WAL), migrations in migrations/, housekeeping
|
||||
server.rs HTTP/1.1 + HTTP/2 listener, optional TLS, graceful shutdown
|
||||
wbxml/ WBXML encoder/decoder + MS-ASWBXML code pages
|
||||
eas/ ActiveSync protocol
|
||||
mod.rs request parsing (plain/base64 query), auth, provisioning, dispatcher
|
||||
state.rs SyncKey {uuid}N and states (item fingerprints)
|
||||
folders.rs FolderSync / Create / Update / Delete
|
||||
sync.rs Sync, GetItemEstimate, MoveItems
|
||||
ping.rs Ping and the shared wait-for-changes loop (hanging Sync)
|
||||
provision.rs policies, remote wipe
|
||||
mailcmd.rs SendMail / SmartReply / SmartForward / MeetingResponse
|
||||
itemops.rs ItemOperations, GetAttachment
|
||||
misc.rs Settings, Search, ResolveRecipients
|
||||
convert/ RFC 5322 / iCalendar / vCard <-> ApplicationData
|
||||
backend/
|
||||
imap.rs own async IMAP client (literals, UIDPLUS, MOVE, SPECIAL-USE)
|
||||
dav.rs CalDAV/CardDAV client
|
||||
smtp.rs SMTP (lettre) / sendmail
|
||||
ical.rs iCalendar/vCard parser and serializer
|
||||
tz.rs EAS <-> IANA time zones, dates
|
||||
mime.rs MIME building (SmartReply/Forward)
|
||||
mod.rs session: folder hierarchy, fingerprint listings, operations
|
||||
autodiscover.rs
|
||||
admin.rs panel API, sessions, CSRF, SSE, Prometheus
|
||||
web/ panel (dependency-free HTML/CSS/JS, embedded in the binary)
|
||||
```
|
||||
|
||||
### Synchronisation
|
||||
|
||||
The device state of a folder is a map `item id -> fingerprint` (IMAP: flags; DAV: ETag) stored under the key
|
||||
`{uuid}N`. Sync compares the backend listing with the state and sends the differences (deletes -> changes ->
|
||||
adds, newest mail first) within `WindowSize`. The new state is stored as `N+1`; the previous one is kept to
|
||||
handle lost responses (the device replays the old key). Client adds are idempotent thanks to the `ClientId` map.
|
||||
|
||||
Ping keeps a folder signature (IMAP `STATUS UIDNEXT/MESSAGES/UNSEEN/HIGHESTMODSEQ`, DAV CTag); a full listing
|
||||
comparison only happens when the signature changes.
|
||||
|
||||
Collection ids that a device uses but that do not exist (Z-Push leftovers) are remembered per device and sent
|
||||
as FolderHierarchy Delete on the next FolderSync.
|
||||
|
||||
## Development environment
|
||||
|
||||
```bash
|
||||
sudo apt install dovecot-imapd # any dovecot >= 2.3
|
||||
pip install radicale aiosmtpd
|
||||
./dev.sh backends # Dovecot :11143, Radicale :15232, SMTP sink :12525
|
||||
./dev.sh seed && ./dev.sh # ActivePush :8081 / panel :9091
|
||||
./dev.sh e2e # test of every command against live backends
|
||||
```
|
||||
|
||||
Test accounts: `jan`, `anna`, `biuro`, `kasia` `@test.local`, password `Test-Password-123`.
|
||||
|
||||
`./dev.sh lint` - rustfmt, clippy `-D warnings`, JS syntax check and WBXML tag name check
|
||||
(`scripts/check-wbxml-names.py`). `./dev.sh test` - unit tests (WBXML, IMAP tokenizer, UTF-7, calendar/contact/
|
||||
task conversions, time zones, query parser, CIDR, MIME).
|
||||
|
||||
Protocol debugging: add the login to **ActiveSync -> Logging -> Debug users**; decoded WBXML of requests and
|
||||
responses goes to the log.
|
||||
|
||||
Simulating devices: `active-push probe --device-id F2LX8KQ1N72J --device-type iPhone --model "iPhone 15 Pro" ...`.
|
||||
|
||||
## Documentation screenshots
|
||||
|
||||
`tools/dev/screenshots.js` (Playwright) regenerates `docs/images/` from a running dev instance:
|
||||
|
||||
```bash
|
||||
node tools/dev/screenshots.js http://127.0.0.1:9091 admin 'password'
|
||||
```
|
||||
Reference in new issue
Block a user