Installable app, push notifications about new mail, Install app entry
The webmail is now a PWA: web app manifest, icons (any + maskable, a status-bar badge), theme-coloured title bar following the chosen theme, and an app-icon badge with the unread Inbox count. The service worker is always installed; offline access is on only when it is registered as /sw.js?offline=1, so turning it on or off is an update that applies at once. Notifications (Settings → Accounts → Notifications, per device) use Web Push. Encryption (RFC 8291) and VAPID signing (RFC 8292) are implemented in app/push/webpush.py — pywebpush needs a newer cryptography than we pin — and checked against the RFC's worked example. The server makes its key pair on first use (private half encrypted with MASTER_KEY). New mail found by the live sync in an Inbox enqueues a job 5 s later that tells the user's devices about messages still unread there, under 2 hours old and not from the user; more than three become one "N new messages". A subscription belongs to the session it was made under: signed out or revoked, nothing more is sent there. Endpoints are limited to the known push services (no SSRF). Nothing shows while the app is in front (except on Apple, which requires it). Tested with real pushes through Google's service in Chromium and Opera. The mobile drawer gets "Install app": Chrome's own install dialog where the browser offers one, else short steps for iPhone/iPad, Opera and Firefox, with "Don't show this again". docs/nas-install.md §5.3 covers installing, notifications, Public URL and a later Android app (TWA). Migration 0022: push_subscriptions, app_settings.vapid_*. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -569,6 +569,33 @@ Session cookies get the `Secure` and `__Host-` treatment automatically as soon
|
||||
as the app sees an HTTPS request: nginx forwards `X-Forwarded-Proto`, and the
|
||||
API is started with `--proxy-headers`. Nothing to configure.
|
||||
|
||||
### 5.3 Installing as an app, and notifications about new mail
|
||||
|
||||
Over HTTPS the web app is installable (Chrome/Edge: the install icon in the
|
||||
address bar; Android: *Add to Home screen*; iPhone/iPad: *Share → Add to Home
|
||||
Screen*). Each user turns on **Settings → Accounts → Notifications** per
|
||||
device; new mail reaching an Inbox then shows a notification even with the app
|
||||
closed. Desktop Opera shows them too but has no "install app"; Opera on Android
|
||||
can install. On iPhone/iPad notifications work only from the Home Screen app
|
||||
(iOS 16.4+).
|
||||
|
||||
- The server signs notifications with a key pair it makes on first use, stored
|
||||
in the database (private half encrypted with `MASTER_KEY`). Nothing to set.
|
||||
- Set **Public URL** in the admin panel (e.g. `https://ultimo.email`): push
|
||||
services see it as the contact for our notifications. Without it they see
|
||||
`mailto:postmaster@APP_DOMAIN`.
|
||||
- The API container must reach the push services over HTTPS (port 443):
|
||||
`fcm.googleapis.com`, `*.google.com`, `*.push.services.mozilla.com`,
|
||||
`*.push.apple.com`, `*.notify.windows.com`.
|
||||
- The notification shows sender, subject and the first line; it travels
|
||||
end-to-end encrypted through the browser vendor's push service.
|
||||
|
||||
**Later: an Android app (TWA).** The installable web app is what a Trusted
|
||||
Web Activity wraps (e.g. with Bubblewrap from `/manifest.webmanifest`). It
|
||||
then also needs `https://ultimo.email/.well-known/assetlinks.json` naming the
|
||||
Android package and its signing-certificate fingerprint — served by nginx
|
||||
like any other static file.
|
||||
|
||||
---
|
||||
|
||||
## 6. Resource usage
|
||||
|
||||
Reference in New Issue
Block a user