32 lines
4.9 KiB
Markdown
32 lines
4.9 KiB
Markdown
# Web Push transport
|
|
|
|
The transport uses [webpush-java](https://github.com/web-push-libs/webpush-java) 5.1.2 only for AES128GCM encryption and VAPID request generation. Its transitive dependencies are disabled; jose4j 0.9.6 and BouncyCastle bcprov-jdk18on 1.85.2 are explicitly selected. The library's legacy HTTP clients and CLI are not included.
|
|
|
|
The JDK HTTP client uses a five-second connection timeout and a twenty-second request timeout, with redirects disabled. Response bodies are discarded. Only HTTPS endpoints on fcm.googleapis.com, updates.push.services.mozilla.com and web.push.apple.com are accepted. Userinfo, fragments, nonstandard ports and other hosts are rejected before any request. The encoder's FCM path conversion is retained. Supporting another push provider requires explicitly reviewing and adding its host.
|
|
|
|
Payloads contain localized reminder text, the dated Work form link, a daily notification tag and the journal icon. TTL is bounded by the remaining reminder window. HTTP 2xx is acceptance by the push service, not proof of delivery to a device. 404/410 disables the unchanged subscription version; other statuses are retryable. Transport errors are handled by the dispatcher without exposing endpoints, keys or payloads in error logs.
|
|
|
|
WebPushTransportTest captures the prepared request without sending it externally. It verifies the VAPID signature with the server public key and decrypts the AES128GCM payload with the subscriber private key and auth secret. It also checks FCM path conversion, TTL, timeout, response mapping and endpoint rejection.
|
|
|
|
No production key or network sender is activated by this change. Runtime configuration and scheduling are implemented below; server key provisioning, browser opt-in and real device acceptance remain open. Existing database data and schema are unchanged.
|
|
|
|
Validation: full local `tools/ci-jvm` run passed on 2026-09-09, including operations tests, JVM tests, production JAR, frontend tests and production smoke. Packaged dependencies were inspected to confirm the selected versions and absence of the excluded HTTP clients.
|
|
|
|
## Runtime configuration
|
|
|
|
`WERKJOURNAL_PUSH_ENABLED` defaults to `false`. When explicitly set to `true`, Spring creates the transport, dispatcher and scheduler. Both `WERKJOURNAL_PUSH_PUBLIC_KEY` and `WERKJOURNAL_PUSH_PRIVATE_KEY` must contain the matching base64url VAPID key pair. An invalid pair fails startup with a generic error that does not include the configured secrets. Put these values only in the protected systemd environment file, never in Git or command arguments. `WERKJOURNAL_PUSH_SUBJECT` defaults to `mailto:werkjournal@javagil.de`.
|
|
|
|
The scheduler starts after 60 seconds and checks again 30 seconds after each completed batch, processing at most 16 reservations per tick. Queue state survives restart. A failed tick is retried later without printing subscriber details. The maintenance file defaults to `~/doms/werkjournal.javagil.de/htdocs-ssl/maintenance.flag`; `WERKJOURNAL_PUSH_MAINTENANCE_FILE` may override it with an absolute path. An unavailable parent directory suppresses delivery.
|
|
|
|
PushRuntimeTest and WebPushTransportTest cover disabled and enabled Spring configurations, valid/invalid keys, no immediate send at context startup, maintenance gating and bounded scheduler batches. Server key provisioning and real device opt-in remain pending; this change does not enable production sending.
|
|
|
|
## Server key provisioning
|
|
|
|
`remote backend setup-push` generates a P-256 VAPID pair using the installed JDK directly on the deployment host. Private key material is captured by the provisioning process and written only to `~/.config/werkjournal/environment` with mode 600; it is not printed or downloaded. Existing environment contents are preserved. An existing complete pair is retained byte-for-byte, while partial key configuration, duplicate push settings, insecure file permissions and symlinks are rejected. The deployment lock protects the atomic configuration update against a concurrent deployment.
|
|
|
|
The command leaves delivery disabled and does not restart the application. It never rotates existing keys: rotation would invalidate browser subscriptions and needs a separate deliberate workflow. Tests cover repeat invocation, preservation on generator failure, partial configuration and file protections.
|
|
|
|
## Production activation, 2026-09-09
|
|
|
|
After CI deployed 76df11b successfully, delivery was enabled in the protected server environment using the existing key pair. Activation held the deployment lock, refused pending deployment/maintenance, checked the required installed revision, used the maintenance page during restart and verified application/Flow readiness before reopening. No database files were changed by the activation procedure. The public login endpoint returned HTTP 200 afterward. No synthetic notification was sent. Each device still requires explicit opt-in in Settings; actual Android delivery remains an acceptance check.
|