From 6569aad605f8a2ee642bf17cae6ac8a2f407d53b Mon Sep 17 00:00:00 2001 From: Santo Shakil Date: Tue, 27 Oct 2026 19:23:26 +0600 Subject: [PATCH] feat(server): accept the iOS app origin for mobile passkeys (#32733) (cherry picked from commit 1119e9c7a7c9f5ad657aa4e893b897772f75a124) --- server/src/services/passkey.service.spec.ts | 3 ++- server/src/services/passkey.service.ts | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/server/src/services/passkey.service.spec.ts b/server/src/services/passkey.service.spec.ts index 37bb23af2..4ebabda70 100644 --- a/server/src/services/passkey.service.spec.ts +++ b/server/src/services/passkey.service.spec.ts @@ -308,7 +308,7 @@ describe(PasskeyService.name, () => { expect(mocks.passkey.create).not.toHaveBeenCalled(); }); - it('should verify against the android app origins when the origin header is missing', async () => { + it('should verify against the mobile app origins when the origin header is missing', async () => { const auth = AuthFactory.from().session().build(); const passkey = PasskeyFactory.create({ userId: auth.user.id }); @@ -323,6 +323,7 @@ describe(PasskeyService.name, () => { expect(mocks.webAuthn.verifyRegistrationResponse).toHaveBeenCalledWith( expect.objectContaining({ expectedOrigin: [ + 'https://my.immich.app', 'android:apk-key-hash:hsXEVd-vSYWSOo81rbMdDJ4LlX1_lMLSr2okOKqWACA', 'android:apk-key-hash:WiLBg0dUBfVJxOufsmwuk6PvnFdmFQp684yNP-UVzNY', ], diff --git a/server/src/services/passkey.service.ts b/server/src/services/passkey.service.ts index 3499c85e6..5392931db 100644 --- a/server/src/services/passkey.service.ts +++ b/server/src/services/passkey.service.ts @@ -32,6 +32,9 @@ const CHALLENGE_TTL = Duration.fromObject({ minutes: 5 }); const MOBILE_RP_ID = 'my.immich.app'; +// iOS apps send https:// + the rp id as their origin +const IOS_ORIGIN = `https://${MOBILE_RP_ID}`; + // keep in sync with https://my.immich.app/.well-known/assetlinks.json const ANDROID_CERTIFICATE_FINGERPRINTS = [ '86:C5:C4:55:DF:AF:49:85:92:3A:8F:35:AD:B3:1D:0C:9E:0B:95:7D:7F:94:C2:D2:AF:6A:24:38:AA:96:00:20', @@ -273,7 +276,7 @@ export class PasskeyService extends BaseService { const origin = headers.origin; // no origin implies a mobile app if (!origin) { - return { origin: ANDROID_ORIGINS, rpId: MOBILE_RP_ID }; + return { origin: [IOS_ORIGIN, ...ANDROID_ORIGINS], rpId: MOBILE_RP_ID }; } let hostname: string;