Repository navigation
feat(mobile): deliver an encrypted test notification to one installation #199
Description
Current status (2026-10-16)
Completed within this ticket's written implementation and automated-test boundary. Checked criteria below refer to that boundary, not full physical-device acceptance. The real-persistence tracer, actual Worker/NSE consumers, encryption vectors, migration, provider classification and authenticated routing are covered; real sandbox decryption and cold notification open additionally passed. Foreground delegate behavior is automated evidence, not an observed physical banner count.
Evidence: implementation merged in #206; acceptance checkpoint merged in #218. Candidate Server CI passed 90 mobile-push integration and 95 mobile-router tests. iOS CI passed 473 tests, zero skipped, including all three actual Rust ciphertext consumers. The unchanged Worker has 73 workerd plus one native ingress test; unchanged bilingual guidance has passing documentation CI. Local zh-Hans verification passed 64/64 and all six native redirect-boundary checks passed. Earlier-SHA Worker/docs results are reused evidence, not a fresh candidate-wide run.
The dedicated ServerBee Worker is deployed. One authorized real APNs sandbox test reached a dedicated Simulator: registration revision 2, persisted Server receipt accepted/Accepted, NSE-decrypted background presentation, and opening the existing notification from a terminated app into Settings. No simctl push injection was used. The system required side-swipe to open; earlier failed harness attempts remain recorded. Initial enqueue and raw APNs HTTP responses were not separately captured; the Server receipt reports the Relay/APNs verdict and still correctly says presentation=unobserved. The dedicated session was revoked and confirmed absent. This is not physical-device or production evidence.
Remaining live acceptance is retained in #205 and #196: Production, physical presentation/navigation, foreground banner count and arrival while terminated. Closing this implementation ticket does not close or waive those gates.
Dated checkpoints below are historical. This status supersedes earlier statements that the Worker is undeployed or that all live APNs checks are unrun; production and physical-device gates remain pending.
Parent
Architecture decision update (2026-10-03)
The current scope follows the approved public, stateless Cloudflare Workers Relay decision in #196 and #206. The earlier App Attest/challenge/device-grant requirements are superseded, without a replacement authorization service. Server login, installation ownership, key lifecycle, exact-target offline session revocation and account isolation remain required. Implementation and automated verification are recorded in #206 at ae5add35bb8b26c005b7a3d4c5dc173d22e949ee. Acceptance checkboxes remain unchanged; live-device acceptance remains separate and pending.
What to build
The user taps Test Notification in iOS, and the authenticated Server sends an encrypted message through the public stateless Worker Relay to that installation. The Notification Service Extension renders it, and tapping it safely opens the current account. This is the first complete delivery tracer bullet.
Acceptance criteria
- The test operation derives the recipient from the authenticated mobile installation and cannot broadcast to other devices or accept a caller-selected victim.
- Generate and register per-installation content keys through authenticated secure setup; keep the device copy in shared Keychain storage for the Notification Service Extension and never send the key to the Relay.
- Rust encryption and Swift decryption share versioned AES-256-GCM interoperability vectors with authenticated identity metadata, fresh nonces, and bounded payloads.
- The public Worker accepts the token/environment, event identity/expiry and unchanged encrypted envelope without a grant, and uses fixed APNs hosts/operator-controlled topic bindings, correct push type/priority/expiry, hard streaming and payload bounds, WebCrypto JWT reuse, Workers
fetch, and provider-verdict handling. Bound rate-limit state and best-effort source/target/instance-wide protections; do not claim strict global quota enforcement. - The notification extension decrypts and localizes authentic business content or retains only fixed generic fallback text; no plaintext notification content or content key is forwarded through the Relay. Explicitly document that a public caller with a valid token can cause generic fallback notifications and that arbitrary/self-owned-token requests can consume quota; AEAD does not prevent those abuses.
- Buffer early registration callbacks and cold-launch taps until authentication and stores are ready; reject old deployment/account targets, and show one foreground system banner.
- Show provider acceptance separately from observed presentation; classify configuration/payload errors separately from invalid device conditions and prevent late errors from invalidating a replacement token.
- Separate new Relay registrations from legacy direct-APNs fan-out so migration cannot notify the same installation through both paths; keep legitimate existing external channels working.
- Verify the complete test-message path using real Server persistence, actual Relay/extension boundaries and shared vectors, with only Apple/network/system boundaries substituted. Include an isolated real-device smoke checklist without claiming unrun APNs delivery.
Blocked by
- feat(ios): opt in to verified mobile notification registration #198: feat(ios): opt in to verified mobile notification registration
Implementation verification checkpoint (2026-10-03)
At ae5add35bb8b26c005b7a3d4c5dc173d22e949ee, Rust-to-Worker/iOS CI ran two real Rust trace producers and all three native ciphertext consumers. Actual Notification Service Extension rendering and authenticated cold-tap routing passed within the 423-test iOS suite, with zero failures and no XCTest skips. Worker CI passed 61 workerd tests plus one native HTTP/TCP-reset cancellation regression, along with types and the production bundle dry-run.
These automated boundaries do not establish live APNs provider acceptance, delivery, or physical-device presentation/taps. Those checks and Worker deployment remain NOT RUN. PR #206 records all 17 green checks; acceptance checkboxes remain unchanged.
Activity