Skip to content

Commit 662b772

Browse files
authored
Add crypto events to crypto-api (#4443)
* Move used Crypto event into crypto api * Use new crypto events in rust crypto * Remove `WillUpdateDevices` event from CryptoApi * Use new crypto events in old crypto events * Compute type of CryptoEvent enum * Rename CryptoEvent and CryptoEventHandlerMap as legacy * - Rename `RustCryptoEvent` as `CryptoEvent` - Declare `CryptoEventHandlerMap` into the crypto api * Add `WillUpdateDevices` back to new crypto events to avoid circular imports between old crypto and the cryto api * Extends old crypto handler map with the new crypto map * Review fixes * Add more explicit documentations
1 parent 5508993 commit 662b772

File tree

11 files changed

+190
-167
lines changed

11 files changed

+190
-167
lines changed

spec/unit/rust-crypto/PerSessionKeyBackupDownloader.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import { RustBackupCryptoEventMap, RustBackupCryptoEvents, RustBackupManager } f
2626
import * as TestData from "../../test-utils/test-data";
2727
import {
2828
ConnectionError,
29-
CryptoEvent,
3029
HttpApiEvent,
3130
HttpApiEventHandlerMap,
3231
IHttpOpts,
@@ -37,6 +36,7 @@ import {
3736
import * as testData from "../../test-utils/test-data";
3837
import { BackupDecryptor } from "../../../src/common-crypto/CryptoBackend";
3938
import { KeyBackupSession } from "../../../src/crypto-api/keybackup";
39+
import { CryptoEvent } from "../../../src/crypto-api/index.ts";
4040

4141
describe("PerSessionKeyBackupDownloader", () => {
4242
/** The downloader under test */

spec/unit/rust-crypto/backup.spec.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import { Mocked } from "jest-mock";
22
import fetchMock from "fetch-mock-jest";
33
import * as RustSdkCryptoJs from "@matrix-org/matrix-sdk-crypto-wasm";
44

5-
import { CryptoEvent, HttpApiEvent, HttpApiEventHandlerMap, MatrixHttpApi, TypedEventEmitter } from "../../../src";
5+
import { HttpApiEvent, HttpApiEventHandlerMap, MatrixHttpApi, TypedEventEmitter } from "../../../src";
6+
import { CryptoEvent } from "../../../src/crypto-api/index.ts";
67
import { OutgoingRequestProcessor } from "../../../src/rust-crypto/OutgoingRequestProcessor";
78
import * as testData from "../../test-utils/test-data";
89
import * as TestData from "../../test-utils/test-data";

spec/unit/rust-crypto/rust-crypto.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ import fetchMock from "fetch-mock-jest";
3030
import { RustCrypto } from "../../../src/rust-crypto/rust-crypto";
3131
import { initRustCrypto } from "../../../src/rust-crypto";
3232
import {
33-
CryptoEvent,
3433
Device,
3534
DeviceVerification,
3635
encodeBase64,
@@ -71,6 +70,7 @@ import { ClientEvent, ClientEventHandlerMap } from "../../../src/client";
7170
import { Curve25519AuthData } from "../../../src/crypto-api/keybackup";
7271
import encryptAESSecretStorageItem from "../../../src/utils/encryptAESSecretStorageItem.ts";
7372
import { CryptoStore, SecretStorePrivateKeys } from "../../../src/crypto/store/base";
73+
import { CryptoEvent } from "../../../src/crypto-api/index.ts";
7474

7575
const TEST_USER = "@alice:example.com";
7676
const TEST_DEVICE_ID = "TEST_DEVICE";

src/client.ts

Lines changed: 36 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ import {
7676
} from "./http-api/index.ts";
7777
import {
7878
Crypto,
79-
CryptoEvent,
80-
CryptoEventHandlerMap,
79+
CryptoEvent as LegacyCryptoEvent,
80+
CryptoEventHandlerMap as LegacyCryptoEventHandlerMap,
8181
fixBackupKey,
8282
ICheckOwnCrossSigningTrustOpts,
8383
ICryptoCallbacks,
@@ -227,6 +227,8 @@ import {
227227
CryptoApi,
228228
decodeRecoveryKey,
229229
ImportRoomKeysOpts,
230+
CryptoEvent,
231+
CryptoEventHandlerMap,
230232
} from "./crypto-api/index.ts";
231233
import { DeviceInfoMap } from "./crypto/DeviceList.ts";
232234
import {
@@ -939,23 +941,25 @@ type RoomStateEvents =
939941
| RoomStateEvent.Update
940942
| RoomStateEvent.Marker;
941943

942-
type CryptoEvents =
943-
| CryptoEvent.KeySignatureUploadFailure
944-
| CryptoEvent.KeyBackupStatus
945-
| CryptoEvent.KeyBackupFailed
946-
| CryptoEvent.KeyBackupSessionsRemaining
947-
| CryptoEvent.KeyBackupDecryptionKeyCached
948-
| CryptoEvent.RoomKeyRequest
949-
| CryptoEvent.RoomKeyRequestCancellation
950-
| CryptoEvent.VerificationRequest
951-
| CryptoEvent.VerificationRequestReceived
952-
| CryptoEvent.DeviceVerificationChanged
953-
| CryptoEvent.UserTrustStatusChanged
954-
| CryptoEvent.KeysChanged
955-
| CryptoEvent.Warning
956-
| CryptoEvent.DevicesUpdated
957-
| CryptoEvent.WillUpdateDevices
958-
| CryptoEvent.LegacyCryptoStoreMigrationProgress;
944+
type LegacyCryptoEvents =
945+
| LegacyCryptoEvent.KeySignatureUploadFailure
946+
| LegacyCryptoEvent.KeyBackupStatus
947+
| LegacyCryptoEvent.KeyBackupFailed
948+
| LegacyCryptoEvent.KeyBackupSessionsRemaining
949+
| LegacyCryptoEvent.KeyBackupDecryptionKeyCached
950+
| LegacyCryptoEvent.RoomKeyRequest
951+
| LegacyCryptoEvent.RoomKeyRequestCancellation
952+
| LegacyCryptoEvent.VerificationRequest
953+
| LegacyCryptoEvent.VerificationRequestReceived
954+
| LegacyCryptoEvent.DeviceVerificationChanged
955+
| LegacyCryptoEvent.UserTrustStatusChanged
956+
| LegacyCryptoEvent.KeysChanged
957+
| LegacyCryptoEvent.Warning
958+
| LegacyCryptoEvent.DevicesUpdated
959+
| LegacyCryptoEvent.WillUpdateDevices
960+
| LegacyCryptoEvent.LegacyCryptoStoreMigrationProgress;
961+
962+
type CryptoEvents = (typeof CryptoEvent)[keyof typeof CryptoEvent];
959963

960964
type MatrixEventEvents = MatrixEventEvent.Decrypted | MatrixEventEvent.Replaced | MatrixEventEvent.VisibilityChange;
961965

@@ -976,6 +980,7 @@ export type EmittedEvents =
976980
| ClientEvent
977981
| RoomEvents
978982
| RoomStateEvents
983+
| LegacyCryptoEvents
979984
| CryptoEvents
980985
| MatrixEventEvents
981986
| RoomMemberEvents
@@ -1187,6 +1192,7 @@ export type ClientEventHandlerMap = {
11871192
[ClientEvent.TurnServersError]: (error: Error, fatal: boolean) => void;
11881193
} & RoomEventHandlerMap &
11891194
RoomStateEventHandlerMap &
1195+
LegacyCryptoEventHandlerMap &
11901196
CryptoEventHandlerMap &
11911197
MatrixEventHandlerMap &
11921198
RoomMemberEventHandlerMap &
@@ -2176,16 +2182,16 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
21762182
const crypto = new Crypto(this, userId, this.deviceId, this.store, this.cryptoStore, this.verificationMethods!);
21772183

21782184
this.reEmitter.reEmit(crypto, [
2179-
CryptoEvent.KeyBackupFailed,
2180-
CryptoEvent.KeyBackupSessionsRemaining,
2181-
CryptoEvent.RoomKeyRequest,
2182-
CryptoEvent.RoomKeyRequestCancellation,
2183-
CryptoEvent.Warning,
2184-
CryptoEvent.DevicesUpdated,
2185-
CryptoEvent.WillUpdateDevices,
2186-
CryptoEvent.DeviceVerificationChanged,
2187-
CryptoEvent.UserTrustStatusChanged,
2188-
CryptoEvent.KeysChanged,
2185+
LegacyCryptoEvent.KeyBackupFailed,
2186+
LegacyCryptoEvent.KeyBackupSessionsRemaining,
2187+
LegacyCryptoEvent.RoomKeyRequest,
2188+
LegacyCryptoEvent.RoomKeyRequestCancellation,
2189+
LegacyCryptoEvent.Warning,
2190+
LegacyCryptoEvent.DevicesUpdated,
2191+
LegacyCryptoEvent.WillUpdateDevices,
2192+
LegacyCryptoEvent.DeviceVerificationChanged,
2193+
LegacyCryptoEvent.UserTrustStatusChanged,
2194+
LegacyCryptoEvent.KeysChanged,
21892195
]);
21902196

21912197
this.logger.debug("Crypto: initialising crypto object...");
@@ -2443,7 +2449,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
24432449
* @returns
24442450
*
24452451
* @remarks
2446-
* Fires {@link CryptoEvent.DeviceVerificationChanged}
2452+
* Fires {@link LegacyCryptoEvent.DeviceVerificationChanged}
24472453
*
24482454
* @deprecated Not supported for Rust Cryptography.
24492455
*/

src/crypto-api/CryptoEvent.ts

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/*
2+
* Copyright 2024 The Matrix.org Foundation C.I.C.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
/**
18+
* Events emitted by the {@link CryptoApi}
19+
*/
20+
export enum CryptoEvent {
21+
/**
22+
* Fires when the trust status of a user changes.
23+
* The payload is a pair (userId, userTrustLevel). The trust level is one of the values from UserVerificationStatus.
24+
*/
25+
UserTrustStatusChanged = "userTrustStatusChanged",
26+
27+
/**
28+
* Fires when the key backup status changes.
29+
* The payload is a boolean indicating whether the key backup is enabled.
30+
*/
31+
KeyBackupStatus = "crypto.keyBackupStatus",
32+
33+
/**
34+
* Fires when we failed to back up the keys
35+
* The payload is the error code of the error that occurred.
36+
*/
37+
KeyBackupFailed = "crypto.keyBackupFailed",
38+
39+
/**
40+
* Fires when the number of sessions that can be backed up changes.
41+
* The payload is the remaining number of sessions that can be backed up.
42+
*/
43+
KeyBackupSessionsRemaining = "crypto.keyBackupSessionsRemaining",
44+
45+
/**
46+
* Fires when a new valid backup decryption key is in cache.
47+
* This will happen when a secret is received from another session, from secret storage,
48+
* or when a new backup is created from this session.
49+
*
50+
* The payload is the version of the backup for which we have the key for.
51+
*
52+
* This event is only fired by the rust crypto backend.
53+
*/
54+
KeyBackupDecryptionKeyCached = "crypto.keyBackupDecryptionKeyCached",
55+
56+
/**
57+
* Fires when a key verification request is received.
58+
* The payload is a VerificationRequest object representing the request.
59+
*/
60+
VerificationRequestReceived = "crypto.verificationRequestReceived",
61+
62+
/** @deprecated Use {@link DevicesUpdated} instead when using rust crypto */
63+
WillUpdateDevices = "crypto.willUpdateDevices",
64+
65+
/**
66+
* Fires whenever the stored devices for a user have been updated
67+
* The payload is a pair (userIds, initialFetch).
68+
*/
69+
DevicesUpdated = "crypto.devicesUpdated",
70+
71+
/**
72+
* Fires when the user's cross-signing keys have changed or cross-signing
73+
* has been enabled/disabled. The client can use getStoredCrossSigningForUser
74+
* with the user ID of the logged in user to check if cross-signing is
75+
* enabled on the account. If enabled, it can test whether the current key
76+
* is trusted using with checkUserTrust with the user ID of the logged
77+
* in user. The checkOwnCrossSigningTrust function may be used to reconcile
78+
* the trust in the account key.
79+
*
80+
* The cross-signing API is currently UNSTABLE and may change without notice.
81+
* @experimental
82+
*/
83+
KeysChanged = "crossSigning.keysChanged",
84+
85+
/**
86+
* Fires when data is being migrated from legacy crypto to rust crypto.
87+
*
88+
* The payload is a pair `(progress, total)`, where `progress` is the number of steps completed so far, and
89+
* `total` is the total number of steps. When migration is complete, a final instance of the event is emitted, with
90+
* `progress === total === -1`.
91+
*/
92+
LegacyCryptoStoreMigrationProgress = "crypto.legacyCryptoStoreMigrationProgress",
93+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright 2024 The Matrix.org Foundation C.I.C.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { CryptoEvent } from "./CryptoEvent.ts";
18+
import { VerificationRequest } from "./verification.ts";
19+
import { UserVerificationStatus } from "./index.ts";
20+
import { RustBackupCryptoEventMap } from "../rust-crypto/backup.ts";
21+
22+
/**
23+
* A map of the {@link CryptoEvent} fired by the {@link CryptoApi} and their payloads.
24+
*/
25+
export type CryptoEventHandlerMap = {
26+
[CryptoEvent.VerificationRequestReceived]: (request: VerificationRequest) => void;
27+
[CryptoEvent.UserTrustStatusChanged]: (userId: string, userTrustLevel: UserVerificationStatus) => void;
28+
[CryptoEvent.KeyBackupDecryptionKeyCached]: (version: string) => void;
29+
[CryptoEvent.KeysChanged]: (data: {}) => void;
30+
[CryptoEvent.WillUpdateDevices]: (users: string[], initialFetch: boolean) => void;
31+
[CryptoEvent.DevicesUpdated]: (users: string[], initialFetch: boolean) => void;
32+
} & RustBackupCryptoEventMap;

src/crypto-api/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1083,3 +1083,5 @@ export * from "./verification.ts";
10831083
export * from "./keybackup.ts";
10841084
export * from "./recovery-key.ts";
10851085
export * from "./key-passphrase.ts";
1086+
export * from "./CryptoEvent.ts";
1087+
export * from "./CryptoEventHandlerMap.ts";

0 commit comments

Comments
 (0)