diff --git a/src/frontend/src/flows/recovery/recoverWith/device.ts b/src/frontend/src/flows/recovery/recoverWith/device.ts index 323de659f5..cba8326d96 100644 --- a/src/frontend/src/flows/recovery/recoverWith/device.ts +++ b/src/frontend/src/flows/recovery/recoverWith/device.ts @@ -3,7 +3,7 @@ import infoToastCopy from "$src/components/infoToast/copy.json"; import { promptUserNumberTemplate } from "$src/components/promptUserNumber"; import { toast } from "$src/components/toast"; import { I18n } from "$src/i18n"; -import { convertToCredentialData } from "$src/utils/credential-devices"; +import { convertToValidCredentialData } from "$src/utils/credential-devices"; import { AuthFail, Connection, @@ -111,7 +111,7 @@ const attemptRecovery = async ({ } const credentialData = recoveryCredentials - .map(convertToCredentialData) + .map(convertToValidCredentialData) .filter(nonNullish); return await connection.fromWebauthnCredentials(userNumber, credentialData); diff --git a/src/frontend/src/utils/credential-devices.ts b/src/frontend/src/utils/credential-devices.ts index 930b3bc3ce..21a1c9dce4 100644 --- a/src/frontend/src/utils/credential-devices.ts +++ b/src/frontend/src/utils/credential-devices.ts @@ -11,7 +11,7 @@ export type CredentialData = { const derFromPubkey = (pubkey: DeviceKey): DerEncodedPublicKey => new Uint8Array(pubkey).buffer as DerEncodedPublicKey; -export const convertToCredentialData = ( +export const convertToValidCredentialData = ( device: Omit ): CredentialData | undefined => { // In certain cases, e.g. Chrome on Windows 10, an invalid credential id is diff --git a/src/frontend/src/utils/iiConnection.test.ts b/src/frontend/src/utils/iiConnection.test.ts index 15a7e210b3..2ac6a1768c 100644 --- a/src/frontend/src/utils/iiConnection.test.ts +++ b/src/frontend/src/utils/iiConnection.test.ts @@ -10,7 +10,10 @@ import { } from "$src/repositories/identityMetadata"; import { ActorSubclass, DerEncodedPublicKey, Signature } from "@dfinity/agent"; import { DelegationIdentity, WebAuthnIdentity } from "@dfinity/identity"; -import { CredentialData, convertToCredentialData } from "./credential-devices"; +import { + CredentialData, + convertToValidCredentialData, +} from "./credential-devices"; import { AuthenticatedConnection, Connection } from "./iiConnection"; import { MultiWebAuthnIdentity } from "./multiWebAuthnIdentity"; @@ -171,7 +174,7 @@ describe("Connection.login", () => { expect(loginResult.showAddCurrentDevice).toBe(false); expect(MultiWebAuthnIdentity.fromCredentials).toHaveBeenCalledTimes(1); expect(MultiWebAuthnIdentity.fromCredentials).toHaveBeenCalledWith( - [convertToCredentialData(mockDevice)], + [convertToValidCredentialData(mockDevice)], "identity.ic0.app" ); } @@ -181,10 +184,10 @@ describe("Connection.login", () => { // This one would fail because it's not the device the user is using at the moment. const currentOriginDevice: DeviceData = createMockDevice(currentOrigin); const currentOriginCredentialData = - convertToCredentialData(currentOriginDevice); + convertToValidCredentialData(currentOriginDevice); const currentDevice: DeviceData = createMockDevice(); const currentDeviceCredentialData = - convertToCredentialData(currentDevice); + convertToValidCredentialData(currentDevice); const mockActor = { identity_info: vi.fn().mockResolvedValue({ Ok: { metadata: [] } }), lookup: vi.fn().mockResolvedValue([currentOriginDevice, currentDevice]), @@ -230,10 +233,10 @@ describe("Connection.login", () => { it("connection doesn't exclude rpId if user has only one domain", async () => { const currentOriginDevice: DeviceData = createMockDevice(currentOrigin); const currentOriginCredentialData = - convertToCredentialData(currentOriginDevice); + convertToValidCredentialData(currentOriginDevice); const currentOriginDevice2: DeviceData = createMockDevice(currentOrigin); const currentOriginCredentialData2 = - convertToCredentialData(currentOriginDevice2); + convertToValidCredentialData(currentOriginDevice2); const mockActor = { identity_info: vi.fn().mockResolvedValue({ Ok: { metadata: [] } }), lookup: vi @@ -298,7 +301,7 @@ describe("Connection.login", () => { expect(loginResult.connection).toBeInstanceOf(AuthenticatedConnection); expect(MultiWebAuthnIdentity.fromCredentials).toHaveBeenCalledTimes(1); expect(MultiWebAuthnIdentity.fromCredentials).toHaveBeenCalledWith( - [convertToCredentialData(mockDevice)], + [convertToValidCredentialData(mockDevice)], undefined ); } @@ -326,7 +329,7 @@ describe("Connection.login", () => { expect(loginResult.connection).toBeInstanceOf(AuthenticatedConnection); expect(MultiWebAuthnIdentity.fromCredentials).toHaveBeenCalledTimes(1); expect(MultiWebAuthnIdentity.fromCredentials).toHaveBeenCalledWith( - [convertToCredentialData(mockDevice)], + [convertToValidCredentialData(mockDevice)], undefined ); } @@ -335,10 +338,10 @@ describe("Connection.login", () => { it("connection does not exclude rpId when user cancels", async () => { const currentOriginDevice: DeviceData = createMockDevice(currentOrigin); const currentOriginCredentialData = - convertToCredentialData(currentOriginDevice); + convertToValidCredentialData(currentOriginDevice); const currentDevice: DeviceData = createMockDevice(); const currentDeviceCredentialData = - convertToCredentialData(currentDevice); + convertToValidCredentialData(currentDevice); const mockActor = { identity_info: vi.fn().mockResolvedValue({ Ok: { metadata: [] } }), lookup: vi.fn().mockResolvedValue([currentOriginDevice, currentDevice]), @@ -401,7 +404,7 @@ describe("Connection.login", () => { expect(loginResult.connection).toBeInstanceOf(AuthenticatedConnection); expect(MultiWebAuthnIdentity.fromCredentials).toHaveBeenCalledTimes(1); expect(MultiWebAuthnIdentity.fromCredentials).toHaveBeenCalledWith( - [convertToCredentialData(mockDevice)], + [convertToValidCredentialData(mockDevice)], undefined ); } @@ -429,7 +432,7 @@ describe("Connection.login", () => { expect(loginResult.showAddCurrentDevice).toBe(false); expect(MultiWebAuthnIdentity.fromCredentials).toHaveBeenCalledTimes(1); expect(MultiWebAuthnIdentity.fromCredentials).toHaveBeenCalledWith( - [convertToCredentialData(mockDevice)], + [convertToValidCredentialData(mockDevice)], undefined ); } @@ -438,10 +441,10 @@ describe("Connection.login", () => { it("connection does not exclude rpId when user cancels", async () => { const currentOriginDevice: DeviceData = createMockDevice(currentOrigin); const currentOriginCredentialData = - convertToCredentialData(currentOriginDevice); + convertToValidCredentialData(currentOriginDevice); const currentDevice: DeviceData = createMockDevice(); const currentDeviceCredentialData = - convertToCredentialData(currentDevice); + convertToValidCredentialData(currentDevice); const mockActor = { identity_info: vi.fn().mockResolvedValue({ Ok: { metadata: [] } }), lookup: vi.fn().mockResolvedValue([currentOriginDevice, currentDevice]), @@ -501,7 +504,7 @@ describe("Connection.login", () => { await connection.login(BigInt(12345)); expect(MultiWebAuthnIdentity.fromCredentials).toHaveBeenCalledTimes(1); expect(MultiWebAuthnIdentity.fromCredentials).toHaveBeenCalledWith( - [convertToCredentialData(deviceWithCredentialId)], + [convertToValidCredentialData(deviceWithCredentialId)], undefined ); }); @@ -525,7 +528,7 @@ describe("Connection.login", () => { await connection.login(BigInt(12345)); expect(MultiWebAuthnIdentity.fromCredentials).toHaveBeenCalledTimes(1); expect(MultiWebAuthnIdentity.fromCredentials).toHaveBeenCalledWith( - [convertToCredentialData(deviceValidCredentialId)], + [convertToValidCredentialData(deviceValidCredentialId)], undefined ); }); diff --git a/src/frontend/src/utils/iiConnection.ts b/src/frontend/src/utils/iiConnection.ts index cdb9051cbb..d8eeaefad4 100644 --- a/src/frontend/src/utils/iiConnection.ts +++ b/src/frontend/src/utils/iiConnection.ts @@ -50,7 +50,10 @@ import { } from "@dfinity/identity"; import { Principal } from "@dfinity/principal"; import { isNullish, nonNullish } from "@dfinity/utils"; -import { convertToCredentialData, CredentialData } from "./credential-devices"; +import { + convertToValidCredentialData, + CredentialData, +} from "./credential-devices"; import { excludeCredentialsFromOrigins, findWebAuthnRpId, @@ -387,7 +390,7 @@ export class Connection { return this.fromWebauthnCredentials( userNumber, - devices.map(convertToCredentialData).filter(nonNullish) + devices.map(convertToValidCredentialData).filter(nonNullish) ); };