feat(push): accept the TREK apps' push relay as a push service

The apps subscribe to Web Push like a browser, with their own key pair, but
with an endpoint on liketrek's relay: only liketrek holds the apps' APNs and
FCM keys. The server encrypts exactly as for a browser (RFC 8291), so the
relay hands on ciphertext it cannot read and the device decrypts it. Lookalike
hosts stay refused.
This commit is contained in:
Maurice
2026-11-06 13:33:57 +01:00
parent 825469a7f2
commit 30158cddc3
2 changed files with 9 additions and 0 deletions
@@ -20,6 +20,11 @@ export const PUSH_SERVICE_HOSTS: readonly string[] = [
'push.services.mozilla.com',
// Safari on macOS, and Home Screen apps on iOS and iPadOS 16.4+.
'web.push.apple.com',
// The TREK apps' push relay. The app subscribes with its own key pair, the
// server encrypts exactly as for a browser, and the relay hands the ciphertext
// to Apple or Google, so it never reads a notification. Only liketrek holds
// the apps' APNs and FCM keys, which is why every server goes through it.
'push.liketrek.com',
];
/** Services that hand out per-region or per-cluster hosts under one domain. */
@@ -80,6 +80,8 @@ describe('checkPushEndpoint / checkPushSubscription', () => {
'https://web.push.apple.com/QGx9',
'https://api.push.apple.com/3/device/x',
'https://wns2-par02p.notify.windows.com/w/?token=BQYAAA',
// The TREK apps' relay, which hands the ciphertext on to Apple or Google.
'https://push.liketrek.com/v1/apns/production/abc123',
]) {
expect(checkPushEndpoint(endpoint), endpoint).toBe('ok');
expect(isPushServiceEndpoint(endpoint)).toBe(true);
@@ -117,6 +119,8 @@ describe('checkPushEndpoint / checkPushSubscription', () => {
'https://evilnotify.windows.com/x',
'https://.notify.windows.com/x',
'https://push.apple.com/x',
'https://push.liketrek.com.evil.test/v1/apns/x',
'https://evilpush.liketrek.com/v1/apns/x',
]) {
expect(checkPushEndpoint(endpoint), endpoint).not.toBe('ok');
}