Skip to content

Commit 39cf212

Browse files
authored
Expose a new 'userHasCrossSigningKeys' method (#2950)
1 parent 224e592 commit 39cf212

File tree

3 files changed

+91
-1
lines changed

3 files changed

+91
-1
lines changed

spec/unit/crypto/cross-signing.spec.ts

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import HttpBackend from "matrix-mock-request";
2323
import * as olmlib from "../../../src/crypto/olmlib";
2424
import { MatrixError } from '../../../src/http-api';
2525
import { logger } from '../../../src/logger';
26-
import { ICrossSigningKey, ICreateClientOpts, ISignedKey } from '../../../src/client';
26+
import { ICrossSigningKey, ICreateClientOpts, ISignedKey, MatrixClient } from '../../../src/client';
2727
import { CryptoEvent, IBootstrapCrossSigningOpts } from '../../../src/crypto';
2828
import { IDevice } from '../../../src/crypto/deviceinfo';
2929
import { TestClient } from '../../TestClient';
@@ -1137,3 +1137,67 @@ describe("Cross Signing", function() {
11371137
alice.stopClient();
11381138
});
11391139
});
1140+
1141+
describe("userHasCrossSigningKeys", function() {
1142+
if (!global.Olm) {
1143+
return;
1144+
}
1145+
1146+
beforeAll(() => {
1147+
return global.Olm.init();
1148+
});
1149+
1150+
let aliceClient: MatrixClient;
1151+
let httpBackend: HttpBackend;
1152+
beforeEach(async () => {
1153+
const testClient = await makeTestClient({ userId: "@alice:example.com", deviceId: "Osborne2" });
1154+
aliceClient = testClient.client;
1155+
httpBackend = testClient.httpBackend;
1156+
});
1157+
1158+
afterEach(() => {
1159+
aliceClient.stopClient();
1160+
});
1161+
1162+
it("should download devices and return true if one is a cross-signing key", async () => {
1163+
httpBackend
1164+
.when("POST", "/keys/query")
1165+
.respond(200, {
1166+
"master_keys": {
1167+
"@alice:example.com": {
1168+
user_id: "@alice:example.com",
1169+
usage: ["master"],
1170+
keys: {
1171+
"ed25519:nqOvzeuGWT/sRx3h7+MHoInYj3Uk2LD/unI9kDYcHwk":
1172+
"nqOvzeuGWT/sRx3h7+MHoInYj3Uk2LD/unI9kDYcHwk",
1173+
},
1174+
},
1175+
},
1176+
});
1177+
1178+
let result: boolean;
1179+
await Promise.all([
1180+
httpBackend.flush("/keys/query"),
1181+
aliceClient.userHasCrossSigningKeys().then((res) => {result = res;}),
1182+
]);
1183+
expect(result!).toBeTruthy();
1184+
});
1185+
1186+
it("should download devices and return false if there is no cross-signing key", async () => {
1187+
httpBackend
1188+
.when("POST", "/keys/query")
1189+
.respond(200, {});
1190+
1191+
let result: boolean;
1192+
await Promise.all([
1193+
httpBackend.flush("/keys/query"),
1194+
aliceClient.userHasCrossSigningKeys().then((res) => {result = res;}),
1195+
]);
1196+
expect(result!).toBeFalsy();
1197+
});
1198+
1199+
it("throws an error if crypto is disabled", () => {
1200+
aliceClient.crypto = undefined;
1201+
expect(() => aliceClient.userHasCrossSigningKeys()).toThrowError("encryption disabled");
1202+
});
1203+
});

src/client.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2473,6 +2473,19 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
24732473
this.crypto.prepareToEncrypt(room);
24742474
}
24752475

2476+
/**
2477+
* Checks if the user has previously published cross-signing keys
2478+
*
2479+
* This means downloading the devicelist for the user and checking if the list includes
2480+
* the cross-signing pseudo-device.
2481+
*/
2482+
public userHasCrossSigningKeys(): Promise<boolean> {
2483+
if (!this.crypto) {
2484+
throw new Error("End-to-end encryption disabled");
2485+
}
2486+
return this.crypto.userHasCrossSigningKeys();
2487+
}
2488+
24762489
/**
24772490
* Checks whether cross signing:
24782491
* - is enabled on this account and trusted by this device

src/crypto/index.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,19 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
718718
}
719719
}
720720

721+
/**
722+
* Checks if the user has previously published cross-signing keys
723+
*
724+
* This means downloading the devicelist for the user and checking if the list includes
725+
* the cross-signing pseudo-device.
726+
*
727+
* @internal
728+
*/
729+
public async userHasCrossSigningKeys(): Promise<boolean> {
730+
await this.downloadKeys([this.userId]);
731+
return this.deviceList.getStoredCrossSigningForUser(this.userId) !== null;
732+
}
733+
721734
/**
722735
* Checks whether cross signing:
723736
* - is enabled on this account and trusted by this device

0 commit comments

Comments
 (0)