feat(native): push inside the iOS app, through an encrypted relay

The app subscribes to Web Push like a browser, only the app makes the
subscription: it asks for permission, registers with APNs and keeps its own
P-256 key pair and auth secret in a keychain group a notification extension
can share. The endpoint is liketrek's relay for this device's token, so the
server encrypts exactly as for a browser and nobody on the way can read the
notification. The settings card, the test push, sign-in resync and the logout
teardown all take this path where the binary has nativePush; a tapped
notification opens the place it points at, also from a cold start.

The App ID has push enabled, the app carries the aps-environment and
keychain-group entitlements.
This commit is contained in:
Maurice
2026-11-06 13:37:59 +01:00
parent 30158cddc3
commit ad69bbf4a9
10 changed files with 505 additions and 3 deletions
+8
View File
@@ -55,6 +55,14 @@ export interface TrekShellPlugin {
): Promise<{ remove: () => Promise<void> }>;
/** Feature sharedFiles: the booking document shared to TREK before the UI ran. */
takeSharedFile(): Promise<{ file: SharedFilePayload | null }>;
/** Feature nativePush: permission, APNs and the device keys, as a Web Push subscription. Rejects with DENIED. */
registerPush(): Promise<{ endpoint: string; keys: { p256dh: string; auth: string } }>;
/** Feature nativePush: the notification the app was opened from, before the UI ran. */
takeOpenedPush(): Promise<{ url: string | null }>;
addListener(
event: 'pushOpened',
listener: (payload: { url: string }) => void
): Promise<{ remove: () => Promise<void> }>;
}
/** A document shared to TREK, as the native side reads it. */