diff --git a/spec/unit/rust-crypto/rust-crypto.spec.ts b/spec/unit/rust-crypto/rust-crypto.spec.ts index cc52b1792..6ebdf661f 100644 --- a/spec/unit/rust-crypto/rust-crypto.spec.ts +++ b/spec/unit/rust-crypto/rust-crypto.spec.ts @@ -1582,6 +1582,57 @@ describe("RustCrypto", () => { }); }); + describe("withdraw verification", () => { + function createTestSetup(): { olmMachine: Mocked; rustCrypto: RustCrypto } { + const olmMachine = { + getIdentity: jest.fn(), + } as unknown as Mocked; + const rustCrypto = new RustCrypto( + logger, + olmMachine, + {} as MatrixClient["http"], + TEST_USER, + TEST_DEVICE_ID, + {} as ServerSideSecretStorage, + {} as CryptoCallbacks, + ); + return { olmMachine, rustCrypto }; + } + + it("throws an error for an unknown user", async () => { + const { rustCrypto } = createTestSetup(); + await expect(rustCrypto.withdrawVerificationRequirement("@alice:example.com")).rejects.toThrow( + "Cannot withdraw verification of unknown user", + ); + }); + + it("Calls withdraw for other identity", async () => { + const { olmMachine, rustCrypto } = createTestSetup(); + const identity = { + withdrawVerification: jest.fn(), + } as unknown as Mocked; + + olmMachine.getIdentity.mockResolvedValue(identity); + + await rustCrypto.withdrawVerificationRequirement("@bob:example.com"); + + expect(identity.withdrawVerification).toHaveBeenCalled(); + }); + + it("Calls withdraw for own identity", async () => { + const { olmMachine, rustCrypto } = createTestSetup(); + const ownIdentity = { + withdrawVerification: jest.fn(), + } as unknown as Mocked; + + olmMachine.getIdentity.mockResolvedValue(ownIdentity); + + await rustCrypto.withdrawVerificationRequirement("@alice:example.com"); + + expect(ownIdentity.withdrawVerification).toHaveBeenCalled(); + }); + }); + describe("key backup", () => { it("is started when rust crypto is created", async () => { // `RustCrypto.checkKeyBackupAndEnable` async call is made in background in the RustCrypto constructor. diff --git a/src/crypto-api/index.ts b/src/crypto-api/index.ts index 821f84baa..4761be640 100644 --- a/src/crypto-api/index.ts +++ b/src/crypto-api/index.ts @@ -221,6 +221,15 @@ export interface CryptoApi { */ pinCurrentUserIdentity(userId: string): Promise; + /** + * Remove the requirement for this identity to be verified, and pin it. + * + * This is useful if the user was previously verified but is not anymore + * ({@link UserVerificationStatus.wasCrossSigningVerified}) and it is not possible to verify him again now. + * + */ + withdrawVerificationRequirement(userId: string): Promise; + /** * Get the verification status of a given device. * diff --git a/src/crypto/index.ts b/src/crypto/index.ts index 8981da563..d2dff60cd 100644 --- a/src/crypto/index.ts +++ b/src/crypto/index.ts @@ -1576,6 +1576,13 @@ export class Crypto extends TypedEventEmitter { + throw new Error("not implemented"); + } + /** * Check whether a given device is trusted. * diff --git a/src/rust-crypto/rust-crypto.ts b/src/rust-crypto/rust-crypto.ts index cbbf5d0fa..e0f24a216 100644 --- a/src/rust-crypto/rust-crypto.ts +++ b/src/rust-crypto/rust-crypto.ts @@ -699,6 +699,20 @@ export class RustCrypto extends TypedEventEmitter { + const userIdentity: RustSdkCryptoJs.OtherUserIdentity | RustSdkCryptoJs.OwnUserIdentity | undefined = + await this.getOlmMachineOrThrow().getIdentity(new RustSdkCryptoJs.UserId(userId)); + + if (userIdentity === undefined) { + throw new Error("Cannot withdraw verification of unknown user"); + } + + await userIdentity.withdrawVerification(); + } + /** * Implementation of {@link CryptoApi#isCrossSigningReady} */