feat(server): accept the iOS app origin for mobile passkeys (#32733)
(cherry picked from commit 1119e9c7a7c9f5ad657aa4e893b897772f75a124)
This commit is contained in:
@@ -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',
|
||||
],
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user