Skip to content

Commit

Permalink
Add CryptoApi.pinCurrentUserIdentity
Browse files Browse the repository at this point in the history
Expose `pinCurrentMasterKey` from the rust crypto api.
  • Loading branch information
richvdh committed Sep 24, 2024
1 parent aa51d24 commit 2ed9989
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 0 deletions.
35 changes: 35 additions & 0 deletions spec/unit/rust-crypto/rust-crypto.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1376,6 +1376,41 @@ describe("RustCrypto", () => {
});
});

describe("pinCurrentIdentity", () => {
let rustCrypto: RustCrypto;
let olmMachine: Mocked<RustSdkCryptoJs.OlmMachine>;

beforeEach(() => {
olmMachine = {
getIdentity: jest.fn(),
} as unknown as Mocked<RustSdkCryptoJs.OlmMachine>;
rustCrypto = new RustCrypto(
logger,
olmMachine,
{} as MatrixClient["http"],
TEST_USER,
TEST_DEVICE_ID,
{} as ServerSideSecretStorage,
{} as CryptoCallbacks,
);
});

it("throws an error for an unknown user", async () => {
await expect(rustCrypto.pinCurrentUserIdentity("@alice:example.com")).rejects.toThrow(
"Cannot pin identity of unknown user",
);
});

it("throws an error for our own user", async () => {
const ownIdentity = new RustSdkCryptoJs.OwnUserIdentity();
olmMachine.getIdentity.mockResolvedValue(ownIdentity);

await expect(rustCrypto.pinCurrentUserIdentity("@alice:example.com")).rejects.toThrow(
"Cannot pin identity of own user",
);
});
});

describe("key backup", () => {
it("is started when rust crypto is created", async () => {
// `RustCrypto.checkKeyBackupAndEnable` async call is made in background in the RustCrypto constructor.
Expand Down
10 changes: 10 additions & 0 deletions src/crypto-api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,16 @@ export interface CryptoApi {
*/
getUserVerificationStatus(userId: string): Promise<UserVerificationStatus>;

/**
* "Pin" the current identity of the given user, accepting it as genuine.
*
* This is useful if the user has changed identity since we first saw them (leading to
* {@link UserVerificationStatus.needsUserApproval}), and we are now accepting their new identity.
*
* Throws an error if called on our own user ID, or on a user ID that we don't have an identity for.
*/
pinCurrentUserIdentity(userId: string): Promise<void>;

/**
* Get the verification status of a given device.
*
Expand Down
7 changes: 7 additions & 0 deletions src/crypto/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1609,6 +1609,13 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
return this.checkUserTrust(userId);
}

/**
* Implementation of {@link Crypto.CryptoApi.pinCurrentUserIdentity}.
*/
public async pinCurrentUserIdentity(userId: string): Promise<void> {
throw new Error("not implemented");
}

/**
* Check whether a given device is trusted.
*
Expand Down
18 changes: 18 additions & 0 deletions src/rust-crypto/rust-crypto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,24 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, RustCryptoEv
return new UserVerificationStatus(verified, wasVerified, false, needsUserApproval);
}

/**
* Implementation of {@link CryptoApi#pinCurrentUserIdentity}.
*/
public async pinCurrentUserIdentity(userId: string): Promise<void> {
const userIdentity: RustSdkCryptoJs.UserIdentity | RustSdkCryptoJs.OwnUserIdentity | undefined =
await this.getOlmMachineOrThrow().getIdentity(new RustSdkCryptoJs.UserId(userId));

if (userIdentity === undefined) {
throw new Error("Cannot pin identity of unknown user");
}

if (userIdentity instanceof RustSdkCryptoJs.OwnUserIdentity) {
throw new Error("Cannot pin identity of own user");
}

await userIdentity.pinCurrentMasterKey();
}

/**
* Implementation of {@link CryptoApi#isCrossSigningReady}
*/
Expand Down

0 comments on commit 2ed9989

Please sign in to comment.