summaryrefslogtreecommitdiff
path: root/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto')
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/CrossSigning.d.ts214
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/CrossSigning.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/CrossSigning.js711
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/CrossSigning.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/DeviceList.d.ts216
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/DeviceList.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/DeviceList.js877
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/DeviceList.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/EncryptionSetup.d.ts150
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/EncryptionSetup.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/EncryptionSetup.js350
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/EncryptionSetup.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/OlmDevice.d.ts454
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/OlmDevice.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/OlmDevice.js1164
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/OlmDevice.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/OutgoingRoomKeyRequestManager.d.ts109
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/OutgoingRoomKeyRequestManager.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/OutgoingRoomKeyRequestManager.js394
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/OutgoingRoomKeyRequestManager.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/RoomList.d.ts19
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/RoomList.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/RoomList.js63
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/RoomList.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/SecretStorage.d.ts115
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/SecretStorage.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/SecretStorage.js491
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/SecretStorage.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/aes.d.ts35
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/aes.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/aes.js128
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/aes.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/base.d.ts170
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/base.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/base.js226
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/base.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/index.d.ts4
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/index.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/index.js19
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/index.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/megolm.d.ts385
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/megolm.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/megolm.js1682
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/megolm.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/olm.d.ts5
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/olm.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/olm.js269
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/olm.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/api.d.ts89
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/api.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/api.js44
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/api.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/backup.d.ts184
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/backup.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/backup.js654
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/backup.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/crypto.d.ts9
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/crypto.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/crypto.js48
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/crypto.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/dehydration.d.ts34
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/dehydration.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/dehydration.js238
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/dehydration.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/deviceinfo.d.ts102
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/deviceinfo.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/deviceinfo.js150
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/deviceinfo.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/index.d.ts1083
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/index.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/index.js3290
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/index.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/key_passphrase.d.ts15
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/key_passphrase.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/key_passphrase.js68
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/key_passphrase.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/keybackup.d.ts53
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/keybackup.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/keybackup.js6
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/keybackup.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/olmlib.d.ts146
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/olmlib.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/olmlib.js467
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/olmlib.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/recoverykey.d.ts3
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/recoverykey.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/recoverykey.js62
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/recoverykey.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/base.d.ts143
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/base.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/base.js6
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/base.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store-backend.d.ts130
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store-backend.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store-backend.js918
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store-backend.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store.d.ts360
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store.js601
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/localStorage-crypto-store.d.ts49
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/localStorage-crypto-store.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/localStorage-crypto-store.js333
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/localStorage-crypto-store.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/memory-crypto-store.d.ts144
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/memory-crypto-store.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/memory-crypto-store.js429
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/memory-crypto-store.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Base.d.ts87
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Base.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Base.js347
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Base.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Error.d.ts35
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Error.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Error.js101
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Error.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/IllegalMethod.d.ts15
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/IllegalMethod.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/IllegalMethod.js50
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/IllegalMethod.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/QRCode.d.ts54
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/QRCode.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/QRCode.js272
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/QRCode.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SAS.d.ts37
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SAS.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SAS.js453
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SAS.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SASDecimal.d.ts8
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SASDecimal.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SASDecimal.js40
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SASDecimal.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/Channel.d.ts18
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/Channel.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/Channel.js6
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/Channel.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/InRoomChannel.d.ts113
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/InRoomChannel.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/InRoomChannel.js344
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/InRoomChannel.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/ToDeviceChannel.d.ts105
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/ToDeviceChannel.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/ToDeviceChannel.js324
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/ToDeviceChannel.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/VerificationRequest.d.ts208
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/VerificationRequest.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/VerificationRequest.js876
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/VerificationRequest.js.map1
148 files changed, 0 insertions, 21675 deletions
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/CrossSigning.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/CrossSigning.d.ts
deleted file mode 100644
index d9d17d9..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/CrossSigning.d.ts
+++ /dev/null
@@ -1,214 +0,0 @@
-/**
- * Cross signing methods
- */
-import { PkSigning } from "@matrix-org/olm";
-import { DeviceInfo } from "./deviceinfo";
-import { SecretStorage } from "./SecretStorage";
-import { ICrossSigningKey, ISignedKey, MatrixClient } from "../client";
-import { OlmDevice } from "./OlmDevice";
-import { ICryptoCallbacks } from ".";
-import { ISignatures } from "../@types/signed";
-import { CryptoStore } from "./store/base";
-export interface ICacheCallbacks {
- getCrossSigningKeyCache?(type: string, expectedPublicKey?: string): Promise<Uint8Array | null>;
- storeCrossSigningKeyCache?(type: string, key?: Uint8Array): Promise<void>;
-}
-export interface ICrossSigningInfo {
- keys: Record<string, ICrossSigningKey>;
- firstUse: boolean;
- crossSigningVerifiedBefore: boolean;
-}
-export declare class CrossSigningInfo {
- readonly userId: string;
- private callbacks;
- private cacheCallbacks;
- keys: Record<string, ICrossSigningKey>;
- firstUse: boolean;
- private crossSigningVerifiedBefore;
- /**
- * Information about a user's cross-signing keys
- *
- * @param userId - the user that the information is about
- * @param callbacks - Callbacks used to interact with the app
- * Requires getCrossSigningKey and saveCrossSigningKeys
- * @param cacheCallbacks - Callbacks used to interact with the cache
- */
- constructor(userId: string, callbacks?: ICryptoCallbacks, cacheCallbacks?: ICacheCallbacks);
- static fromStorage(obj: ICrossSigningInfo, userId: string): CrossSigningInfo;
- toStorage(): ICrossSigningInfo;
- /**
- * Calls the app callback to ask for a private key
- *
- * @param type - The key type ("master", "self_signing", or "user_signing")
- * @param expectedPubkey - The matching public key or undefined to use
- * the stored public key for the given key type.
- * @returns An array with [ public key, Olm.PkSigning ]
- */
- getCrossSigningKey(type: string, expectedPubkey?: string): Promise<[string, PkSigning]>;
- /**
- * Check whether the private keys exist in secret storage.
- * XXX: This could be static, be we often seem to have an instance when we
- * want to know this anyway...
- *
- * @param secretStorage - The secret store using account data
- * @returns map of key name to key info the secret is encrypted
- * with, or null if it is not present or not encrypted with a trusted
- * key
- */
- isStoredInSecretStorage(secretStorage: SecretStorage<MatrixClient | undefined>): Promise<Record<string, object> | null>;
- /**
- * Store private keys in secret storage for use by other devices. This is
- * typically called in conjunction with the creation of new cross-signing
- * keys.
- *
- * @param keys - The keys to store
- * @param secretStorage - The secret store using account data
- */
- static storeInSecretStorage(keys: Map<string, Uint8Array>, secretStorage: SecretStorage<undefined>): Promise<void>;
- /**
- * Get private keys from secret storage created by some other device. This
- * also passes the private keys to the app-specific callback.
- *
- * @param type - The type of key to get. One of "master",
- * "self_signing", or "user_signing".
- * @param secretStorage - The secret store using account data
- * @returns The private key
- */
- static getFromSecretStorage(type: string, secretStorage: SecretStorage): Promise<Uint8Array | null>;
- /**
- * Check whether the private keys exist in the local key cache.
- *
- * @param type - The type of key to get. One of "master",
- * "self_signing", or "user_signing". Optional, will check all by default.
- * @returns True if all keys are stored in the local cache.
- */
- isStoredInKeyCache(type?: string): Promise<boolean>;
- /**
- * Get cross-signing private keys from the local cache.
- *
- * @returns A map from key type (string) to private key (Uint8Array)
- */
- getCrossSigningKeysFromCache(): Promise<Map<string, Uint8Array>>;
- /**
- * Get the ID used to identify the user. This can also be used to test for
- * the existence of a given key type.
- *
- * @param type - The type of key to get the ID of. One of "master",
- * "self_signing", or "user_signing". Defaults to "master".
- *
- * @returns the ID
- */
- getId(type?: string): string | null;
- /**
- * Create new cross-signing keys for the given key types. The public keys
- * will be held in this class, while the private keys are passed off to the
- * `saveCrossSigningKeys` application callback.
- *
- * @param level - The key types to reset
- */
- resetKeys(level?: CrossSigningLevel): Promise<void>;
- /**
- * unsets the keys, used when another session has reset the keys, to disable cross-signing
- */
- clearKeys(): void;
- setKeys(keys: Record<string, ICrossSigningKey>): void;
- updateCrossSigningVerifiedBefore(isCrossSigningVerified: boolean): void;
- signObject<T extends object>(data: T, type: string): Promise<T & {
- signatures: ISignatures;
- }>;
- signUser(key: CrossSigningInfo): Promise<ICrossSigningKey | undefined>;
- signDevice(userId: string, device: DeviceInfo): Promise<ISignedKey | undefined>;
- /**
- * Check whether a given user is trusted.
- *
- * @param userCrossSigning - Cross signing info for user
- *
- * @returns
- */
- checkUserTrust(userCrossSigning: CrossSigningInfo): UserTrustLevel;
- /**
- * Check whether a given device is trusted.
- *
- * @param userCrossSigning - Cross signing info for user
- * @param device - The device to check
- * @param localTrust - Whether the device is trusted locally
- * @param trustCrossSignedDevices - Whether we trust cross signed devices
- *
- * @returns
- */
- checkDeviceTrust(userCrossSigning: CrossSigningInfo, device: DeviceInfo, localTrust: boolean, trustCrossSignedDevices: boolean): DeviceTrustLevel;
- /**
- * @returns Cache callbacks
- */
- getCacheCallbacks(): ICacheCallbacks;
-}
-export declare enum CrossSigningLevel {
- MASTER = 4,
- USER_SIGNING = 2,
- SELF_SIGNING = 1
-}
-/**
- * Represents the ways in which we trust a user
- */
-export declare class UserTrustLevel {
- private readonly crossSigningVerified;
- private readonly crossSigningVerifiedBefore;
- private readonly tofu;
- constructor(crossSigningVerified: boolean, crossSigningVerifiedBefore: boolean, tofu: boolean);
- /**
- * @returns true if this user is verified via any means
- */
- isVerified(): boolean;
- /**
- * @returns true if this user is verified via cross signing
- */
- isCrossSigningVerified(): boolean;
- /**
- * @returns true if we ever verified this user before (at least for
- * the history of verifications observed by this device).
- */
- wasCrossSigningVerified(): boolean;
- /**
- * @returns true if this user's key is trusted on first use
- */
- isTofu(): boolean;
-}
-/**
- * Represents the ways in which we trust a device
- */
-export declare class DeviceTrustLevel {
- readonly crossSigningVerified: boolean;
- readonly tofu: boolean;
- private readonly localVerified;
- private readonly trustCrossSignedDevices;
- constructor(crossSigningVerified: boolean, tofu: boolean, localVerified: boolean, trustCrossSignedDevices: boolean);
- static fromUserTrustLevel(userTrustLevel: UserTrustLevel, localVerified: boolean, trustCrossSignedDevices: boolean): DeviceTrustLevel;
- /**
- * @returns true if this device is verified via any means
- */
- isVerified(): boolean;
- /**
- * @returns true if this device is verified via cross signing
- */
- isCrossSigningVerified(): boolean;
- /**
- * @returns true if this device is verified locally
- */
- isLocallyVerified(): boolean;
- /**
- * @returns true if this device is trusted from a user's key
- * that is trusted on first use
- */
- isTofu(): boolean;
-}
-export declare function createCryptoStoreCacheCallbacks(store: CryptoStore, olmDevice: OlmDevice): ICacheCallbacks;
-export type KeysDuringVerification = [[string, PkSigning], [string, PkSigning], [string, PkSigning], void];
-/**
- * Request cross-signing keys from another device during verification.
- *
- * @param baseApis - base Matrix API interface
- * @param userId - The user ID being verified
- * @param deviceId - The device ID being verified
- */
-export declare function requestKeysDuringVerification(baseApis: MatrixClient, userId: string, deviceId: string): Promise<KeysDuringVerification | void>;
-//# sourceMappingURL=CrossSigning.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/CrossSigning.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/CrossSigning.d.ts.map
deleted file mode 100644
index 9656a5f..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/CrossSigning.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"CrossSigning.d.ts","sourceRoot":"","sources":["../../src/crypto/CrossSigning.ts"],"names":[],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/CrossSigning.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/CrossSigning.js
deleted file mode 100644
index 21d9f90..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/CrossSigning.js
+++ /dev/null
@@ -1,711 +0,0 @@
-"use strict";
-
-var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.UserTrustLevel = exports.DeviceTrustLevel = exports.CrossSigningLevel = exports.CrossSigningInfo = void 0;
-exports.createCryptoStoreCacheCallbacks = createCryptoStoreCacheCallbacks;
-exports.requestKeysDuringVerification = requestKeysDuringVerification;
-var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
-var _olmlib = require("./olmlib");
-var _logger = require("../logger");
-var _indexeddbCryptoStore = require("../crypto/store/indexeddb-crypto-store");
-var _aes = require("./aes");
-/*
-Copyright 2019 - 2021 The Matrix.org Foundation C.I.C.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-/**
- * Cross signing methods
- */
-
-const KEY_REQUEST_TIMEOUT_MS = 1000 * 60;
-function publicKeyFromKeyInfo(keyInfo) {
- // `keys` is an object with { [`ed25519:${pubKey}`]: pubKey }
- // We assume only a single key, and we want the bare form without type
- // prefix, so we select the values.
- return Object.values(keyInfo.keys)[0];
-}
-class CrossSigningInfo {
- // This tracks whether we've ever verified this user with any identity.
- // When you verify a user, any devices online at the time that receive
- // the verifying signature via the homeserver will latch this to true
- // and can use it in the future to detect cases where the user has
- // become unverified later for any reason.
-
- /**
- * Information about a user's cross-signing keys
- *
- * @param userId - the user that the information is about
- * @param callbacks - Callbacks used to interact with the app
- * Requires getCrossSigningKey and saveCrossSigningKeys
- * @param cacheCallbacks - Callbacks used to interact with the cache
- */
- constructor(userId, callbacks = {}, cacheCallbacks = {}) {
- this.userId = userId;
- this.callbacks = callbacks;
- this.cacheCallbacks = cacheCallbacks;
- (0, _defineProperty2.default)(this, "keys", {});
- (0, _defineProperty2.default)(this, "firstUse", true);
- (0, _defineProperty2.default)(this, "crossSigningVerifiedBefore", false);
- }
- static fromStorage(obj, userId) {
- const res = new CrossSigningInfo(userId);
- for (const prop in obj) {
- if (obj.hasOwnProperty(prop)) {
- // @ts-ignore - ts doesn't like this and nor should we
- res[prop] = obj[prop];
- }
- }
- return res;
- }
- toStorage() {
- return {
- keys: this.keys,
- firstUse: this.firstUse,
- crossSigningVerifiedBefore: this.crossSigningVerifiedBefore
- };
- }
-
- /**
- * Calls the app callback to ask for a private key
- *
- * @param type - The key type ("master", "self_signing", or "user_signing")
- * @param expectedPubkey - The matching public key or undefined to use
- * the stored public key for the given key type.
- * @returns An array with [ public key, Olm.PkSigning ]
- */
- async getCrossSigningKey(type, expectedPubkey) {
- const shouldCache = ["master", "self_signing", "user_signing"].indexOf(type) >= 0;
- if (!this.callbacks.getCrossSigningKey) {
- throw new Error("No getCrossSigningKey callback supplied");
- }
- if (expectedPubkey === undefined) {
- expectedPubkey = this.getId(type);
- }
- function validateKey(key) {
- if (!key) return;
- const signing = new global.Olm.PkSigning();
- const gotPubkey = signing.init_with_seed(key);
- if (gotPubkey === expectedPubkey) {
- return [gotPubkey, signing];
- }
- signing.free();
- }
- let privkey = null;
- if (this.cacheCallbacks.getCrossSigningKeyCache && shouldCache) {
- privkey = await this.cacheCallbacks.getCrossSigningKeyCache(type, expectedPubkey);
- }
- const cacheresult = validateKey(privkey);
- if (cacheresult) {
- return cacheresult;
- }
- privkey = await this.callbacks.getCrossSigningKey(type, expectedPubkey);
- const result = validateKey(privkey);
- if (result) {
- if (this.cacheCallbacks.storeCrossSigningKeyCache && shouldCache) {
- await this.cacheCallbacks.storeCrossSigningKeyCache(type, privkey);
- }
- return result;
- }
-
- /* No keysource even returned a key */
- if (!privkey) {
- throw new Error("getCrossSigningKey callback for " + type + " returned falsey");
- }
-
- /* We got some keys from the keysource, but none of them were valid */
- throw new Error("Key type " + type + " from getCrossSigningKey callback did not match");
- }
-
- /**
- * Check whether the private keys exist in secret storage.
- * XXX: This could be static, be we often seem to have an instance when we
- * want to know this anyway...
- *
- * @param secretStorage - The secret store using account data
- * @returns map of key name to key info the secret is encrypted
- * with, or null if it is not present or not encrypted with a trusted
- * key
- */
- async isStoredInSecretStorage(secretStorage) {
- // check what SSSS keys have encrypted the master key (if any)
- const stored = (await secretStorage.isStored("m.cross_signing.master")) || {};
- // then check which of those SSSS keys have also encrypted the SSK and USK
- function intersect(s) {
- for (const k of Object.keys(stored)) {
- if (!s[k]) {
- delete stored[k];
- }
- }
- }
- for (const type of ["self_signing", "user_signing"]) {
- intersect((await secretStorage.isStored(`m.cross_signing.${type}`)) || {});
- }
- return Object.keys(stored).length ? stored : null;
- }
-
- /**
- * Store private keys in secret storage for use by other devices. This is
- * typically called in conjunction with the creation of new cross-signing
- * keys.
- *
- * @param keys - The keys to store
- * @param secretStorage - The secret store using account data
- */
- static async storeInSecretStorage(keys, secretStorage) {
- for (const [type, privateKey] of keys) {
- const encodedKey = (0, _olmlib.encodeBase64)(privateKey);
- await secretStorage.store(`m.cross_signing.${type}`, encodedKey);
- }
- }
-
- /**
- * Get private keys from secret storage created by some other device. This
- * also passes the private keys to the app-specific callback.
- *
- * @param type - The type of key to get. One of "master",
- * "self_signing", or "user_signing".
- * @param secretStorage - The secret store using account data
- * @returns The private key
- */
- static async getFromSecretStorage(type, secretStorage) {
- const encodedKey = await secretStorage.get(`m.cross_signing.${type}`);
- if (!encodedKey) {
- return null;
- }
- return (0, _olmlib.decodeBase64)(encodedKey);
- }
-
- /**
- * Check whether the private keys exist in the local key cache.
- *
- * @param type - The type of key to get. One of "master",
- * "self_signing", or "user_signing". Optional, will check all by default.
- * @returns True if all keys are stored in the local cache.
- */
- async isStoredInKeyCache(type) {
- const cacheCallbacks = this.cacheCallbacks;
- if (!cacheCallbacks) return false;
- const types = type ? [type] : ["master", "self_signing", "user_signing"];
- for (const t of types) {
- var _cacheCallbacks$getCr;
- if (!(await ((_cacheCallbacks$getCr = cacheCallbacks.getCrossSigningKeyCache) === null || _cacheCallbacks$getCr === void 0 ? void 0 : _cacheCallbacks$getCr.call(cacheCallbacks, t)))) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Get cross-signing private keys from the local cache.
- *
- * @returns A map from key type (string) to private key (Uint8Array)
- */
- async getCrossSigningKeysFromCache() {
- const keys = new Map();
- const cacheCallbacks = this.cacheCallbacks;
- if (!cacheCallbacks) return keys;
- for (const type of ["master", "self_signing", "user_signing"]) {
- var _cacheCallbacks$getCr2;
- const privKey = await ((_cacheCallbacks$getCr2 = cacheCallbacks.getCrossSigningKeyCache) === null || _cacheCallbacks$getCr2 === void 0 ? void 0 : _cacheCallbacks$getCr2.call(cacheCallbacks, type));
- if (!privKey) {
- continue;
- }
- keys.set(type, privKey);
- }
- return keys;
- }
-
- /**
- * Get the ID used to identify the user. This can also be used to test for
- * the existence of a given key type.
- *
- * @param type - The type of key to get the ID of. One of "master",
- * "self_signing", or "user_signing". Defaults to "master".
- *
- * @returns the ID
- */
- getId(type = "master") {
- if (!this.keys[type]) return null;
- const keyInfo = this.keys[type];
- return publicKeyFromKeyInfo(keyInfo);
- }
-
- /**
- * Create new cross-signing keys for the given key types. The public keys
- * will be held in this class, while the private keys are passed off to the
- * `saveCrossSigningKeys` application callback.
- *
- * @param level - The key types to reset
- */
- async resetKeys(level) {
- if (!this.callbacks.saveCrossSigningKeys) {
- throw new Error("No saveCrossSigningKeys callback supplied");
- }
-
- // If we're resetting the master key, we reset all keys
- if (level === undefined || level & CrossSigningLevel.MASTER || !this.keys.master) {
- level = CrossSigningLevel.MASTER | CrossSigningLevel.USER_SIGNING | CrossSigningLevel.SELF_SIGNING;
- } else if (level === 0) {
- return;
- }
- const privateKeys = {};
- const keys = {};
- let masterSigning;
- let masterPub;
- try {
- if (level & CrossSigningLevel.MASTER) {
- masterSigning = new global.Olm.PkSigning();
- privateKeys.master = masterSigning.generate_seed();
- masterPub = masterSigning.init_with_seed(privateKeys.master);
- keys.master = {
- user_id: this.userId,
- usage: ["master"],
- keys: {
- ["ed25519:" + masterPub]: masterPub
- }
- };
- } else {
- [masterPub, masterSigning] = await this.getCrossSigningKey("master");
- }
- if (level & CrossSigningLevel.SELF_SIGNING) {
- const sskSigning = new global.Olm.PkSigning();
- try {
- privateKeys.self_signing = sskSigning.generate_seed();
- const sskPub = sskSigning.init_with_seed(privateKeys.self_signing);
- keys.self_signing = {
- user_id: this.userId,
- usage: ["self_signing"],
- keys: {
- ["ed25519:" + sskPub]: sskPub
- }
- };
- (0, _olmlib.pkSign)(keys.self_signing, masterSigning, this.userId, masterPub);
- } finally {
- sskSigning.free();
- }
- }
- if (level & CrossSigningLevel.USER_SIGNING) {
- const uskSigning = new global.Olm.PkSigning();
- try {
- privateKeys.user_signing = uskSigning.generate_seed();
- const uskPub = uskSigning.init_with_seed(privateKeys.user_signing);
- keys.user_signing = {
- user_id: this.userId,
- usage: ["user_signing"],
- keys: {
- ["ed25519:" + uskPub]: uskPub
- }
- };
- (0, _olmlib.pkSign)(keys.user_signing, masterSigning, this.userId, masterPub);
- } finally {
- uskSigning.free();
- }
- }
- Object.assign(this.keys, keys);
- this.callbacks.saveCrossSigningKeys(privateKeys);
- } finally {
- if (masterSigning) {
- masterSigning.free();
- }
- }
- }
-
- /**
- * unsets the keys, used when another session has reset the keys, to disable cross-signing
- */
- clearKeys() {
- this.keys = {};
- }
- setKeys(keys) {
- const signingKeys = {};
- if (keys.master) {
- if (keys.master.user_id !== this.userId) {
- const error = "Mismatched user ID " + keys.master.user_id + " in master key from " + this.userId;
- _logger.logger.error(error);
- throw new Error(error);
- }
- if (!this.keys.master) {
- // this is the first key we've seen, so first-use is true
- this.firstUse = true;
- } else if (publicKeyFromKeyInfo(keys.master) !== this.getId()) {
- // this is a different key, so first-use is false
- this.firstUse = false;
- } // otherwise, same key, so no change
- signingKeys.master = keys.master;
- } else if (this.keys.master) {
- signingKeys.master = this.keys.master;
- } else {
- throw new Error("Tried to set cross-signing keys without a master key");
- }
- const masterKey = publicKeyFromKeyInfo(signingKeys.master);
-
- // verify signatures
- if (keys.user_signing) {
- if (keys.user_signing.user_id !== this.userId) {
- const error = "Mismatched user ID " + keys.master.user_id + " in user_signing key from " + this.userId;
- _logger.logger.error(error);
- throw new Error(error);
- }
- try {
- (0, _olmlib.pkVerify)(keys.user_signing, masterKey, this.userId);
- } catch (e) {
- _logger.logger.error("invalid signature on user-signing key");
- // FIXME: what do we want to do here?
- throw e;
- }
- }
- if (keys.self_signing) {
- if (keys.self_signing.user_id !== this.userId) {
- const error = "Mismatched user ID " + keys.master.user_id + " in self_signing key from " + this.userId;
- _logger.logger.error(error);
- throw new Error(error);
- }
- try {
- (0, _olmlib.pkVerify)(keys.self_signing, masterKey, this.userId);
- } catch (e) {
- _logger.logger.error("invalid signature on self-signing key");
- // FIXME: what do we want to do here?
- throw e;
- }
- }
-
- // if everything checks out, then save the keys
- if (keys.master) {
- this.keys.master = keys.master;
- // if the master key is set, then the old self-signing and user-signing keys are obsolete
- delete this.keys["self_signing"];
- delete this.keys["user_signing"];
- }
- if (keys.self_signing) {
- this.keys.self_signing = keys.self_signing;
- }
- if (keys.user_signing) {
- this.keys.user_signing = keys.user_signing;
- }
- }
- updateCrossSigningVerifiedBefore(isCrossSigningVerified) {
- // It is critical that this value latches forward from false to true but
- // never back to false to avoid a downgrade attack.
- if (!this.crossSigningVerifiedBefore && isCrossSigningVerified) {
- this.crossSigningVerifiedBefore = true;
- }
- }
- async signObject(data, type) {
- if (!this.keys[type]) {
- throw new Error("Attempted to sign with " + type + " key but no such key present");
- }
- const [pubkey, signing] = await this.getCrossSigningKey(type);
- try {
- (0, _olmlib.pkSign)(data, signing, this.userId, pubkey);
- return data;
- } finally {
- signing.free();
- }
- }
- async signUser(key) {
- if (!this.keys.user_signing) {
- _logger.logger.info("No user signing key: not signing user");
- return;
- }
- return this.signObject(key.keys.master, "user_signing");
- }
- async signDevice(userId, device) {
- if (userId !== this.userId) {
- throw new Error(`Trying to sign ${userId}'s device; can only sign our own device`);
- }
- if (!this.keys.self_signing) {
- _logger.logger.info("No self signing key: not signing device");
- return;
- }
- return this.signObject({
- algorithms: device.algorithms,
- keys: device.keys,
- device_id: device.deviceId,
- user_id: userId
- }, "self_signing");
- }
-
- /**
- * Check whether a given user is trusted.
- *
- * @param userCrossSigning - Cross signing info for user
- *
- * @returns
- */
- checkUserTrust(userCrossSigning) {
- // if we're checking our own key, then it's trusted if the master key
- // and self-signing key match
- if (this.userId === userCrossSigning.userId && this.getId() && this.getId() === userCrossSigning.getId() && this.getId("self_signing") && this.getId("self_signing") === userCrossSigning.getId("self_signing")) {
- return new UserTrustLevel(true, true, this.firstUse);
- }
- if (!this.keys.user_signing) {
- // If there's no user signing key, they can't possibly be verified.
- // They may be TOFU trusted though.
- return new UserTrustLevel(false, false, userCrossSigning.firstUse);
- }
- let userTrusted;
- const userMaster = userCrossSigning.keys.master;
- const uskId = this.getId("user_signing");
- try {
- (0, _olmlib.pkVerify)(userMaster, uskId, this.userId);
- userTrusted = true;
- } catch (e) {
- userTrusted = false;
- }
- return new UserTrustLevel(userTrusted, userCrossSigning.crossSigningVerifiedBefore, userCrossSigning.firstUse);
- }
-
- /**
- * Check whether a given device is trusted.
- *
- * @param userCrossSigning - Cross signing info for user
- * @param device - The device to check
- * @param localTrust - Whether the device is trusted locally
- * @param trustCrossSignedDevices - Whether we trust cross signed devices
- *
- * @returns
- */
- checkDeviceTrust(userCrossSigning, device, localTrust, trustCrossSignedDevices) {
- const userTrust = this.checkUserTrust(userCrossSigning);
- const userSSK = userCrossSigning.keys.self_signing;
- if (!userSSK) {
- // if the user has no self-signing key then we cannot make any
- // trust assertions about this device from cross-signing
- return new DeviceTrustLevel(false, false, localTrust, trustCrossSignedDevices);
- }
- const deviceObj = deviceToObject(device, userCrossSigning.userId);
- try {
- // if we can verify the user's SSK from their master key...
- (0, _olmlib.pkVerify)(userSSK, userCrossSigning.getId(), userCrossSigning.userId);
- // ...and this device's key from their SSK...
- (0, _olmlib.pkVerify)(deviceObj, publicKeyFromKeyInfo(userSSK), userCrossSigning.userId);
- // ...then we trust this device as much as far as we trust the user
- return DeviceTrustLevel.fromUserTrustLevel(userTrust, localTrust, trustCrossSignedDevices);
- } catch (e) {
- return new DeviceTrustLevel(false, false, localTrust, trustCrossSignedDevices);
- }
- }
-
- /**
- * @returns Cache callbacks
- */
- getCacheCallbacks() {
- return this.cacheCallbacks;
- }
-}
-exports.CrossSigningInfo = CrossSigningInfo;
-function deviceToObject(device, userId) {
- return {
- algorithms: device.algorithms,
- keys: device.keys,
- device_id: device.deviceId,
- user_id: userId,
- signatures: device.signatures
- };
-}
-let CrossSigningLevel;
-/**
- * Represents the ways in which we trust a user
- */
-exports.CrossSigningLevel = CrossSigningLevel;
-(function (CrossSigningLevel) {
- CrossSigningLevel[CrossSigningLevel["MASTER"] = 4] = "MASTER";
- CrossSigningLevel[CrossSigningLevel["USER_SIGNING"] = 2] = "USER_SIGNING";
- CrossSigningLevel[CrossSigningLevel["SELF_SIGNING"] = 1] = "SELF_SIGNING";
-})(CrossSigningLevel || (exports.CrossSigningLevel = CrossSigningLevel = {}));
-class UserTrustLevel {
- constructor(crossSigningVerified, crossSigningVerifiedBefore, tofu) {
- this.crossSigningVerified = crossSigningVerified;
- this.crossSigningVerifiedBefore = crossSigningVerifiedBefore;
- this.tofu = tofu;
- }
-
- /**
- * @returns true if this user is verified via any means
- */
- isVerified() {
- return this.isCrossSigningVerified();
- }
-
- /**
- * @returns true if this user is verified via cross signing
- */
- isCrossSigningVerified() {
- return this.crossSigningVerified;
- }
-
- /**
- * @returns true if we ever verified this user before (at least for
- * the history of verifications observed by this device).
- */
- wasCrossSigningVerified() {
- return this.crossSigningVerifiedBefore;
- }
-
- /**
- * @returns true if this user's key is trusted on first use
- */
- isTofu() {
- return this.tofu;
- }
-}
-
-/**
- * Represents the ways in which we trust a device
- */
-exports.UserTrustLevel = UserTrustLevel;
-class DeviceTrustLevel {
- constructor(crossSigningVerified, tofu, localVerified, trustCrossSignedDevices) {
- this.crossSigningVerified = crossSigningVerified;
- this.tofu = tofu;
- this.localVerified = localVerified;
- this.trustCrossSignedDevices = trustCrossSignedDevices;
- }
- static fromUserTrustLevel(userTrustLevel, localVerified, trustCrossSignedDevices) {
- return new DeviceTrustLevel(userTrustLevel.isCrossSigningVerified(), userTrustLevel.isTofu(), localVerified, trustCrossSignedDevices);
- }
-
- /**
- * @returns true if this device is verified via any means
- */
- isVerified() {
- return Boolean(this.isLocallyVerified() || this.trustCrossSignedDevices && this.isCrossSigningVerified());
- }
-
- /**
- * @returns true if this device is verified via cross signing
- */
- isCrossSigningVerified() {
- return this.crossSigningVerified;
- }
-
- /**
- * @returns true if this device is verified locally
- */
- isLocallyVerified() {
- return this.localVerified;
- }
-
- /**
- * @returns true if this device is trusted from a user's key
- * that is trusted on first use
- */
- isTofu() {
- return this.tofu;
- }
-}
-exports.DeviceTrustLevel = DeviceTrustLevel;
-function createCryptoStoreCacheCallbacks(store, olmDevice) {
- return {
- getCrossSigningKeyCache: async function (type, _expectedPublicKey) {
- const key = await new Promise(resolve => {
- return store.doTxn("readonly", [_indexeddbCryptoStore.IndexedDBCryptoStore.STORE_ACCOUNT], txn => {
- store.getSecretStorePrivateKey(txn, resolve, type);
- });
- });
- if (key && key.ciphertext) {
- const pickleKey = Buffer.from(olmDevice.pickleKey);
- const decrypted = await (0, _aes.decryptAES)(key, pickleKey, type);
- return (0, _olmlib.decodeBase64)(decrypted);
- } else {
- return key;
- }
- },
- storeCrossSigningKeyCache: async function (type, key) {
- if (!(key instanceof Uint8Array)) {
- throw new Error(`storeCrossSigningKeyCache expects Uint8Array, got ${key}`);
- }
- const pickleKey = Buffer.from(olmDevice.pickleKey);
- const encryptedKey = await (0, _aes.encryptAES)((0, _olmlib.encodeBase64)(key), pickleKey, type);
- return store.doTxn("readwrite", [_indexeddbCryptoStore.IndexedDBCryptoStore.STORE_ACCOUNT], txn => {
- store.storeSecretStorePrivateKey(txn, type, encryptedKey);
- });
- }
- };
-}
-/**
- * Request cross-signing keys from another device during verification.
- *
- * @param baseApis - base Matrix API interface
- * @param userId - The user ID being verified
- * @param deviceId - The device ID being verified
- */
-async function requestKeysDuringVerification(baseApis, userId, deviceId) {
- // If this is a self-verification, ask the other party for keys
- if (baseApis.getUserId() !== userId) {
- return;
- }
- _logger.logger.log("Cross-signing: Self-verification done; requesting keys");
- // This happens asynchronously, and we're not concerned about waiting for
- // it. We return here in order to test.
- return new Promise((resolve, reject) => {
- const client = baseApis;
- const original = client.crypto.crossSigningInfo;
-
- // We already have all of the infrastructure we need to validate and
- // cache cross-signing keys, so instead of replicating that, here we set
- // up callbacks that request them from the other device and call
- // CrossSigningInfo.getCrossSigningKey() to validate/cache
- const crossSigning = new CrossSigningInfo(original.userId, {
- getCrossSigningKey: async type => {
- _logger.logger.debug("Cross-signing: requesting secret", type, deviceId);
- const {
- promise
- } = client.requestSecret(`m.cross_signing.${type}`, [deviceId]);
- const result = await promise;
- const decoded = (0, _olmlib.decodeBase64)(result);
- return Uint8Array.from(decoded);
- }
- }, original.getCacheCallbacks());
- crossSigning.keys = original.keys;
-
- // XXX: get all keys out if we get one key out
- // https://github.com/vector-im/element-web/issues/12604
- // then change here to reject on the timeout
- // Requests can be ignored, so don't wait around forever
- const timeout = new Promise(resolve => {
- setTimeout(resolve, KEY_REQUEST_TIMEOUT_MS, new Error("Timeout"));
- });
-
- // also request and cache the key backup key
- const backupKeyPromise = (async () => {
- const cachedKey = await client.crypto.getSessionBackupPrivateKey();
- if (!cachedKey) {
- _logger.logger.info("No cached backup key found. Requesting...");
- const secretReq = client.requestSecret("m.megolm_backup.v1", [deviceId]);
- const base64Key = await secretReq.promise;
- _logger.logger.info("Got key backup key, decoding...");
- const decodedKey = (0, _olmlib.decodeBase64)(base64Key);
- _logger.logger.info("Decoded backup key, storing...");
- await client.crypto.storeSessionBackupPrivateKey(Uint8Array.from(decodedKey));
- _logger.logger.info("Backup key stored. Starting backup restore...");
- const backupInfo = await client.getKeyBackupVersion();
- // no need to await for this - just let it go in the bg
- client.restoreKeyBackupWithCache(undefined, undefined, backupInfo).then(() => {
- _logger.logger.info("Backup restored.");
- });
- }
- })();
-
- // We call getCrossSigningKey() for its side-effects
- return Promise.race([Promise.all([crossSigning.getCrossSigningKey("master"), crossSigning.getCrossSigningKey("self_signing"), crossSigning.getCrossSigningKey("user_signing"), backupKeyPromise]), timeout]).then(resolve, reject);
- }).catch(e => {
- _logger.logger.warn("Cross-signing: failure while requesting keys:", e);
- });
-}
-//# sourceMappingURL=CrossSigning.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/CrossSigning.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/CrossSigning.js.map
deleted file mode 100644
index 8a07294..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/CrossSigning.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"CrossSigning.js","names":["_olmlib","require","_logger","_indexeddbCryptoStore","_aes","KEY_REQUEST_TIMEOUT_MS","publicKeyFromKeyInfo","keyInfo","Object","values","keys","CrossSigningInfo","constructor","userId","callbacks","cacheCallbacks","_defineProperty2","default","fromStorage","obj","res","prop","hasOwnProperty","toStorage","firstUse","crossSigningVerifiedBefore","getCrossSigningKey","type","expectedPubkey","shouldCache","indexOf","Error","undefined","getId","validateKey","key","signing","global","Olm","PkSigning","gotPubkey","init_with_seed","free","privkey","getCrossSigningKeyCache","cacheresult","result","storeCrossSigningKeyCache","isStoredInSecretStorage","secretStorage","stored","isStored","intersect","s","k","length","storeInSecretStorage","privateKey","encodedKey","encodeBase64","store","getFromSecretStorage","get","decodeBase64","isStoredInKeyCache","types","t","_cacheCallbacks$getCr","call","getCrossSigningKeysFromCache","Map","_cacheCallbacks$getCr2","privKey","set","resetKeys","level","saveCrossSigningKeys","CrossSigningLevel","MASTER","master","USER_SIGNING","SELF_SIGNING","privateKeys","masterSigning","masterPub","generate_seed","user_id","usage","sskSigning","self_signing","sskPub","pkSign","uskSigning","user_signing","uskPub","assign","clearKeys","setKeys","signingKeys","error","logger","masterKey","pkVerify","e","updateCrossSigningVerifiedBefore","isCrossSigningVerified","signObject","data","pubkey","signUser","info","signDevice","device","algorithms","device_id","deviceId","checkUserTrust","userCrossSigning","UserTrustLevel","userTrusted","userMaster","uskId","checkDeviceTrust","localTrust","trustCrossSignedDevices","userTrust","userSSK","DeviceTrustLevel","deviceObj","deviceToObject","fromUserTrustLevel","getCacheCallbacks","exports","signatures","crossSigningVerified","tofu","isVerified","wasCrossSigningVerified","isTofu","localVerified","userTrustLevel","Boolean","isLocallyVerified","createCryptoStoreCacheCallbacks","olmDevice","_expectedPublicKey","Promise","resolve","doTxn","IndexedDBCryptoStore","STORE_ACCOUNT","txn","getSecretStorePrivateKey","ciphertext","pickleKey","Buffer","from","decrypted","decryptAES","Uint8Array","encryptedKey","encryptAES","storeSecretStorePrivateKey","requestKeysDuringVerification","baseApis","getUserId","log","reject","client","original","crypto","crossSigningInfo","crossSigning","debug","promise","requestSecret","decoded","timeout","setTimeout","backupKeyPromise","cachedKey","getSessionBackupPrivateKey","secretReq","base64Key","decodedKey","storeSessionBackupPrivateKey","backupInfo","getKeyBackupVersion","restoreKeyBackupWithCache","then","race","all","catch","warn"],"sources":["../../src/crypto/CrossSigning.ts"],"sourcesContent":["/*\nCopyright 2019 - 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n/**\n * Cross signing methods\n */\n\nimport { PkSigning } from \"@matrix-org/olm\";\n\nimport { decodeBase64, encodeBase64, IObject, pkSign, pkVerify } from \"./olmlib\";\nimport { logger } from \"../logger\";\nimport { IndexedDBCryptoStore } from \"../crypto/store/indexeddb-crypto-store\";\nimport { decryptAES, encryptAES } from \"./aes\";\nimport { DeviceInfo } from \"./deviceinfo\";\nimport { SecretStorage } from \"./SecretStorage\";\nimport { ICrossSigningKey, ISignedKey, MatrixClient } from \"../client\";\nimport { OlmDevice } from \"./OlmDevice\";\nimport { ICryptoCallbacks } from \".\";\nimport { ISignatures } from \"../@types/signed\";\nimport { CryptoStore, SecretStorePrivateKeys } from \"./store/base\";\nimport { SecretStorageKeyDescription } from \"../secret-storage\";\n\nconst KEY_REQUEST_TIMEOUT_MS = 1000 * 60;\n\nfunction publicKeyFromKeyInfo(keyInfo: ICrossSigningKey): string {\n // `keys` is an object with { [`ed25519:${pubKey}`]: pubKey }\n // We assume only a single key, and we want the bare form without type\n // prefix, so we select the values.\n return Object.values(keyInfo.keys)[0];\n}\n\nexport interface ICacheCallbacks {\n getCrossSigningKeyCache?(type: string, expectedPublicKey?: string): Promise<Uint8Array | null>;\n storeCrossSigningKeyCache?(type: string, key?: Uint8Array): Promise<void>;\n}\n\nexport interface ICrossSigningInfo {\n keys: Record<string, ICrossSigningKey>;\n firstUse: boolean;\n crossSigningVerifiedBefore: boolean;\n}\n\nexport class CrossSigningInfo {\n public keys: Record<string, ICrossSigningKey> = {};\n public firstUse = true;\n // This tracks whether we've ever verified this user with any identity.\n // When you verify a user, any devices online at the time that receive\n // the verifying signature via the homeserver will latch this to true\n // and can use it in the future to detect cases where the user has\n // become unverified later for any reason.\n private crossSigningVerifiedBefore = false;\n\n /**\n * Information about a user's cross-signing keys\n *\n * @param userId - the user that the information is about\n * @param callbacks - Callbacks used to interact with the app\n * Requires getCrossSigningKey and saveCrossSigningKeys\n * @param cacheCallbacks - Callbacks used to interact with the cache\n */\n public constructor(\n public readonly userId: string,\n private callbacks: ICryptoCallbacks = {},\n private cacheCallbacks: ICacheCallbacks = {},\n ) {}\n\n public static fromStorage(obj: ICrossSigningInfo, userId: string): CrossSigningInfo {\n const res = new CrossSigningInfo(userId);\n for (const prop in obj) {\n if (obj.hasOwnProperty(prop)) {\n // @ts-ignore - ts doesn't like this and nor should we\n res[prop] = obj[prop];\n }\n }\n return res;\n }\n\n public toStorage(): ICrossSigningInfo {\n return {\n keys: this.keys,\n firstUse: this.firstUse,\n crossSigningVerifiedBefore: this.crossSigningVerifiedBefore,\n };\n }\n\n /**\n * Calls the app callback to ask for a private key\n *\n * @param type - The key type (\"master\", \"self_signing\", or \"user_signing\")\n * @param expectedPubkey - The matching public key or undefined to use\n * the stored public key for the given key type.\n * @returns An array with [ public key, Olm.PkSigning ]\n */\n public async getCrossSigningKey(type: string, expectedPubkey?: string): Promise<[string, PkSigning]> {\n const shouldCache = [\"master\", \"self_signing\", \"user_signing\"].indexOf(type) >= 0;\n\n if (!this.callbacks.getCrossSigningKey) {\n throw new Error(\"No getCrossSigningKey callback supplied\");\n }\n\n if (expectedPubkey === undefined) {\n expectedPubkey = this.getId(type)!;\n }\n\n function validateKey(key: Uint8Array | null): [string, PkSigning] | undefined {\n if (!key) return;\n const signing = new global.Olm.PkSigning();\n const gotPubkey = signing.init_with_seed(key);\n if (gotPubkey === expectedPubkey) {\n return [gotPubkey, signing];\n }\n signing.free();\n }\n\n let privkey: Uint8Array | null = null;\n if (this.cacheCallbacks.getCrossSigningKeyCache && shouldCache) {\n privkey = await this.cacheCallbacks.getCrossSigningKeyCache(type, expectedPubkey);\n }\n\n const cacheresult = validateKey(privkey);\n if (cacheresult) {\n return cacheresult;\n }\n\n privkey = await this.callbacks.getCrossSigningKey(type, expectedPubkey);\n const result = validateKey(privkey);\n if (result) {\n if (this.cacheCallbacks.storeCrossSigningKeyCache && shouldCache) {\n await this.cacheCallbacks.storeCrossSigningKeyCache(type, privkey!);\n }\n return result;\n }\n\n /* No keysource even returned a key */\n if (!privkey) {\n throw new Error(\"getCrossSigningKey callback for \" + type + \" returned falsey\");\n }\n\n /* We got some keys from the keysource, but none of them were valid */\n throw new Error(\"Key type \" + type + \" from getCrossSigningKey callback did not match\");\n }\n\n /**\n * Check whether the private keys exist in secret storage.\n * XXX: This could be static, be we often seem to have an instance when we\n * want to know this anyway...\n *\n * @param secretStorage - The secret store using account data\n * @returns map of key name to key info the secret is encrypted\n * with, or null if it is not present or not encrypted with a trusted\n * key\n */\n public async isStoredInSecretStorage(\n secretStorage: SecretStorage<MatrixClient | undefined>,\n ): Promise<Record<string, object> | null> {\n // check what SSSS keys have encrypted the master key (if any)\n const stored = (await secretStorage.isStored(\"m.cross_signing.master\")) || {};\n // then check which of those SSSS keys have also encrypted the SSK and USK\n function intersect(s: Record<string, SecretStorageKeyDescription>): void {\n for (const k of Object.keys(stored)) {\n if (!s[k]) {\n delete stored[k];\n }\n }\n }\n for (const type of [\"self_signing\", \"user_signing\"]) {\n intersect((await secretStorage.isStored(`m.cross_signing.${type}`)) || {});\n }\n return Object.keys(stored).length ? stored : null;\n }\n\n /**\n * Store private keys in secret storage for use by other devices. This is\n * typically called in conjunction with the creation of new cross-signing\n * keys.\n *\n * @param keys - The keys to store\n * @param secretStorage - The secret store using account data\n */\n public static async storeInSecretStorage(\n keys: Map<string, Uint8Array>,\n secretStorage: SecretStorage<undefined>,\n ): Promise<void> {\n for (const [type, privateKey] of keys) {\n const encodedKey = encodeBase64(privateKey);\n await secretStorage.store(`m.cross_signing.${type}`, encodedKey);\n }\n }\n\n /**\n * Get private keys from secret storage created by some other device. This\n * also passes the private keys to the app-specific callback.\n *\n * @param type - The type of key to get. One of \"master\",\n * \"self_signing\", or \"user_signing\".\n * @param secretStorage - The secret store using account data\n * @returns The private key\n */\n public static async getFromSecretStorage(type: string, secretStorage: SecretStorage): Promise<Uint8Array | null> {\n const encodedKey = await secretStorage.get(`m.cross_signing.${type}`);\n if (!encodedKey) {\n return null;\n }\n return decodeBase64(encodedKey);\n }\n\n /**\n * Check whether the private keys exist in the local key cache.\n *\n * @param type - The type of key to get. One of \"master\",\n * \"self_signing\", or \"user_signing\". Optional, will check all by default.\n * @returns True if all keys are stored in the local cache.\n */\n public async isStoredInKeyCache(type?: string): Promise<boolean> {\n const cacheCallbacks = this.cacheCallbacks;\n if (!cacheCallbacks) return false;\n const types = type ? [type] : [\"master\", \"self_signing\", \"user_signing\"];\n for (const t of types) {\n if (!(await cacheCallbacks.getCrossSigningKeyCache?.(t))) {\n return false;\n }\n }\n return true;\n }\n\n /**\n * Get cross-signing private keys from the local cache.\n *\n * @returns A map from key type (string) to private key (Uint8Array)\n */\n public async getCrossSigningKeysFromCache(): Promise<Map<string, Uint8Array>> {\n const keys = new Map();\n const cacheCallbacks = this.cacheCallbacks;\n if (!cacheCallbacks) return keys;\n for (const type of [\"master\", \"self_signing\", \"user_signing\"]) {\n const privKey = await cacheCallbacks.getCrossSigningKeyCache?.(type);\n if (!privKey) {\n continue;\n }\n keys.set(type, privKey);\n }\n return keys;\n }\n\n /**\n * Get the ID used to identify the user. This can also be used to test for\n * the existence of a given key type.\n *\n * @param type - The type of key to get the ID of. One of \"master\",\n * \"self_signing\", or \"user_signing\". Defaults to \"master\".\n *\n * @returns the ID\n */\n public getId(type = \"master\"): string | null {\n if (!this.keys[type]) return null;\n const keyInfo = this.keys[type];\n return publicKeyFromKeyInfo(keyInfo);\n }\n\n /**\n * Create new cross-signing keys for the given key types. The public keys\n * will be held in this class, while the private keys are passed off to the\n * `saveCrossSigningKeys` application callback.\n *\n * @param level - The key types to reset\n */\n public async resetKeys(level?: CrossSigningLevel): Promise<void> {\n if (!this.callbacks.saveCrossSigningKeys) {\n throw new Error(\"No saveCrossSigningKeys callback supplied\");\n }\n\n // If we're resetting the master key, we reset all keys\n if (level === undefined || level & CrossSigningLevel.MASTER || !this.keys.master) {\n level = CrossSigningLevel.MASTER | CrossSigningLevel.USER_SIGNING | CrossSigningLevel.SELF_SIGNING;\n } else if (level === (0 as CrossSigningLevel)) {\n return;\n }\n\n const privateKeys: Record<string, Uint8Array> = {};\n const keys: Record<string, ICrossSigningKey> = {};\n let masterSigning;\n let masterPub;\n\n try {\n if (level & CrossSigningLevel.MASTER) {\n masterSigning = new global.Olm.PkSigning();\n privateKeys.master = masterSigning.generate_seed();\n masterPub = masterSigning.init_with_seed(privateKeys.master);\n keys.master = {\n user_id: this.userId,\n usage: [\"master\"],\n keys: {\n [\"ed25519:\" + masterPub]: masterPub,\n },\n };\n } else {\n [masterPub, masterSigning] = await this.getCrossSigningKey(\"master\");\n }\n\n if (level & CrossSigningLevel.SELF_SIGNING) {\n const sskSigning = new global.Olm.PkSigning();\n try {\n privateKeys.self_signing = sskSigning.generate_seed();\n const sskPub = sskSigning.init_with_seed(privateKeys.self_signing);\n keys.self_signing = {\n user_id: this.userId,\n usage: [\"self_signing\"],\n keys: {\n [\"ed25519:\" + sskPub]: sskPub,\n },\n };\n pkSign(keys.self_signing, masterSigning, this.userId, masterPub);\n } finally {\n sskSigning.free();\n }\n }\n\n if (level & CrossSigningLevel.USER_SIGNING) {\n const uskSigning = new global.Olm.PkSigning();\n try {\n privateKeys.user_signing = uskSigning.generate_seed();\n const uskPub = uskSigning.init_with_seed(privateKeys.user_signing);\n keys.user_signing = {\n user_id: this.userId,\n usage: [\"user_signing\"],\n keys: {\n [\"ed25519:\" + uskPub]: uskPub,\n },\n };\n pkSign(keys.user_signing, masterSigning, this.userId, masterPub);\n } finally {\n uskSigning.free();\n }\n }\n\n Object.assign(this.keys, keys);\n this.callbacks.saveCrossSigningKeys(privateKeys);\n } finally {\n if (masterSigning) {\n masterSigning.free();\n }\n }\n }\n\n /**\n * unsets the keys, used when another session has reset the keys, to disable cross-signing\n */\n public clearKeys(): void {\n this.keys = {};\n }\n\n public setKeys(keys: Record<string, ICrossSigningKey>): void {\n const signingKeys: Record<string, ICrossSigningKey> = {};\n if (keys.master) {\n if (keys.master.user_id !== this.userId) {\n const error = \"Mismatched user ID \" + keys.master.user_id + \" in master key from \" + this.userId;\n logger.error(error);\n throw new Error(error);\n }\n if (!this.keys.master) {\n // this is the first key we've seen, so first-use is true\n this.firstUse = true;\n } else if (publicKeyFromKeyInfo(keys.master) !== this.getId()) {\n // this is a different key, so first-use is false\n this.firstUse = false;\n } // otherwise, same key, so no change\n signingKeys.master = keys.master;\n } else if (this.keys.master) {\n signingKeys.master = this.keys.master;\n } else {\n throw new Error(\"Tried to set cross-signing keys without a master key\");\n }\n const masterKey = publicKeyFromKeyInfo(signingKeys.master);\n\n // verify signatures\n if (keys.user_signing) {\n if (keys.user_signing.user_id !== this.userId) {\n const error = \"Mismatched user ID \" + keys.master.user_id + \" in user_signing key from \" + this.userId;\n logger.error(error);\n throw new Error(error);\n }\n try {\n pkVerify(keys.user_signing, masterKey, this.userId);\n } catch (e) {\n logger.error(\"invalid signature on user-signing key\");\n // FIXME: what do we want to do here?\n throw e;\n }\n }\n if (keys.self_signing) {\n if (keys.self_signing.user_id !== this.userId) {\n const error = \"Mismatched user ID \" + keys.master.user_id + \" in self_signing key from \" + this.userId;\n logger.error(error);\n throw new Error(error);\n }\n try {\n pkVerify(keys.self_signing, masterKey, this.userId);\n } catch (e) {\n logger.error(\"invalid signature on self-signing key\");\n // FIXME: what do we want to do here?\n throw e;\n }\n }\n\n // if everything checks out, then save the keys\n if (keys.master) {\n this.keys.master = keys.master;\n // if the master key is set, then the old self-signing and user-signing keys are obsolete\n delete this.keys[\"self_signing\"];\n delete this.keys[\"user_signing\"];\n }\n if (keys.self_signing) {\n this.keys.self_signing = keys.self_signing;\n }\n if (keys.user_signing) {\n this.keys.user_signing = keys.user_signing;\n }\n }\n\n public updateCrossSigningVerifiedBefore(isCrossSigningVerified: boolean): void {\n // It is critical that this value latches forward from false to true but\n // never back to false to avoid a downgrade attack.\n if (!this.crossSigningVerifiedBefore && isCrossSigningVerified) {\n this.crossSigningVerifiedBefore = true;\n }\n }\n\n public async signObject<T extends object>(data: T, type: string): Promise<T & { signatures: ISignatures }> {\n if (!this.keys[type]) {\n throw new Error(\"Attempted to sign with \" + type + \" key but no such key present\");\n }\n const [pubkey, signing] = await this.getCrossSigningKey(type);\n try {\n pkSign(data, signing, this.userId, pubkey);\n return data as T & { signatures: ISignatures };\n } finally {\n signing.free();\n }\n }\n\n public async signUser(key: CrossSigningInfo): Promise<ICrossSigningKey | undefined> {\n if (!this.keys.user_signing) {\n logger.info(\"No user signing key: not signing user\");\n return;\n }\n return this.signObject(key.keys.master, \"user_signing\");\n }\n\n public async signDevice(userId: string, device: DeviceInfo): Promise<ISignedKey | undefined> {\n if (userId !== this.userId) {\n throw new Error(`Trying to sign ${userId}'s device; can only sign our own device`);\n }\n if (!this.keys.self_signing) {\n logger.info(\"No self signing key: not signing device\");\n return;\n }\n return this.signObject<Omit<ISignedKey, \"signatures\">>(\n {\n algorithms: device.algorithms,\n keys: device.keys,\n device_id: device.deviceId,\n user_id: userId,\n },\n \"self_signing\",\n );\n }\n\n /**\n * Check whether a given user is trusted.\n *\n * @param userCrossSigning - Cross signing info for user\n *\n * @returns\n */\n public checkUserTrust(userCrossSigning: CrossSigningInfo): UserTrustLevel {\n // if we're checking our own key, then it's trusted if the master key\n // and self-signing key match\n if (\n this.userId === userCrossSigning.userId &&\n this.getId() &&\n this.getId() === userCrossSigning.getId() &&\n this.getId(\"self_signing\") &&\n this.getId(\"self_signing\") === userCrossSigning.getId(\"self_signing\")\n ) {\n return new UserTrustLevel(true, true, this.firstUse);\n }\n\n if (!this.keys.user_signing) {\n // If there's no user signing key, they can't possibly be verified.\n // They may be TOFU trusted though.\n return new UserTrustLevel(false, false, userCrossSigning.firstUse);\n }\n\n let userTrusted: boolean;\n const userMaster = userCrossSigning.keys.master;\n const uskId = this.getId(\"user_signing\")!;\n try {\n pkVerify(userMaster, uskId, this.userId);\n userTrusted = true;\n } catch (e) {\n userTrusted = false;\n }\n return new UserTrustLevel(userTrusted, userCrossSigning.crossSigningVerifiedBefore, userCrossSigning.firstUse);\n }\n\n /**\n * Check whether a given device is trusted.\n *\n * @param userCrossSigning - Cross signing info for user\n * @param device - The device to check\n * @param localTrust - Whether the device is trusted locally\n * @param trustCrossSignedDevices - Whether we trust cross signed devices\n *\n * @returns\n */\n public checkDeviceTrust(\n userCrossSigning: CrossSigningInfo,\n device: DeviceInfo,\n localTrust: boolean,\n trustCrossSignedDevices: boolean,\n ): DeviceTrustLevel {\n const userTrust = this.checkUserTrust(userCrossSigning);\n\n const userSSK = userCrossSigning.keys.self_signing;\n if (!userSSK) {\n // if the user has no self-signing key then we cannot make any\n // trust assertions about this device from cross-signing\n return new DeviceTrustLevel(false, false, localTrust, trustCrossSignedDevices);\n }\n\n const deviceObj = deviceToObject(device, userCrossSigning.userId);\n try {\n // if we can verify the user's SSK from their master key...\n pkVerify(userSSK, userCrossSigning.getId()!, userCrossSigning.userId);\n // ...and this device's key from their SSK...\n pkVerify(deviceObj, publicKeyFromKeyInfo(userSSK), userCrossSigning.userId);\n // ...then we trust this device as much as far as we trust the user\n return DeviceTrustLevel.fromUserTrustLevel(userTrust, localTrust, trustCrossSignedDevices);\n } catch (e) {\n return new DeviceTrustLevel(false, false, localTrust, trustCrossSignedDevices);\n }\n }\n\n /**\n * @returns Cache callbacks\n */\n public getCacheCallbacks(): ICacheCallbacks {\n return this.cacheCallbacks;\n }\n}\n\ninterface DeviceObject extends IObject {\n algorithms: string[];\n keys: Record<string, string>;\n device_id: string;\n user_id: string;\n}\n\nfunction deviceToObject(device: DeviceInfo, userId: string): DeviceObject {\n return {\n algorithms: device.algorithms,\n keys: device.keys,\n device_id: device.deviceId,\n user_id: userId,\n signatures: device.signatures,\n };\n}\n\nexport enum CrossSigningLevel {\n MASTER = 4,\n USER_SIGNING = 2,\n SELF_SIGNING = 1,\n}\n\n/**\n * Represents the ways in which we trust a user\n */\nexport class UserTrustLevel {\n public constructor(\n private readonly crossSigningVerified: boolean,\n private readonly crossSigningVerifiedBefore: boolean,\n private readonly tofu: boolean,\n ) {}\n\n /**\n * @returns true if this user is verified via any means\n */\n public isVerified(): boolean {\n return this.isCrossSigningVerified();\n }\n\n /**\n * @returns true if this user is verified via cross signing\n */\n public isCrossSigningVerified(): boolean {\n return this.crossSigningVerified;\n }\n\n /**\n * @returns true if we ever verified this user before (at least for\n * the history of verifications observed by this device).\n */\n public wasCrossSigningVerified(): boolean {\n return this.crossSigningVerifiedBefore;\n }\n\n /**\n * @returns true if this user's key is trusted on first use\n */\n public isTofu(): boolean {\n return this.tofu;\n }\n}\n\n/**\n * Represents the ways in which we trust a device\n */\nexport class DeviceTrustLevel {\n public constructor(\n public readonly crossSigningVerified: boolean,\n public readonly tofu: boolean,\n private readonly localVerified: boolean,\n private readonly trustCrossSignedDevices: boolean,\n ) {}\n\n public static fromUserTrustLevel(\n userTrustLevel: UserTrustLevel,\n localVerified: boolean,\n trustCrossSignedDevices: boolean,\n ): DeviceTrustLevel {\n return new DeviceTrustLevel(\n userTrustLevel.isCrossSigningVerified(),\n userTrustLevel.isTofu(),\n localVerified,\n trustCrossSignedDevices,\n );\n }\n\n /**\n * @returns true if this device is verified via any means\n */\n public isVerified(): boolean {\n return Boolean(this.isLocallyVerified() || (this.trustCrossSignedDevices && this.isCrossSigningVerified()));\n }\n\n /**\n * @returns true if this device is verified via cross signing\n */\n public isCrossSigningVerified(): boolean {\n return this.crossSigningVerified;\n }\n\n /**\n * @returns true if this device is verified locally\n */\n public isLocallyVerified(): boolean {\n return this.localVerified;\n }\n\n /**\n * @returns true if this device is trusted from a user's key\n * that is trusted on first use\n */\n public isTofu(): boolean {\n return this.tofu;\n }\n}\n\nexport function createCryptoStoreCacheCallbacks(store: CryptoStore, olmDevice: OlmDevice): ICacheCallbacks {\n return {\n getCrossSigningKeyCache: async function (\n type: keyof SecretStorePrivateKeys,\n _expectedPublicKey: string,\n ): Promise<Uint8Array> {\n const key = await new Promise<any>((resolve) => {\n return store.doTxn(\"readonly\", [IndexedDBCryptoStore.STORE_ACCOUNT], (txn) => {\n store.getSecretStorePrivateKey(txn, resolve, type);\n });\n });\n\n if (key && key.ciphertext) {\n const pickleKey = Buffer.from(olmDevice.pickleKey);\n const decrypted = await decryptAES(key, pickleKey, type);\n return decodeBase64(decrypted);\n } else {\n return key;\n }\n },\n storeCrossSigningKeyCache: async function (\n type: keyof SecretStorePrivateKeys,\n key?: Uint8Array,\n ): Promise<void> {\n if (!(key instanceof Uint8Array)) {\n throw new Error(`storeCrossSigningKeyCache expects Uint8Array, got ${key}`);\n }\n const pickleKey = Buffer.from(olmDevice.pickleKey);\n const encryptedKey = await encryptAES(encodeBase64(key), pickleKey, type);\n return store.doTxn(\"readwrite\", [IndexedDBCryptoStore.STORE_ACCOUNT], (txn) => {\n store.storeSecretStorePrivateKey(txn, type, encryptedKey);\n });\n },\n };\n}\n\nexport type KeysDuringVerification = [[string, PkSigning], [string, PkSigning], [string, PkSigning], void];\n\n/**\n * Request cross-signing keys from another device during verification.\n *\n * @param baseApis - base Matrix API interface\n * @param userId - The user ID being verified\n * @param deviceId - The device ID being verified\n */\nexport async function requestKeysDuringVerification(\n baseApis: MatrixClient,\n userId: string,\n deviceId: string,\n): Promise<KeysDuringVerification | void> {\n // If this is a self-verification, ask the other party for keys\n if (baseApis.getUserId() !== userId) {\n return;\n }\n logger.log(\"Cross-signing: Self-verification done; requesting keys\");\n // This happens asynchronously, and we're not concerned about waiting for\n // it. We return here in order to test.\n return new Promise<KeysDuringVerification | void>((resolve, reject) => {\n const client = baseApis;\n const original = client.crypto!.crossSigningInfo;\n\n // We already have all of the infrastructure we need to validate and\n // cache cross-signing keys, so instead of replicating that, here we set\n // up callbacks that request them from the other device and call\n // CrossSigningInfo.getCrossSigningKey() to validate/cache\n const crossSigning = new CrossSigningInfo(\n original.userId,\n {\n getCrossSigningKey: async (type): Promise<Uint8Array> => {\n logger.debug(\"Cross-signing: requesting secret\", type, deviceId);\n const { promise } = client.requestSecret(`m.cross_signing.${type}`, [deviceId]);\n const result = await promise;\n const decoded = decodeBase64(result);\n return Uint8Array.from(decoded);\n },\n },\n original.getCacheCallbacks(),\n );\n crossSigning.keys = original.keys;\n\n // XXX: get all keys out if we get one key out\n // https://github.com/vector-im/element-web/issues/12604\n // then change here to reject on the timeout\n // Requests can be ignored, so don't wait around forever\n const timeout = new Promise<void>((resolve) => {\n setTimeout(resolve, KEY_REQUEST_TIMEOUT_MS, new Error(\"Timeout\"));\n });\n\n // also request and cache the key backup key\n const backupKeyPromise = (async (): Promise<void> => {\n const cachedKey = await client.crypto!.getSessionBackupPrivateKey();\n if (!cachedKey) {\n logger.info(\"No cached backup key found. Requesting...\");\n const secretReq = client.requestSecret(\"m.megolm_backup.v1\", [deviceId]);\n const base64Key = await secretReq.promise;\n logger.info(\"Got key backup key, decoding...\");\n const decodedKey = decodeBase64(base64Key);\n logger.info(\"Decoded backup key, storing...\");\n await client.crypto!.storeSessionBackupPrivateKey(Uint8Array.from(decodedKey));\n logger.info(\"Backup key stored. Starting backup restore...\");\n const backupInfo = await client.getKeyBackupVersion();\n // no need to await for this - just let it go in the bg\n client.restoreKeyBackupWithCache(undefined, undefined, backupInfo!).then(() => {\n logger.info(\"Backup restored.\");\n });\n }\n })();\n\n // We call getCrossSigningKey() for its side-effects\n return Promise.race<KeysDuringVerification | void>([\n Promise.all([\n crossSigning.getCrossSigningKey(\"master\"),\n crossSigning.getCrossSigningKey(\"self_signing\"),\n crossSigning.getCrossSigningKey(\"user_signing\"),\n backupKeyPromise,\n ]) as Promise<KeysDuringVerification>,\n timeout,\n ]).then(resolve, reject);\n }).catch((e) => {\n logger.warn(\"Cross-signing: failure while requesting keys:\", e);\n });\n}\n"],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/DeviceList.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/DeviceList.d.ts
deleted file mode 100644
index 6c124fa..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/DeviceList.d.ts
+++ /dev/null
@@ -1,216 +0,0 @@
-import { DeviceInfo, IDevice } from "./deviceinfo";
-import { CrossSigningInfo, ICrossSigningInfo } from "./CrossSigning";
-import { MatrixClient } from "../client";
-import { OlmDevice } from "./OlmDevice";
-import { CryptoStore } from "./store/base";
-import { TypedEventEmitter } from "../models/typed-event-emitter";
-import { CryptoEvent, CryptoEventHandlerMap } from "./index";
-export declare enum TrackingStatus {
- NotTracked = 0,
- PendingDownload = 1,
- DownloadInProgress = 2,
- UpToDate = 3
-}
-export type DeviceInfoMap = Map<string, Map<string, DeviceInfo>>;
-type EmittedEvents = CryptoEvent.WillUpdateDevices | CryptoEvent.DevicesUpdated | CryptoEvent.UserCrossSigningUpdated;
-export declare class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHandlerMap> {
- private readonly cryptoStore;
- readonly keyDownloadChunkSize: number;
- private devices;
- crossSigningInfo: {
- [userId: string]: ICrossSigningInfo;
- };
- private userByIdentityKey;
- private deviceTrackingStatus;
- private syncToken;
- private keyDownloadsInProgressByUser;
- private dirty;
- private savePromise;
- private resolveSavePromise;
- private savePromiseTime;
- private saveTimer;
- private hasFetched;
- private readonly serialiser;
- constructor(baseApis: MatrixClient, cryptoStore: CryptoStore, olmDevice: OlmDevice, keyDownloadChunkSize?: number);
- /**
- * Load the device tracking state from storage
- */
- load(): Promise<void>;
- stop(): void;
- /**
- * Save the device tracking state to storage, if any changes are
- * pending other than updating the sync token
- *
- * The actual save will be delayed by a short amount of time to
- * aggregate multiple writes to the database.
- *
- * @param delay - Time in ms before which the save actually happens.
- * By default, the save is delayed for a short period in order to batch
- * multiple writes, but this behaviour can be disabled by passing 0.
- *
- * @returns true if the data was saved, false if
- * it was not (eg. because no changes were pending). The promise
- * will only resolve once the data is saved, so may take some time
- * to resolve.
- */
- saveIfDirty(delay?: number): Promise<boolean>;
- /**
- * Gets the sync token last set with setSyncToken
- *
- * @returns The sync token
- */
- getSyncToken(): string | null;
- /**
- * Sets the sync token that the app will pass as the 'since' to the /sync
- * endpoint next time it syncs.
- * The sync token must always be set after any changes made as a result of
- * data in that sync since setting the sync token to a newer one will mean
- * those changed will not be synced from the server if a new client starts
- * up with that data.
- *
- * @param st - The sync token
- */
- setSyncToken(st: string | null): void;
- /**
- * Ensures up to date keys for a list of users are stored in the session store,
- * downloading and storing them if they're not (or if forceDownload is
- * true).
- * @param userIds - The users to fetch.
- * @param forceDownload - Always download the keys even if cached.
- *
- * @returns A promise which resolves to a map userId-\>deviceId-\>{@link DeviceInfo}.
- */
- downloadKeys(userIds: string[], forceDownload: boolean): Promise<DeviceInfoMap>;
- /**
- * Get the stored device keys for a list of user ids
- *
- * @param userIds - the list of users to list keys for.
- *
- * @returns userId-\>deviceId-\>{@link DeviceInfo}.
- */
- private getDevicesFromStore;
- /**
- * Returns a list of all user IDs the DeviceList knows about
- *
- * @returns All known user IDs
- */
- getKnownUserIds(): string[];
- /**
- * Get the stored device keys for a user id
- *
- * @param userId - the user to list keys for.
- *
- * @returns list of devices, or null if we haven't
- * managed to get a list of devices for this user yet.
- */
- getStoredDevicesForUser(userId: string): DeviceInfo[] | null;
- /**
- * Get the stored device data for a user, in raw object form
- *
- * @param userId - the user to get data for
- *
- * @returns `deviceId->{object}` devices, or undefined if
- * there is no data for this user.
- */
- getRawStoredDevicesForUser(userId: string): Record<string, IDevice>;
- getStoredCrossSigningForUser(userId: string): CrossSigningInfo | null;
- storeCrossSigningForUser(userId: string, info: ICrossSigningInfo): void;
- /**
- * Get the stored keys for a single device
- *
- *
- * @returns device, or undefined
- * if we don't know about this device
- */
- getStoredDevice(userId: string, deviceId: string): DeviceInfo | undefined;
- /**
- * Get a user ID by one of their device's curve25519 identity key
- *
- * @param algorithm - encryption algorithm
- * @param senderKey - curve25519 key to match
- *
- * @returns user ID
- */
- getUserByIdentityKey(algorithm: string, senderKey: string): string | null;
- /**
- * Find a device by curve25519 identity key
- *
- * @param algorithm - encryption algorithm
- * @param senderKey - curve25519 key to match
- */
- getDeviceByIdentityKey(algorithm: string, senderKey: string): DeviceInfo | null;
- /**
- * Replaces the list of devices for a user with the given device list
- *
- * @param userId - The user ID
- * @param devices - New device info for user
- */
- storeDevicesForUser(userId: string, devices: Record<string, IDevice>): void;
- /**
- * flag the given user for device-list tracking, if they are not already.
- *
- * This will mean that a subsequent call to refreshOutdatedDeviceLists()
- * will download the device list for the user, and that subsequent calls to
- * invalidateUserDeviceList will trigger more updates.
- *
- */
- startTrackingDeviceList(userId: string): void;
- /**
- * Mark the given user as no longer being tracked for device-list updates.
- *
- * This won't affect any in-progress downloads, which will still go on to
- * complete; it will just mean that we don't think that we have an up-to-date
- * list for future calls to downloadKeys.
- *
- */
- stopTrackingDeviceList(userId: string): void;
- /**
- * Set all users we're currently tracking to untracked
- *
- * This will flag each user whose devices we are tracking as in need of an
- * update.
- */
- stopTrackingAllDeviceLists(): void;
- /**
- * Mark the cached device list for the given user outdated.
- *
- * If we are not tracking this user's devices, we'll do nothing. Otherwise
- * we flag the user as needing an update.
- *
- * This doesn't actually set off an update, so that several users can be
- * batched together. Call refreshOutdatedDeviceLists() for that.
- *
- */
- invalidateUserDeviceList(userId: string): void;
- /**
- * If we have users who have outdated device lists, start key downloads for them
- *
- * @returns which completes when the download completes; normally there
- * is no need to wait for this (it's mostly for the unit tests).
- */
- refreshOutdatedDeviceLists(): Promise<void>;
- /**
- * Set the stored device data for a user, in raw object form
- * Used only by internal class DeviceListUpdateSerialiser
- *
- * @param userId - the user to get data for
- *
- * @param devices - `deviceId->{object}` the new devices
- */
- setRawStoredDevicesForUser(userId: string, devices: Record<string, IDevice>): void;
- setRawStoredCrossSigningForUser(userId: string, info: ICrossSigningInfo): void;
- /**
- * Fire off download update requests for the given users, and update the
- * device list tracking status for them, and the
- * keyDownloadsInProgressByUser map for them.
- *
- * @param users - list of userIds
- *
- * @returns resolves when all the users listed have
- * been updated. rejects if there was a problem updating any of the
- * users.
- */
- private doKeyDownload;
-}
-export {};
-//# sourceMappingURL=DeviceList.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/DeviceList.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/DeviceList.d.ts.map
deleted file mode 100644
index 9c1e98e..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/DeviceList.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"DeviceList.d.ts","sourceRoot":"","sources":["../../src/crypto/DeviceList.ts"],"names":[],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/DeviceList.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/DeviceList.js
deleted file mode 100644
index bdf90a3..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/DeviceList.js
+++ /dev/null
@@ -1,877 +0,0 @@
-"use strict";
-
-var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.TrackingStatus = exports.DeviceList = void 0;
-var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
-var _logger = require("../logger");
-var _deviceinfo = require("./deviceinfo");
-var _CrossSigning = require("./CrossSigning");
-var olmlib = _interopRequireWildcard(require("./olmlib"));
-var _indexeddbCryptoStore = require("./store/indexeddb-crypto-store");
-var _utils = require("../utils");
-var _typedEventEmitter = require("../models/typed-event-emitter");
-var _index = require("./index");
-function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
-function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
-/*
-Copyright 2017 - 2021 The Matrix.org Foundation C.I.C.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-/**
- * Manages the list of other users' devices
- */
-/* State transition diagram for DeviceList.deviceTrackingStatus
- *
- * |
- * stopTrackingDeviceList V
- * +---------------------> NOT_TRACKED
- * | |
- * +<--------------------+ | startTrackingDeviceList
- * | | V
- * | +-------------> PENDING_DOWNLOAD <--------------------+-+
- * | | ^ | | |
- * | | restart download | | start download | | invalidateUserDeviceList
- * | | client failed | | | |
- * | | | V | |
- * | +------------ DOWNLOAD_IN_PROGRESS -------------------+ |
- * | | | |
- * +<-------------------+ | download successful |
- * ^ V |
- * +----------------------- UP_TO_DATE ------------------------+
- */
-// constants for DeviceList.deviceTrackingStatus
-let TrackingStatus; // user-Id → device-Id → DeviceInfo
-exports.TrackingStatus = TrackingStatus;
-(function (TrackingStatus) {
- TrackingStatus[TrackingStatus["NotTracked"] = 0] = "NotTracked";
- TrackingStatus[TrackingStatus["PendingDownload"] = 1] = "PendingDownload";
- TrackingStatus[TrackingStatus["DownloadInProgress"] = 2] = "DownloadInProgress";
- TrackingStatus[TrackingStatus["UpToDate"] = 3] = "UpToDate";
-})(TrackingStatus || (exports.TrackingStatus = TrackingStatus = {}));
-class DeviceList extends _typedEventEmitter.TypedEventEmitter {
- // map of identity keys to the user who owns it
-
- // which users we are tracking device status for.
- // loaded from storage in load()
-
- // The 'next_batch' sync token at the point the data was written,
- // ie. a token representing the point immediately after the
- // moment represented by the snapshot in the db.
-
- // Set whenever changes are made other than setting the sync token
-
- // Promise resolved when device data is saved
-
- // Function that resolves the save promise
-
- // The time the save is scheduled for
-
- // The timer used to delay the save
-
- // True if we have fetched data from the server or loaded a non-empty
- // set of device data from the store
-
- constructor(baseApis, cryptoStore, olmDevice,
- // Maximum number of user IDs per request to prevent server overload (#1619)
- keyDownloadChunkSize = 250) {
- super();
- this.cryptoStore = cryptoStore;
- this.keyDownloadChunkSize = keyDownloadChunkSize;
- (0, _defineProperty2.default)(this, "devices", {});
- (0, _defineProperty2.default)(this, "crossSigningInfo", {});
- (0, _defineProperty2.default)(this, "userByIdentityKey", {});
- (0, _defineProperty2.default)(this, "deviceTrackingStatus", {});
- (0, _defineProperty2.default)(this, "syncToken", null);
- (0, _defineProperty2.default)(this, "keyDownloadsInProgressByUser", new Map());
- (0, _defineProperty2.default)(this, "dirty", false);
- (0, _defineProperty2.default)(this, "savePromise", null);
- (0, _defineProperty2.default)(this, "resolveSavePromise", null);
- (0, _defineProperty2.default)(this, "savePromiseTime", null);
- (0, _defineProperty2.default)(this, "saveTimer", null);
- (0, _defineProperty2.default)(this, "hasFetched", null);
- (0, _defineProperty2.default)(this, "serialiser", void 0);
- this.serialiser = new DeviceListUpdateSerialiser(baseApis, olmDevice, this);
- }
-
- /**
- * Load the device tracking state from storage
- */
- async load() {
- await this.cryptoStore.doTxn("readonly", [_indexeddbCryptoStore.IndexedDBCryptoStore.STORE_DEVICE_DATA], txn => {
- this.cryptoStore.getEndToEndDeviceData(txn, deviceData => {
- var _deviceData$syncToken;
- this.hasFetched = Boolean(deviceData && deviceData.devices);
- this.devices = deviceData ? deviceData.devices : {};
- this.crossSigningInfo = deviceData ? deviceData.crossSigningInfo || {} : {};
- this.deviceTrackingStatus = deviceData ? deviceData.trackingStatus : {};
- this.syncToken = (_deviceData$syncToken = deviceData === null || deviceData === void 0 ? void 0 : deviceData.syncToken) !== null && _deviceData$syncToken !== void 0 ? _deviceData$syncToken : null;
- this.userByIdentityKey = {};
- for (const user of Object.keys(this.devices)) {
- const userDevices = this.devices[user];
- for (const device of Object.keys(userDevices)) {
- const idKey = userDevices[device].keys["curve25519:" + device];
- if (idKey !== undefined) {
- this.userByIdentityKey[idKey] = user;
- }
- }
- }
- });
- });
- for (const u of Object.keys(this.deviceTrackingStatus)) {
- // if a download was in progress when we got shut down, it isn't any more.
- if (this.deviceTrackingStatus[u] == TrackingStatus.DownloadInProgress) {
- this.deviceTrackingStatus[u] = TrackingStatus.PendingDownload;
- }
- }
- }
- stop() {
- if (this.saveTimer !== null) {
- clearTimeout(this.saveTimer);
- }
- }
-
- /**
- * Save the device tracking state to storage, if any changes are
- * pending other than updating the sync token
- *
- * The actual save will be delayed by a short amount of time to
- * aggregate multiple writes to the database.
- *
- * @param delay - Time in ms before which the save actually happens.
- * By default, the save is delayed for a short period in order to batch
- * multiple writes, but this behaviour can be disabled by passing 0.
- *
- * @returns true if the data was saved, false if
- * it was not (eg. because no changes were pending). The promise
- * will only resolve once the data is saved, so may take some time
- * to resolve.
- */
- async saveIfDirty(delay = 500) {
- if (!this.dirty) return Promise.resolve(false);
- // Delay saves for a bit so we can aggregate multiple saves that happen
- // in quick succession (eg. when a whole room's devices are marked as known)
-
- const targetTime = Date.now() + delay;
- if (this.savePromiseTime && targetTime < this.savePromiseTime) {
- // There's a save scheduled but for after we would like: cancel
- // it & schedule one for the time we want
- clearTimeout(this.saveTimer);
- this.saveTimer = null;
- this.savePromiseTime = null;
- // (but keep the save promise since whatever called save before
- // will still want to know when the save is done)
- }
-
- let savePromise = this.savePromise;
- if (savePromise === null) {
- savePromise = new Promise(resolve => {
- this.resolveSavePromise = resolve;
- });
- this.savePromise = savePromise;
- }
- if (this.saveTimer === null) {
- const resolveSavePromise = this.resolveSavePromise;
- this.savePromiseTime = targetTime;
- this.saveTimer = setTimeout(() => {
- _logger.logger.log("Saving device tracking data", this.syncToken);
-
- // null out savePromise now (after the delay but before the write),
- // otherwise we could return the existing promise when the save has
- // actually already happened.
- this.savePromiseTime = null;
- this.saveTimer = null;
- this.savePromise = null;
- this.resolveSavePromise = null;
- this.cryptoStore.doTxn("readwrite", [_indexeddbCryptoStore.IndexedDBCryptoStore.STORE_DEVICE_DATA], txn => {
- var _this$syncToken;
- this.cryptoStore.storeEndToEndDeviceData({
- devices: this.devices,
- crossSigningInfo: this.crossSigningInfo,
- trackingStatus: this.deviceTrackingStatus,
- syncToken: (_this$syncToken = this.syncToken) !== null && _this$syncToken !== void 0 ? _this$syncToken : undefined
- }, txn);
- }).then(() => {
- // The device list is considered dirty until the write completes.
- this.dirty = false;
- resolveSavePromise === null || resolveSavePromise === void 0 ? void 0 : resolveSavePromise(true);
- }, err => {
- _logger.logger.error("Failed to save device tracking data", this.syncToken);
- _logger.logger.error(err);
- });
- }, delay);
- }
- return savePromise;
- }
-
- /**
- * Gets the sync token last set with setSyncToken
- *
- * @returns The sync token
- */
- getSyncToken() {
- return this.syncToken;
- }
-
- /**
- * Sets the sync token that the app will pass as the 'since' to the /sync
- * endpoint next time it syncs.
- * The sync token must always be set after any changes made as a result of
- * data in that sync since setting the sync token to a newer one will mean
- * those changed will not be synced from the server if a new client starts
- * up with that data.
- *
- * @param st - The sync token
- */
- setSyncToken(st) {
- this.syncToken = st;
- }
-
- /**
- * Ensures up to date keys for a list of users are stored in the session store,
- * downloading and storing them if they're not (or if forceDownload is
- * true).
- * @param userIds - The users to fetch.
- * @param forceDownload - Always download the keys even if cached.
- *
- * @returns A promise which resolves to a map userId-\>deviceId-\>{@link DeviceInfo}.
- */
- downloadKeys(userIds, forceDownload) {
- const usersToDownload = [];
- const promises = [];
- userIds.forEach(u => {
- const trackingStatus = this.deviceTrackingStatus[u];
- if (this.keyDownloadsInProgressByUser.has(u)) {
- // already a key download in progress/queued for this user; its results
- // will be good enough for us.
- _logger.logger.log(`downloadKeys: already have a download in progress for ` + `${u}: awaiting its result`);
- promises.push(this.keyDownloadsInProgressByUser.get(u));
- } else if (forceDownload || trackingStatus != TrackingStatus.UpToDate) {
- usersToDownload.push(u);
- }
- });
- if (usersToDownload.length != 0) {
- _logger.logger.log("downloadKeys: downloading for", usersToDownload);
- const downloadPromise = this.doKeyDownload(usersToDownload);
- promises.push(downloadPromise);
- }
- if (promises.length === 0) {
- _logger.logger.log("downloadKeys: already have all necessary keys");
- }
- return Promise.all(promises).then(() => {
- return this.getDevicesFromStore(userIds);
- });
- }
-
- /**
- * Get the stored device keys for a list of user ids
- *
- * @param userIds - the list of users to list keys for.
- *
- * @returns userId-\>deviceId-\>{@link DeviceInfo}.
- */
- getDevicesFromStore(userIds) {
- const stored = new Map();
- userIds.forEach(userId => {
- var _this$getStoredDevice;
- const deviceMap = new Map();
- (_this$getStoredDevice = this.getStoredDevicesForUser(userId)) === null || _this$getStoredDevice === void 0 ? void 0 : _this$getStoredDevice.forEach(function (device) {
- deviceMap.set(device.deviceId, device);
- });
- stored.set(userId, deviceMap);
- });
- return stored;
- }
-
- /**
- * Returns a list of all user IDs the DeviceList knows about
- *
- * @returns All known user IDs
- */
- getKnownUserIds() {
- return Object.keys(this.devices);
- }
-
- /**
- * Get the stored device keys for a user id
- *
- * @param userId - the user to list keys for.
- *
- * @returns list of devices, or null if we haven't
- * managed to get a list of devices for this user yet.
- */
- getStoredDevicesForUser(userId) {
- const devs = this.devices[userId];
- if (!devs) {
- return null;
- }
- const res = [];
- for (const deviceId in devs) {
- if (devs.hasOwnProperty(deviceId)) {
- res.push(_deviceinfo.DeviceInfo.fromStorage(devs[deviceId], deviceId));
- }
- }
- return res;
- }
-
- /**
- * Get the stored device data for a user, in raw object form
- *
- * @param userId - the user to get data for
- *
- * @returns `deviceId->{object}` devices, or undefined if
- * there is no data for this user.
- */
- getRawStoredDevicesForUser(userId) {
- return this.devices[userId];
- }
- getStoredCrossSigningForUser(userId) {
- if (!this.crossSigningInfo[userId]) return null;
- return _CrossSigning.CrossSigningInfo.fromStorage(this.crossSigningInfo[userId], userId);
- }
- storeCrossSigningForUser(userId, info) {
- this.crossSigningInfo[userId] = info;
- this.dirty = true;
- }
-
- /**
- * Get the stored keys for a single device
- *
- *
- * @returns device, or undefined
- * if we don't know about this device
- */
- getStoredDevice(userId, deviceId) {
- const devs = this.devices[userId];
- if (!(devs !== null && devs !== void 0 && devs[deviceId])) {
- return undefined;
- }
- return _deviceinfo.DeviceInfo.fromStorage(devs[deviceId], deviceId);
- }
-
- /**
- * Get a user ID by one of their device's curve25519 identity key
- *
- * @param algorithm - encryption algorithm
- * @param senderKey - curve25519 key to match
- *
- * @returns user ID
- */
- getUserByIdentityKey(algorithm, senderKey) {
- if (algorithm !== olmlib.OLM_ALGORITHM && algorithm !== olmlib.MEGOLM_ALGORITHM) {
- // we only deal in olm keys
- return null;
- }
- return this.userByIdentityKey[senderKey];
- }
-
- /**
- * Find a device by curve25519 identity key
- *
- * @param algorithm - encryption algorithm
- * @param senderKey - curve25519 key to match
- */
- getDeviceByIdentityKey(algorithm, senderKey) {
- const userId = this.getUserByIdentityKey(algorithm, senderKey);
- if (!userId) {
- return null;
- }
- const devices = this.devices[userId];
- if (!devices) {
- return null;
- }
- for (const deviceId in devices) {
- if (!devices.hasOwnProperty(deviceId)) {
- continue;
- }
- const device = devices[deviceId];
- for (const keyId in device.keys) {
- if (!device.keys.hasOwnProperty(keyId)) {
- continue;
- }
- if (keyId.indexOf("curve25519:") !== 0) {
- continue;
- }
- const deviceKey = device.keys[keyId];
- if (deviceKey == senderKey) {
- return _deviceinfo.DeviceInfo.fromStorage(device, deviceId);
- }
- }
- }
-
- // doesn't match a known device
- return null;
- }
-
- /**
- * Replaces the list of devices for a user with the given device list
- *
- * @param userId - The user ID
- * @param devices - New device info for user
- */
- storeDevicesForUser(userId, devices) {
- this.setRawStoredDevicesForUser(userId, devices);
- this.dirty = true;
- }
-
- /**
- * flag the given user for device-list tracking, if they are not already.
- *
- * This will mean that a subsequent call to refreshOutdatedDeviceLists()
- * will download the device list for the user, and that subsequent calls to
- * invalidateUserDeviceList will trigger more updates.
- *
- */
- startTrackingDeviceList(userId) {
- // sanity-check the userId. This is mostly paranoia, but if synapse
- // can't parse the userId we give it as an mxid, it 500s the whole
- // request and we can never update the device lists again (because
- // the broken userId is always 'invalid' and always included in any
- // refresh request).
- // By checking it is at least a string, we can eliminate a class of
- // silly errors.
- if (typeof userId !== "string") {
- throw new Error("userId must be a string; was " + userId);
- }
- if (!this.deviceTrackingStatus[userId]) {
- _logger.logger.log("Now tracking device list for " + userId);
- this.deviceTrackingStatus[userId] = TrackingStatus.PendingDownload;
- // we don't yet persist the tracking status, since there may be a lot
- // of calls; we save all data together once the sync is done
- this.dirty = true;
- }
- }
-
- /**
- * Mark the given user as no longer being tracked for device-list updates.
- *
- * This won't affect any in-progress downloads, which will still go on to
- * complete; it will just mean that we don't think that we have an up-to-date
- * list for future calls to downloadKeys.
- *
- */
- stopTrackingDeviceList(userId) {
- if (this.deviceTrackingStatus[userId]) {
- _logger.logger.log("No longer tracking device list for " + userId);
- this.deviceTrackingStatus[userId] = TrackingStatus.NotTracked;
-
- // we don't yet persist the tracking status, since there may be a lot
- // of calls; we save all data together once the sync is done
- this.dirty = true;
- }
- }
-
- /**
- * Set all users we're currently tracking to untracked
- *
- * This will flag each user whose devices we are tracking as in need of an
- * update.
- */
- stopTrackingAllDeviceLists() {
- for (const userId of Object.keys(this.deviceTrackingStatus)) {
- this.deviceTrackingStatus[userId] = TrackingStatus.NotTracked;
- }
- this.dirty = true;
- }
-
- /**
- * Mark the cached device list for the given user outdated.
- *
- * If we are not tracking this user's devices, we'll do nothing. Otherwise
- * we flag the user as needing an update.
- *
- * This doesn't actually set off an update, so that several users can be
- * batched together. Call refreshOutdatedDeviceLists() for that.
- *
- */
- invalidateUserDeviceList(userId) {
- if (this.deviceTrackingStatus[userId]) {
- _logger.logger.log("Marking device list outdated for", userId);
- this.deviceTrackingStatus[userId] = TrackingStatus.PendingDownload;
-
- // we don't yet persist the tracking status, since there may be a lot
- // of calls; we save all data together once the sync is done
- this.dirty = true;
- }
- }
-
- /**
- * If we have users who have outdated device lists, start key downloads for them
- *
- * @returns which completes when the download completes; normally there
- * is no need to wait for this (it's mostly for the unit tests).
- */
- refreshOutdatedDeviceLists() {
- this.saveIfDirty();
- const usersToDownload = [];
- for (const userId of Object.keys(this.deviceTrackingStatus)) {
- const stat = this.deviceTrackingStatus[userId];
- if (stat == TrackingStatus.PendingDownload) {
- usersToDownload.push(userId);
- }
- }
- return this.doKeyDownload(usersToDownload);
- }
-
- /**
- * Set the stored device data for a user, in raw object form
- * Used only by internal class DeviceListUpdateSerialiser
- *
- * @param userId - the user to get data for
- *
- * @param devices - `deviceId->{object}` the new devices
- */
- setRawStoredDevicesForUser(userId, devices) {
- // remove old devices from userByIdentityKey
- if (this.devices[userId] !== undefined) {
- for (const [deviceId, dev] of Object.entries(this.devices[userId])) {
- const identityKey = dev.keys["curve25519:" + deviceId];
- delete this.userByIdentityKey[identityKey];
- }
- }
- this.devices[userId] = devices;
-
- // add new devices into userByIdentityKey
- for (const [deviceId, dev] of Object.entries(devices)) {
- const identityKey = dev.keys["curve25519:" + deviceId];
- this.userByIdentityKey[identityKey] = userId;
- }
- }
- setRawStoredCrossSigningForUser(userId, info) {
- this.crossSigningInfo[userId] = info;
- }
-
- /**
- * Fire off download update requests for the given users, and update the
- * device list tracking status for them, and the
- * keyDownloadsInProgressByUser map for them.
- *
- * @param users - list of userIds
- *
- * @returns resolves when all the users listed have
- * been updated. rejects if there was a problem updating any of the
- * users.
- */
- doKeyDownload(users) {
- if (users.length === 0) {
- // nothing to do
- return Promise.resolve();
- }
- const prom = this.serialiser.updateDevicesForUsers(users, this.syncToken).then(() => {
- finished(true);
- }, e => {
- _logger.logger.error("Error downloading keys for " + users + ":", e);
- finished(false);
- throw e;
- });
- users.forEach(u => {
- this.keyDownloadsInProgressByUser.set(u, prom);
- const stat = this.deviceTrackingStatus[u];
- if (stat == TrackingStatus.PendingDownload) {
- this.deviceTrackingStatus[u] = TrackingStatus.DownloadInProgress;
- }
- });
- const finished = success => {
- this.emit(_index.CryptoEvent.WillUpdateDevices, users, !this.hasFetched);
- users.forEach(u => {
- this.dirty = true;
-
- // we may have queued up another download request for this user
- // since we started this request. If that happens, we should
- // ignore the completion of the first one.
- if (this.keyDownloadsInProgressByUser.get(u) !== prom) {
- _logger.logger.log("Another update in the queue for", u, "- not marking up-to-date");
- return;
- }
- this.keyDownloadsInProgressByUser.delete(u);
- const stat = this.deviceTrackingStatus[u];
- if (stat == TrackingStatus.DownloadInProgress) {
- if (success) {
- // we didn't get any new invalidations since this download started:
- // this user's device list is now up to date.
- this.deviceTrackingStatus[u] = TrackingStatus.UpToDate;
- _logger.logger.log("Device list for", u, "now up to date");
- } else {
- this.deviceTrackingStatus[u] = TrackingStatus.PendingDownload;
- }
- }
- });
- this.saveIfDirty();
- this.emit(_index.CryptoEvent.DevicesUpdated, users, !this.hasFetched);
- this.hasFetched = true;
- };
- return prom;
- }
-}
-
-/**
- * Serialises updates to device lists
- *
- * Ensures that results from /keys/query are not overwritten if a second call
- * completes *before* an earlier one.
- *
- * It currently does this by ensuring only one call to /keys/query happens at a
- * time (and queuing other requests up).
- */
-exports.DeviceList = DeviceList;
-class DeviceListUpdateSerialiser {
- // users which are queued for download
- // userId -> true
-
- // deferred which is resolved when the queued users are downloaded.
- // non-null indicates that we have users queued for download.
-
- // The sync token we send with the requests
-
- /*
- * @param baseApis - Base API object
- * @param olmDevice - The Olm Device
- * @param deviceList - The device list object, the device list to be updated
- */
- constructor(baseApis, olmDevice, deviceList) {
- this.baseApis = baseApis;
- this.olmDevice = olmDevice;
- this.deviceList = deviceList;
- (0, _defineProperty2.default)(this, "downloadInProgress", false);
- (0, _defineProperty2.default)(this, "keyDownloadsQueuedByUser", {});
- (0, _defineProperty2.default)(this, "queuedQueryDeferred", void 0);
- (0, _defineProperty2.default)(this, "syncToken", void 0);
- }
-
- /**
- * Make a key query request for the given users
- *
- * @param users - list of user ids
- *
- * @param syncToken - sync token to pass in the query request, to
- * help the HS give the most recent results
- *
- * @returns resolves when all the users listed have
- * been updated. rejects if there was a problem updating any of the
- * users.
- */
- updateDevicesForUsers(users, syncToken) {
- users.forEach(u => {
- this.keyDownloadsQueuedByUser[u] = true;
- });
- if (!this.queuedQueryDeferred) {
- this.queuedQueryDeferred = (0, _utils.defer)();
- }
-
- // We always take the new sync token and just use the latest one we've
- // been given, since it just needs to be at least as recent as the
- // sync response the device invalidation message arrived in
- this.syncToken = syncToken;
- if (this.downloadInProgress) {
- // just queue up these users
- _logger.logger.log("Queued key download for", users);
- return this.queuedQueryDeferred.promise;
- }
-
- // start a new download.
- return this.doQueuedQueries();
- }
- doQueuedQueries() {
- if (this.downloadInProgress) {
- throw new Error("DeviceListUpdateSerialiser.doQueuedQueries called with request active");
- }
- const downloadUsers = Object.keys(this.keyDownloadsQueuedByUser);
- this.keyDownloadsQueuedByUser = {};
- const deferred = this.queuedQueryDeferred;
- this.queuedQueryDeferred = undefined;
- _logger.logger.log("Starting key download for", downloadUsers);
- this.downloadInProgress = true;
- const opts = {};
- if (this.syncToken) {
- opts.token = this.syncToken;
- }
- const factories = [];
- for (let i = 0; i < downloadUsers.length; i += this.deviceList.keyDownloadChunkSize) {
- const userSlice = downloadUsers.slice(i, i + this.deviceList.keyDownloadChunkSize);
- factories.push(() => this.baseApis.downloadKeysForUsers(userSlice, opts));
- }
- (0, _utils.chunkPromises)(factories, 3).then(async responses => {
- const dk = Object.assign({}, ...responses.map(res => res.device_keys || {}));
- const masterKeys = Object.assign({}, ...responses.map(res => res.master_keys || {}));
- const ssks = Object.assign({}, ...responses.map(res => res.self_signing_keys || {}));
- const usks = Object.assign({}, ...responses.map(res => res.user_signing_keys || {}));
-
- // yield to other things that want to execute in between users, to
- // avoid wedging the CPU
- // (https://github.com/vector-im/element-web/issues/3158)
- //
- // of course we ought to do this in a web worker or similar, but
- // this serves as an easy solution for now.
- for (const userId of downloadUsers) {
- await (0, _utils.sleep)(5);
- try {
- await this.processQueryResponseForUser(userId, dk[userId], {
- master: masterKeys === null || masterKeys === void 0 ? void 0 : masterKeys[userId],
- self_signing: ssks === null || ssks === void 0 ? void 0 : ssks[userId],
- user_signing: usks === null || usks === void 0 ? void 0 : usks[userId]
- });
- } catch (e) {
- // log the error but continue, so that one bad key
- // doesn't kill the whole process
- _logger.logger.error(`Error processing keys for ${userId}:`, e);
- }
- }
- }).then(() => {
- _logger.logger.log("Completed key download for " + downloadUsers);
- this.downloadInProgress = false;
- deferred === null || deferred === void 0 ? void 0 : deferred.resolve();
-
- // if we have queued users, fire off another request.
- if (this.queuedQueryDeferred) {
- this.doQueuedQueries();
- }
- }, e => {
- _logger.logger.warn("Error downloading keys for " + downloadUsers + ":", e);
- this.downloadInProgress = false;
- deferred === null || deferred === void 0 ? void 0 : deferred.reject(e);
- });
- return deferred.promise;
- }
- async processQueryResponseForUser(userId, dkResponse, crossSigningResponse) {
- _logger.logger.log("got device keys for " + userId + ":", dkResponse);
- _logger.logger.log("got cross-signing keys for " + userId + ":", crossSigningResponse);
- {
- // map from deviceid -> deviceinfo for this user
- const userStore = {};
- const devs = this.deviceList.getRawStoredDevicesForUser(userId);
- if (devs) {
- Object.keys(devs).forEach(deviceId => {
- const d = _deviceinfo.DeviceInfo.fromStorage(devs[deviceId], deviceId);
- userStore[deviceId] = d;
- });
- }
- await updateStoredDeviceKeysForUser(this.olmDevice, userId, userStore, dkResponse || {}, this.baseApis.getUserId(), this.baseApis.deviceId);
-
- // put the updates into the object that will be returned as our results
- const storage = {};
- Object.keys(userStore).forEach(deviceId => {
- storage[deviceId] = userStore[deviceId].toStorage();
- });
- this.deviceList.setRawStoredDevicesForUser(userId, storage);
- }
-
- // now do the same for the cross-signing keys
- {
- // FIXME: should we be ignoring empty cross-signing responses, or
- // should we be dropping the keys?
- if (crossSigningResponse && (crossSigningResponse.master || crossSigningResponse.self_signing || crossSigningResponse.user_signing)) {
- const crossSigning = this.deviceList.getStoredCrossSigningForUser(userId) || new _CrossSigning.CrossSigningInfo(userId);
- crossSigning.setKeys(crossSigningResponse);
- this.deviceList.setRawStoredCrossSigningForUser(userId, crossSigning.toStorage());
-
- // NB. Unlike most events in the js-sdk, this one is internal to the
- // js-sdk and is not re-emitted
- this.deviceList.emit(_index.CryptoEvent.UserCrossSigningUpdated, userId);
- }
- }
- }
-}
-async function updateStoredDeviceKeysForUser(olmDevice, userId, userStore, userResult, localUserId, localDeviceId) {
- let updated = false;
-
- // remove any devices in the store which aren't in the response
- for (const deviceId in userStore) {
- if (!userStore.hasOwnProperty(deviceId)) {
- continue;
- }
- if (!(deviceId in userResult)) {
- if (userId === localUserId && deviceId === localDeviceId) {
- _logger.logger.warn(`Local device ${deviceId} missing from sync, skipping removal`);
- continue;
- }
- _logger.logger.log("Device " + userId + ":" + deviceId + " has been removed");
- delete userStore[deviceId];
- updated = true;
- }
- }
- for (const deviceId in userResult) {
- if (!userResult.hasOwnProperty(deviceId)) {
- continue;
- }
- const deviceResult = userResult[deviceId];
-
- // check that the user_id and device_id in the response object are
- // correct
- if (deviceResult.user_id !== userId) {
- _logger.logger.warn("Mismatched user_id " + deviceResult.user_id + " in keys from " + userId + ":" + deviceId);
- continue;
- }
- if (deviceResult.device_id !== deviceId) {
- _logger.logger.warn("Mismatched device_id " + deviceResult.device_id + " in keys from " + userId + ":" + deviceId);
- continue;
- }
- if (await storeDeviceKeys(olmDevice, userStore, deviceResult)) {
- updated = true;
- }
- }
- return updated;
-}
-
-/*
- * Process a device in a /query response, and add it to the userStore
- *
- * returns (a promise for) true if a change was made, else false
- */
-async function storeDeviceKeys(olmDevice, userStore, deviceResult) {
- if (!deviceResult.keys) {
- // no keys?
- return false;
- }
- const deviceId = deviceResult.device_id;
- const userId = deviceResult.user_id;
- const signKeyId = "ed25519:" + deviceId;
- const signKey = deviceResult.keys[signKeyId];
- if (!signKey) {
- _logger.logger.warn("Device " + userId + ":" + deviceId + " has no ed25519 key");
- return false;
- }
- const unsigned = deviceResult.unsigned || {};
- const signatures = deviceResult.signatures || {};
- try {
- await olmlib.verifySignature(olmDevice, deviceResult, userId, deviceId, signKey);
- } catch (e) {
- _logger.logger.warn("Unable to verify signature on device " + userId + ":" + deviceId + ":" + e);
- return false;
- }
-
- // DeviceInfo
- let deviceStore;
- if (deviceId in userStore) {
- // already have this device.
- deviceStore = userStore[deviceId];
- if (deviceStore.getFingerprint() != signKey) {
- // this should only happen if the list has been MITMed; we are
- // best off sticking with the original keys.
- //
- // Should we warn the user about it somehow?
- _logger.logger.warn("Ed25519 key for device " + userId + ":" + deviceId + " has changed");
- return false;
- }
- } else {
- userStore[deviceId] = deviceStore = new _deviceinfo.DeviceInfo(deviceId);
- }
- deviceStore.keys = deviceResult.keys || {};
- deviceStore.algorithms = deviceResult.algorithms || [];
- deviceStore.unsigned = unsigned;
- deviceStore.signatures = signatures;
- return true;
-}
-//# sourceMappingURL=DeviceList.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/DeviceList.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/DeviceList.js.map
deleted file mode 100644
index 56c04c2..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/DeviceList.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"DeviceList.js","names":["_logger","require","_deviceinfo","_CrossSigning","olmlib","_interopRequireWildcard","_indexeddbCryptoStore","_utils","_typedEventEmitter","_index","_getRequireWildcardCache","nodeInterop","WeakMap","cacheBabelInterop","cacheNodeInterop","obj","__esModule","default","cache","has","get","newObj","hasPropertyDescriptor","Object","defineProperty","getOwnPropertyDescriptor","key","prototype","hasOwnProperty","call","desc","set","TrackingStatus","exports","DeviceList","TypedEventEmitter","constructor","baseApis","cryptoStore","olmDevice","keyDownloadChunkSize","_defineProperty2","Map","serialiser","DeviceListUpdateSerialiser","load","doTxn","IndexedDBCryptoStore","STORE_DEVICE_DATA","txn","getEndToEndDeviceData","deviceData","_deviceData$syncToken","hasFetched","Boolean","devices","crossSigningInfo","deviceTrackingStatus","trackingStatus","syncToken","userByIdentityKey","user","keys","userDevices","device","idKey","undefined","u","DownloadInProgress","PendingDownload","stop","saveTimer","clearTimeout","saveIfDirty","delay","dirty","Promise","resolve","targetTime","Date","now","savePromiseTime","savePromise","resolveSavePromise","setTimeout","logger","log","_this$syncToken","storeEndToEndDeviceData","then","err","error","getSyncToken","setSyncToken","st","downloadKeys","userIds","forceDownload","usersToDownload","promises","forEach","keyDownloadsInProgressByUser","push","UpToDate","length","downloadPromise","doKeyDownload","all","getDevicesFromStore","stored","userId","_this$getStoredDevice","deviceMap","getStoredDevicesForUser","deviceId","getKnownUserIds","devs","res","DeviceInfo","fromStorage","getRawStoredDevicesForUser","getStoredCrossSigningForUser","CrossSigningInfo","storeCrossSigningForUser","info","getStoredDevice","getUserByIdentityKey","algorithm","senderKey","OLM_ALGORITHM","MEGOLM_ALGORITHM","getDeviceByIdentityKey","keyId","indexOf","deviceKey","storeDevicesForUser","setRawStoredDevicesForUser","startTrackingDeviceList","Error","stopTrackingDeviceList","NotTracked","stopTrackingAllDeviceLists","invalidateUserDeviceList","refreshOutdatedDeviceLists","stat","dev","entries","identityKey","setRawStoredCrossSigningForUser","users","prom","updateDevicesForUsers","finished","e","success","emit","CryptoEvent","WillUpdateDevices","delete","DevicesUpdated","deviceList","keyDownloadsQueuedByUser","queuedQueryDeferred","defer","downloadInProgress","promise","doQueuedQueries","downloadUsers","deferred","opts","token","factories","i","userSlice","slice","downloadKeysForUsers","chunkPromises","responses","dk","assign","map","device_keys","masterKeys","master_keys","ssks","self_signing_keys","usks","user_signing_keys","sleep","processQueryResponseForUser","master","self_signing","user_signing","warn","reject","dkResponse","crossSigningResponse","userStore","d","updateStoredDeviceKeysForUser","getUserId","storage","toStorage","crossSigning","setKeys","UserCrossSigningUpdated","userResult","localUserId","localDeviceId","updated","deviceResult","user_id","device_id","storeDeviceKeys","signKeyId","signKey","unsigned","signatures","verifySignature","deviceStore","getFingerprint","algorithms"],"sources":["../../src/crypto/DeviceList.ts"],"sourcesContent":["/*\nCopyright 2017 - 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n/**\n * Manages the list of other users' devices\n */\n\nimport { logger } from \"../logger\";\nimport { DeviceInfo, IDevice } from \"./deviceinfo\";\nimport { CrossSigningInfo, ICrossSigningInfo } from \"./CrossSigning\";\nimport * as olmlib from \"./olmlib\";\nimport { IndexedDBCryptoStore } from \"./store/indexeddb-crypto-store\";\nimport { chunkPromises, defer, IDeferred, sleep } from \"../utils\";\nimport { DeviceKeys, IDownloadKeyResult, Keys, MatrixClient, SigningKeys } from \"../client\";\nimport { OlmDevice } from \"./OlmDevice\";\nimport { CryptoStore } from \"./store/base\";\nimport { TypedEventEmitter } from \"../models/typed-event-emitter\";\nimport { CryptoEvent, CryptoEventHandlerMap } from \"./index\";\n\n/* State transition diagram for DeviceList.deviceTrackingStatus\n *\n * |\n * stopTrackingDeviceList V\n * +---------------------> NOT_TRACKED\n * | |\n * +<--------------------+ | startTrackingDeviceList\n * | | V\n * | +-------------> PENDING_DOWNLOAD <--------------------+-+\n * | | ^ | | |\n * | | restart download | | start download | | invalidateUserDeviceList\n * | | client failed | | | |\n * | | | V | |\n * | +------------ DOWNLOAD_IN_PROGRESS -------------------+ |\n * | | | |\n * +<-------------------+ | download successful |\n * ^ V |\n * +----------------------- UP_TO_DATE ------------------------+\n */\n\n// constants for DeviceList.deviceTrackingStatus\nexport enum TrackingStatus {\n NotTracked,\n PendingDownload,\n DownloadInProgress,\n UpToDate,\n}\n\n// user-Id → device-Id → DeviceInfo\nexport type DeviceInfoMap = Map<string, Map<string, DeviceInfo>>;\n\ntype EmittedEvents = CryptoEvent.WillUpdateDevices | CryptoEvent.DevicesUpdated | CryptoEvent.UserCrossSigningUpdated;\n\nexport class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHandlerMap> {\n private devices: { [userId: string]: { [deviceId: string]: IDevice } } = {};\n\n public crossSigningInfo: { [userId: string]: ICrossSigningInfo } = {};\n\n // map of identity keys to the user who owns it\n private userByIdentityKey: Record<string, string> = {};\n\n // which users we are tracking device status for.\n private deviceTrackingStatus: { [userId: string]: TrackingStatus } = {}; // loaded from storage in load()\n\n // The 'next_batch' sync token at the point the data was written,\n // ie. a token representing the point immediately after the\n // moment represented by the snapshot in the db.\n private syncToken: string | null = null;\n\n private keyDownloadsInProgressByUser = new Map<string, Promise<void>>();\n\n // Set whenever changes are made other than setting the sync token\n private dirty = false;\n\n // Promise resolved when device data is saved\n private savePromise: Promise<boolean> | null = null;\n // Function that resolves the save promise\n private resolveSavePromise: ((saved: boolean) => void) | null = null;\n // The time the save is scheduled for\n private savePromiseTime: number | null = null;\n // The timer used to delay the save\n private saveTimer: ReturnType<typeof setTimeout> | null = null;\n // True if we have fetched data from the server or loaded a non-empty\n // set of device data from the store\n private hasFetched: boolean | null = null;\n\n private readonly serialiser: DeviceListUpdateSerialiser;\n\n public constructor(\n baseApis: MatrixClient,\n private readonly cryptoStore: CryptoStore,\n olmDevice: OlmDevice,\n // Maximum number of user IDs per request to prevent server overload (#1619)\n public readonly keyDownloadChunkSize = 250,\n ) {\n super();\n\n this.serialiser = new DeviceListUpdateSerialiser(baseApis, olmDevice, this);\n }\n\n /**\n * Load the device tracking state from storage\n */\n public async load(): Promise<void> {\n await this.cryptoStore.doTxn(\"readonly\", [IndexedDBCryptoStore.STORE_DEVICE_DATA], (txn) => {\n this.cryptoStore.getEndToEndDeviceData(txn, (deviceData) => {\n this.hasFetched = Boolean(deviceData && deviceData.devices);\n this.devices = deviceData ? deviceData.devices : {};\n this.crossSigningInfo = deviceData ? deviceData.crossSigningInfo || {} : {};\n this.deviceTrackingStatus = deviceData ? deviceData.trackingStatus : {};\n this.syncToken = deviceData?.syncToken ?? null;\n this.userByIdentityKey = {};\n for (const user of Object.keys(this.devices)) {\n const userDevices = this.devices[user];\n for (const device of Object.keys(userDevices)) {\n const idKey = userDevices[device].keys[\"curve25519:\" + device];\n if (idKey !== undefined) {\n this.userByIdentityKey[idKey] = user;\n }\n }\n }\n });\n });\n\n for (const u of Object.keys(this.deviceTrackingStatus)) {\n // if a download was in progress when we got shut down, it isn't any more.\n if (this.deviceTrackingStatus[u] == TrackingStatus.DownloadInProgress) {\n this.deviceTrackingStatus[u] = TrackingStatus.PendingDownload;\n }\n }\n }\n\n public stop(): void {\n if (this.saveTimer !== null) {\n clearTimeout(this.saveTimer);\n }\n }\n\n /**\n * Save the device tracking state to storage, if any changes are\n * pending other than updating the sync token\n *\n * The actual save will be delayed by a short amount of time to\n * aggregate multiple writes to the database.\n *\n * @param delay - Time in ms before which the save actually happens.\n * By default, the save is delayed for a short period in order to batch\n * multiple writes, but this behaviour can be disabled by passing 0.\n *\n * @returns true if the data was saved, false if\n * it was not (eg. because no changes were pending). The promise\n * will only resolve once the data is saved, so may take some time\n * to resolve.\n */\n public async saveIfDirty(delay = 500): Promise<boolean> {\n if (!this.dirty) return Promise.resolve(false);\n // Delay saves for a bit so we can aggregate multiple saves that happen\n // in quick succession (eg. when a whole room's devices are marked as known)\n\n const targetTime = Date.now() + delay;\n if (this.savePromiseTime && targetTime < this.savePromiseTime) {\n // There's a save scheduled but for after we would like: cancel\n // it & schedule one for the time we want\n clearTimeout(this.saveTimer!);\n this.saveTimer = null;\n this.savePromiseTime = null;\n // (but keep the save promise since whatever called save before\n // will still want to know when the save is done)\n }\n\n let savePromise = this.savePromise;\n if (savePromise === null) {\n savePromise = new Promise((resolve) => {\n this.resolveSavePromise = resolve;\n });\n this.savePromise = savePromise;\n }\n\n if (this.saveTimer === null) {\n const resolveSavePromise = this.resolveSavePromise;\n this.savePromiseTime = targetTime;\n this.saveTimer = setTimeout(() => {\n logger.log(\"Saving device tracking data\", this.syncToken);\n\n // null out savePromise now (after the delay but before the write),\n // otherwise we could return the existing promise when the save has\n // actually already happened.\n this.savePromiseTime = null;\n this.saveTimer = null;\n this.savePromise = null;\n this.resolveSavePromise = null;\n\n this.cryptoStore\n .doTxn(\"readwrite\", [IndexedDBCryptoStore.STORE_DEVICE_DATA], (txn) => {\n this.cryptoStore.storeEndToEndDeviceData(\n {\n devices: this.devices,\n crossSigningInfo: this.crossSigningInfo,\n trackingStatus: this.deviceTrackingStatus,\n syncToken: this.syncToken ?? undefined,\n },\n txn,\n );\n })\n .then(\n () => {\n // The device list is considered dirty until the write completes.\n this.dirty = false;\n resolveSavePromise?.(true);\n },\n (err) => {\n logger.error(\"Failed to save device tracking data\", this.syncToken);\n logger.error(err);\n },\n );\n }, delay);\n }\n\n return savePromise;\n }\n\n /**\n * Gets the sync token last set with setSyncToken\n *\n * @returns The sync token\n */\n public getSyncToken(): string | null {\n return this.syncToken;\n }\n\n /**\n * Sets the sync token that the app will pass as the 'since' to the /sync\n * endpoint next time it syncs.\n * The sync token must always be set after any changes made as a result of\n * data in that sync since setting the sync token to a newer one will mean\n * those changed will not be synced from the server if a new client starts\n * up with that data.\n *\n * @param st - The sync token\n */\n public setSyncToken(st: string | null): void {\n this.syncToken = st;\n }\n\n /**\n * Ensures up to date keys for a list of users are stored in the session store,\n * downloading and storing them if they're not (or if forceDownload is\n * true).\n * @param userIds - The users to fetch.\n * @param forceDownload - Always download the keys even if cached.\n *\n * @returns A promise which resolves to a map userId-\\>deviceId-\\>{@link DeviceInfo}.\n */\n public downloadKeys(userIds: string[], forceDownload: boolean): Promise<DeviceInfoMap> {\n const usersToDownload: string[] = [];\n const promises: Promise<unknown>[] = [];\n\n userIds.forEach((u) => {\n const trackingStatus = this.deviceTrackingStatus[u];\n if (this.keyDownloadsInProgressByUser.has(u)) {\n // already a key download in progress/queued for this user; its results\n // will be good enough for us.\n logger.log(`downloadKeys: already have a download in progress for ` + `${u}: awaiting its result`);\n promises.push(this.keyDownloadsInProgressByUser.get(u)!);\n } else if (forceDownload || trackingStatus != TrackingStatus.UpToDate) {\n usersToDownload.push(u);\n }\n });\n\n if (usersToDownload.length != 0) {\n logger.log(\"downloadKeys: downloading for\", usersToDownload);\n const downloadPromise = this.doKeyDownload(usersToDownload);\n promises.push(downloadPromise);\n }\n\n if (promises.length === 0) {\n logger.log(\"downloadKeys: already have all necessary keys\");\n }\n\n return Promise.all(promises).then(() => {\n return this.getDevicesFromStore(userIds);\n });\n }\n\n /**\n * Get the stored device keys for a list of user ids\n *\n * @param userIds - the list of users to list keys for.\n *\n * @returns userId-\\>deviceId-\\>{@link DeviceInfo}.\n */\n private getDevicesFromStore(userIds: string[]): DeviceInfoMap {\n const stored: DeviceInfoMap = new Map();\n userIds.forEach((userId) => {\n const deviceMap = new Map();\n this.getStoredDevicesForUser(userId)?.forEach(function (device) {\n deviceMap.set(device.deviceId, device);\n });\n stored.set(userId, deviceMap);\n });\n return stored;\n }\n\n /**\n * Returns a list of all user IDs the DeviceList knows about\n *\n * @returns All known user IDs\n */\n public getKnownUserIds(): string[] {\n return Object.keys(this.devices);\n }\n\n /**\n * Get the stored device keys for a user id\n *\n * @param userId - the user to list keys for.\n *\n * @returns list of devices, or null if we haven't\n * managed to get a list of devices for this user yet.\n */\n public getStoredDevicesForUser(userId: string): DeviceInfo[] | null {\n const devs = this.devices[userId];\n if (!devs) {\n return null;\n }\n const res: DeviceInfo[] = [];\n for (const deviceId in devs) {\n if (devs.hasOwnProperty(deviceId)) {\n res.push(DeviceInfo.fromStorage(devs[deviceId], deviceId));\n }\n }\n return res;\n }\n\n /**\n * Get the stored device data for a user, in raw object form\n *\n * @param userId - the user to get data for\n *\n * @returns `deviceId->{object}` devices, or undefined if\n * there is no data for this user.\n */\n public getRawStoredDevicesForUser(userId: string): Record<string, IDevice> {\n return this.devices[userId];\n }\n\n public getStoredCrossSigningForUser(userId: string): CrossSigningInfo | null {\n if (!this.crossSigningInfo[userId]) return null;\n\n return CrossSigningInfo.fromStorage(this.crossSigningInfo[userId], userId);\n }\n\n public storeCrossSigningForUser(userId: string, info: ICrossSigningInfo): void {\n this.crossSigningInfo[userId] = info;\n this.dirty = true;\n }\n\n /**\n * Get the stored keys for a single device\n *\n *\n * @returns device, or undefined\n * if we don't know about this device\n */\n public getStoredDevice(userId: string, deviceId: string): DeviceInfo | undefined {\n const devs = this.devices[userId];\n if (!devs?.[deviceId]) {\n return undefined;\n }\n return DeviceInfo.fromStorage(devs[deviceId], deviceId);\n }\n\n /**\n * Get a user ID by one of their device's curve25519 identity key\n *\n * @param algorithm - encryption algorithm\n * @param senderKey - curve25519 key to match\n *\n * @returns user ID\n */\n public getUserByIdentityKey(algorithm: string, senderKey: string): string | null {\n if (algorithm !== olmlib.OLM_ALGORITHM && algorithm !== olmlib.MEGOLM_ALGORITHM) {\n // we only deal in olm keys\n return null;\n }\n\n return this.userByIdentityKey[senderKey];\n }\n\n /**\n * Find a device by curve25519 identity key\n *\n * @param algorithm - encryption algorithm\n * @param senderKey - curve25519 key to match\n */\n public getDeviceByIdentityKey(algorithm: string, senderKey: string): DeviceInfo | null {\n const userId = this.getUserByIdentityKey(algorithm, senderKey);\n if (!userId) {\n return null;\n }\n\n const devices = this.devices[userId];\n if (!devices) {\n return null;\n }\n\n for (const deviceId in devices) {\n if (!devices.hasOwnProperty(deviceId)) {\n continue;\n }\n\n const device = devices[deviceId];\n for (const keyId in device.keys) {\n if (!device.keys.hasOwnProperty(keyId)) {\n continue;\n }\n if (keyId.indexOf(\"curve25519:\") !== 0) {\n continue;\n }\n const deviceKey = device.keys[keyId];\n if (deviceKey == senderKey) {\n return DeviceInfo.fromStorage(device, deviceId);\n }\n }\n }\n\n // doesn't match a known device\n return null;\n }\n\n /**\n * Replaces the list of devices for a user with the given device list\n *\n * @param userId - The user ID\n * @param devices - New device info for user\n */\n public storeDevicesForUser(userId: string, devices: Record<string, IDevice>): void {\n this.setRawStoredDevicesForUser(userId, devices);\n this.dirty = true;\n }\n\n /**\n * flag the given user for device-list tracking, if they are not already.\n *\n * This will mean that a subsequent call to refreshOutdatedDeviceLists()\n * will download the device list for the user, and that subsequent calls to\n * invalidateUserDeviceList will trigger more updates.\n *\n */\n public startTrackingDeviceList(userId: string): void {\n // sanity-check the userId. This is mostly paranoia, but if synapse\n // can't parse the userId we give it as an mxid, it 500s the whole\n // request and we can never update the device lists again (because\n // the broken userId is always 'invalid' and always included in any\n // refresh request).\n // By checking it is at least a string, we can eliminate a class of\n // silly errors.\n if (typeof userId !== \"string\") {\n throw new Error(\"userId must be a string; was \" + userId);\n }\n if (!this.deviceTrackingStatus[userId]) {\n logger.log(\"Now tracking device list for \" + userId);\n this.deviceTrackingStatus[userId] = TrackingStatus.PendingDownload;\n // we don't yet persist the tracking status, since there may be a lot\n // of calls; we save all data together once the sync is done\n this.dirty = true;\n }\n }\n\n /**\n * Mark the given user as no longer being tracked for device-list updates.\n *\n * This won't affect any in-progress downloads, which will still go on to\n * complete; it will just mean that we don't think that we have an up-to-date\n * list for future calls to downloadKeys.\n *\n */\n public stopTrackingDeviceList(userId: string): void {\n if (this.deviceTrackingStatus[userId]) {\n logger.log(\"No longer tracking device list for \" + userId);\n this.deviceTrackingStatus[userId] = TrackingStatus.NotTracked;\n\n // we don't yet persist the tracking status, since there may be a lot\n // of calls; we save all data together once the sync is done\n this.dirty = true;\n }\n }\n\n /**\n * Set all users we're currently tracking to untracked\n *\n * This will flag each user whose devices we are tracking as in need of an\n * update.\n */\n public stopTrackingAllDeviceLists(): void {\n for (const userId of Object.keys(this.deviceTrackingStatus)) {\n this.deviceTrackingStatus[userId] = TrackingStatus.NotTracked;\n }\n this.dirty = true;\n }\n\n /**\n * Mark the cached device list for the given user outdated.\n *\n * If we are not tracking this user's devices, we'll do nothing. Otherwise\n * we flag the user as needing an update.\n *\n * This doesn't actually set off an update, so that several users can be\n * batched together. Call refreshOutdatedDeviceLists() for that.\n *\n */\n public invalidateUserDeviceList(userId: string): void {\n if (this.deviceTrackingStatus[userId]) {\n logger.log(\"Marking device list outdated for\", userId);\n this.deviceTrackingStatus[userId] = TrackingStatus.PendingDownload;\n\n // we don't yet persist the tracking status, since there may be a lot\n // of calls; we save all data together once the sync is done\n this.dirty = true;\n }\n }\n\n /**\n * If we have users who have outdated device lists, start key downloads for them\n *\n * @returns which completes when the download completes; normally there\n * is no need to wait for this (it's mostly for the unit tests).\n */\n public refreshOutdatedDeviceLists(): Promise<void> {\n this.saveIfDirty();\n\n const usersToDownload: string[] = [];\n for (const userId of Object.keys(this.deviceTrackingStatus)) {\n const stat = this.deviceTrackingStatus[userId];\n if (stat == TrackingStatus.PendingDownload) {\n usersToDownload.push(userId);\n }\n }\n\n return this.doKeyDownload(usersToDownload);\n }\n\n /**\n * Set the stored device data for a user, in raw object form\n * Used only by internal class DeviceListUpdateSerialiser\n *\n * @param userId - the user to get data for\n *\n * @param devices - `deviceId->{object}` the new devices\n */\n public setRawStoredDevicesForUser(userId: string, devices: Record<string, IDevice>): void {\n // remove old devices from userByIdentityKey\n if (this.devices[userId] !== undefined) {\n for (const [deviceId, dev] of Object.entries(this.devices[userId])) {\n const identityKey = dev.keys[\"curve25519:\" + deviceId];\n\n delete this.userByIdentityKey[identityKey];\n }\n }\n\n this.devices[userId] = devices;\n\n // add new devices into userByIdentityKey\n for (const [deviceId, dev] of Object.entries(devices)) {\n const identityKey = dev.keys[\"curve25519:\" + deviceId];\n\n this.userByIdentityKey[identityKey] = userId;\n }\n }\n\n public setRawStoredCrossSigningForUser(userId: string, info: ICrossSigningInfo): void {\n this.crossSigningInfo[userId] = info;\n }\n\n /**\n * Fire off download update requests for the given users, and update the\n * device list tracking status for them, and the\n * keyDownloadsInProgressByUser map for them.\n *\n * @param users - list of userIds\n *\n * @returns resolves when all the users listed have\n * been updated. rejects if there was a problem updating any of the\n * users.\n */\n private doKeyDownload(users: string[]): Promise<void> {\n if (users.length === 0) {\n // nothing to do\n return Promise.resolve();\n }\n\n const prom = this.serialiser.updateDevicesForUsers(users, this.syncToken!).then(\n () => {\n finished(true);\n },\n (e) => {\n logger.error(\"Error downloading keys for \" + users + \":\", e);\n finished(false);\n throw e;\n },\n );\n\n users.forEach((u) => {\n this.keyDownloadsInProgressByUser.set(u, prom);\n const stat = this.deviceTrackingStatus[u];\n if (stat == TrackingStatus.PendingDownload) {\n this.deviceTrackingStatus[u] = TrackingStatus.DownloadInProgress;\n }\n });\n\n const finished = (success: boolean): void => {\n this.emit(CryptoEvent.WillUpdateDevices, users, !this.hasFetched);\n users.forEach((u) => {\n this.dirty = true;\n\n // we may have queued up another download request for this user\n // since we started this request. If that happens, we should\n // ignore the completion of the first one.\n if (this.keyDownloadsInProgressByUser.get(u) !== prom) {\n logger.log(\"Another update in the queue for\", u, \"- not marking up-to-date\");\n return;\n }\n this.keyDownloadsInProgressByUser.delete(u);\n const stat = this.deviceTrackingStatus[u];\n if (stat == TrackingStatus.DownloadInProgress) {\n if (success) {\n // we didn't get any new invalidations since this download started:\n // this user's device list is now up to date.\n this.deviceTrackingStatus[u] = TrackingStatus.UpToDate;\n logger.log(\"Device list for\", u, \"now up to date\");\n } else {\n this.deviceTrackingStatus[u] = TrackingStatus.PendingDownload;\n }\n }\n });\n this.saveIfDirty();\n this.emit(CryptoEvent.DevicesUpdated, users, !this.hasFetched);\n this.hasFetched = true;\n };\n\n return prom;\n }\n}\n\n/**\n * Serialises updates to device lists\n *\n * Ensures that results from /keys/query are not overwritten if a second call\n * completes *before* an earlier one.\n *\n * It currently does this by ensuring only one call to /keys/query happens at a\n * time (and queuing other requests up).\n */\nclass DeviceListUpdateSerialiser {\n private downloadInProgress = false;\n\n // users which are queued for download\n // userId -> true\n private keyDownloadsQueuedByUser: Record<string, boolean> = {};\n\n // deferred which is resolved when the queued users are downloaded.\n // non-null indicates that we have users queued for download.\n private queuedQueryDeferred?: IDeferred<void>;\n\n private syncToken?: string; // The sync token we send with the requests\n\n /*\n * @param baseApis - Base API object\n * @param olmDevice - The Olm Device\n * @param deviceList - The device list object, the device list to be updated\n */\n public constructor(\n private readonly baseApis: MatrixClient,\n private readonly olmDevice: OlmDevice,\n private readonly deviceList: DeviceList,\n ) {}\n\n /**\n * Make a key query request for the given users\n *\n * @param users - list of user ids\n *\n * @param syncToken - sync token to pass in the query request, to\n * help the HS give the most recent results\n *\n * @returns resolves when all the users listed have\n * been updated. rejects if there was a problem updating any of the\n * users.\n */\n public updateDevicesForUsers(users: string[], syncToken: string): Promise<void> {\n users.forEach((u) => {\n this.keyDownloadsQueuedByUser[u] = true;\n });\n\n if (!this.queuedQueryDeferred) {\n this.queuedQueryDeferred = defer();\n }\n\n // We always take the new sync token and just use the latest one we've\n // been given, since it just needs to be at least as recent as the\n // sync response the device invalidation message arrived in\n this.syncToken = syncToken;\n\n if (this.downloadInProgress) {\n // just queue up these users\n logger.log(\"Queued key download for\", users);\n return this.queuedQueryDeferred.promise;\n }\n\n // start a new download.\n return this.doQueuedQueries();\n }\n\n private doQueuedQueries(): Promise<void> {\n if (this.downloadInProgress) {\n throw new Error(\"DeviceListUpdateSerialiser.doQueuedQueries called with request active\");\n }\n\n const downloadUsers = Object.keys(this.keyDownloadsQueuedByUser);\n this.keyDownloadsQueuedByUser = {};\n const deferred = this.queuedQueryDeferred;\n this.queuedQueryDeferred = undefined;\n\n logger.log(\"Starting key download for\", downloadUsers);\n this.downloadInProgress = true;\n\n const opts: Parameters<MatrixClient[\"downloadKeysForUsers\"]>[1] = {};\n if (this.syncToken) {\n opts.token = this.syncToken;\n }\n\n const factories: Array<() => Promise<IDownloadKeyResult>> = [];\n for (let i = 0; i < downloadUsers.length; i += this.deviceList.keyDownloadChunkSize) {\n const userSlice = downloadUsers.slice(i, i + this.deviceList.keyDownloadChunkSize);\n factories.push(() => this.baseApis.downloadKeysForUsers(userSlice, opts));\n }\n\n chunkPromises(factories, 3)\n .then(async (responses: IDownloadKeyResult[]) => {\n const dk: IDownloadKeyResult[\"device_keys\"] = Object.assign(\n {},\n ...responses.map((res) => res.device_keys || {}),\n );\n const masterKeys: IDownloadKeyResult[\"master_keys\"] = Object.assign(\n {},\n ...responses.map((res) => res.master_keys || {}),\n );\n const ssks: IDownloadKeyResult[\"self_signing_keys\"] = Object.assign(\n {},\n ...responses.map((res) => res.self_signing_keys || {}),\n );\n const usks: IDownloadKeyResult[\"user_signing_keys\"] = Object.assign(\n {},\n ...responses.map((res) => res.user_signing_keys || {}),\n );\n\n // yield to other things that want to execute in between users, to\n // avoid wedging the CPU\n // (https://github.com/vector-im/element-web/issues/3158)\n //\n // of course we ought to do this in a web worker or similar, but\n // this serves as an easy solution for now.\n for (const userId of downloadUsers) {\n await sleep(5);\n try {\n await this.processQueryResponseForUser(userId, dk[userId], {\n master: masterKeys?.[userId],\n self_signing: ssks?.[userId],\n user_signing: usks?.[userId],\n });\n } catch (e) {\n // log the error but continue, so that one bad key\n // doesn't kill the whole process\n logger.error(`Error processing keys for ${userId}:`, e);\n }\n }\n })\n .then(\n () => {\n logger.log(\"Completed key download for \" + downloadUsers);\n\n this.downloadInProgress = false;\n deferred?.resolve();\n\n // if we have queued users, fire off another request.\n if (this.queuedQueryDeferred) {\n this.doQueuedQueries();\n }\n },\n (e) => {\n logger.warn(\"Error downloading keys for \" + downloadUsers + \":\", e);\n this.downloadInProgress = false;\n deferred?.reject(e);\n },\n );\n\n return deferred!.promise;\n }\n\n private async processQueryResponseForUser(\n userId: string,\n dkResponse: DeviceKeys,\n crossSigningResponse: {\n master?: Keys;\n self_signing?: SigningKeys;\n user_signing?: SigningKeys;\n },\n ): Promise<void> {\n logger.log(\"got device keys for \" + userId + \":\", dkResponse);\n logger.log(\"got cross-signing keys for \" + userId + \":\", crossSigningResponse);\n\n {\n // map from deviceid -> deviceinfo for this user\n const userStore: Record<string, DeviceInfo> = {};\n const devs = this.deviceList.getRawStoredDevicesForUser(userId);\n if (devs) {\n Object.keys(devs).forEach((deviceId) => {\n const d = DeviceInfo.fromStorage(devs[deviceId], deviceId);\n userStore[deviceId] = d;\n });\n }\n\n await updateStoredDeviceKeysForUser(\n this.olmDevice,\n userId,\n userStore,\n dkResponse || {},\n this.baseApis.getUserId()!,\n this.baseApis.deviceId!,\n );\n\n // put the updates into the object that will be returned as our results\n const storage: Record<string, IDevice> = {};\n Object.keys(userStore).forEach((deviceId) => {\n storage[deviceId] = userStore[deviceId].toStorage();\n });\n\n this.deviceList.setRawStoredDevicesForUser(userId, storage);\n }\n\n // now do the same for the cross-signing keys\n {\n // FIXME: should we be ignoring empty cross-signing responses, or\n // should we be dropping the keys?\n if (\n crossSigningResponse &&\n (crossSigningResponse.master || crossSigningResponse.self_signing || crossSigningResponse.user_signing)\n ) {\n const crossSigning =\n this.deviceList.getStoredCrossSigningForUser(userId) || new CrossSigningInfo(userId);\n\n crossSigning.setKeys(crossSigningResponse);\n\n this.deviceList.setRawStoredCrossSigningForUser(userId, crossSigning.toStorage());\n\n // NB. Unlike most events in the js-sdk, this one is internal to the\n // js-sdk and is not re-emitted\n this.deviceList.emit(CryptoEvent.UserCrossSigningUpdated, userId);\n }\n }\n }\n}\n\nasync function updateStoredDeviceKeysForUser(\n olmDevice: OlmDevice,\n userId: string,\n userStore: Record<string, DeviceInfo>,\n userResult: IDownloadKeyResult[\"device_keys\"][\"user_id\"],\n localUserId: string,\n localDeviceId: string,\n): Promise<boolean> {\n let updated = false;\n\n // remove any devices in the store which aren't in the response\n for (const deviceId in userStore) {\n if (!userStore.hasOwnProperty(deviceId)) {\n continue;\n }\n\n if (!(deviceId in userResult)) {\n if (userId === localUserId && deviceId === localDeviceId) {\n logger.warn(`Local device ${deviceId} missing from sync, skipping removal`);\n continue;\n }\n\n logger.log(\"Device \" + userId + \":\" + deviceId + \" has been removed\");\n delete userStore[deviceId];\n updated = true;\n }\n }\n\n for (const deviceId in userResult) {\n if (!userResult.hasOwnProperty(deviceId)) {\n continue;\n }\n\n const deviceResult = userResult[deviceId];\n\n // check that the user_id and device_id in the response object are\n // correct\n if (deviceResult.user_id !== userId) {\n logger.warn(\"Mismatched user_id \" + deviceResult.user_id + \" in keys from \" + userId + \":\" + deviceId);\n continue;\n }\n if (deviceResult.device_id !== deviceId) {\n logger.warn(\"Mismatched device_id \" + deviceResult.device_id + \" in keys from \" + userId + \":\" + deviceId);\n continue;\n }\n\n if (await storeDeviceKeys(olmDevice, userStore, deviceResult)) {\n updated = true;\n }\n }\n\n return updated;\n}\n\n/*\n * Process a device in a /query response, and add it to the userStore\n *\n * returns (a promise for) true if a change was made, else false\n */\nasync function storeDeviceKeys(\n olmDevice: OlmDevice,\n userStore: Record<string, DeviceInfo>,\n deviceResult: IDownloadKeyResult[\"device_keys\"][\"user_id\"][\"device_id\"],\n): Promise<boolean> {\n if (!deviceResult.keys) {\n // no keys?\n return false;\n }\n\n const deviceId = deviceResult.device_id;\n const userId = deviceResult.user_id;\n\n const signKeyId = \"ed25519:\" + deviceId;\n const signKey = deviceResult.keys[signKeyId];\n if (!signKey) {\n logger.warn(\"Device \" + userId + \":\" + deviceId + \" has no ed25519 key\");\n return false;\n }\n\n const unsigned = deviceResult.unsigned || {};\n const signatures = deviceResult.signatures || {};\n\n try {\n await olmlib.verifySignature(olmDevice, deviceResult, userId, deviceId, signKey);\n } catch (e) {\n logger.warn(\"Unable to verify signature on device \" + userId + \":\" + deviceId + \":\" + e);\n return false;\n }\n\n // DeviceInfo\n let deviceStore;\n\n if (deviceId in userStore) {\n // already have this device.\n deviceStore = userStore[deviceId];\n\n if (deviceStore.getFingerprint() != signKey) {\n // this should only happen if the list has been MITMed; we are\n // best off sticking with the original keys.\n //\n // Should we warn the user about it somehow?\n logger.warn(\"Ed25519 key for device \" + userId + \":\" + deviceId + \" has changed\");\n return false;\n }\n } else {\n userStore[deviceId] = deviceStore = new DeviceInfo(deviceId);\n }\n\n deviceStore.keys = deviceResult.keys || {};\n deviceStore.algorithms = deviceResult.algorithms || [];\n deviceStore.unsigned = unsigned;\n deviceStore.signatures = signatures;\n return true;\n}\n"],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/EncryptionSetup.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/EncryptionSetup.d.ts
deleted file mode 100644
index 30fd408..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/EncryptionSetup.d.ts
+++ /dev/null
@@ -1,150 +0,0 @@
-import { IContent, MatrixEvent } from "../models/event";
-import { ICacheCallbacks } from "./CrossSigning";
-import { Crypto, ICryptoCallbacks, IBootstrapCrossSigningOpts } from "./index";
-import { ClientEvent, ClientEventHandlerMap, ICrossSigningKey, ISignedKey, KeySignatures } from "../client";
-import { IKeyBackupInfo } from "./keybackup";
-import { TypedEventEmitter } from "../models/typed-event-emitter";
-import { IAccountDataClient } from "./SecretStorage";
-import { SecretStorageKeyDescription } from "../secret-storage";
-interface ICrossSigningKeys {
- authUpload: IBootstrapCrossSigningOpts["authUploadDeviceSigningKeys"];
- keys: Record<"master" | "self_signing" | "user_signing", ICrossSigningKey>;
-}
-/**
- * Builds an EncryptionSetupOperation by calling any of the add.. methods.
- * Once done, `buildOperation()` can be called which allows to apply to operation.
- *
- * This is used as a helper by Crypto to keep track of all the network requests
- * and other side-effects of bootstrapping, so it can be applied in one go (and retried in the future)
- * Also keeps track of all the private keys created during bootstrapping, so we don't need to prompt for them
- * more than once.
- */
-export declare class EncryptionSetupBuilder {
- readonly accountDataClientAdapter: AccountDataClientAdapter;
- readonly crossSigningCallbacks: CrossSigningCallbacks;
- readonly ssssCryptoCallbacks: SSSSCryptoCallbacks;
- private crossSigningKeys?;
- private keySignatures?;
- private keyBackupInfo?;
- private sessionBackupPrivateKey?;
- /**
- * @param accountData - pre-existing account data, will only be read, not written.
- * @param delegateCryptoCallbacks - crypto callbacks to delegate to if the key isn't in cache yet
- */
- constructor(accountData: Map<string, MatrixEvent>, delegateCryptoCallbacks?: ICryptoCallbacks);
- /**
- * Adds new cross-signing public keys
- *
- * @param authUpload - Function called to await an interactive auth
- * flow when uploading device signing keys.
- * Args:
- * A function that makes the request requiring auth. Receives
- * the auth data as an object. Can be called multiple times, first with
- * an empty authDict, to obtain the flows.
- * @param keys - the new keys
- */
- addCrossSigningKeys(authUpload: ICrossSigningKeys["authUpload"], keys: ICrossSigningKeys["keys"]): void;
- /**
- * Adds the key backup info to be updated on the server
- *
- * Used either to create a new key backup, or add signatures
- * from the new MSK.
- *
- * @param keyBackupInfo - as received from/sent to the server
- */
- addSessionBackup(keyBackupInfo: IKeyBackupInfo): void;
- /**
- * Adds the session backup private key to be updated in the local cache
- *
- * Used after fixing the format of the key
- *
- */
- addSessionBackupPrivateKeyToCache(privateKey: Uint8Array): void;
- /**
- * Add signatures from a given user and device/x-sign key
- * Used to sign the new cross-signing key with the device key
- *
- */
- addKeySignature(userId: string, deviceId: string, signature: ISignedKey): void;
- setAccountData(type: string, content: object): Promise<void>;
- /**
- * builds the operation containing all the parts that have been added to the builder
- */
- buildOperation(): EncryptionSetupOperation;
- /**
- * Stores the created keys locally.
- *
- * This does not yet store the operation in a way that it can be restored,
- * but that is the idea in the future.
- */
- persist(crypto: Crypto): Promise<void>;
-}
-/**
- * Can be created from EncryptionSetupBuilder, or
- * (in a follow-up PR, not implemented yet) restored from storage, to retry.
- *
- * It does not have knowledge of any private keys, unlike the builder.
- */
-export declare class EncryptionSetupOperation {
- private readonly accountData;
- private readonly crossSigningKeys?;
- private readonly keyBackupInfo?;
- private readonly keySignatures?;
- /**
- */
- constructor(accountData: Map<string, object>, crossSigningKeys?: ICrossSigningKeys | undefined, keyBackupInfo?: IKeyBackupInfo | undefined, keySignatures?: KeySignatures | undefined);
- /**
- * Runs the (remaining part of, in the future) operation by sending requests to the server.
- */
- apply(crypto: Crypto): Promise<void>;
-}
-/**
- * Catches account data set by SecretStorage during bootstrapping by
- * implementing the methods related to account data in MatrixClient
- */
-declare class AccountDataClientAdapter extends TypedEventEmitter<ClientEvent.AccountData, ClientEventHandlerMap> implements IAccountDataClient {
- private readonly existingValues;
- readonly values: Map<string, MatrixEvent>;
- /**
- * @param existingValues - existing account data
- */
- constructor(existingValues: Map<string, MatrixEvent>);
- /**
- * @returns the content of the account data
- */
- getAccountDataFromServer<T extends {
- [k: string]: any;
- }>(type: string): Promise<T>;
- /**
- * @returns the content of the account data
- */
- getAccountData(type: string): IContent | null;
- setAccountData(type: string, content: any): Promise<{}>;
-}
-/**
- * Catches the private cross-signing keys set during bootstrapping
- * by both cache callbacks (see createCryptoStoreCacheCallbacks) as non-cache callbacks.
- * See CrossSigningInfo constructor
- */
-declare class CrossSigningCallbacks implements ICryptoCallbacks, ICacheCallbacks {
- readonly privateKeys: Map<string, Uint8Array>;
- getCrossSigningKeyCache(type: string, expectedPublicKey: string): Promise<Uint8Array | null>;
- storeCrossSigningKeyCache(type: string, key: Uint8Array): Promise<void>;
- getCrossSigningKey(type: string, expectedPubkey: string): Promise<Uint8Array | null>;
- saveCrossSigningKeys(privateKeys: Record<string, Uint8Array>): void;
-}
-/**
- * Catches the 4S private key set during bootstrapping by implementing
- * the SecretStorage crypto callbacks
- */
-declare class SSSSCryptoCallbacks {
- private readonly delegateCryptoCallbacks?;
- private readonly privateKeys;
- constructor(delegateCryptoCallbacks?: ICryptoCallbacks | undefined);
- getSecretStorageKey({ keys }: {
- keys: Record<string, SecretStorageKeyDescription>;
- }, name: string): Promise<[string, Uint8Array] | null>;
- addPrivateKey(keyId: string, keyInfo: SecretStorageKeyDescription, privKey: Uint8Array): void;
-}
-export {};
-//# sourceMappingURL=EncryptionSetup.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/EncryptionSetup.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/EncryptionSetup.d.ts.map
deleted file mode 100644
index b35bc8a..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/EncryptionSetup.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"EncryptionSetup.d.ts","sourceRoot":"","sources":["../../src/crypto/EncryptionSetup.ts"],"names":[],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/EncryptionSetup.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/EncryptionSetup.js
deleted file mode 100644
index a0e98ca..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/EncryptionSetup.js
+++ /dev/null
@@ -1,350 +0,0 @@
-"use strict";
-
-var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.EncryptionSetupOperation = exports.EncryptionSetupBuilder = void 0;
-var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
-var _logger = require("../logger");
-var _event = require("../models/event");
-var _CrossSigning = require("./CrossSigning");
-var _indexeddbCryptoStore = require("./store/indexeddb-crypto-store");
-var _httpApi = require("../http-api");
-var _client = require("../client");
-var _typedEventEmitter = require("../models/typed-event-emitter");
-/*
-Copyright 2021 The Matrix.org Foundation C.I.C.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-/**
- * Builds an EncryptionSetupOperation by calling any of the add.. methods.
- * Once done, `buildOperation()` can be called which allows to apply to operation.
- *
- * This is used as a helper by Crypto to keep track of all the network requests
- * and other side-effects of bootstrapping, so it can be applied in one go (and retried in the future)
- * Also keeps track of all the private keys created during bootstrapping, so we don't need to prompt for them
- * more than once.
- */
-class EncryptionSetupBuilder {
- /**
- * @param accountData - pre-existing account data, will only be read, not written.
- * @param delegateCryptoCallbacks - crypto callbacks to delegate to if the key isn't in cache yet
- */
- constructor(accountData, delegateCryptoCallbacks) {
- (0, _defineProperty2.default)(this, "accountDataClientAdapter", void 0);
- (0, _defineProperty2.default)(this, "crossSigningCallbacks", void 0);
- (0, _defineProperty2.default)(this, "ssssCryptoCallbacks", void 0);
- (0, _defineProperty2.default)(this, "crossSigningKeys", void 0);
- (0, _defineProperty2.default)(this, "keySignatures", void 0);
- (0, _defineProperty2.default)(this, "keyBackupInfo", void 0);
- (0, _defineProperty2.default)(this, "sessionBackupPrivateKey", void 0);
- this.accountDataClientAdapter = new AccountDataClientAdapter(accountData);
- this.crossSigningCallbacks = new CrossSigningCallbacks();
- this.ssssCryptoCallbacks = new SSSSCryptoCallbacks(delegateCryptoCallbacks);
- }
-
- /**
- * Adds new cross-signing public keys
- *
- * @param authUpload - Function called to await an interactive auth
- * flow when uploading device signing keys.
- * Args:
- * A function that makes the request requiring auth. Receives
- * the auth data as an object. Can be called multiple times, first with
- * an empty authDict, to obtain the flows.
- * @param keys - the new keys
- */
- addCrossSigningKeys(authUpload, keys) {
- this.crossSigningKeys = {
- authUpload,
- keys
- };
- }
-
- /**
- * Adds the key backup info to be updated on the server
- *
- * Used either to create a new key backup, or add signatures
- * from the new MSK.
- *
- * @param keyBackupInfo - as received from/sent to the server
- */
- addSessionBackup(keyBackupInfo) {
- this.keyBackupInfo = keyBackupInfo;
- }
-
- /**
- * Adds the session backup private key to be updated in the local cache
- *
- * Used after fixing the format of the key
- *
- */
- addSessionBackupPrivateKeyToCache(privateKey) {
- this.sessionBackupPrivateKey = privateKey;
- }
-
- /**
- * Add signatures from a given user and device/x-sign key
- * Used to sign the new cross-signing key with the device key
- *
- */
- addKeySignature(userId, deviceId, signature) {
- if (!this.keySignatures) {
- this.keySignatures = {};
- }
- const userSignatures = this.keySignatures[userId] || {};
- this.keySignatures[userId] = userSignatures;
- userSignatures[deviceId] = signature;
- }
- async setAccountData(type, content) {
- await this.accountDataClientAdapter.setAccountData(type, content);
- }
-
- /**
- * builds the operation containing all the parts that have been added to the builder
- */
- buildOperation() {
- const accountData = this.accountDataClientAdapter.values;
- return new EncryptionSetupOperation(accountData, this.crossSigningKeys, this.keyBackupInfo, this.keySignatures);
- }
-
- /**
- * Stores the created keys locally.
- *
- * This does not yet store the operation in a way that it can be restored,
- * but that is the idea in the future.
- */
- async persist(crypto) {
- // store private keys in cache
- if (this.crossSigningKeys) {
- const cacheCallbacks = (0, _CrossSigning.createCryptoStoreCacheCallbacks)(crypto.cryptoStore, crypto.olmDevice);
- for (const type of ["master", "self_signing", "user_signing"]) {
- var _cacheCallbacks$store;
- _logger.logger.log(`Cache ${type} cross-signing private key locally`);
- const privateKey = this.crossSigningCallbacks.privateKeys.get(type);
- await ((_cacheCallbacks$store = cacheCallbacks.storeCrossSigningKeyCache) === null || _cacheCallbacks$store === void 0 ? void 0 : _cacheCallbacks$store.call(cacheCallbacks, type, privateKey));
- }
- // store own cross-sign pubkeys as trusted
- await crypto.cryptoStore.doTxn("readwrite", [_indexeddbCryptoStore.IndexedDBCryptoStore.STORE_ACCOUNT], txn => {
- crypto.cryptoStore.storeCrossSigningKeys(txn, this.crossSigningKeys.keys);
- });
- }
- // store session backup key in cache
- if (this.sessionBackupPrivateKey) {
- await crypto.storeSessionBackupPrivateKey(this.sessionBackupPrivateKey);
- }
- }
-}
-
-/**
- * Can be created from EncryptionSetupBuilder, or
- * (in a follow-up PR, not implemented yet) restored from storage, to retry.
- *
- * It does not have knowledge of any private keys, unlike the builder.
- */
-exports.EncryptionSetupBuilder = EncryptionSetupBuilder;
-class EncryptionSetupOperation {
- /**
- */
- constructor(accountData, crossSigningKeys, keyBackupInfo, keySignatures) {
- this.accountData = accountData;
- this.crossSigningKeys = crossSigningKeys;
- this.keyBackupInfo = keyBackupInfo;
- this.keySignatures = keySignatures;
- }
-
- /**
- * Runs the (remaining part of, in the future) operation by sending requests to the server.
- */
- async apply(crypto) {
- const baseApis = crypto.baseApis;
- // upload cross-signing keys
- if (this.crossSigningKeys) {
- var _this$crossSigningKey, _this$crossSigningKey2;
- const keys = {};
- for (const [name, key] of Object.entries(this.crossSigningKeys.keys)) {
- keys[name + "_key"] = key;
- }
-
- // We must only call `uploadDeviceSigningKeys` from inside this auth
- // helper to ensure we properly handle auth errors.
- await ((_this$crossSigningKey = (_this$crossSigningKey2 = this.crossSigningKeys).authUpload) === null || _this$crossSigningKey === void 0 ? void 0 : _this$crossSigningKey.call(_this$crossSigningKey2, authDict => {
- return baseApis.uploadDeviceSigningKeys(authDict, keys);
- }));
-
- // pass the new keys to the main instance of our own CrossSigningInfo.
- crypto.crossSigningInfo.setKeys(this.crossSigningKeys.keys);
- }
- // set account data
- if (this.accountData) {
- for (const [type, content] of this.accountData) {
- await baseApis.setAccountData(type, content);
- }
- }
- // upload first cross-signing signatures with the new key
- // (e.g. signing our own device)
- if (this.keySignatures) {
- await baseApis.uploadKeySignatures(this.keySignatures);
- }
- // need to create/update key backup info
- if (this.keyBackupInfo) {
- if (this.keyBackupInfo.version) {
- // session backup signature
- // The backup is trusted because the user provided the private key.
- // Sign the backup with the cross signing key so the key backup can
- // be trusted via cross-signing.
- await baseApis.http.authedRequest(_httpApi.Method.Put, "/room_keys/version/" + this.keyBackupInfo.version, undefined, {
- algorithm: this.keyBackupInfo.algorithm,
- auth_data: this.keyBackupInfo.auth_data
- }, {
- prefix: _httpApi.ClientPrefix.V3
- });
- } else {
- // add new key backup
- await baseApis.http.authedRequest(_httpApi.Method.Post, "/room_keys/version", undefined, this.keyBackupInfo, {
- prefix: _httpApi.ClientPrefix.V3
- });
- }
- }
- }
-}
-
-/**
- * Catches account data set by SecretStorage during bootstrapping by
- * implementing the methods related to account data in MatrixClient
- */
-exports.EncryptionSetupOperation = EncryptionSetupOperation;
-class AccountDataClientAdapter extends _typedEventEmitter.TypedEventEmitter {
- //
-
- /**
- * @param existingValues - existing account data
- */
- constructor(existingValues) {
- super();
- this.existingValues = existingValues;
- (0, _defineProperty2.default)(this, "values", new Map());
- }
-
- /**
- * @returns the content of the account data
- */
- getAccountDataFromServer(type) {
- return Promise.resolve(this.getAccountData(type));
- }
-
- /**
- * @returns the content of the account data
- */
- getAccountData(type) {
- const modifiedValue = this.values.get(type);
- if (modifiedValue) {
- return modifiedValue;
- }
- const existingValue = this.existingValues.get(type);
- if (existingValue) {
- return existingValue.getContent();
- }
- return null;
- }
- setAccountData(type, content) {
- const lastEvent = this.values.get(type);
- this.values.set(type, content);
- // ensure accountData is emitted on the next tick,
- // as SecretStorage listens for it while calling this method
- // and it seems to rely on this.
- return Promise.resolve().then(() => {
- const event = new _event.MatrixEvent({
- type,
- content
- });
- this.emit(_client.ClientEvent.AccountData, event, lastEvent);
- return {};
- });
- }
-}
-
-/**
- * Catches the private cross-signing keys set during bootstrapping
- * by both cache callbacks (see createCryptoStoreCacheCallbacks) as non-cache callbacks.
- * See CrossSigningInfo constructor
- */
-class CrossSigningCallbacks {
- constructor() {
- (0, _defineProperty2.default)(this, "privateKeys", new Map());
- }
- // cache callbacks
- getCrossSigningKeyCache(type, expectedPublicKey) {
- return this.getCrossSigningKey(type, expectedPublicKey);
- }
- storeCrossSigningKeyCache(type, key) {
- this.privateKeys.set(type, key);
- return Promise.resolve();
- }
-
- // non-cache callbacks
- getCrossSigningKey(type, expectedPubkey) {
- var _this$privateKeys$get;
- return Promise.resolve((_this$privateKeys$get = this.privateKeys.get(type)) !== null && _this$privateKeys$get !== void 0 ? _this$privateKeys$get : null);
- }
- saveCrossSigningKeys(privateKeys) {
- for (const [type, privateKey] of Object.entries(privateKeys)) {
- this.privateKeys.set(type, privateKey);
- }
- }
-}
-
-/**
- * Catches the 4S private key set during bootstrapping by implementing
- * the SecretStorage crypto callbacks
- */
-class SSSSCryptoCallbacks {
- constructor(delegateCryptoCallbacks) {
- this.delegateCryptoCallbacks = delegateCryptoCallbacks;
- (0, _defineProperty2.default)(this, "privateKeys", new Map());
- }
- async getSecretStorageKey({
- keys
- }, name) {
- var _this$delegateCryptoC;
- for (const keyId of Object.keys(keys)) {
- const privateKey = this.privateKeys.get(keyId);
- if (privateKey) {
- return [keyId, privateKey];
- }
- }
- // if we don't have the key cached yet, ask
- // for it to the general crypto callbacks and cache it
- if (this !== null && this !== void 0 && (_this$delegateCryptoC = this.delegateCryptoCallbacks) !== null && _this$delegateCryptoC !== void 0 && _this$delegateCryptoC.getSecretStorageKey) {
- const result = await this.delegateCryptoCallbacks.getSecretStorageKey({
- keys
- }, name);
- if (result) {
- const [keyId, privateKey] = result;
- this.privateKeys.set(keyId, privateKey);
- }
- return result;
- }
- return null;
- }
- addPrivateKey(keyId, keyInfo, privKey) {
- var _this$delegateCryptoC2, _this$delegateCryptoC3;
- this.privateKeys.set(keyId, privKey);
- // Also pass along to application to cache if it wishes
- (_this$delegateCryptoC2 = this.delegateCryptoCallbacks) === null || _this$delegateCryptoC2 === void 0 ? void 0 : (_this$delegateCryptoC3 = _this$delegateCryptoC2.cacheSecretStorageKey) === null || _this$delegateCryptoC3 === void 0 ? void 0 : _this$delegateCryptoC3.call(_this$delegateCryptoC2, keyId, keyInfo, privKey);
- }
-}
-//# sourceMappingURL=EncryptionSetup.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/EncryptionSetup.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/EncryptionSetup.js.map
deleted file mode 100644
index 9b80af9..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/EncryptionSetup.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"EncryptionSetup.js","names":["_logger","require","_event","_CrossSigning","_indexeddbCryptoStore","_httpApi","_client","_typedEventEmitter","EncryptionSetupBuilder","constructor","accountData","delegateCryptoCallbacks","_defineProperty2","default","accountDataClientAdapter","AccountDataClientAdapter","crossSigningCallbacks","CrossSigningCallbacks","ssssCryptoCallbacks","SSSSCryptoCallbacks","addCrossSigningKeys","authUpload","keys","crossSigningKeys","addSessionBackup","keyBackupInfo","addSessionBackupPrivateKeyToCache","privateKey","sessionBackupPrivateKey","addKeySignature","userId","deviceId","signature","keySignatures","userSignatures","setAccountData","type","content","buildOperation","values","EncryptionSetupOperation","persist","crypto","cacheCallbacks","createCryptoStoreCacheCallbacks","cryptoStore","olmDevice","_cacheCallbacks$store","logger","log","privateKeys","get","storeCrossSigningKeyCache","call","doTxn","IndexedDBCryptoStore","STORE_ACCOUNT","txn","storeCrossSigningKeys","storeSessionBackupPrivateKey","exports","apply","baseApis","_this$crossSigningKey","_this$crossSigningKey2","name","key","Object","entries","authDict","uploadDeviceSigningKeys","crossSigningInfo","setKeys","uploadKeySignatures","version","http","authedRequest","Method","Put","undefined","algorithm","auth_data","prefix","ClientPrefix","V3","Post","TypedEventEmitter","existingValues","Map","getAccountDataFromServer","Promise","resolve","getAccountData","modifiedValue","existingValue","getContent","lastEvent","set","then","event","MatrixEvent","emit","ClientEvent","AccountData","getCrossSigningKeyCache","expectedPublicKey","getCrossSigningKey","expectedPubkey","_this$privateKeys$get","saveCrossSigningKeys","getSecretStorageKey","_this$delegateCryptoC","keyId","result","addPrivateKey","keyInfo","privKey","_this$delegateCryptoC2","_this$delegateCryptoC3","cacheSecretStorageKey"],"sources":["../../src/crypto/EncryptionSetup.ts"],"sourcesContent":["/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { logger } from \"../logger\";\nimport { IContent, MatrixEvent } from \"../models/event\";\nimport { createCryptoStoreCacheCallbacks, ICacheCallbacks } from \"./CrossSigning\";\nimport { IndexedDBCryptoStore } from \"./store/indexeddb-crypto-store\";\nimport { Method, ClientPrefix } from \"../http-api\";\nimport { Crypto, ICryptoCallbacks, IBootstrapCrossSigningOpts } from \"./index\";\nimport {\n ClientEvent,\n ClientEventHandlerMap,\n CrossSigningKeys,\n ICrossSigningKey,\n ISignedKey,\n KeySignatures,\n} from \"../client\";\nimport { IKeyBackupInfo } from \"./keybackup\";\nimport { TypedEventEmitter } from \"../models/typed-event-emitter\";\nimport { IAccountDataClient } from \"./SecretStorage\";\nimport { SecretStorageKeyDescription } from \"../secret-storage\";\n\ninterface ICrossSigningKeys {\n authUpload: IBootstrapCrossSigningOpts[\"authUploadDeviceSigningKeys\"];\n keys: Record<\"master\" | \"self_signing\" | \"user_signing\", ICrossSigningKey>;\n}\n\n/**\n * Builds an EncryptionSetupOperation by calling any of the add.. methods.\n * Once done, `buildOperation()` can be called which allows to apply to operation.\n *\n * This is used as a helper by Crypto to keep track of all the network requests\n * and other side-effects of bootstrapping, so it can be applied in one go (and retried in the future)\n * Also keeps track of all the private keys created during bootstrapping, so we don't need to prompt for them\n * more than once.\n */\nexport class EncryptionSetupBuilder {\n public readonly accountDataClientAdapter: AccountDataClientAdapter;\n public readonly crossSigningCallbacks: CrossSigningCallbacks;\n public readonly ssssCryptoCallbacks: SSSSCryptoCallbacks;\n\n private crossSigningKeys?: ICrossSigningKeys;\n private keySignatures?: KeySignatures;\n private keyBackupInfo?: IKeyBackupInfo;\n private sessionBackupPrivateKey?: Uint8Array;\n\n /**\n * @param accountData - pre-existing account data, will only be read, not written.\n * @param delegateCryptoCallbacks - crypto callbacks to delegate to if the key isn't in cache yet\n */\n public constructor(accountData: Map<string, MatrixEvent>, delegateCryptoCallbacks?: ICryptoCallbacks) {\n this.accountDataClientAdapter = new AccountDataClientAdapter(accountData);\n this.crossSigningCallbacks = new CrossSigningCallbacks();\n this.ssssCryptoCallbacks = new SSSSCryptoCallbacks(delegateCryptoCallbacks);\n }\n\n /**\n * Adds new cross-signing public keys\n *\n * @param authUpload - Function called to await an interactive auth\n * flow when uploading device signing keys.\n * Args:\n * A function that makes the request requiring auth. Receives\n * the auth data as an object. Can be called multiple times, first with\n * an empty authDict, to obtain the flows.\n * @param keys - the new keys\n */\n public addCrossSigningKeys(authUpload: ICrossSigningKeys[\"authUpload\"], keys: ICrossSigningKeys[\"keys\"]): void {\n this.crossSigningKeys = { authUpload, keys };\n }\n\n /**\n * Adds the key backup info to be updated on the server\n *\n * Used either to create a new key backup, or add signatures\n * from the new MSK.\n *\n * @param keyBackupInfo - as received from/sent to the server\n */\n public addSessionBackup(keyBackupInfo: IKeyBackupInfo): void {\n this.keyBackupInfo = keyBackupInfo;\n }\n\n /**\n * Adds the session backup private key to be updated in the local cache\n *\n * Used after fixing the format of the key\n *\n */\n public addSessionBackupPrivateKeyToCache(privateKey: Uint8Array): void {\n this.sessionBackupPrivateKey = privateKey;\n }\n\n /**\n * Add signatures from a given user and device/x-sign key\n * Used to sign the new cross-signing key with the device key\n *\n */\n public addKeySignature(userId: string, deviceId: string, signature: ISignedKey): void {\n if (!this.keySignatures) {\n this.keySignatures = {};\n }\n const userSignatures = this.keySignatures[userId] || {};\n this.keySignatures[userId] = userSignatures;\n userSignatures[deviceId] = signature;\n }\n\n public async setAccountData(type: string, content: object): Promise<void> {\n await this.accountDataClientAdapter.setAccountData(type, content);\n }\n\n /**\n * builds the operation containing all the parts that have been added to the builder\n */\n public buildOperation(): EncryptionSetupOperation {\n const accountData = this.accountDataClientAdapter.values;\n return new EncryptionSetupOperation(accountData, this.crossSigningKeys, this.keyBackupInfo, this.keySignatures);\n }\n\n /**\n * Stores the created keys locally.\n *\n * This does not yet store the operation in a way that it can be restored,\n * but that is the idea in the future.\n */\n public async persist(crypto: Crypto): Promise<void> {\n // store private keys in cache\n if (this.crossSigningKeys) {\n const cacheCallbacks = createCryptoStoreCacheCallbacks(crypto.cryptoStore, crypto.olmDevice);\n for (const type of [\"master\", \"self_signing\", \"user_signing\"]) {\n logger.log(`Cache ${type} cross-signing private key locally`);\n const privateKey = this.crossSigningCallbacks.privateKeys.get(type);\n await cacheCallbacks.storeCrossSigningKeyCache?.(type, privateKey);\n }\n // store own cross-sign pubkeys as trusted\n await crypto.cryptoStore.doTxn(\"readwrite\", [IndexedDBCryptoStore.STORE_ACCOUNT], (txn) => {\n crypto.cryptoStore.storeCrossSigningKeys(txn, this.crossSigningKeys!.keys);\n });\n }\n // store session backup key in cache\n if (this.sessionBackupPrivateKey) {\n await crypto.storeSessionBackupPrivateKey(this.sessionBackupPrivateKey);\n }\n }\n}\n\n/**\n * Can be created from EncryptionSetupBuilder, or\n * (in a follow-up PR, not implemented yet) restored from storage, to retry.\n *\n * It does not have knowledge of any private keys, unlike the builder.\n */\nexport class EncryptionSetupOperation {\n /**\n */\n public constructor(\n private readonly accountData: Map<string, object>,\n private readonly crossSigningKeys?: ICrossSigningKeys,\n private readonly keyBackupInfo?: IKeyBackupInfo,\n private readonly keySignatures?: KeySignatures,\n ) {}\n\n /**\n * Runs the (remaining part of, in the future) operation by sending requests to the server.\n */\n public async apply(crypto: Crypto): Promise<void> {\n const baseApis = crypto.baseApis;\n // upload cross-signing keys\n if (this.crossSigningKeys) {\n const keys: Partial<CrossSigningKeys> = {};\n for (const [name, key] of Object.entries(this.crossSigningKeys.keys)) {\n keys[((name as keyof ICrossSigningKeys[\"keys\"]) + \"_key\") as keyof CrossSigningKeys] = key;\n }\n\n // We must only call `uploadDeviceSigningKeys` from inside this auth\n // helper to ensure we properly handle auth errors.\n await this.crossSigningKeys.authUpload?.((authDict) => {\n return baseApis.uploadDeviceSigningKeys(authDict, keys as CrossSigningKeys);\n });\n\n // pass the new keys to the main instance of our own CrossSigningInfo.\n crypto.crossSigningInfo.setKeys(this.crossSigningKeys.keys);\n }\n // set account data\n if (this.accountData) {\n for (const [type, content] of this.accountData) {\n await baseApis.setAccountData(type, content);\n }\n }\n // upload first cross-signing signatures with the new key\n // (e.g. signing our own device)\n if (this.keySignatures) {\n await baseApis.uploadKeySignatures(this.keySignatures);\n }\n // need to create/update key backup info\n if (this.keyBackupInfo) {\n if (this.keyBackupInfo.version) {\n // session backup signature\n // The backup is trusted because the user provided the private key.\n // Sign the backup with the cross signing key so the key backup can\n // be trusted via cross-signing.\n await baseApis.http.authedRequest(\n Method.Put,\n \"/room_keys/version/\" + this.keyBackupInfo.version,\n undefined,\n {\n algorithm: this.keyBackupInfo.algorithm,\n auth_data: this.keyBackupInfo.auth_data,\n },\n { prefix: ClientPrefix.V3 },\n );\n } else {\n // add new key backup\n await baseApis.http.authedRequest(Method.Post, \"/room_keys/version\", undefined, this.keyBackupInfo, {\n prefix: ClientPrefix.V3,\n });\n }\n }\n }\n}\n\n/**\n * Catches account data set by SecretStorage during bootstrapping by\n * implementing the methods related to account data in MatrixClient\n */\nclass AccountDataClientAdapter\n extends TypedEventEmitter<ClientEvent.AccountData, ClientEventHandlerMap>\n implements IAccountDataClient\n{\n //\n public readonly values = new Map<string, MatrixEvent>();\n\n /**\n * @param existingValues - existing account data\n */\n public constructor(private readonly existingValues: Map<string, MatrixEvent>) {\n super();\n }\n\n /**\n * @returns the content of the account data\n */\n public getAccountDataFromServer<T extends { [k: string]: any }>(type: string): Promise<T> {\n return Promise.resolve(this.getAccountData(type) as T);\n }\n\n /**\n * @returns the content of the account data\n */\n public getAccountData(type: string): IContent | null {\n const modifiedValue = this.values.get(type);\n if (modifiedValue) {\n return modifiedValue;\n }\n const existingValue = this.existingValues.get(type);\n if (existingValue) {\n return existingValue.getContent();\n }\n return null;\n }\n\n public setAccountData(type: string, content: any): Promise<{}> {\n const lastEvent = this.values.get(type);\n this.values.set(type, content);\n // ensure accountData is emitted on the next tick,\n // as SecretStorage listens for it while calling this method\n // and it seems to rely on this.\n return Promise.resolve().then(() => {\n const event = new MatrixEvent({ type, content });\n this.emit(ClientEvent.AccountData, event, lastEvent);\n return {};\n });\n }\n}\n\n/**\n * Catches the private cross-signing keys set during bootstrapping\n * by both cache callbacks (see createCryptoStoreCacheCallbacks) as non-cache callbacks.\n * See CrossSigningInfo constructor\n */\nclass CrossSigningCallbacks implements ICryptoCallbacks, ICacheCallbacks {\n public readonly privateKeys = new Map<string, Uint8Array>();\n\n // cache callbacks\n public getCrossSigningKeyCache(type: string, expectedPublicKey: string): Promise<Uint8Array | null> {\n return this.getCrossSigningKey(type, expectedPublicKey);\n }\n\n public storeCrossSigningKeyCache(type: string, key: Uint8Array): Promise<void> {\n this.privateKeys.set(type, key);\n return Promise.resolve();\n }\n\n // non-cache callbacks\n public getCrossSigningKey(type: string, expectedPubkey: string): Promise<Uint8Array | null> {\n return Promise.resolve(this.privateKeys.get(type) ?? null);\n }\n\n public saveCrossSigningKeys(privateKeys: Record<string, Uint8Array>): void {\n for (const [type, privateKey] of Object.entries(privateKeys)) {\n this.privateKeys.set(type, privateKey);\n }\n }\n}\n\n/**\n * Catches the 4S private key set during bootstrapping by implementing\n * the SecretStorage crypto callbacks\n */\nclass SSSSCryptoCallbacks {\n private readonly privateKeys = new Map<string, Uint8Array>();\n\n public constructor(private readonly delegateCryptoCallbacks?: ICryptoCallbacks) {}\n\n public async getSecretStorageKey(\n { keys }: { keys: Record<string, SecretStorageKeyDescription> },\n name: string,\n ): Promise<[string, Uint8Array] | null> {\n for (const keyId of Object.keys(keys)) {\n const privateKey = this.privateKeys.get(keyId);\n if (privateKey) {\n return [keyId, privateKey];\n }\n }\n // if we don't have the key cached yet, ask\n // for it to the general crypto callbacks and cache it\n if (this?.delegateCryptoCallbacks?.getSecretStorageKey) {\n const result = await this.delegateCryptoCallbacks.getSecretStorageKey({ keys }, name);\n if (result) {\n const [keyId, privateKey] = result;\n this.privateKeys.set(keyId, privateKey);\n }\n return result;\n }\n return null;\n }\n\n public addPrivateKey(keyId: string, keyInfo: SecretStorageKeyDescription, privKey: Uint8Array): void {\n this.privateKeys.set(keyId, privKey);\n // Also pass along to application to cache if it wishes\n this.delegateCryptoCallbacks?.cacheSecretStorageKey?.(keyId, keyInfo, privKey);\n }\n}\n"],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/OlmDevice.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/OlmDevice.d.ts
deleted file mode 100644
index 3b8bbe9..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/OlmDevice.d.ts
+++ /dev/null
@@ -1,454 +0,0 @@
-import { PrefixedLogger } from "../logger";
-import { CryptoStore, IProblem, ISessionInfo } from "./store/base";
-import { IOlmDevice, IOutboundGroupSessionKey } from "./algorithms/megolm";
-import { IMegolmSessionData, OlmGroupSessionExtraData } from "../@types/crypto";
-import { IMessage } from "./algorithms/olm";
-export declare class PayloadTooLargeError extends Error {
- readonly data: {
- errcode: string;
- error: string;
- };
-}
-interface IInitOpts {
- fromExportedDevice?: IExportedDevice;
- pickleKey?: string;
-}
-/** data stored in the session store about an inbound group session */
-export interface InboundGroupSessionData {
- room_id: string;
- /** pickled Olm.InboundGroupSession */
- session: string;
- keysClaimed: Record<string, string>;
- /** Devices involved in forwarding this session to us (normally empty). */
- forwardingCurve25519KeyChain: string[];
- /** whether this session is untrusted. */
- untrusted?: boolean;
- /** whether this session exists during the room being set to shared history. */
- sharedHistory?: boolean;
-}
-export interface IDecryptedGroupMessage {
- result: string;
- keysClaimed: Record<string, string>;
- senderKey: string;
- forwardingCurve25519KeyChain: string[];
- untrusted: boolean;
-}
-export interface IInboundSession {
- payload: string;
- session_id: string;
-}
-export interface IExportedDevice {
- pickleKey: string;
- pickledAccount: string;
- sessions: ISessionInfo[];
-}
-interface IInboundGroupSessionKey {
- chain_index: number;
- key: string;
- forwarding_curve25519_key_chain: string[];
- sender_claimed_ed25519_key: string | null;
- shared_history: boolean;
- untrusted?: boolean;
-}
-type OneTimeKeys = {
- curve25519: {
- [keyId: string]: string;
- };
-};
-/**
- * Manages the olm cryptography functions. Each OlmDevice has a single
- * OlmAccount and a number of OlmSessions.
- *
- * Accounts and sessions are kept pickled in the cryptoStore.
- */
-export declare class OlmDevice {
- private readonly cryptoStore;
- pickleKey: string;
- /** Curve25519 key for the account, unknown until we load the account from storage in init() */
- deviceCurve25519Key: string | null;
- /** Ed25519 key for the account, unknown until we load the account from storage in init() */
- deviceEd25519Key: string | null;
- private maxOneTimeKeys;
- private outboundGroupSessionStore;
- private inboundGroupSessionMessageIndexes;
- sessionsInProgress: Record<string, Promise<void>>;
- olmPrekeyPromise: Promise<any>;
- constructor(cryptoStore: CryptoStore);
- /**
- * @returns The version of Olm.
- */
- static getOlmVersion(): [number, number, number];
- /**
- * Initialise the OlmAccount. This must be called before any other operations
- * on the OlmDevice.
- *
- * Data from an exported Olm device can be provided
- * in order to re-create this device.
- *
- * Attempts to load the OlmAccount from the crypto store, or creates one if none is
- * found.
- *
- * Reads the device keys from the OlmAccount object.
- *
- * @param fromExportedDevice - (Optional) data from exported device
- * that must be re-created.
- * If present, opts.pickleKey is ignored
- * (exported data already provides a pickle key)
- * @param pickleKey - (Optional) pickle key to set instead of default one
- */
- init({ pickleKey, fromExportedDevice }?: IInitOpts): Promise<void>;
- /**
- * Populates the crypto store using data that was exported from an existing device.
- * Note that for now only the “account” and “sessions” stores are populated;
- * Other stores will be as with a new device.
- *
- * @param exportedData - Data exported from another device
- * through the “export” method.
- * @param account - an olm account to initialize
- */
- private initialiseFromExportedDevice;
- private initialiseAccount;
- /**
- * extract our OlmAccount from the crypto store and call the given function
- * with the account object
- * The `account` object is usable only within the callback passed to this
- * function and will be freed as soon the callback returns. It is *not*
- * usable for the rest of the lifetime of the transaction.
- * This function requires a live transaction object from cryptoStore.doTxn()
- * and therefore may only be called in a doTxn() callback.
- *
- * @param txn - Opaque transaction object from cryptoStore.doTxn()
- * @internal
- */
- private getAccount;
- private storeAccount;
- /**
- * Export data for re-creating the Olm device later.
- * TODO export data other than just account and (P2P) sessions.
- *
- * @returns The exported data
- */
- export(): Promise<IExportedDevice>;
- /**
- * extract an OlmSession from the session store and call the given function
- * The session is usable only within the callback passed to this
- * function and will be freed as soon the callback returns. It is *not*
- * usable for the rest of the lifetime of the transaction.
- *
- * @param txn - Opaque transaction object from cryptoStore.doTxn()
- * @internal
- */
- private getSession;
- /**
- * Creates a session object from a session pickle and executes the given
- * function with it. The session object is destroyed once the function
- * returns.
- *
- * @internal
- */
- private unpickleSession;
- /**
- * store our OlmSession in the session store
- *
- * @param sessionInfo - `{session: OlmSession, lastReceivedMessageTs: int}`
- * @param txn - Opaque transaction object from cryptoStore.doTxn()
- * @internal
- */
- private saveSession;
- /**
- * get an OlmUtility and call the given function
- *
- * @returns result of func
- * @internal
- */
- private getUtility;
- /**
- * Signs a message with the ed25519 key for this account.
- *
- * @param message - message to be signed
- * @returns base64-encoded signature
- */
- sign(message: string): Promise<string>;
- /**
- * Get the current (unused, unpublished) one-time keys for this account.
- *
- * @returns one time keys; an object with the single property
- * <tt>curve25519</tt>, which is itself an object mapping key id to Curve25519
- * key.
- */
- getOneTimeKeys(): Promise<OneTimeKeys>;
- /**
- * Get the maximum number of one-time keys we can store.
- *
- * @returns number of keys
- */
- maxNumberOfOneTimeKeys(): number;
- /**
- * Marks all of the one-time keys as published.
- */
- markKeysAsPublished(): Promise<void>;
- /**
- * Generate some new one-time keys
- *
- * @param numKeys - number of keys to generate
- * @returns Resolved once the account is saved back having generated the keys
- */
- generateOneTimeKeys(numKeys: number): Promise<void>;
- /**
- * Generate a new fallback keys
- *
- * @returns Resolved once the account is saved back having generated the key
- */
- generateFallbackKey(): Promise<void>;
- getFallbackKey(): Promise<Record<string, Record<string, string>>>;
- forgetOldFallbackKey(): Promise<void>;
- /**
- * Generate a new outbound session
- *
- * The new session will be stored in the cryptoStore.
- *
- * @param theirIdentityKey - remote user's Curve25519 identity key
- * @param theirOneTimeKey - remote user's one-time Curve25519 key
- * @returns sessionId for the outbound session.
- */
- createOutboundSession(theirIdentityKey: string, theirOneTimeKey: string): Promise<string>;
- /**
- * Generate a new inbound session, given an incoming message
- *
- * @param theirDeviceIdentityKey - remote user's Curve25519 identity key
- * @param messageType - messageType field from the received message (must be 0)
- * @param ciphertext - base64-encoded body from the received message
- *
- * @returns decrypted payload, and
- * session id of new session
- *
- * @throws Error if the received message was not valid (for instance, it didn't use a valid one-time key).
- */
- createInboundSession(theirDeviceIdentityKey: string, messageType: number, ciphertext: string): Promise<IInboundSession>;
- /**
- * Get a list of known session IDs for the given device
- *
- * @param theirDeviceIdentityKey - Curve25519 identity key for the
- * remote device
- * @returns a list of known session ids for the device
- */
- getSessionIdsForDevice(theirDeviceIdentityKey: string): Promise<string[]>;
- /**
- * Get the right olm session id for encrypting messages to the given identity key
- *
- * @param theirDeviceIdentityKey - Curve25519 identity key for the
- * remote device
- * @param nowait - Don't wait for an in-progress session to complete.
- * This should only be set to true of the calling function is the function
- * that marked the session as being in-progress.
- * @param log - A possibly customised log
- * @returns session id, or null if no established session
- */
- getSessionIdForDevice(theirDeviceIdentityKey: string, nowait?: boolean, log?: PrefixedLogger): Promise<string | null>;
- /**
- * Get information on the active Olm sessions for a device.
- * <p>
- * Returns an array, with an entry for each active session. The first entry in
- * the result will be the one used for outgoing messages. Each entry contains
- * the keys 'hasReceivedMessage' (true if the session has received an incoming
- * message and is therefore past the pre-key stage), and 'sessionId'.
- *
- * @param deviceIdentityKey - Curve25519 identity key for the device
- * @param nowait - Don't wait for an in-progress session to complete.
- * This should only be set to true of the calling function is the function
- * that marked the session as being in-progress.
- * @param log - A possibly customised log
- */
- getSessionInfoForDevice(deviceIdentityKey: string, nowait?: boolean, log?: PrefixedLogger): Promise<{
- sessionId: string;
- lastReceivedMessageTs: number;
- hasReceivedMessage: boolean;
- }[]>;
- /**
- * Encrypt an outgoing message using an existing session
- *
- * @param theirDeviceIdentityKey - Curve25519 identity key for the
- * remote device
- * @param sessionId - the id of the active session
- * @param payloadString - payload to be encrypted and sent
- *
- * @returns ciphertext
- */
- encryptMessage(theirDeviceIdentityKey: string, sessionId: string, payloadString: string): Promise<IMessage>;
- /**
- * Decrypt an incoming message using an existing session
- *
- * @param theirDeviceIdentityKey - Curve25519 identity key for the
- * remote device
- * @param sessionId - the id of the active session
- * @param messageType - messageType field from the received message
- * @param ciphertext - base64-encoded body from the received message
- *
- * @returns decrypted payload.
- */
- decryptMessage(theirDeviceIdentityKey: string, sessionId: string, messageType: number, ciphertext: string): Promise<string>;
- /**
- * Determine if an incoming messages is a prekey message matching an existing session
- *
- * @param theirDeviceIdentityKey - Curve25519 identity key for the
- * remote device
- * @param sessionId - the id of the active session
- * @param messageType - messageType field from the received message
- * @param ciphertext - base64-encoded body from the received message
- *
- * @returns true if the received message is a prekey message which matches
- * the given session.
- */
- matchesSession(theirDeviceIdentityKey: string, sessionId: string, messageType: number, ciphertext: string): Promise<boolean>;
- recordSessionProblem(deviceKey: string, type: string, fixed: boolean): Promise<void>;
- sessionMayHaveProblems(deviceKey: string, timestamp: number): Promise<IProblem | null>;
- filterOutNotifiedErrorDevices(devices: IOlmDevice[]): Promise<IOlmDevice[]>;
- /**
- * store an OutboundGroupSession in outboundGroupSessionStore
- *
- * @internal
- */
- private saveOutboundGroupSession;
- /**
- * extract an OutboundGroupSession from outboundGroupSessionStore and call the
- * given function
- *
- * @returns result of func
- * @internal
- */
- private getOutboundGroupSession;
- /**
- * Generate a new outbound group session
- *
- * @returns sessionId for the outbound session.
- */
- createOutboundGroupSession(): string;
- /**
- * Encrypt an outgoing message with an outbound group session
- *
- * @param sessionId - the id of the outboundgroupsession
- * @param payloadString - payload to be encrypted and sent
- *
- * @returns ciphertext
- */
- encryptGroupMessage(sessionId: string, payloadString: string): string;
- /**
- * Get the session keys for an outbound group session
- *
- * @param sessionId - the id of the outbound group session
- *
- * @returns current chain index, and
- * base64-encoded secret key.
- */
- getOutboundGroupSessionKey(sessionId: string): IOutboundGroupSessionKey;
- /**
- * Unpickle a session from a sessionData object and invoke the given function.
- * The session is valid only until func returns.
- *
- * @param sessionData - Object describing the session.
- * @param func - Invoked with the unpickled session
- * @returns result of func
- */
- private unpickleInboundGroupSession;
- /**
- * extract an InboundGroupSession from the crypto store and call the given function
- *
- * @param roomId - The room ID to extract the session for, or null to fetch
- * sessions for any room.
- * @param txn - Opaque transaction object from cryptoStore.doTxn()
- * @param func - function to call.
- *
- * @internal
- */
- private getInboundGroupSession;
- /**
- * Add an inbound group session to the session store
- *
- * @param roomId - room in which this session will be used
- * @param senderKey - base64-encoded curve25519 key of the sender
- * @param forwardingCurve25519KeyChain - Devices involved in forwarding
- * this session to us.
- * @param sessionId - session identifier
- * @param sessionKey - base64-encoded secret key
- * @param keysClaimed - Other keys the sender claims.
- * @param exportFormat - true if the megolm keys are in export format
- * (ie, they lack an ed25519 signature)
- * @param extraSessionData - any other data to be include with the session
- */
- addInboundGroupSession(roomId: string, senderKey: string, forwardingCurve25519KeyChain: string[], sessionId: string, sessionKey: string, keysClaimed: Record<string, string>, exportFormat: boolean, extraSessionData?: OlmGroupSessionExtraData): Promise<void>;
- /**
- * Record in the data store why an inbound group session was withheld.
- *
- * @param roomId - room that the session belongs to
- * @param senderKey - base64-encoded curve25519 key of the sender
- * @param sessionId - session identifier
- * @param code - reason code
- * @param reason - human-readable version of `code`
- */
- addInboundGroupSessionWithheld(roomId: string, senderKey: string, sessionId: string, code: string, reason: string): Promise<void>;
- /**
- * Decrypt a received message with an inbound group session
- *
- * @param roomId - room in which the message was received
- * @param senderKey - base64-encoded curve25519 key of the sender
- * @param sessionId - session identifier
- * @param body - base64-encoded body of the encrypted message
- * @param eventId - ID of the event being decrypted
- * @param timestamp - timestamp of the event being decrypted
- *
- * @returns null if the sessionId is unknown
- */
- decryptGroupMessage(roomId: string, senderKey: string, sessionId: string, body: string, eventId: string, timestamp: number): Promise<IDecryptedGroupMessage | null>;
- /**
- * Determine if we have the keys for a given megolm session
- *
- * @param roomId - room in which the message was received
- * @param senderKey - base64-encoded curve25519 key of the sender
- * @param sessionId - session identifier
- *
- * @returns true if we have the keys to this session
- */
- hasInboundSessionKeys(roomId: string, senderKey: string, sessionId: string): Promise<boolean>;
- /**
- * Extract the keys to a given megolm session, for sharing
- *
- * @param roomId - room in which the message was received
- * @param senderKey - base64-encoded curve25519 key of the sender
- * @param sessionId - session identifier
- * @param chainIndex - The chain index at which to export the session.
- * If omitted, export at the first index we know about.
- *
- * @returns
- * details of the session key. The key is a base64-encoded megolm key in
- * export format.
- *
- * @throws Error If the given chain index could not be obtained from the known
- * index (ie. the given chain index is before the first we have).
- */
- getInboundGroupSessionKey(roomId: string, senderKey: string, sessionId: string, chainIndex?: number): Promise<IInboundGroupSessionKey | null>;
- /**
- * Export an inbound group session
- *
- * @param senderKey - base64-encoded curve25519 key of the sender
- * @param sessionId - session identifier
- * @param sessionData - The session object from the store
- * @returns exported session data
- */
- exportInboundGroupSession(senderKey: string, sessionId: string, sessionData: InboundGroupSessionData): IMegolmSessionData;
- getSharedHistoryInboundGroupSessions(roomId: string): Promise<[senderKey: string, sessionId: string][]>;
- /**
- * Verify an ed25519 signature.
- *
- * @param key - ed25519 key
- * @param message - message which was signed
- * @param signature - base64-encoded signature to be checked
- *
- * @throws Error if there is a problem with the verification. If the key was
- * too small then the message will be "OLM.INVALID_BASE64". If the signature
- * was invalid then the message will be "OLM.BAD_MESSAGE_MAC".
- */
- verifySignature(key: string, message: string, signature: string): void;
-}
-export declare const WITHHELD_MESSAGES: Record<string, string>;
-export {};
-//# sourceMappingURL=OlmDevice.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/OlmDevice.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/OlmDevice.d.ts.map
deleted file mode 100644
index 710db52..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/OlmDevice.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"OlmDevice.d.ts","sourceRoot":"","sources":["../../src/crypto/OlmDevice.ts"],"names":[],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/OlmDevice.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/OlmDevice.js
deleted file mode 100644
index adfbe01..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/OlmDevice.js
+++ /dev/null
@@ -1,1164 +0,0 @@
-"use strict";
-
-var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.WITHHELD_MESSAGES = exports.PayloadTooLargeError = exports.OlmDevice = void 0;
-var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
-var _logger = require("../logger");
-var _indexeddbCryptoStore = require("./store/indexeddb-crypto-store");
-var algorithms = _interopRequireWildcard(require("./algorithms"));
-function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
-function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
-/*
-Copyright 2016 - 2021 The Matrix.org Foundation C.I.C.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-// The maximum size of an event is 65K, and we base64 the content, so this is a
-// reasonable approximation to the biggest plaintext we can encrypt.
-const MAX_PLAINTEXT_LENGTH = 65536 * 3 / 4;
-class PayloadTooLargeError extends Error {
- constructor(...args) {
- super(...args);
- (0, _defineProperty2.default)(this, "data", {
- errcode: "M_TOO_LARGE",
- error: "Payload too large for encrypted message"
- });
- }
-}
-exports.PayloadTooLargeError = PayloadTooLargeError;
-function checkPayloadLength(payloadString) {
- if (payloadString === undefined) {
- throw new Error("payloadString undefined");
- }
- if (payloadString.length > MAX_PLAINTEXT_LENGTH) {
- // might as well fail early here rather than letting the olm library throw
- // a cryptic memory allocation error.
- //
- // Note that even if we manage to do the encryption, the message send may fail,
- // because by the time we've wrapped the ciphertext in the event object, it may
- // exceed 65K. But at least we won't just fail with "abort()" in that case.
- throw new PayloadTooLargeError(`Message too long (${payloadString.length} bytes). ` + `The maximum for an encrypted message is ${MAX_PLAINTEXT_LENGTH} bytes.`);
- }
-}
-/**
- * Manages the olm cryptography functions. Each OlmDevice has a single
- * OlmAccount and a number of OlmSessions.
- *
- * Accounts and sessions are kept pickled in the cryptoStore.
- */
-class OlmDevice {
- // set by consumers
-
- /** Curve25519 key for the account, unknown until we load the account from storage in init() */
-
- /** Ed25519 key for the account, unknown until we load the account from storage in init() */
-
- // we don't bother stashing outboundgroupsessions in the cryptoStore -
- // instead we keep them here.
-
- // Store a set of decrypted message indexes for each group session.
- // This partially mitigates a replay attack where a MITM resends a group
- // message into the room.
- //
- // When we decrypt a message and the message index matches a previously
- // decrypted message, one possible cause of that is that we are decrypting
- // the same event, and may not indicate an actual replay attack. For
- // example, this could happen if we receive events, forget about them, and
- // then re-fetch them when we backfill. So we store the event ID and
- // timestamp corresponding to each message index when we first decrypt it,
- // and compare these against the event ID and timestamp every time we use
- // that same index. If they match, then we're probably decrypting the same
- // event and we don't consider it a replay attack.
- //
- // Keys are strings of form "<senderKey>|<session_id>|<message_index>"
- // Values are objects of the form "{id: <event id>, timestamp: <ts>}"
-
- // Keep track of sessions that we're starting, so that we don't start
- // multiple sessions for the same device at the same time.
- // set by consumers
-
- // Used by olm to serialise prekey message decryptions
- // set by consumers
-
- constructor(cryptoStore) {
- this.cryptoStore = cryptoStore;
- (0, _defineProperty2.default)(this, "pickleKey", "DEFAULT_KEY");
- (0, _defineProperty2.default)(this, "deviceCurve25519Key", null);
- (0, _defineProperty2.default)(this, "deviceEd25519Key", null);
- (0, _defineProperty2.default)(this, "maxOneTimeKeys", null);
- (0, _defineProperty2.default)(this, "outboundGroupSessionStore", {});
- (0, _defineProperty2.default)(this, "inboundGroupSessionMessageIndexes", {});
- (0, _defineProperty2.default)(this, "sessionsInProgress", {});
- (0, _defineProperty2.default)(this, "olmPrekeyPromise", Promise.resolve());
- }
-
- /**
- * @returns The version of Olm.
- */
- static getOlmVersion() {
- return global.Olm.get_library_version();
- }
-
- /**
- * Initialise the OlmAccount. This must be called before any other operations
- * on the OlmDevice.
- *
- * Data from an exported Olm device can be provided
- * in order to re-create this device.
- *
- * Attempts to load the OlmAccount from the crypto store, or creates one if none is
- * found.
- *
- * Reads the device keys from the OlmAccount object.
- *
- * @param fromExportedDevice - (Optional) data from exported device
- * that must be re-created.
- * If present, opts.pickleKey is ignored
- * (exported data already provides a pickle key)
- * @param pickleKey - (Optional) pickle key to set instead of default one
- */
- async init({
- pickleKey,
- fromExportedDevice
- } = {}) {
- let e2eKeys;
- const account = new global.Olm.Account();
- try {
- if (fromExportedDevice) {
- if (pickleKey) {
- _logger.logger.warn("ignoring opts.pickleKey" + " because opts.fromExportedDevice is present.");
- }
- this.pickleKey = fromExportedDevice.pickleKey;
- await this.initialiseFromExportedDevice(fromExportedDevice, account);
- } else {
- if (pickleKey) {
- this.pickleKey = pickleKey;
- }
- await this.initialiseAccount(account);
- }
- e2eKeys = JSON.parse(account.identity_keys());
- this.maxOneTimeKeys = account.max_number_of_one_time_keys();
- } finally {
- account.free();
- }
- this.deviceCurve25519Key = e2eKeys.curve25519;
- this.deviceEd25519Key = e2eKeys.ed25519;
- }
-
- /**
- * Populates the crypto store using data that was exported from an existing device.
- * Note that for now only the “account” and “sessions” stores are populated;
- * Other stores will be as with a new device.
- *
- * @param exportedData - Data exported from another device
- * through the “export” method.
- * @param account - an olm account to initialize
- */
- async initialiseFromExportedDevice(exportedData, account) {
- await this.cryptoStore.doTxn("readwrite", [_indexeddbCryptoStore.IndexedDBCryptoStore.STORE_ACCOUNT, _indexeddbCryptoStore.IndexedDBCryptoStore.STORE_SESSIONS], txn => {
- this.cryptoStore.storeAccount(txn, exportedData.pickledAccount);
- exportedData.sessions.forEach(session => {
- const {
- deviceKey,
- sessionId
- } = session;
- const sessionInfo = {
- session: session.session,
- lastReceivedMessageTs: session.lastReceivedMessageTs
- };
- this.cryptoStore.storeEndToEndSession(deviceKey, sessionId, sessionInfo, txn);
- });
- });
- account.unpickle(this.pickleKey, exportedData.pickledAccount);
- }
- async initialiseAccount(account) {
- await this.cryptoStore.doTxn("readwrite", [_indexeddbCryptoStore.IndexedDBCryptoStore.STORE_ACCOUNT], txn => {
- this.cryptoStore.getAccount(txn, pickledAccount => {
- if (pickledAccount !== null) {
- account.unpickle(this.pickleKey, pickledAccount);
- } else {
- account.create();
- pickledAccount = account.pickle(this.pickleKey);
- this.cryptoStore.storeAccount(txn, pickledAccount);
- }
- });
- });
- }
-
- /**
- * extract our OlmAccount from the crypto store and call the given function
- * with the account object
- * The `account` object is usable only within the callback passed to this
- * function and will be freed as soon the callback returns. It is *not*
- * usable for the rest of the lifetime of the transaction.
- * This function requires a live transaction object from cryptoStore.doTxn()
- * and therefore may only be called in a doTxn() callback.
- *
- * @param txn - Opaque transaction object from cryptoStore.doTxn()
- * @internal
- */
- getAccount(txn, func) {
- this.cryptoStore.getAccount(txn, pickledAccount => {
- const account = new global.Olm.Account();
- try {
- account.unpickle(this.pickleKey, pickledAccount);
- func(account);
- } finally {
- account.free();
- }
- });
- }
-
- /*
- * Saves an account to the crypto store.
- * This function requires a live transaction object from cryptoStore.doTxn()
- * and therefore may only be called in a doTxn() callback.
- *
- * @param txn - Opaque transaction object from cryptoStore.doTxn()
- * @param Olm.Account object
- * @internal
- */
- storeAccount(txn, account) {
- this.cryptoStore.storeAccount(txn, account.pickle(this.pickleKey));
- }
-
- /**
- * Export data for re-creating the Olm device later.
- * TODO export data other than just account and (P2P) sessions.
- *
- * @returns The exported data
- */
- async export() {
- const result = {
- pickleKey: this.pickleKey
- };
- await this.cryptoStore.doTxn("readonly", [_indexeddbCryptoStore.IndexedDBCryptoStore.STORE_ACCOUNT, _indexeddbCryptoStore.IndexedDBCryptoStore.STORE_SESSIONS], txn => {
- this.cryptoStore.getAccount(txn, pickledAccount => {
- result.pickledAccount = pickledAccount;
- });
- result.sessions = [];
- // Note that the pickledSession object we get in the callback
- // is not exactly the same thing you get in method _getSession
- // see documentation of IndexedDBCryptoStore.getAllEndToEndSessions
- this.cryptoStore.getAllEndToEndSessions(txn, pickledSession => {
- result.sessions.push(pickledSession);
- });
- });
- return result;
- }
-
- /**
- * extract an OlmSession from the session store and call the given function
- * The session is usable only within the callback passed to this
- * function and will be freed as soon the callback returns. It is *not*
- * usable for the rest of the lifetime of the transaction.
- *
- * @param txn - Opaque transaction object from cryptoStore.doTxn()
- * @internal
- */
- getSession(deviceKey, sessionId, txn, func) {
- this.cryptoStore.getEndToEndSession(deviceKey, sessionId, txn, sessionInfo => {
- this.unpickleSession(sessionInfo, func);
- });
- }
-
- /**
- * Creates a session object from a session pickle and executes the given
- * function with it. The session object is destroyed once the function
- * returns.
- *
- * @internal
- */
- unpickleSession(sessionInfo, func) {
- const session = new global.Olm.Session();
- try {
- session.unpickle(this.pickleKey, sessionInfo.session);
- const unpickledSessInfo = Object.assign({}, sessionInfo, {
- session
- });
- func(unpickledSessInfo);
- } finally {
- session.free();
- }
- }
-
- /**
- * store our OlmSession in the session store
- *
- * @param sessionInfo - `{session: OlmSession, lastReceivedMessageTs: int}`
- * @param txn - Opaque transaction object from cryptoStore.doTxn()
- * @internal
- */
- saveSession(deviceKey, sessionInfo, txn) {
- const sessionId = sessionInfo.session.session_id();
- _logger.logger.debug(`Saving Olm session ${sessionId} with device ${deviceKey}: ${sessionInfo.session.describe()}`);
-
- // Why do we re-use the input object for this, overwriting the same key with a different
- // type? Is it because we want to erase the unpickled session to enforce that it's no longer
- // used? A comment would be great.
- const pickledSessionInfo = Object.assign(sessionInfo, {
- session: sessionInfo.session.pickle(this.pickleKey)
- });
- this.cryptoStore.storeEndToEndSession(deviceKey, sessionId, pickledSessionInfo, txn);
- }
-
- /**
- * get an OlmUtility and call the given function
- *
- * @returns result of func
- * @internal
- */
- getUtility(func) {
- const utility = new global.Olm.Utility();
- try {
- return func(utility);
- } finally {
- utility.free();
- }
- }
-
- /**
- * Signs a message with the ed25519 key for this account.
- *
- * @param message - message to be signed
- * @returns base64-encoded signature
- */
- async sign(message) {
- let result;
- await this.cryptoStore.doTxn("readonly", [_indexeddbCryptoStore.IndexedDBCryptoStore.STORE_ACCOUNT], txn => {
- this.getAccount(txn, account => {
- result = account.sign(message);
- });
- });
- return result;
- }
-
- /**
- * Get the current (unused, unpublished) one-time keys for this account.
- *
- * @returns one time keys; an object with the single property
- * <tt>curve25519</tt>, which is itself an object mapping key id to Curve25519
- * key.
- */
- async getOneTimeKeys() {
- let result;
- await this.cryptoStore.doTxn("readonly", [_indexeddbCryptoStore.IndexedDBCryptoStore.STORE_ACCOUNT], txn => {
- this.getAccount(txn, account => {
- result = JSON.parse(account.one_time_keys());
- });
- });
- return result;
- }
-
- /**
- * Get the maximum number of one-time keys we can store.
- *
- * @returns number of keys
- */
- maxNumberOfOneTimeKeys() {
- var _this$maxOneTimeKeys;
- return (_this$maxOneTimeKeys = this.maxOneTimeKeys) !== null && _this$maxOneTimeKeys !== void 0 ? _this$maxOneTimeKeys : -1;
- }
-
- /**
- * Marks all of the one-time keys as published.
- */
- async markKeysAsPublished() {
- await this.cryptoStore.doTxn("readwrite", [_indexeddbCryptoStore.IndexedDBCryptoStore.STORE_ACCOUNT], txn => {
- this.getAccount(txn, account => {
- account.mark_keys_as_published();
- this.storeAccount(txn, account);
- });
- });
- }
-
- /**
- * Generate some new one-time keys
- *
- * @param numKeys - number of keys to generate
- * @returns Resolved once the account is saved back having generated the keys
- */
- generateOneTimeKeys(numKeys) {
- return this.cryptoStore.doTxn("readwrite", [_indexeddbCryptoStore.IndexedDBCryptoStore.STORE_ACCOUNT], txn => {
- this.getAccount(txn, account => {
- account.generate_one_time_keys(numKeys);
- this.storeAccount(txn, account);
- });
- });
- }
-
- /**
- * Generate a new fallback keys
- *
- * @returns Resolved once the account is saved back having generated the key
- */
- async generateFallbackKey() {
- await this.cryptoStore.doTxn("readwrite", [_indexeddbCryptoStore.IndexedDBCryptoStore.STORE_ACCOUNT], txn => {
- this.getAccount(txn, account => {
- account.generate_fallback_key();
- this.storeAccount(txn, account);
- });
- });
- }
- async getFallbackKey() {
- let result;
- await this.cryptoStore.doTxn("readonly", [_indexeddbCryptoStore.IndexedDBCryptoStore.STORE_ACCOUNT], txn => {
- this.getAccount(txn, account => {
- result = JSON.parse(account.unpublished_fallback_key());
- });
- });
- return result;
- }
- async forgetOldFallbackKey() {
- await this.cryptoStore.doTxn("readwrite", [_indexeddbCryptoStore.IndexedDBCryptoStore.STORE_ACCOUNT], txn => {
- this.getAccount(txn, account => {
- account.forget_old_fallback_key();
- this.storeAccount(txn, account);
- });
- });
- }
-
- /**
- * Generate a new outbound session
- *
- * The new session will be stored in the cryptoStore.
- *
- * @param theirIdentityKey - remote user's Curve25519 identity key
- * @param theirOneTimeKey - remote user's one-time Curve25519 key
- * @returns sessionId for the outbound session.
- */
- async createOutboundSession(theirIdentityKey, theirOneTimeKey) {
- let newSessionId;
- await this.cryptoStore.doTxn("readwrite", [_indexeddbCryptoStore.IndexedDBCryptoStore.STORE_ACCOUNT, _indexeddbCryptoStore.IndexedDBCryptoStore.STORE_SESSIONS], txn => {
- this.getAccount(txn, account => {
- const session = new global.Olm.Session();
- try {
- session.create_outbound(account, theirIdentityKey, theirOneTimeKey);
- newSessionId = session.session_id();
- this.storeAccount(txn, account);
- const sessionInfo = {
- session,
- // Pretend we've received a message at this point, otherwise
- // if we try to send a message to the device, it won't use
- // this session
- lastReceivedMessageTs: Date.now()
- };
- this.saveSession(theirIdentityKey, sessionInfo, txn);
- } finally {
- session.free();
- }
- });
- }, _logger.logger.withPrefix("[createOutboundSession]"));
- return newSessionId;
- }
-
- /**
- * Generate a new inbound session, given an incoming message
- *
- * @param theirDeviceIdentityKey - remote user's Curve25519 identity key
- * @param messageType - messageType field from the received message (must be 0)
- * @param ciphertext - base64-encoded body from the received message
- *
- * @returns decrypted payload, and
- * session id of new session
- *
- * @throws Error if the received message was not valid (for instance, it didn't use a valid one-time key).
- */
- async createInboundSession(theirDeviceIdentityKey, messageType, ciphertext) {
- if (messageType !== 0) {
- throw new Error("Need messageType == 0 to create inbound session");
- }
- let result; // eslint-disable-line camelcase
- await this.cryptoStore.doTxn("readwrite", [_indexeddbCryptoStore.IndexedDBCryptoStore.STORE_ACCOUNT, _indexeddbCryptoStore.IndexedDBCryptoStore.STORE_SESSIONS], txn => {
- this.getAccount(txn, account => {
- const session = new global.Olm.Session();
- try {
- session.create_inbound_from(account, theirDeviceIdentityKey, ciphertext);
- account.remove_one_time_keys(session);
- this.storeAccount(txn, account);
- const payloadString = session.decrypt(messageType, ciphertext);
- const sessionInfo = {
- session,
- // this counts as a received message: set last received message time
- // to now
- lastReceivedMessageTs: Date.now()
- };
- this.saveSession(theirDeviceIdentityKey, sessionInfo, txn);
- result = {
- payload: payloadString,
- session_id: session.session_id()
- };
- } finally {
- session.free();
- }
- });
- }, _logger.logger.withPrefix("[createInboundSession]"));
- return result;
- }
-
- /**
- * Get a list of known session IDs for the given device
- *
- * @param theirDeviceIdentityKey - Curve25519 identity key for the
- * remote device
- * @returns a list of known session ids for the device
- */
- async getSessionIdsForDevice(theirDeviceIdentityKey) {
- const log = _logger.logger.withPrefix("[getSessionIdsForDevice]");
- if (theirDeviceIdentityKey in this.sessionsInProgress) {
- log.debug(`Waiting for Olm session for ${theirDeviceIdentityKey} to be created`);
- try {
- await this.sessionsInProgress[theirDeviceIdentityKey];
- } catch (e) {
- // if the session failed to be created, just fall through and
- // return an empty result
- }
- }
- let sessionIds;
- await this.cryptoStore.doTxn("readonly", [_indexeddbCryptoStore.IndexedDBCryptoStore.STORE_SESSIONS], txn => {
- this.cryptoStore.getEndToEndSessions(theirDeviceIdentityKey, txn, sessions => {
- sessionIds = Object.keys(sessions);
- });
- }, log);
- return sessionIds;
- }
-
- /**
- * Get the right olm session id for encrypting messages to the given identity key
- *
- * @param theirDeviceIdentityKey - Curve25519 identity key for the
- * remote device
- * @param nowait - Don't wait for an in-progress session to complete.
- * This should only be set to true of the calling function is the function
- * that marked the session as being in-progress.
- * @param log - A possibly customised log
- * @returns session id, or null if no established session
- */
- async getSessionIdForDevice(theirDeviceIdentityKey, nowait = false, log) {
- const sessionInfos = await this.getSessionInfoForDevice(theirDeviceIdentityKey, nowait, log);
- if (sessionInfos.length === 0) {
- return null;
- }
- // Use the session that has most recently received a message
- let idxOfBest = 0;
- for (let i = 1; i < sessionInfos.length; i++) {
- const thisSessInfo = sessionInfos[i];
- const thisLastReceived = thisSessInfo.lastReceivedMessageTs === undefined ? 0 : thisSessInfo.lastReceivedMessageTs;
- const bestSessInfo = sessionInfos[idxOfBest];
- const bestLastReceived = bestSessInfo.lastReceivedMessageTs === undefined ? 0 : bestSessInfo.lastReceivedMessageTs;
- if (thisLastReceived > bestLastReceived || thisLastReceived === bestLastReceived && thisSessInfo.sessionId < bestSessInfo.sessionId) {
- idxOfBest = i;
- }
- }
- return sessionInfos[idxOfBest].sessionId;
- }
-
- /**
- * Get information on the active Olm sessions for a device.
- * <p>
- * Returns an array, with an entry for each active session. The first entry in
- * the result will be the one used for outgoing messages. Each entry contains
- * the keys 'hasReceivedMessage' (true if the session has received an incoming
- * message and is therefore past the pre-key stage), and 'sessionId'.
- *
- * @param deviceIdentityKey - Curve25519 identity key for the device
- * @param nowait - Don't wait for an in-progress session to complete.
- * This should only be set to true of the calling function is the function
- * that marked the session as being in-progress.
- * @param log - A possibly customised log
- */
- async getSessionInfoForDevice(deviceIdentityKey, nowait = false, log = _logger.logger) {
- log = log.withPrefix("[getSessionInfoForDevice]");
- if (deviceIdentityKey in this.sessionsInProgress && !nowait) {
- log.debug(`Waiting for Olm session for ${deviceIdentityKey} to be created`);
- try {
- await this.sessionsInProgress[deviceIdentityKey];
- } catch (e) {
- // if the session failed to be created, then just fall through and
- // return an empty result
- }
- }
- const info = [];
- await this.cryptoStore.doTxn("readonly", [_indexeddbCryptoStore.IndexedDBCryptoStore.STORE_SESSIONS], txn => {
- this.cryptoStore.getEndToEndSessions(deviceIdentityKey, txn, sessions => {
- const sessionIds = Object.keys(sessions).sort();
- for (const sessionId of sessionIds) {
- this.unpickleSession(sessions[sessionId], sessInfo => {
- info.push({
- lastReceivedMessageTs: sessInfo.lastReceivedMessageTs,
- hasReceivedMessage: sessInfo.session.has_received_message(),
- sessionId
- });
- });
- }
- });
- }, log);
- return info;
- }
-
- /**
- * Encrypt an outgoing message using an existing session
- *
- * @param theirDeviceIdentityKey - Curve25519 identity key for the
- * remote device
- * @param sessionId - the id of the active session
- * @param payloadString - payload to be encrypted and sent
- *
- * @returns ciphertext
- */
- async encryptMessage(theirDeviceIdentityKey, sessionId, payloadString) {
- checkPayloadLength(payloadString);
- let res;
- await this.cryptoStore.doTxn("readwrite", [_indexeddbCryptoStore.IndexedDBCryptoStore.STORE_SESSIONS], txn => {
- this.getSession(theirDeviceIdentityKey, sessionId, txn, sessionInfo => {
- const sessionDesc = sessionInfo.session.describe();
- _logger.logger.log("encryptMessage: Olm Session ID " + sessionId + " to " + theirDeviceIdentityKey + ": " + sessionDesc);
- res = sessionInfo.session.encrypt(payloadString);
- this.saveSession(theirDeviceIdentityKey, sessionInfo, txn);
- });
- }, _logger.logger.withPrefix("[encryptMessage]"));
- return res;
- }
-
- /**
- * Decrypt an incoming message using an existing session
- *
- * @param theirDeviceIdentityKey - Curve25519 identity key for the
- * remote device
- * @param sessionId - the id of the active session
- * @param messageType - messageType field from the received message
- * @param ciphertext - base64-encoded body from the received message
- *
- * @returns decrypted payload.
- */
- async decryptMessage(theirDeviceIdentityKey, sessionId, messageType, ciphertext) {
- let payloadString;
- await this.cryptoStore.doTxn("readwrite", [_indexeddbCryptoStore.IndexedDBCryptoStore.STORE_SESSIONS], txn => {
- this.getSession(theirDeviceIdentityKey, sessionId, txn, sessionInfo => {
- const sessionDesc = sessionInfo.session.describe();
- _logger.logger.log("decryptMessage: Olm Session ID " + sessionId + " from " + theirDeviceIdentityKey + ": " + sessionDesc);
- payloadString = sessionInfo.session.decrypt(messageType, ciphertext);
- sessionInfo.lastReceivedMessageTs = Date.now();
- this.saveSession(theirDeviceIdentityKey, sessionInfo, txn);
- });
- }, _logger.logger.withPrefix("[decryptMessage]"));
- return payloadString;
- }
-
- /**
- * Determine if an incoming messages is a prekey message matching an existing session
- *
- * @param theirDeviceIdentityKey - Curve25519 identity key for the
- * remote device
- * @param sessionId - the id of the active session
- * @param messageType - messageType field from the received message
- * @param ciphertext - base64-encoded body from the received message
- *
- * @returns true if the received message is a prekey message which matches
- * the given session.
- */
- async matchesSession(theirDeviceIdentityKey, sessionId, messageType, ciphertext) {
- if (messageType !== 0) {
- return false;
- }
- let matches;
- await this.cryptoStore.doTxn("readonly", [_indexeddbCryptoStore.IndexedDBCryptoStore.STORE_SESSIONS], txn => {
- this.getSession(theirDeviceIdentityKey, sessionId, txn, sessionInfo => {
- matches = sessionInfo.session.matches_inbound(ciphertext);
- });
- }, _logger.logger.withPrefix("[matchesSession]"));
- return matches;
- }
- async recordSessionProblem(deviceKey, type, fixed) {
- _logger.logger.info(`Recording problem on olm session with ${deviceKey} of type ${type}. Recreating: ${fixed}`);
- await this.cryptoStore.storeEndToEndSessionProblem(deviceKey, type, fixed);
- }
- sessionMayHaveProblems(deviceKey, timestamp) {
- return this.cryptoStore.getEndToEndSessionProblem(deviceKey, timestamp);
- }
- filterOutNotifiedErrorDevices(devices) {
- return this.cryptoStore.filterOutNotifiedErrorDevices(devices);
- }
-
- // Outbound group session
- // ======================
-
- /**
- * store an OutboundGroupSession in outboundGroupSessionStore
- *
- * @internal
- */
- saveOutboundGroupSession(session) {
- this.outboundGroupSessionStore[session.session_id()] = session.pickle(this.pickleKey);
- }
-
- /**
- * extract an OutboundGroupSession from outboundGroupSessionStore and call the
- * given function
- *
- * @returns result of func
- * @internal
- */
- getOutboundGroupSession(sessionId, func) {
- const pickled = this.outboundGroupSessionStore[sessionId];
- if (pickled === undefined) {
- throw new Error("Unknown outbound group session " + sessionId);
- }
- const session = new global.Olm.OutboundGroupSession();
- try {
- session.unpickle(this.pickleKey, pickled);
- return func(session);
- } finally {
- session.free();
- }
- }
-
- /**
- * Generate a new outbound group session
- *
- * @returns sessionId for the outbound session.
- */
- createOutboundGroupSession() {
- const session = new global.Olm.OutboundGroupSession();
- try {
- session.create();
- this.saveOutboundGroupSession(session);
- return session.session_id();
- } finally {
- session.free();
- }
- }
-
- /**
- * Encrypt an outgoing message with an outbound group session
- *
- * @param sessionId - the id of the outboundgroupsession
- * @param payloadString - payload to be encrypted and sent
- *
- * @returns ciphertext
- */
- encryptGroupMessage(sessionId, payloadString) {
- _logger.logger.log(`encrypting msg with megolm session ${sessionId}`);
- checkPayloadLength(payloadString);
- return this.getOutboundGroupSession(sessionId, session => {
- const res = session.encrypt(payloadString);
- this.saveOutboundGroupSession(session);
- return res;
- });
- }
-
- /**
- * Get the session keys for an outbound group session
- *
- * @param sessionId - the id of the outbound group session
- *
- * @returns current chain index, and
- * base64-encoded secret key.
- */
- getOutboundGroupSessionKey(sessionId) {
- return this.getOutboundGroupSession(sessionId, function (session) {
- return {
- chain_index: session.message_index(),
- key: session.session_key()
- };
- });
- }
-
- // Inbound group session
- // =====================
-
- /**
- * Unpickle a session from a sessionData object and invoke the given function.
- * The session is valid only until func returns.
- *
- * @param sessionData - Object describing the session.
- * @param func - Invoked with the unpickled session
- * @returns result of func
- */
- unpickleInboundGroupSession(sessionData, func) {
- const session = new global.Olm.InboundGroupSession();
- try {
- session.unpickle(this.pickleKey, sessionData.session);
- return func(session);
- } finally {
- session.free();
- }
- }
-
- /**
- * extract an InboundGroupSession from the crypto store and call the given function
- *
- * @param roomId - The room ID to extract the session for, or null to fetch
- * sessions for any room.
- * @param txn - Opaque transaction object from cryptoStore.doTxn()
- * @param func - function to call.
- *
- * @internal
- */
- getInboundGroupSession(roomId, senderKey, sessionId, txn, func) {
- this.cryptoStore.getEndToEndInboundGroupSession(senderKey, sessionId, txn, (sessionData, withheld) => {
- if (sessionData === null) {
- func(null, null, withheld);
- return;
- }
-
- // if we were given a room ID, check that the it matches the original one for the session. This stops
- // the HS pretending a message was targeting a different room.
- if (roomId !== null && roomId !== sessionData.room_id) {
- throw new Error("Mismatched room_id for inbound group session (expected " + sessionData.room_id + ", was " + roomId + ")");
- }
- this.unpickleInboundGroupSession(sessionData, session => {
- func(session, sessionData, withheld);
- });
- });
- }
-
- /**
- * Add an inbound group session to the session store
- *
- * @param roomId - room in which this session will be used
- * @param senderKey - base64-encoded curve25519 key of the sender
- * @param forwardingCurve25519KeyChain - Devices involved in forwarding
- * this session to us.
- * @param sessionId - session identifier
- * @param sessionKey - base64-encoded secret key
- * @param keysClaimed - Other keys the sender claims.
- * @param exportFormat - true if the megolm keys are in export format
- * (ie, they lack an ed25519 signature)
- * @param extraSessionData - any other data to be include with the session
- */
- async addInboundGroupSession(roomId, senderKey, forwardingCurve25519KeyChain, sessionId, sessionKey, keysClaimed, exportFormat, extraSessionData = {}) {
- await this.cryptoStore.doTxn("readwrite", [_indexeddbCryptoStore.IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS, _indexeddbCryptoStore.IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS_WITHHELD, _indexeddbCryptoStore.IndexedDBCryptoStore.STORE_SHARED_HISTORY_INBOUND_GROUP_SESSIONS], txn => {
- /* if we already have this session, consider updating it */
- this.getInboundGroupSession(roomId, senderKey, sessionId, txn, (existingSession, existingSessionData) => {
- // new session.
- const session = new global.Olm.InboundGroupSession();
- try {
- if (exportFormat) {
- session.import_session(sessionKey);
- } else {
- session.create(sessionKey);
- }
- if (sessionId != session.session_id()) {
- throw new Error("Mismatched group session ID from senderKey: " + senderKey);
- }
- if (existingSession) {
- _logger.logger.log(`Update for megolm session ${senderKey}|${sessionId}`);
- if (existingSession.first_known_index() <= session.first_known_index()) {
- if (!existingSessionData.untrusted || extraSessionData.untrusted) {
- // existing session has less-than-or-equal index
- // (i.e. can decrypt at least as much), and the
- // new session's trust does not win over the old
- // session's trust, so keep it
- _logger.logger.log(`Keeping existing megolm session ${senderKey}|${sessionId}`);
- return;
- }
- if (existingSession.first_known_index() < session.first_known_index()) {
- // We want to upgrade the existing session's trust,
- // but we can't just use the new session because we'll
- // lose the lower index. Check that the sessions connect
- // properly, and then manually set the existing session
- // as trusted.
- if (existingSession.export_session(session.first_known_index()) === session.export_session(session.first_known_index())) {
- _logger.logger.info("Upgrading trust of existing megolm session " + `${senderKey}|${sessionId} based on newly-received trusted session`);
- existingSessionData.untrusted = false;
- this.cryptoStore.storeEndToEndInboundGroupSession(senderKey, sessionId, existingSessionData, txn);
- } else {
- _logger.logger.warn(`Newly-received megolm session ${senderKey}|$sessionId}` + " does not match existing session! Keeping existing session");
- }
- return;
- }
- // If the sessions have the same index, go ahead and store the new trusted one.
- }
- }
-
- _logger.logger.info(`Storing megolm session ${senderKey}|${sessionId} with first index ` + session.first_known_index());
- const sessionData = Object.assign({}, extraSessionData, {
- room_id: roomId,
- session: session.pickle(this.pickleKey),
- keysClaimed: keysClaimed,
- forwardingCurve25519KeyChain: forwardingCurve25519KeyChain
- });
- this.cryptoStore.storeEndToEndInboundGroupSession(senderKey, sessionId, sessionData, txn);
- if (!existingSession && extraSessionData.sharedHistory) {
- this.cryptoStore.addSharedHistoryInboundGroupSession(roomId, senderKey, sessionId, txn);
- }
- } finally {
- session.free();
- }
- });
- }, _logger.logger.withPrefix("[addInboundGroupSession]"));
- }
-
- /**
- * Record in the data store why an inbound group session was withheld.
- *
- * @param roomId - room that the session belongs to
- * @param senderKey - base64-encoded curve25519 key of the sender
- * @param sessionId - session identifier
- * @param code - reason code
- * @param reason - human-readable version of `code`
- */
- async addInboundGroupSessionWithheld(roomId, senderKey, sessionId, code, reason) {
- await this.cryptoStore.doTxn("readwrite", [_indexeddbCryptoStore.IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS_WITHHELD], txn => {
- this.cryptoStore.storeEndToEndInboundGroupSessionWithheld(senderKey, sessionId, {
- room_id: roomId,
- code: code,
- reason: reason
- }, txn);
- });
- }
-
- /**
- * Decrypt a received message with an inbound group session
- *
- * @param roomId - room in which the message was received
- * @param senderKey - base64-encoded curve25519 key of the sender
- * @param sessionId - session identifier
- * @param body - base64-encoded body of the encrypted message
- * @param eventId - ID of the event being decrypted
- * @param timestamp - timestamp of the event being decrypted
- *
- * @returns null if the sessionId is unknown
- */
- async decryptGroupMessage(roomId, senderKey, sessionId, body, eventId, timestamp) {
- let result = null;
- // when the localstorage crypto store is used as an indexeddb backend,
- // exceptions thrown from within the inner function are not passed through
- // to the top level, so we store exceptions in a variable and raise them at
- // the end
- let error;
- await this.cryptoStore.doTxn("readwrite", [_indexeddbCryptoStore.IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS, _indexeddbCryptoStore.IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS_WITHHELD], txn => {
- this.getInboundGroupSession(roomId, senderKey, sessionId, txn, (session, sessionData, withheld) => {
- if (session === null || sessionData === null) {
- if (withheld) {
- error = new algorithms.DecryptionError("MEGOLM_UNKNOWN_INBOUND_SESSION_ID", calculateWithheldMessage(withheld), {
- session: senderKey + "|" + sessionId
- });
- }
- result = null;
- return;
- }
- let res;
- try {
- res = session.decrypt(body);
- } catch (e) {
- if ((e === null || e === void 0 ? void 0 : e.message) === "OLM.UNKNOWN_MESSAGE_INDEX" && withheld) {
- error = new algorithms.DecryptionError("MEGOLM_UNKNOWN_INBOUND_SESSION_ID", calculateWithheldMessage(withheld), {
- session: senderKey + "|" + sessionId
- });
- } else {
- error = e;
- }
- return;
- }
- let plaintext = res.plaintext;
- if (plaintext === undefined) {
- // @ts-ignore - Compatibility for older olm versions.
- plaintext = res;
- } else {
- // Check if we have seen this message index before to detect replay attacks.
- // If the event ID and timestamp are specified, and the match the event ID
- // and timestamp from the last time we used this message index, then we
- // don't consider it a replay attack.
- const messageIndexKey = senderKey + "|" + sessionId + "|" + res.message_index;
- if (messageIndexKey in this.inboundGroupSessionMessageIndexes) {
- const msgInfo = this.inboundGroupSessionMessageIndexes[messageIndexKey];
- if (msgInfo.id !== eventId || msgInfo.timestamp !== timestamp) {
- error = new Error("Duplicate message index, possible replay attack: " + messageIndexKey);
- return;
- }
- }
- this.inboundGroupSessionMessageIndexes[messageIndexKey] = {
- id: eventId,
- timestamp: timestamp
- };
- }
- sessionData.session = session.pickle(this.pickleKey);
- this.cryptoStore.storeEndToEndInboundGroupSession(senderKey, sessionId, sessionData, txn);
- result = {
- result: plaintext,
- keysClaimed: sessionData.keysClaimed || {},
- senderKey: senderKey,
- forwardingCurve25519KeyChain: sessionData.forwardingCurve25519KeyChain || [],
- untrusted: !!sessionData.untrusted
- };
- });
- }, _logger.logger.withPrefix("[decryptGroupMessage]"));
- if (error) {
- throw error;
- }
- return result;
- }
-
- /**
- * Determine if we have the keys for a given megolm session
- *
- * @param roomId - room in which the message was received
- * @param senderKey - base64-encoded curve25519 key of the sender
- * @param sessionId - session identifier
- *
- * @returns true if we have the keys to this session
- */
- async hasInboundSessionKeys(roomId, senderKey, sessionId) {
- let result;
- await this.cryptoStore.doTxn("readonly", [_indexeddbCryptoStore.IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS, _indexeddbCryptoStore.IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS_WITHHELD], txn => {
- this.cryptoStore.getEndToEndInboundGroupSession(senderKey, sessionId, txn, sessionData => {
- if (sessionData === null) {
- result = false;
- return;
- }
- if (roomId !== sessionData.room_id) {
- _logger.logger.warn(`requested keys for inbound group session ${senderKey}|` + `${sessionId}, with incorrect room_id ` + `(expected ${sessionData.room_id}, ` + `was ${roomId})`);
- result = false;
- } else {
- result = true;
- }
- });
- }, _logger.logger.withPrefix("[hasInboundSessionKeys]"));
- return result;
- }
-
- /**
- * Extract the keys to a given megolm session, for sharing
- *
- * @param roomId - room in which the message was received
- * @param senderKey - base64-encoded curve25519 key of the sender
- * @param sessionId - session identifier
- * @param chainIndex - The chain index at which to export the session.
- * If omitted, export at the first index we know about.
- *
- * @returns
- * details of the session key. The key is a base64-encoded megolm key in
- * export format.
- *
- * @throws Error If the given chain index could not be obtained from the known
- * index (ie. the given chain index is before the first we have).
- */
- async getInboundGroupSessionKey(roomId, senderKey, sessionId, chainIndex) {
- let result = null;
- await this.cryptoStore.doTxn("readonly", [_indexeddbCryptoStore.IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS, _indexeddbCryptoStore.IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS_WITHHELD], txn => {
- this.getInboundGroupSession(roomId, senderKey, sessionId, txn, (session, sessionData) => {
- if (session === null || sessionData === null) {
- result = null;
- return;
- }
- if (chainIndex === undefined) {
- chainIndex = session.first_known_index();
- }
- const exportedSession = session.export_session(chainIndex);
- const claimedKeys = sessionData.keysClaimed || {};
- const senderEd25519Key = claimedKeys.ed25519 || null;
- const forwardingKeyChain = sessionData.forwardingCurve25519KeyChain || [];
- // older forwarded keys didn't set the "untrusted"
- // property, but can be identified by having a
- // non-empty forwarding key chain. These keys should
- // be marked as untrusted since we don't know that they
- // can be trusted
- const untrusted = "untrusted" in sessionData ? sessionData.untrusted : forwardingKeyChain.length > 0;
- result = {
- chain_index: chainIndex,
- key: exportedSession,
- forwarding_curve25519_key_chain: forwardingKeyChain,
- sender_claimed_ed25519_key: senderEd25519Key,
- shared_history: sessionData.sharedHistory || false,
- untrusted: untrusted
- };
- });
- }, _logger.logger.withPrefix("[getInboundGroupSessionKey]"));
- return result;
- }
-
- /**
- * Export an inbound group session
- *
- * @param senderKey - base64-encoded curve25519 key of the sender
- * @param sessionId - session identifier
- * @param sessionData - The session object from the store
- * @returns exported session data
- */
- exportInboundGroupSession(senderKey, sessionId, sessionData) {
- return this.unpickleInboundGroupSession(sessionData, session => {
- const messageIndex = session.first_known_index();
- return {
- "sender_key": senderKey,
- "sender_claimed_keys": sessionData.keysClaimed,
- "room_id": sessionData.room_id,
- "session_id": sessionId,
- "session_key": session.export_session(messageIndex),
- "forwarding_curve25519_key_chain": sessionData.forwardingCurve25519KeyChain || [],
- "first_known_index": session.first_known_index(),
- "org.matrix.msc3061.shared_history": sessionData.sharedHistory || false
- };
- });
- }
- async getSharedHistoryInboundGroupSessions(roomId) {
- let result;
- await this.cryptoStore.doTxn("readonly", [_indexeddbCryptoStore.IndexedDBCryptoStore.STORE_SHARED_HISTORY_INBOUND_GROUP_SESSIONS], txn => {
- result = this.cryptoStore.getSharedHistoryInboundGroupSessions(roomId, txn);
- }, _logger.logger.withPrefix("[getSharedHistoryInboundGroupSessionsForRoom]"));
- return result;
- }
-
- // Utilities
- // =========
-
- /**
- * Verify an ed25519 signature.
- *
- * @param key - ed25519 key
- * @param message - message which was signed
- * @param signature - base64-encoded signature to be checked
- *
- * @throws Error if there is a problem with the verification. If the key was
- * too small then the message will be "OLM.INVALID_BASE64". If the signature
- * was invalid then the message will be "OLM.BAD_MESSAGE_MAC".
- */
- verifySignature(key, message, signature) {
- this.getUtility(function (util) {
- util.ed25519_verify(key, message, signature);
- });
- }
-}
-exports.OlmDevice = OlmDevice;
-const WITHHELD_MESSAGES = {
- "m.unverified": "The sender has disabled encrypting to unverified devices.",
- "m.blacklisted": "The sender has blocked you.",
- "m.unauthorised": "You are not authorised to read the message.",
- "m.no_olm": "Unable to establish a secure channel."
-};
-
-/**
- * Calculate the message to use for the exception when a session key is withheld.
- *
- * @param withheld - An object that describes why the key was withheld.
- *
- * @returns the message
- *
- * @internal
- */
-exports.WITHHELD_MESSAGES = WITHHELD_MESSAGES;
-function calculateWithheldMessage(withheld) {
- if (withheld.code && withheld.code in WITHHELD_MESSAGES) {
- return WITHHELD_MESSAGES[withheld.code];
- } else if (withheld.reason) {
- return withheld.reason;
- } else {
- return "decryption key withheld";
- }
-}
-//# sourceMappingURL=OlmDevice.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/OlmDevice.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/OlmDevice.js.map
deleted file mode 100644
index 2801abe..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/OlmDevice.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"OlmDevice.js","names":["_logger","require","_indexeddbCryptoStore","algorithms","_interopRequireWildcard","_getRequireWildcardCache","nodeInterop","WeakMap","cacheBabelInterop","cacheNodeInterop","obj","__esModule","default","cache","has","get","newObj","hasPropertyDescriptor","Object","defineProperty","getOwnPropertyDescriptor","key","prototype","hasOwnProperty","call","desc","set","MAX_PLAINTEXT_LENGTH","PayloadTooLargeError","Error","constructor","args","_defineProperty2","errcode","error","exports","checkPayloadLength","payloadString","undefined","length","OlmDevice","cryptoStore","Promise","resolve","getOlmVersion","global","Olm","get_library_version","init","pickleKey","fromExportedDevice","e2eKeys","account","Account","logger","warn","initialiseFromExportedDevice","initialiseAccount","JSON","parse","identity_keys","maxOneTimeKeys","max_number_of_one_time_keys","free","deviceCurve25519Key","curve25519","deviceEd25519Key","ed25519","exportedData","doTxn","IndexedDBCryptoStore","STORE_ACCOUNT","STORE_SESSIONS","txn","storeAccount","pickledAccount","sessions","forEach","session","deviceKey","sessionId","sessionInfo","lastReceivedMessageTs","storeEndToEndSession","unpickle","getAccount","create","pickle","func","export","result","getAllEndToEndSessions","pickledSession","push","getSession","getEndToEndSession","unpickleSession","Session","unpickledSessInfo","assign","saveSession","session_id","debug","describe","pickledSessionInfo","getUtility","utility","Utility","sign","message","getOneTimeKeys","one_time_keys","maxNumberOfOneTimeKeys","_this$maxOneTimeKeys","markKeysAsPublished","mark_keys_as_published","generateOneTimeKeys","numKeys","generate_one_time_keys","generateFallbackKey","generate_fallback_key","getFallbackKey","unpublished_fallback_key","forgetOldFallbackKey","forget_old_fallback_key","createOutboundSession","theirIdentityKey","theirOneTimeKey","newSessionId","create_outbound","Date","now","withPrefix","createInboundSession","theirDeviceIdentityKey","messageType","ciphertext","create_inbound_from","remove_one_time_keys","decrypt","payload","getSessionIdsForDevice","log","sessionsInProgress","e","sessionIds","getEndToEndSessions","keys","getSessionIdForDevice","nowait","sessionInfos","getSessionInfoForDevice","idxOfBest","i","thisSessInfo","thisLastReceived","bestSessInfo","bestLastReceived","deviceIdentityKey","info","sort","sessInfo","hasReceivedMessage","has_received_message","encryptMessage","res","sessionDesc","encrypt","decryptMessage","matchesSession","matches","matches_inbound","recordSessionProblem","type","fixed","storeEndToEndSessionProblem","sessionMayHaveProblems","timestamp","getEndToEndSessionProblem","filterOutNotifiedErrorDevices","devices","saveOutboundGroupSession","outboundGroupSessionStore","getOutboundGroupSession","pickled","OutboundGroupSession","createOutboundGroupSession","encryptGroupMessage","getOutboundGroupSessionKey","chain_index","message_index","session_key","unpickleInboundGroupSession","sessionData","InboundGroupSession","getInboundGroupSession","roomId","senderKey","getEndToEndInboundGroupSession","withheld","room_id","addInboundGroupSession","forwardingCurve25519KeyChain","sessionKey","keysClaimed","exportFormat","extraSessionData","STORE_INBOUND_GROUP_SESSIONS","STORE_INBOUND_GROUP_SESSIONS_WITHHELD","STORE_SHARED_HISTORY_INBOUND_GROUP_SESSIONS","existingSession","existingSessionData","import_session","first_known_index","untrusted","export_session","storeEndToEndInboundGroupSession","sharedHistory","addSharedHistoryInboundGroupSession","addInboundGroupSessionWithheld","code","reason","storeEndToEndInboundGroupSessionWithheld","decryptGroupMessage","body","eventId","DecryptionError","calculateWithheldMessage","plaintext","messageIndexKey","inboundGroupSessionMessageIndexes","msgInfo","id","hasInboundSessionKeys","getInboundGroupSessionKey","chainIndex","exportedSession","claimedKeys","senderEd25519Key","forwardingKeyChain","forwarding_curve25519_key_chain","sender_claimed_ed25519_key","shared_history","exportInboundGroupSession","messageIndex","getSharedHistoryInboundGroupSessions","verifySignature","signature","util","ed25519_verify","WITHHELD_MESSAGES"],"sources":["../../src/crypto/OlmDevice.ts"],"sourcesContent":["/*\nCopyright 2016 - 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { Account, InboundGroupSession, OutboundGroupSession, Session, Utility } from \"@matrix-org/olm\";\n\nimport { logger, PrefixedLogger } from \"../logger\";\nimport { IndexedDBCryptoStore } from \"./store/indexeddb-crypto-store\";\nimport * as algorithms from \"./algorithms\";\nimport { CryptoStore, IProblem, ISessionInfo, IWithheld } from \"./store/base\";\nimport { IOlmDevice, IOutboundGroupSessionKey } from \"./algorithms/megolm\";\nimport { IMegolmSessionData, OlmGroupSessionExtraData } from \"../@types/crypto\";\nimport { IMessage } from \"./algorithms/olm\";\n\n// The maximum size of an event is 65K, and we base64 the content, so this is a\n// reasonable approximation to the biggest plaintext we can encrypt.\nconst MAX_PLAINTEXT_LENGTH = (65536 * 3) / 4;\n\nexport class PayloadTooLargeError extends Error {\n public readonly data = {\n errcode: \"M_TOO_LARGE\",\n error: \"Payload too large for encrypted message\",\n };\n}\n\nfunction checkPayloadLength(payloadString: string): void {\n if (payloadString === undefined) {\n throw new Error(\"payloadString undefined\");\n }\n\n if (payloadString.length > MAX_PLAINTEXT_LENGTH) {\n // might as well fail early here rather than letting the olm library throw\n // a cryptic memory allocation error.\n //\n // Note that even if we manage to do the encryption, the message send may fail,\n // because by the time we've wrapped the ciphertext in the event object, it may\n // exceed 65K. But at least we won't just fail with \"abort()\" in that case.\n throw new PayloadTooLargeError(\n `Message too long (${payloadString.length} bytes). ` +\n `The maximum for an encrypted message is ${MAX_PLAINTEXT_LENGTH} bytes.`,\n );\n }\n}\n\ninterface IInitOpts {\n fromExportedDevice?: IExportedDevice;\n pickleKey?: string;\n}\n\n/** data stored in the session store about an inbound group session */\nexport interface InboundGroupSessionData {\n room_id: string; // eslint-disable-line camelcase\n /** pickled Olm.InboundGroupSession */\n session: string;\n keysClaimed: Record<string, string>;\n /** Devices involved in forwarding this session to us (normally empty). */\n forwardingCurve25519KeyChain: string[];\n /** whether this session is untrusted. */\n untrusted?: boolean;\n /** whether this session exists during the room being set to shared history. */\n sharedHistory?: boolean;\n}\n\nexport interface IDecryptedGroupMessage {\n result: string;\n keysClaimed: Record<string, string>;\n senderKey: string;\n forwardingCurve25519KeyChain: string[];\n untrusted: boolean;\n}\n\nexport interface IInboundSession {\n payload: string;\n session_id: string;\n}\n\nexport interface IExportedDevice {\n pickleKey: string;\n pickledAccount: string;\n sessions: ISessionInfo[];\n}\n\ninterface IUnpickledSessionInfo extends Omit<ISessionInfo, \"session\"> {\n session: Session;\n}\n\n/* eslint-disable camelcase */\ninterface IInboundGroupSessionKey {\n chain_index: number;\n key: string;\n forwarding_curve25519_key_chain: string[];\n sender_claimed_ed25519_key: string | null;\n shared_history: boolean;\n untrusted?: boolean;\n}\n/* eslint-enable camelcase */\n\ntype OneTimeKeys = { curve25519: { [keyId: string]: string } };\n\n/**\n * Manages the olm cryptography functions. Each OlmDevice has a single\n * OlmAccount and a number of OlmSessions.\n *\n * Accounts and sessions are kept pickled in the cryptoStore.\n */\nexport class OlmDevice {\n public pickleKey = \"DEFAULT_KEY\"; // set by consumers\n\n /** Curve25519 key for the account, unknown until we load the account from storage in init() */\n public deviceCurve25519Key: string | null = null;\n /** Ed25519 key for the account, unknown until we load the account from storage in init() */\n public deviceEd25519Key: string | null = null;\n private maxOneTimeKeys: number | null = null;\n\n // we don't bother stashing outboundgroupsessions in the cryptoStore -\n // instead we keep them here.\n private outboundGroupSessionStore: Record<string, string> = {};\n\n // Store a set of decrypted message indexes for each group session.\n // This partially mitigates a replay attack where a MITM resends a group\n // message into the room.\n //\n // When we decrypt a message and the message index matches a previously\n // decrypted message, one possible cause of that is that we are decrypting\n // the same event, and may not indicate an actual replay attack. For\n // example, this could happen if we receive events, forget about them, and\n // then re-fetch them when we backfill. So we store the event ID and\n // timestamp corresponding to each message index when we first decrypt it,\n // and compare these against the event ID and timestamp every time we use\n // that same index. If they match, then we're probably decrypting the same\n // event and we don't consider it a replay attack.\n //\n // Keys are strings of form \"<senderKey>|<session_id>|<message_index>\"\n // Values are objects of the form \"{id: <event id>, timestamp: <ts>}\"\n private inboundGroupSessionMessageIndexes: Record<string, { id: string; timestamp: number }> = {};\n\n // Keep track of sessions that we're starting, so that we don't start\n // multiple sessions for the same device at the same time.\n public sessionsInProgress: Record<string, Promise<void>> = {}; // set by consumers\n\n // Used by olm to serialise prekey message decryptions\n public olmPrekeyPromise: Promise<any> = Promise.resolve(); // set by consumers\n\n public constructor(private readonly cryptoStore: CryptoStore) {}\n\n /**\n * @returns The version of Olm.\n */\n public static getOlmVersion(): [number, number, number] {\n return global.Olm.get_library_version();\n }\n\n /**\n * Initialise the OlmAccount. This must be called before any other operations\n * on the OlmDevice.\n *\n * Data from an exported Olm device can be provided\n * in order to re-create this device.\n *\n * Attempts to load the OlmAccount from the crypto store, or creates one if none is\n * found.\n *\n * Reads the device keys from the OlmAccount object.\n *\n * @param fromExportedDevice - (Optional) data from exported device\n * that must be re-created.\n * If present, opts.pickleKey is ignored\n * (exported data already provides a pickle key)\n * @param pickleKey - (Optional) pickle key to set instead of default one\n */\n public async init({ pickleKey, fromExportedDevice }: IInitOpts = {}): Promise<void> {\n let e2eKeys;\n const account = new global.Olm.Account();\n\n try {\n if (fromExportedDevice) {\n if (pickleKey) {\n logger.warn(\"ignoring opts.pickleKey\" + \" because opts.fromExportedDevice is present.\");\n }\n this.pickleKey = fromExportedDevice.pickleKey;\n await this.initialiseFromExportedDevice(fromExportedDevice, account);\n } else {\n if (pickleKey) {\n this.pickleKey = pickleKey;\n }\n await this.initialiseAccount(account);\n }\n e2eKeys = JSON.parse(account.identity_keys());\n\n this.maxOneTimeKeys = account.max_number_of_one_time_keys();\n } finally {\n account.free();\n }\n\n this.deviceCurve25519Key = e2eKeys.curve25519;\n this.deviceEd25519Key = e2eKeys.ed25519;\n }\n\n /**\n * Populates the crypto store using data that was exported from an existing device.\n * Note that for now only the “account” and “sessions” stores are populated;\n * Other stores will be as with a new device.\n *\n * @param exportedData - Data exported from another device\n * through the “export” method.\n * @param account - an olm account to initialize\n */\n private async initialiseFromExportedDevice(exportedData: IExportedDevice, account: Account): Promise<void> {\n await this.cryptoStore.doTxn(\n \"readwrite\",\n [IndexedDBCryptoStore.STORE_ACCOUNT, IndexedDBCryptoStore.STORE_SESSIONS],\n (txn) => {\n this.cryptoStore.storeAccount(txn, exportedData.pickledAccount);\n exportedData.sessions.forEach((session) => {\n const { deviceKey, sessionId } = session;\n const sessionInfo = {\n session: session.session,\n lastReceivedMessageTs: session.lastReceivedMessageTs,\n };\n this.cryptoStore.storeEndToEndSession(deviceKey!, sessionId!, sessionInfo, txn);\n });\n },\n );\n account.unpickle(this.pickleKey, exportedData.pickledAccount);\n }\n\n private async initialiseAccount(account: Account): Promise<void> {\n await this.cryptoStore.doTxn(\"readwrite\", [IndexedDBCryptoStore.STORE_ACCOUNT], (txn) => {\n this.cryptoStore.getAccount(txn, (pickledAccount) => {\n if (pickledAccount !== null) {\n account.unpickle(this.pickleKey, pickledAccount);\n } else {\n account.create();\n pickledAccount = account.pickle(this.pickleKey);\n this.cryptoStore.storeAccount(txn, pickledAccount);\n }\n });\n });\n }\n\n /**\n * extract our OlmAccount from the crypto store and call the given function\n * with the account object\n * The `account` object is usable only within the callback passed to this\n * function and will be freed as soon the callback returns. It is *not*\n * usable for the rest of the lifetime of the transaction.\n * This function requires a live transaction object from cryptoStore.doTxn()\n * and therefore may only be called in a doTxn() callback.\n *\n * @param txn - Opaque transaction object from cryptoStore.doTxn()\n * @internal\n */\n private getAccount(txn: unknown, func: (account: Account) => void): void {\n this.cryptoStore.getAccount(txn, (pickledAccount: string | null) => {\n const account = new global.Olm.Account();\n try {\n account.unpickle(this.pickleKey, pickledAccount!);\n func(account);\n } finally {\n account.free();\n }\n });\n }\n\n /*\n * Saves an account to the crypto store.\n * This function requires a live transaction object from cryptoStore.doTxn()\n * and therefore may only be called in a doTxn() callback.\n *\n * @param txn - Opaque transaction object from cryptoStore.doTxn()\n * @param Olm.Account object\n * @internal\n */\n private storeAccount(txn: unknown, account: Account): void {\n this.cryptoStore.storeAccount(txn, account.pickle(this.pickleKey));\n }\n\n /**\n * Export data for re-creating the Olm device later.\n * TODO export data other than just account and (P2P) sessions.\n *\n * @returns The exported data\n */\n public async export(): Promise<IExportedDevice> {\n const result: Partial<IExportedDevice> = {\n pickleKey: this.pickleKey,\n };\n\n await this.cryptoStore.doTxn(\n \"readonly\",\n [IndexedDBCryptoStore.STORE_ACCOUNT, IndexedDBCryptoStore.STORE_SESSIONS],\n (txn) => {\n this.cryptoStore.getAccount(txn, (pickledAccount: string | null) => {\n result.pickledAccount = pickledAccount!;\n });\n result.sessions = [];\n // Note that the pickledSession object we get in the callback\n // is not exactly the same thing you get in method _getSession\n // see documentation of IndexedDBCryptoStore.getAllEndToEndSessions\n this.cryptoStore.getAllEndToEndSessions(txn, (pickledSession) => {\n result.sessions!.push(pickledSession!);\n });\n },\n );\n return result as IExportedDevice;\n }\n\n /**\n * extract an OlmSession from the session store and call the given function\n * The session is usable only within the callback passed to this\n * function and will be freed as soon the callback returns. It is *not*\n * usable for the rest of the lifetime of the transaction.\n *\n * @param txn - Opaque transaction object from cryptoStore.doTxn()\n * @internal\n */\n private getSession(\n deviceKey: string,\n sessionId: string,\n txn: unknown,\n func: (unpickledSessionInfo: IUnpickledSessionInfo) => void,\n ): void {\n this.cryptoStore.getEndToEndSession(deviceKey, sessionId, txn, (sessionInfo: ISessionInfo | null) => {\n this.unpickleSession(sessionInfo!, func);\n });\n }\n\n /**\n * Creates a session object from a session pickle and executes the given\n * function with it. The session object is destroyed once the function\n * returns.\n *\n * @internal\n */\n private unpickleSession(\n sessionInfo: ISessionInfo,\n func: (unpickledSessionInfo: IUnpickledSessionInfo) => void,\n ): void {\n const session = new global.Olm.Session();\n try {\n session.unpickle(this.pickleKey, sessionInfo.session!);\n const unpickledSessInfo: IUnpickledSessionInfo = Object.assign({}, sessionInfo, { session });\n\n func(unpickledSessInfo);\n } finally {\n session.free();\n }\n }\n\n /**\n * store our OlmSession in the session store\n *\n * @param sessionInfo - `{session: OlmSession, lastReceivedMessageTs: int}`\n * @param txn - Opaque transaction object from cryptoStore.doTxn()\n * @internal\n */\n private saveSession(deviceKey: string, sessionInfo: IUnpickledSessionInfo, txn: unknown): void {\n const sessionId = sessionInfo.session.session_id();\n logger.debug(`Saving Olm session ${sessionId} with device ${deviceKey}: ${sessionInfo.session.describe()}`);\n\n // Why do we re-use the input object for this, overwriting the same key with a different\n // type? Is it because we want to erase the unpickled session to enforce that it's no longer\n // used? A comment would be great.\n const pickledSessionInfo = Object.assign(sessionInfo, {\n session: sessionInfo.session.pickle(this.pickleKey),\n });\n this.cryptoStore.storeEndToEndSession(deviceKey, sessionId, pickledSessionInfo, txn);\n }\n\n /**\n * get an OlmUtility and call the given function\n *\n * @returns result of func\n * @internal\n */\n private getUtility<T>(func: (utility: Utility) => T): T {\n const utility = new global.Olm.Utility();\n try {\n return func(utility);\n } finally {\n utility.free();\n }\n }\n\n /**\n * Signs a message with the ed25519 key for this account.\n *\n * @param message - message to be signed\n * @returns base64-encoded signature\n */\n public async sign(message: string): Promise<string> {\n let result: string;\n await this.cryptoStore.doTxn(\"readonly\", [IndexedDBCryptoStore.STORE_ACCOUNT], (txn) => {\n this.getAccount(txn, (account: Account) => {\n result = account.sign(message);\n });\n });\n return result!;\n }\n\n /**\n * Get the current (unused, unpublished) one-time keys for this account.\n *\n * @returns one time keys; an object with the single property\n * <tt>curve25519</tt>, which is itself an object mapping key id to Curve25519\n * key.\n */\n public async getOneTimeKeys(): Promise<OneTimeKeys> {\n let result: OneTimeKeys;\n await this.cryptoStore.doTxn(\"readonly\", [IndexedDBCryptoStore.STORE_ACCOUNT], (txn) => {\n this.getAccount(txn, (account) => {\n result = JSON.parse(account.one_time_keys());\n });\n });\n\n return result!;\n }\n\n /**\n * Get the maximum number of one-time keys we can store.\n *\n * @returns number of keys\n */\n public maxNumberOfOneTimeKeys(): number {\n return this.maxOneTimeKeys ?? -1;\n }\n\n /**\n * Marks all of the one-time keys as published.\n */\n public async markKeysAsPublished(): Promise<void> {\n await this.cryptoStore.doTxn(\"readwrite\", [IndexedDBCryptoStore.STORE_ACCOUNT], (txn) => {\n this.getAccount(txn, (account: Account) => {\n account.mark_keys_as_published();\n this.storeAccount(txn, account);\n });\n });\n }\n\n /**\n * Generate some new one-time keys\n *\n * @param numKeys - number of keys to generate\n * @returns Resolved once the account is saved back having generated the keys\n */\n public generateOneTimeKeys(numKeys: number): Promise<void> {\n return this.cryptoStore.doTxn(\"readwrite\", [IndexedDBCryptoStore.STORE_ACCOUNT], (txn) => {\n this.getAccount(txn, (account) => {\n account.generate_one_time_keys(numKeys);\n this.storeAccount(txn, account);\n });\n });\n }\n\n /**\n * Generate a new fallback keys\n *\n * @returns Resolved once the account is saved back having generated the key\n */\n public async generateFallbackKey(): Promise<void> {\n await this.cryptoStore.doTxn(\"readwrite\", [IndexedDBCryptoStore.STORE_ACCOUNT], (txn) => {\n this.getAccount(txn, (account) => {\n account.generate_fallback_key();\n this.storeAccount(txn, account);\n });\n });\n }\n\n public async getFallbackKey(): Promise<Record<string, Record<string, string>>> {\n let result: Record<string, Record<string, string>>;\n await this.cryptoStore.doTxn(\"readonly\", [IndexedDBCryptoStore.STORE_ACCOUNT], (txn) => {\n this.getAccount(txn, (account: Account) => {\n result = JSON.parse(account.unpublished_fallback_key());\n });\n });\n return result!;\n }\n\n public async forgetOldFallbackKey(): Promise<void> {\n await this.cryptoStore.doTxn(\"readwrite\", [IndexedDBCryptoStore.STORE_ACCOUNT], (txn) => {\n this.getAccount(txn, (account: Account) => {\n account.forget_old_fallback_key();\n this.storeAccount(txn, account);\n });\n });\n }\n\n /**\n * Generate a new outbound session\n *\n * The new session will be stored in the cryptoStore.\n *\n * @param theirIdentityKey - remote user's Curve25519 identity key\n * @param theirOneTimeKey - remote user's one-time Curve25519 key\n * @returns sessionId for the outbound session.\n */\n public async createOutboundSession(theirIdentityKey: string, theirOneTimeKey: string): Promise<string> {\n let newSessionId: string;\n await this.cryptoStore.doTxn(\n \"readwrite\",\n [IndexedDBCryptoStore.STORE_ACCOUNT, IndexedDBCryptoStore.STORE_SESSIONS],\n (txn) => {\n this.getAccount(txn, (account: Account) => {\n const session = new global.Olm.Session();\n try {\n session.create_outbound(account, theirIdentityKey, theirOneTimeKey);\n newSessionId = session.session_id();\n this.storeAccount(txn, account);\n const sessionInfo: IUnpickledSessionInfo = {\n session,\n // Pretend we've received a message at this point, otherwise\n // if we try to send a message to the device, it won't use\n // this session\n lastReceivedMessageTs: Date.now(),\n };\n this.saveSession(theirIdentityKey, sessionInfo, txn);\n } finally {\n session.free();\n }\n });\n },\n logger.withPrefix(\"[createOutboundSession]\"),\n );\n return newSessionId!;\n }\n\n /**\n * Generate a new inbound session, given an incoming message\n *\n * @param theirDeviceIdentityKey - remote user's Curve25519 identity key\n * @param messageType - messageType field from the received message (must be 0)\n * @param ciphertext - base64-encoded body from the received message\n *\n * @returns decrypted payload, and\n * session id of new session\n *\n * @throws Error if the received message was not valid (for instance, it didn't use a valid one-time key).\n */\n public async createInboundSession(\n theirDeviceIdentityKey: string,\n messageType: number,\n ciphertext: string,\n ): Promise<IInboundSession> {\n if (messageType !== 0) {\n throw new Error(\"Need messageType == 0 to create inbound session\");\n }\n\n let result: { payload: string; session_id: string }; // eslint-disable-line camelcase\n await this.cryptoStore.doTxn(\n \"readwrite\",\n [IndexedDBCryptoStore.STORE_ACCOUNT, IndexedDBCryptoStore.STORE_SESSIONS],\n (txn) => {\n this.getAccount(txn, (account: Account) => {\n const session = new global.Olm.Session();\n try {\n session.create_inbound_from(account, theirDeviceIdentityKey, ciphertext);\n account.remove_one_time_keys(session);\n this.storeAccount(txn, account);\n\n const payloadString = session.decrypt(messageType, ciphertext);\n\n const sessionInfo: IUnpickledSessionInfo = {\n session,\n // this counts as a received message: set last received message time\n // to now\n lastReceivedMessageTs: Date.now(),\n };\n this.saveSession(theirDeviceIdentityKey, sessionInfo, txn);\n\n result = {\n payload: payloadString,\n session_id: session.session_id(),\n };\n } finally {\n session.free();\n }\n });\n },\n logger.withPrefix(\"[createInboundSession]\"),\n );\n\n return result!;\n }\n\n /**\n * Get a list of known session IDs for the given device\n *\n * @param theirDeviceIdentityKey - Curve25519 identity key for the\n * remote device\n * @returns a list of known session ids for the device\n */\n public async getSessionIdsForDevice(theirDeviceIdentityKey: string): Promise<string[]> {\n const log = logger.withPrefix(\"[getSessionIdsForDevice]\");\n\n if (theirDeviceIdentityKey in this.sessionsInProgress) {\n log.debug(`Waiting for Olm session for ${theirDeviceIdentityKey} to be created`);\n try {\n await this.sessionsInProgress[theirDeviceIdentityKey];\n } catch (e) {\n // if the session failed to be created, just fall through and\n // return an empty result\n }\n }\n let sessionIds: string[];\n await this.cryptoStore.doTxn(\n \"readonly\",\n [IndexedDBCryptoStore.STORE_SESSIONS],\n (txn) => {\n this.cryptoStore.getEndToEndSessions(theirDeviceIdentityKey, txn, (sessions) => {\n sessionIds = Object.keys(sessions);\n });\n },\n log,\n );\n\n return sessionIds!;\n }\n\n /**\n * Get the right olm session id for encrypting messages to the given identity key\n *\n * @param theirDeviceIdentityKey - Curve25519 identity key for the\n * remote device\n * @param nowait - Don't wait for an in-progress session to complete.\n * This should only be set to true of the calling function is the function\n * that marked the session as being in-progress.\n * @param log - A possibly customised log\n * @returns session id, or null if no established session\n */\n public async getSessionIdForDevice(\n theirDeviceIdentityKey: string,\n nowait = false,\n log?: PrefixedLogger,\n ): Promise<string | null> {\n const sessionInfos = await this.getSessionInfoForDevice(theirDeviceIdentityKey, nowait, log);\n\n if (sessionInfos.length === 0) {\n return null;\n }\n // Use the session that has most recently received a message\n let idxOfBest = 0;\n for (let i = 1; i < sessionInfos.length; i++) {\n const thisSessInfo = sessionInfos[i];\n const thisLastReceived =\n thisSessInfo.lastReceivedMessageTs === undefined ? 0 : thisSessInfo.lastReceivedMessageTs;\n\n const bestSessInfo = sessionInfos[idxOfBest];\n const bestLastReceived =\n bestSessInfo.lastReceivedMessageTs === undefined ? 0 : bestSessInfo.lastReceivedMessageTs;\n if (\n thisLastReceived > bestLastReceived ||\n (thisLastReceived === bestLastReceived && thisSessInfo.sessionId < bestSessInfo.sessionId)\n ) {\n idxOfBest = i;\n }\n }\n return sessionInfos[idxOfBest].sessionId;\n }\n\n /**\n * Get information on the active Olm sessions for a device.\n * <p>\n * Returns an array, with an entry for each active session. The first entry in\n * the result will be the one used for outgoing messages. Each entry contains\n * the keys 'hasReceivedMessage' (true if the session has received an incoming\n * message and is therefore past the pre-key stage), and 'sessionId'.\n *\n * @param deviceIdentityKey - Curve25519 identity key for the device\n * @param nowait - Don't wait for an in-progress session to complete.\n * This should only be set to true of the calling function is the function\n * that marked the session as being in-progress.\n * @param log - A possibly customised log\n */\n public async getSessionInfoForDevice(\n deviceIdentityKey: string,\n nowait = false,\n log = logger,\n ): Promise<{ sessionId: string; lastReceivedMessageTs: number; hasReceivedMessage: boolean }[]> {\n log = log.withPrefix(\"[getSessionInfoForDevice]\");\n\n if (deviceIdentityKey in this.sessionsInProgress && !nowait) {\n log.debug(`Waiting for Olm session for ${deviceIdentityKey} to be created`);\n try {\n await this.sessionsInProgress[deviceIdentityKey];\n } catch (e) {\n // if the session failed to be created, then just fall through and\n // return an empty result\n }\n }\n const info: {\n lastReceivedMessageTs: number;\n hasReceivedMessage: boolean;\n sessionId: string;\n }[] = [];\n\n await this.cryptoStore.doTxn(\n \"readonly\",\n [IndexedDBCryptoStore.STORE_SESSIONS],\n (txn) => {\n this.cryptoStore.getEndToEndSessions(deviceIdentityKey, txn, (sessions) => {\n const sessionIds = Object.keys(sessions).sort();\n for (const sessionId of sessionIds) {\n this.unpickleSession(sessions[sessionId], (sessInfo: IUnpickledSessionInfo) => {\n info.push({\n lastReceivedMessageTs: sessInfo.lastReceivedMessageTs!,\n hasReceivedMessage: sessInfo.session.has_received_message(),\n sessionId,\n });\n });\n }\n });\n },\n log,\n );\n\n return info;\n }\n\n /**\n * Encrypt an outgoing message using an existing session\n *\n * @param theirDeviceIdentityKey - Curve25519 identity key for the\n * remote device\n * @param sessionId - the id of the active session\n * @param payloadString - payload to be encrypted and sent\n *\n * @returns ciphertext\n */\n public async encryptMessage(\n theirDeviceIdentityKey: string,\n sessionId: string,\n payloadString: string,\n ): Promise<IMessage> {\n checkPayloadLength(payloadString);\n\n let res: IMessage;\n await this.cryptoStore.doTxn(\n \"readwrite\",\n [IndexedDBCryptoStore.STORE_SESSIONS],\n (txn) => {\n this.getSession(theirDeviceIdentityKey, sessionId, txn, (sessionInfo) => {\n const sessionDesc = sessionInfo.session.describe();\n logger.log(\n \"encryptMessage: Olm Session ID \" +\n sessionId +\n \" to \" +\n theirDeviceIdentityKey +\n \": \" +\n sessionDesc,\n );\n res = sessionInfo.session.encrypt(payloadString);\n this.saveSession(theirDeviceIdentityKey, sessionInfo, txn);\n });\n },\n logger.withPrefix(\"[encryptMessage]\"),\n );\n return res!;\n }\n\n /**\n * Decrypt an incoming message using an existing session\n *\n * @param theirDeviceIdentityKey - Curve25519 identity key for the\n * remote device\n * @param sessionId - the id of the active session\n * @param messageType - messageType field from the received message\n * @param ciphertext - base64-encoded body from the received message\n *\n * @returns decrypted payload.\n */\n public async decryptMessage(\n theirDeviceIdentityKey: string,\n sessionId: string,\n messageType: number,\n ciphertext: string,\n ): Promise<string> {\n let payloadString: string;\n await this.cryptoStore.doTxn(\n \"readwrite\",\n [IndexedDBCryptoStore.STORE_SESSIONS],\n (txn) => {\n this.getSession(theirDeviceIdentityKey, sessionId, txn, (sessionInfo: IUnpickledSessionInfo) => {\n const sessionDesc = sessionInfo.session.describe();\n logger.log(\n \"decryptMessage: Olm Session ID \" +\n sessionId +\n \" from \" +\n theirDeviceIdentityKey +\n \": \" +\n sessionDesc,\n );\n payloadString = sessionInfo.session.decrypt(messageType, ciphertext);\n sessionInfo.lastReceivedMessageTs = Date.now();\n this.saveSession(theirDeviceIdentityKey, sessionInfo, txn);\n });\n },\n logger.withPrefix(\"[decryptMessage]\"),\n );\n return payloadString!;\n }\n\n /**\n * Determine if an incoming messages is a prekey message matching an existing session\n *\n * @param theirDeviceIdentityKey - Curve25519 identity key for the\n * remote device\n * @param sessionId - the id of the active session\n * @param messageType - messageType field from the received message\n * @param ciphertext - base64-encoded body from the received message\n *\n * @returns true if the received message is a prekey message which matches\n * the given session.\n */\n public async matchesSession(\n theirDeviceIdentityKey: string,\n sessionId: string,\n messageType: number,\n ciphertext: string,\n ): Promise<boolean> {\n if (messageType !== 0) {\n return false;\n }\n\n let matches: boolean;\n await this.cryptoStore.doTxn(\n \"readonly\",\n [IndexedDBCryptoStore.STORE_SESSIONS],\n (txn) => {\n this.getSession(theirDeviceIdentityKey, sessionId, txn, (sessionInfo) => {\n matches = sessionInfo.session.matches_inbound(ciphertext);\n });\n },\n logger.withPrefix(\"[matchesSession]\"),\n );\n return matches!;\n }\n\n public async recordSessionProblem(deviceKey: string, type: string, fixed: boolean): Promise<void> {\n logger.info(`Recording problem on olm session with ${deviceKey} of type ${type}. Recreating: ${fixed}`);\n await this.cryptoStore.storeEndToEndSessionProblem(deviceKey, type, fixed);\n }\n\n public sessionMayHaveProblems(deviceKey: string, timestamp: number): Promise<IProblem | null> {\n return this.cryptoStore.getEndToEndSessionProblem(deviceKey, timestamp);\n }\n\n public filterOutNotifiedErrorDevices(devices: IOlmDevice[]): Promise<IOlmDevice[]> {\n return this.cryptoStore.filterOutNotifiedErrorDevices(devices);\n }\n\n // Outbound group session\n // ======================\n\n /**\n * store an OutboundGroupSession in outboundGroupSessionStore\n *\n * @internal\n */\n private saveOutboundGroupSession(session: OutboundGroupSession): void {\n this.outboundGroupSessionStore[session.session_id()] = session.pickle(this.pickleKey);\n }\n\n /**\n * extract an OutboundGroupSession from outboundGroupSessionStore and call the\n * given function\n *\n * @returns result of func\n * @internal\n */\n private getOutboundGroupSession<T>(sessionId: string, func: (session: OutboundGroupSession) => T): T {\n const pickled = this.outboundGroupSessionStore[sessionId];\n if (pickled === undefined) {\n throw new Error(\"Unknown outbound group session \" + sessionId);\n }\n\n const session = new global.Olm.OutboundGroupSession();\n try {\n session.unpickle(this.pickleKey, pickled);\n return func(session);\n } finally {\n session.free();\n }\n }\n\n /**\n * Generate a new outbound group session\n *\n * @returns sessionId for the outbound session.\n */\n public createOutboundGroupSession(): string {\n const session = new global.Olm.OutboundGroupSession();\n try {\n session.create();\n this.saveOutboundGroupSession(session);\n return session.session_id();\n } finally {\n session.free();\n }\n }\n\n /**\n * Encrypt an outgoing message with an outbound group session\n *\n * @param sessionId - the id of the outboundgroupsession\n * @param payloadString - payload to be encrypted and sent\n *\n * @returns ciphertext\n */\n public encryptGroupMessage(sessionId: string, payloadString: string): string {\n logger.log(`encrypting msg with megolm session ${sessionId}`);\n\n checkPayloadLength(payloadString);\n\n return this.getOutboundGroupSession(sessionId, (session: OutboundGroupSession) => {\n const res = session.encrypt(payloadString);\n this.saveOutboundGroupSession(session);\n return res;\n });\n }\n\n /**\n * Get the session keys for an outbound group session\n *\n * @param sessionId - the id of the outbound group session\n *\n * @returns current chain index, and\n * base64-encoded secret key.\n */\n public getOutboundGroupSessionKey(sessionId: string): IOutboundGroupSessionKey {\n return this.getOutboundGroupSession(sessionId, function (session: OutboundGroupSession) {\n return {\n chain_index: session.message_index(),\n key: session.session_key(),\n };\n });\n }\n\n // Inbound group session\n // =====================\n\n /**\n * Unpickle a session from a sessionData object and invoke the given function.\n * The session is valid only until func returns.\n *\n * @param sessionData - Object describing the session.\n * @param func - Invoked with the unpickled session\n * @returns result of func\n */\n private unpickleInboundGroupSession<T>(\n sessionData: InboundGroupSessionData,\n func: (session: InboundGroupSession) => T,\n ): T {\n const session = new global.Olm.InboundGroupSession();\n try {\n session.unpickle(this.pickleKey, sessionData.session);\n return func(session);\n } finally {\n session.free();\n }\n }\n\n /**\n * extract an InboundGroupSession from the crypto store and call the given function\n *\n * @param roomId - The room ID to extract the session for, or null to fetch\n * sessions for any room.\n * @param txn - Opaque transaction object from cryptoStore.doTxn()\n * @param func - function to call.\n *\n * @internal\n */\n private getInboundGroupSession(\n roomId: string,\n senderKey: string,\n sessionId: string,\n txn: unknown,\n func: (\n session: InboundGroupSession | null,\n data: InboundGroupSessionData | null,\n withheld: IWithheld | null,\n ) => void,\n ): void {\n this.cryptoStore.getEndToEndInboundGroupSession(\n senderKey,\n sessionId,\n txn,\n (sessionData: InboundGroupSessionData | null, withheld: IWithheld | null) => {\n if (sessionData === null) {\n func(null, null, withheld);\n return;\n }\n\n // if we were given a room ID, check that the it matches the original one for the session. This stops\n // the HS pretending a message was targeting a different room.\n if (roomId !== null && roomId !== sessionData.room_id) {\n throw new Error(\n \"Mismatched room_id for inbound group session (expected \" +\n sessionData.room_id +\n \", was \" +\n roomId +\n \")\",\n );\n }\n\n this.unpickleInboundGroupSession(sessionData, (session: InboundGroupSession) => {\n func(session, sessionData, withheld);\n });\n },\n );\n }\n\n /**\n * Add an inbound group session to the session store\n *\n * @param roomId - room in which this session will be used\n * @param senderKey - base64-encoded curve25519 key of the sender\n * @param forwardingCurve25519KeyChain - Devices involved in forwarding\n * this session to us.\n * @param sessionId - session identifier\n * @param sessionKey - base64-encoded secret key\n * @param keysClaimed - Other keys the sender claims.\n * @param exportFormat - true if the megolm keys are in export format\n * (ie, they lack an ed25519 signature)\n * @param extraSessionData - any other data to be include with the session\n */\n public async addInboundGroupSession(\n roomId: string,\n senderKey: string,\n forwardingCurve25519KeyChain: string[],\n sessionId: string,\n sessionKey: string,\n keysClaimed: Record<string, string>,\n exportFormat: boolean,\n extraSessionData: OlmGroupSessionExtraData = {},\n ): Promise<void> {\n await this.cryptoStore.doTxn(\n \"readwrite\",\n [\n IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS,\n IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS_WITHHELD,\n IndexedDBCryptoStore.STORE_SHARED_HISTORY_INBOUND_GROUP_SESSIONS,\n ],\n (txn) => {\n /* if we already have this session, consider updating it */\n this.getInboundGroupSession(\n roomId,\n senderKey,\n sessionId,\n txn,\n (\n existingSession: InboundGroupSession | null,\n existingSessionData: InboundGroupSessionData | null,\n ) => {\n // new session.\n const session = new global.Olm.InboundGroupSession();\n try {\n if (exportFormat) {\n session.import_session(sessionKey);\n } else {\n session.create(sessionKey);\n }\n if (sessionId != session.session_id()) {\n throw new Error(\"Mismatched group session ID from senderKey: \" + senderKey);\n }\n\n if (existingSession) {\n logger.log(`Update for megolm session ${senderKey}|${sessionId}`);\n if (existingSession.first_known_index() <= session.first_known_index()) {\n if (!existingSessionData!.untrusted || extraSessionData.untrusted) {\n // existing session has less-than-or-equal index\n // (i.e. can decrypt at least as much), and the\n // new session's trust does not win over the old\n // session's trust, so keep it\n logger.log(`Keeping existing megolm session ${senderKey}|${sessionId}`);\n return;\n }\n if (existingSession.first_known_index() < session.first_known_index()) {\n // We want to upgrade the existing session's trust,\n // but we can't just use the new session because we'll\n // lose the lower index. Check that the sessions connect\n // properly, and then manually set the existing session\n // as trusted.\n if (\n existingSession.export_session(session.first_known_index()) ===\n session.export_session(session.first_known_index())\n ) {\n logger.info(\n \"Upgrading trust of existing megolm session \" +\n `${senderKey}|${sessionId} based on newly-received trusted session`,\n );\n existingSessionData!.untrusted = false;\n this.cryptoStore.storeEndToEndInboundGroupSession(\n senderKey,\n sessionId,\n existingSessionData!,\n txn,\n );\n } else {\n logger.warn(\n `Newly-received megolm session ${senderKey}|$sessionId}` +\n \" does not match existing session! Keeping existing session\",\n );\n }\n return;\n }\n // If the sessions have the same index, go ahead and store the new trusted one.\n }\n }\n\n logger.info(\n `Storing megolm session ${senderKey}|${sessionId} with first index ` +\n session.first_known_index(),\n );\n\n const sessionData = Object.assign({}, extraSessionData, {\n room_id: roomId,\n session: session.pickle(this.pickleKey),\n keysClaimed: keysClaimed,\n forwardingCurve25519KeyChain: forwardingCurve25519KeyChain,\n });\n\n this.cryptoStore.storeEndToEndInboundGroupSession(senderKey, sessionId, sessionData, txn);\n\n if (!existingSession && extraSessionData.sharedHistory) {\n this.cryptoStore.addSharedHistoryInboundGroupSession(roomId, senderKey, sessionId, txn);\n }\n } finally {\n session.free();\n }\n },\n );\n },\n logger.withPrefix(\"[addInboundGroupSession]\"),\n );\n }\n\n /**\n * Record in the data store why an inbound group session was withheld.\n *\n * @param roomId - room that the session belongs to\n * @param senderKey - base64-encoded curve25519 key of the sender\n * @param sessionId - session identifier\n * @param code - reason code\n * @param reason - human-readable version of `code`\n */\n public async addInboundGroupSessionWithheld(\n roomId: string,\n senderKey: string,\n sessionId: string,\n code: string,\n reason: string,\n ): Promise<void> {\n await this.cryptoStore.doTxn(\n \"readwrite\",\n [IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS_WITHHELD],\n (txn) => {\n this.cryptoStore.storeEndToEndInboundGroupSessionWithheld(\n senderKey,\n sessionId,\n {\n room_id: roomId,\n code: code,\n reason: reason,\n },\n txn,\n );\n },\n );\n }\n\n /**\n * Decrypt a received message with an inbound group session\n *\n * @param roomId - room in which the message was received\n * @param senderKey - base64-encoded curve25519 key of the sender\n * @param sessionId - session identifier\n * @param body - base64-encoded body of the encrypted message\n * @param eventId - ID of the event being decrypted\n * @param timestamp - timestamp of the event being decrypted\n *\n * @returns null if the sessionId is unknown\n */\n public async decryptGroupMessage(\n roomId: string,\n senderKey: string,\n sessionId: string,\n body: string,\n eventId: string,\n timestamp: number,\n ): Promise<IDecryptedGroupMessage | null> {\n let result: IDecryptedGroupMessage | null = null;\n // when the localstorage crypto store is used as an indexeddb backend,\n // exceptions thrown from within the inner function are not passed through\n // to the top level, so we store exceptions in a variable and raise them at\n // the end\n let error: Error;\n\n await this.cryptoStore.doTxn(\n \"readwrite\",\n [\n IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS,\n IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS_WITHHELD,\n ],\n (txn) => {\n this.getInboundGroupSession(roomId, senderKey, sessionId, txn, (session, sessionData, withheld) => {\n if (session === null || sessionData === null) {\n if (withheld) {\n error = new algorithms.DecryptionError(\n \"MEGOLM_UNKNOWN_INBOUND_SESSION_ID\",\n calculateWithheldMessage(withheld),\n {\n session: senderKey + \"|\" + sessionId,\n },\n );\n }\n result = null;\n return;\n }\n let res: ReturnType<InboundGroupSession[\"decrypt\"]>;\n try {\n res = session.decrypt(body);\n } catch (e) {\n if ((<Error>e)?.message === \"OLM.UNKNOWN_MESSAGE_INDEX\" && withheld) {\n error = new algorithms.DecryptionError(\n \"MEGOLM_UNKNOWN_INBOUND_SESSION_ID\",\n calculateWithheldMessage(withheld),\n {\n session: senderKey + \"|\" + sessionId,\n },\n );\n } else {\n error = <Error>e;\n }\n return;\n }\n\n let plaintext: string = res.plaintext;\n if (plaintext === undefined) {\n // @ts-ignore - Compatibility for older olm versions.\n plaintext = res as string;\n } else {\n // Check if we have seen this message index before to detect replay attacks.\n // If the event ID and timestamp are specified, and the match the event ID\n // and timestamp from the last time we used this message index, then we\n // don't consider it a replay attack.\n const messageIndexKey = senderKey + \"|\" + sessionId + \"|\" + res.message_index;\n if (messageIndexKey in this.inboundGroupSessionMessageIndexes) {\n const msgInfo = this.inboundGroupSessionMessageIndexes[messageIndexKey];\n if (msgInfo.id !== eventId || msgInfo.timestamp !== timestamp) {\n error = new Error(\n \"Duplicate message index, possible replay attack: \" + messageIndexKey,\n );\n return;\n }\n }\n this.inboundGroupSessionMessageIndexes[messageIndexKey] = {\n id: eventId,\n timestamp: timestamp,\n };\n }\n\n sessionData.session = session.pickle(this.pickleKey);\n this.cryptoStore.storeEndToEndInboundGroupSession(senderKey, sessionId, sessionData, txn);\n result = {\n result: plaintext,\n keysClaimed: sessionData.keysClaimed || {},\n senderKey: senderKey,\n forwardingCurve25519KeyChain: sessionData.forwardingCurve25519KeyChain || [],\n untrusted: !!sessionData.untrusted,\n };\n });\n },\n logger.withPrefix(\"[decryptGroupMessage]\"),\n );\n\n if (error!) {\n throw error;\n }\n return result!;\n }\n\n /**\n * Determine if we have the keys for a given megolm session\n *\n * @param roomId - room in which the message was received\n * @param senderKey - base64-encoded curve25519 key of the sender\n * @param sessionId - session identifier\n *\n * @returns true if we have the keys to this session\n */\n public async hasInboundSessionKeys(roomId: string, senderKey: string, sessionId: string): Promise<boolean> {\n let result: boolean;\n await this.cryptoStore.doTxn(\n \"readonly\",\n [\n IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS,\n IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS_WITHHELD,\n ],\n (txn) => {\n this.cryptoStore.getEndToEndInboundGroupSession(senderKey, sessionId, txn, (sessionData) => {\n if (sessionData === null) {\n result = false;\n return;\n }\n\n if (roomId !== sessionData.room_id) {\n logger.warn(\n `requested keys for inbound group session ${senderKey}|` +\n `${sessionId}, with incorrect room_id ` +\n `(expected ${sessionData.room_id}, ` +\n `was ${roomId})`,\n );\n result = false;\n } else {\n result = true;\n }\n });\n },\n logger.withPrefix(\"[hasInboundSessionKeys]\"),\n );\n\n return result!;\n }\n\n /**\n * Extract the keys to a given megolm session, for sharing\n *\n * @param roomId - room in which the message was received\n * @param senderKey - base64-encoded curve25519 key of the sender\n * @param sessionId - session identifier\n * @param chainIndex - The chain index at which to export the session.\n * If omitted, export at the first index we know about.\n *\n * @returns\n * details of the session key. The key is a base64-encoded megolm key in\n * export format.\n *\n * @throws Error If the given chain index could not be obtained from the known\n * index (ie. the given chain index is before the first we have).\n */\n public async getInboundGroupSessionKey(\n roomId: string,\n senderKey: string,\n sessionId: string,\n chainIndex?: number,\n ): Promise<IInboundGroupSessionKey | null> {\n let result: IInboundGroupSessionKey | null = null;\n await this.cryptoStore.doTxn(\n \"readonly\",\n [\n IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS,\n IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS_WITHHELD,\n ],\n (txn) => {\n this.getInboundGroupSession(roomId, senderKey, sessionId, txn, (session, sessionData) => {\n if (session === null || sessionData === null) {\n result = null;\n return;\n }\n\n if (chainIndex === undefined) {\n chainIndex = session.first_known_index();\n }\n\n const exportedSession = session.export_session(chainIndex);\n\n const claimedKeys = sessionData.keysClaimed || {};\n const senderEd25519Key = claimedKeys.ed25519 || null;\n\n const forwardingKeyChain = sessionData.forwardingCurve25519KeyChain || [];\n // older forwarded keys didn't set the \"untrusted\"\n // property, but can be identified by having a\n // non-empty forwarding key chain. These keys should\n // be marked as untrusted since we don't know that they\n // can be trusted\n const untrusted =\n \"untrusted\" in sessionData ? sessionData.untrusted : forwardingKeyChain.length > 0;\n\n result = {\n chain_index: chainIndex,\n key: exportedSession,\n forwarding_curve25519_key_chain: forwardingKeyChain,\n sender_claimed_ed25519_key: senderEd25519Key,\n shared_history: sessionData.sharedHistory || false,\n untrusted: untrusted,\n };\n });\n },\n logger.withPrefix(\"[getInboundGroupSessionKey]\"),\n );\n\n return result;\n }\n\n /**\n * Export an inbound group session\n *\n * @param senderKey - base64-encoded curve25519 key of the sender\n * @param sessionId - session identifier\n * @param sessionData - The session object from the store\n * @returns exported session data\n */\n public exportInboundGroupSession(\n senderKey: string,\n sessionId: string,\n sessionData: InboundGroupSessionData,\n ): IMegolmSessionData {\n return this.unpickleInboundGroupSession(sessionData, (session) => {\n const messageIndex = session.first_known_index();\n\n return {\n \"sender_key\": senderKey,\n \"sender_claimed_keys\": sessionData.keysClaimed,\n \"room_id\": sessionData.room_id,\n \"session_id\": sessionId,\n \"session_key\": session.export_session(messageIndex),\n \"forwarding_curve25519_key_chain\": sessionData.forwardingCurve25519KeyChain || [],\n \"first_known_index\": session.first_known_index(),\n \"org.matrix.msc3061.shared_history\": sessionData.sharedHistory || false,\n } as IMegolmSessionData;\n });\n }\n\n public async getSharedHistoryInboundGroupSessions(\n roomId: string,\n ): Promise<[senderKey: string, sessionId: string][]> {\n let result: Promise<[senderKey: string, sessionId: string][]>;\n await this.cryptoStore.doTxn(\n \"readonly\",\n [IndexedDBCryptoStore.STORE_SHARED_HISTORY_INBOUND_GROUP_SESSIONS],\n (txn) => {\n result = this.cryptoStore.getSharedHistoryInboundGroupSessions(roomId, txn);\n },\n logger.withPrefix(\"[getSharedHistoryInboundGroupSessionsForRoom]\"),\n );\n return result!;\n }\n\n // Utilities\n // =========\n\n /**\n * Verify an ed25519 signature.\n *\n * @param key - ed25519 key\n * @param message - message which was signed\n * @param signature - base64-encoded signature to be checked\n *\n * @throws Error if there is a problem with the verification. If the key was\n * too small then the message will be \"OLM.INVALID_BASE64\". If the signature\n * was invalid then the message will be \"OLM.BAD_MESSAGE_MAC\".\n */\n public verifySignature(key: string, message: string, signature: string): void {\n this.getUtility(function (util: Utility) {\n util.ed25519_verify(key, message, signature);\n });\n }\n}\n\nexport const WITHHELD_MESSAGES: Record<string, string> = {\n \"m.unverified\": \"The sender has disabled encrypting to unverified devices.\",\n \"m.blacklisted\": \"The sender has blocked you.\",\n \"m.unauthorised\": \"You are not authorised to read the message.\",\n \"m.no_olm\": \"Unable to establish a secure channel.\",\n};\n\n/**\n * Calculate the message to use for the exception when a session key is withheld.\n *\n * @param withheld - An object that describes why the key was withheld.\n *\n * @returns the message\n *\n * @internal\n */\nfunction calculateWithheldMessage(withheld: IWithheld): string {\n if (withheld.code && withheld.code in WITHHELD_MESSAGES) {\n return WITHHELD_MESSAGES[withheld.code];\n } else if (withheld.reason) {\n return withheld.reason;\n } else {\n return \"decryption key withheld\";\n }\n}\n"],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/OutgoingRoomKeyRequestManager.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/OutgoingRoomKeyRequestManager.d.ts
deleted file mode 100644
index 6e5bf8c..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/OutgoingRoomKeyRequestManager.d.ts
+++ /dev/null
@@ -1,109 +0,0 @@
-import { MatrixClient } from "../client";
-import { IRoomKeyRequestBody, IRoomKeyRequestRecipient } from "./index";
-import { CryptoStore, OutgoingRoomKeyRequest } from "./store/base";
-/**
- * possible states for a room key request
- *
- * The state machine looks like:
- * ```
- *
- * | (cancellation sent)
- * | .-------------------------------------------------.
- * | | |
- * V V (cancellation requested) |
- * UNSENT -----------------------------+ |
- * | | |
- * | | |
- * | (send successful) | CANCELLATION_PENDING_AND_WILL_RESEND
- * V | Λ
- * SENT | |
- * |-------------------------------- | --------------'
- * | | (cancellation requested with intent
- * | | to resend the original request)
- * | |
- * | (cancellation requested) |
- * V |
- * CANCELLATION_PENDING |
- * | |
- * | (cancellation sent) |
- * V |
- * (deleted) <---------------------------+
- * ```
- */
-export declare enum RoomKeyRequestState {
- /** request not yet sent */
- Unsent = 0,
- /** request sent, awaiting reply */
- Sent = 1,
- /** reply received, cancellation not yet sent */
- CancellationPending = 2,
- /**
- * Cancellation not yet sent and will transition to UNSENT instead of
- * being deleted once the cancellation has been sent.
- */
- CancellationPendingAndWillResend = 3
-}
-export declare class OutgoingRoomKeyRequestManager {
- private readonly baseApis;
- private readonly deviceId;
- private readonly cryptoStore;
- private sendOutgoingRoomKeyRequestsTimer?;
- private sendOutgoingRoomKeyRequestsRunning;
- private clientRunning;
- constructor(baseApis: MatrixClient, deviceId: string, cryptoStore: CryptoStore);
- /**
- * Called when the client is stopped. Stops any running background processes.
- */
- stop(): void;
- /**
- * Send any requests that have been queued
- */
- sendQueuedRequests(): void;
- /**
- * Queue up a room key request, if we haven't already queued or sent one.
- *
- * The `requestBody` is compared (with a deep-equality check) against
- * previous queued or sent requests and if it matches, no change is made.
- * Otherwise, a request is added to the pending list, and a job is started
- * in the background to send it.
- *
- * @param resend - whether to resend the key request if there is
- * already one
- *
- * @returns resolves when the request has been added to the
- * pending list (or we have established that a similar request already
- * exists)
- */
- queueRoomKeyRequest(requestBody: IRoomKeyRequestBody, recipients: IRoomKeyRequestRecipient[], resend?: boolean): Promise<void>;
- /**
- * Cancel room key requests, if any match the given requestBody
- *
- *
- * @returns resolves when the request has been updated in our
- * pending list.
- */
- cancelRoomKeyRequest(requestBody: IRoomKeyRequestBody): Promise<unknown>;
- /**
- * Look for room key requests by target device and state
- *
- * @param userId - Target user ID
- * @param deviceId - Target device ID
- *
- * @returns resolves to a list of all the {@link OutgoingRoomKeyRequest}
- */
- getOutgoingSentRoomKeyRequest(userId: string, deviceId: string): Promise<OutgoingRoomKeyRequest[]>;
- /**
- * Find anything in `sent` state, and kick it around the loop again.
- * This is intended for situations where something substantial has changed, and we
- * don't really expect the other end to even care about the cancellation.
- * For example, after initialization or self-verification.
- * @returns An array of `queueRoomKeyRequest` outputs.
- */
- cancelAndResendAllOutgoingRequests(): Promise<void[]>;
- private startTimer;
- private sendOutgoingRoomKeyRequests;
- private sendOutgoingRoomKeyRequest;
- private sendOutgoingRoomKeyRequestCancellation;
- private sendMessageToDevices;
-}
-//# sourceMappingURL=OutgoingRoomKeyRequestManager.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/OutgoingRoomKeyRequestManager.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/OutgoingRoomKeyRequestManager.d.ts.map
deleted file mode 100644
index 19d0444..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/OutgoingRoomKeyRequestManager.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"OutgoingRoomKeyRequestManager.d.ts","sourceRoot":"","sources":["../../src/crypto/OutgoingRoomKeyRequestManager.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAC;AACxE,OAAO,EAAE,WAAW,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAenE;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,oBAAY,mBAAmB;IAC3B,2BAA2B;IAC3B,MAAM,IAAA;IACN,mCAAmC;IACnC,IAAI,IAAA;IACJ,gDAAgD;IAChD,mBAAmB,IAAA;IACnB;;;OAGG;IACH,gCAAgC,IAAA;CACnC;AAkBD,qBAAa,6BAA6B;IAYlC,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAXhC,OAAO,CAAC,gCAAgC,CAAC,CAAgC;IAIzE,OAAO,CAAC,kCAAkC,CAAS;IAEnD,OAAO,CAAC,aAAa,CAAQ;gBAGR,QAAQ,EAAE,YAAY,EACtB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,WAAW;IAG7C;;OAEG;IACI,IAAI,IAAI,IAAI;IAMnB;;OAEG;IACI,kBAAkB,IAAI,IAAI;IAIjC;;;;;;;;;;;;;;OAcG;IACU,mBAAmB,CAC5B,WAAW,EAAE,mBAAmB,EAChC,UAAU,EAAE,wBAAwB,EAAE,EACtC,MAAM,UAAQ,GACf,OAAO,CAAC,IAAI,CAAC;IAqFhB;;;;;;OAMG;IACI,oBAAoB,CAAC,WAAW,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC;IAmE/E;;;;;;;OAOG;IACI,6BAA6B,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,EAAE,CAAC;IAIzG;;;;;;OAMG;IACU,kCAAkC,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;IASlE,OAAO,CAAC,UAAU;YA+BJ,2BAA2B;IAuCzC,OAAO,CAAC,0BAA0B;IAuBlC,OAAO,CAAC,sCAAsC;IA+B9C,OAAO,CAAC,oBAAoB;CAgB/B"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/OutgoingRoomKeyRequestManager.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/OutgoingRoomKeyRequestManager.js
deleted file mode 100644
index 2bd25ba..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/OutgoingRoomKeyRequestManager.js
+++ /dev/null
@@ -1,394 +0,0 @@
-"use strict";
-
-var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.RoomKeyRequestState = exports.OutgoingRoomKeyRequestManager = void 0;
-var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
-var _uuid = require("uuid");
-var _logger = require("../logger");
-var _event = require("../@types/event");
-var _utils = require("../utils");
-function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
-function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
-/**
- * Internal module. Management of outgoing room key requests.
- *
- * See https://docs.google.com/document/d/1m4gQkcnJkxNuBmb5NoFCIadIY-DyqqNAS3lloE73BlQ
- * for draft documentation on what we're supposed to be implementing here.
- */
-
-// delay between deciding we want some keys, and sending out the request, to
-// allow for (a) it turning up anyway, (b) grouping requests together
-const SEND_KEY_REQUESTS_DELAY_MS = 500;
-
-/**
- * possible states for a room key request
- *
- * The state machine looks like:
- * ```
- *
- * | (cancellation sent)
- * | .-------------------------------------------------.
- * | | |
- * V V (cancellation requested) |
- * UNSENT -----------------------------+ |
- * | | |
- * | | |
- * | (send successful) | CANCELLATION_PENDING_AND_WILL_RESEND
- * V | Λ
- * SENT | |
- * |-------------------------------- | --------------'
- * | | (cancellation requested with intent
- * | | to resend the original request)
- * | |
- * | (cancellation requested) |
- * V |
- * CANCELLATION_PENDING |
- * | |
- * | (cancellation sent) |
- * V |
- * (deleted) <---------------------------+
- * ```
- */
-let RoomKeyRequestState;
-exports.RoomKeyRequestState = RoomKeyRequestState;
-(function (RoomKeyRequestState) {
- RoomKeyRequestState[RoomKeyRequestState["Unsent"] = 0] = "Unsent";
- RoomKeyRequestState[RoomKeyRequestState["Sent"] = 1] = "Sent";
- RoomKeyRequestState[RoomKeyRequestState["CancellationPending"] = 2] = "CancellationPending";
- RoomKeyRequestState[RoomKeyRequestState["CancellationPendingAndWillResend"] = 3] = "CancellationPendingAndWillResend";
-})(RoomKeyRequestState || (exports.RoomKeyRequestState = RoomKeyRequestState = {}));
-class OutgoingRoomKeyRequestManager {
- // handle for the delayed call to sendOutgoingRoomKeyRequests. Non-null
- // if the callback has been set, or if it is still running.
-
- // sanity check to ensure that we don't end up with two concurrent runs
- // of sendOutgoingRoomKeyRequests
-
- constructor(baseApis, deviceId, cryptoStore) {
- this.baseApis = baseApis;
- this.deviceId = deviceId;
- this.cryptoStore = cryptoStore;
- (0, _defineProperty2.default)(this, "sendOutgoingRoomKeyRequestsTimer", void 0);
- (0, _defineProperty2.default)(this, "sendOutgoingRoomKeyRequestsRunning", false);
- (0, _defineProperty2.default)(this, "clientRunning", true);
- }
-
- /**
- * Called when the client is stopped. Stops any running background processes.
- */
- stop() {
- _logger.logger.log("stopping OutgoingRoomKeyRequestManager");
- // stop the timer on the next run
- this.clientRunning = false;
- }
-
- /**
- * Send any requests that have been queued
- */
- sendQueuedRequests() {
- this.startTimer();
- }
-
- /**
- * Queue up a room key request, if we haven't already queued or sent one.
- *
- * The `requestBody` is compared (with a deep-equality check) against
- * previous queued or sent requests and if it matches, no change is made.
- * Otherwise, a request is added to the pending list, and a job is started
- * in the background to send it.
- *
- * @param resend - whether to resend the key request if there is
- * already one
- *
- * @returns resolves when the request has been added to the
- * pending list (or we have established that a similar request already
- * exists)
- */
- async queueRoomKeyRequest(requestBody, recipients, resend = false) {
- const req = await this.cryptoStore.getOutgoingRoomKeyRequest(requestBody);
- if (!req) {
- await this.cryptoStore.getOrAddOutgoingRoomKeyRequest({
- requestBody: requestBody,
- recipients: recipients,
- requestId: this.baseApis.makeTxnId(),
- state: RoomKeyRequestState.Unsent
- });
- } else {
- switch (req.state) {
- case RoomKeyRequestState.CancellationPendingAndWillResend:
- case RoomKeyRequestState.Unsent:
- // nothing to do here, since we're going to send a request anyways
- return;
- case RoomKeyRequestState.CancellationPending:
- {
- // existing request is about to be cancelled. If we want to
- // resend, then change the state so that it resends after
- // cancelling. Otherwise, just cancel the cancellation.
- const state = resend ? RoomKeyRequestState.CancellationPendingAndWillResend : RoomKeyRequestState.Sent;
- await this.cryptoStore.updateOutgoingRoomKeyRequest(req.requestId, RoomKeyRequestState.CancellationPending, {
- state,
- cancellationTxnId: this.baseApis.makeTxnId()
- });
- break;
- }
- case RoomKeyRequestState.Sent:
- {
- // a request has already been sent. If we don't want to
- // resend, then do nothing. If we do want to, then cancel the
- // existing request and send a new one.
- if (resend) {
- const state = RoomKeyRequestState.CancellationPendingAndWillResend;
- const updatedReq = await this.cryptoStore.updateOutgoingRoomKeyRequest(req.requestId, RoomKeyRequestState.Sent, {
- state,
- cancellationTxnId: this.baseApis.makeTxnId(),
- // need to use a new transaction ID so that
- // the request gets sent
- requestTxnId: this.baseApis.makeTxnId()
- });
- if (!updatedReq) {
- // updateOutgoingRoomKeyRequest couldn't find the request
- // in state ROOM_KEY_REQUEST_STATES.SENT, so we must have
- // raced with another tab to mark the request cancelled.
- // Try again, to make sure the request is resent.
- return this.queueRoomKeyRequest(requestBody, recipients, resend);
- }
-
- // We don't want to wait for the timer, so we send it
- // immediately. (We might actually end up racing with the timer,
- // but that's ok: even if we make the request twice, we'll do it
- // with the same transaction_id, so only one message will get
- // sent).
- //
- // (We also don't want to wait for the response from the server
- // here, as it will slow down processing of received keys if we
- // do.)
- try {
- await this.sendOutgoingRoomKeyRequestCancellation(updatedReq, true);
- } catch (e) {
- _logger.logger.error("Error sending room key request cancellation;" + " will retry later.", e);
- }
- // The request has transitioned from
- // CANCELLATION_PENDING_AND_WILL_RESEND to UNSENT. We
- // still need to resend the request which is now UNSENT, so
- // start the timer if it isn't already started.
- }
-
- break;
- }
- default:
- throw new Error("unhandled state: " + req.state);
- }
- }
- }
-
- /**
- * Cancel room key requests, if any match the given requestBody
- *
- *
- * @returns resolves when the request has been updated in our
- * pending list.
- */
- cancelRoomKeyRequest(requestBody) {
- return this.cryptoStore.getOutgoingRoomKeyRequest(requestBody).then(req => {
- if (!req) {
- // no request was made for this key
- return;
- }
- switch (req.state) {
- case RoomKeyRequestState.CancellationPending:
- case RoomKeyRequestState.CancellationPendingAndWillResend:
- // nothing to do here
- return;
- case RoomKeyRequestState.Unsent:
- // just delete it
-
- // FIXME: ghahah we may have attempted to send it, and
- // not yet got a successful response. So the server
- // may have seen it, so we still need to send a cancellation
- // in that case :/
-
- _logger.logger.log("deleting unnecessary room key request for " + stringifyRequestBody(requestBody));
- return this.cryptoStore.deleteOutgoingRoomKeyRequest(req.requestId, RoomKeyRequestState.Unsent);
- case RoomKeyRequestState.Sent:
- {
- // send a cancellation.
- return this.cryptoStore.updateOutgoingRoomKeyRequest(req.requestId, RoomKeyRequestState.Sent, {
- state: RoomKeyRequestState.CancellationPending,
- cancellationTxnId: this.baseApis.makeTxnId()
- }).then(updatedReq => {
- if (!updatedReq) {
- // updateOutgoingRoomKeyRequest couldn't find the
- // request in state ROOM_KEY_REQUEST_STATES.SENT,
- // so we must have raced with another tab to mark
- // the request cancelled. There is no point in
- // sending another cancellation since the other tab
- // will do it.
- _logger.logger.log("Tried to cancel room key request for " + stringifyRequestBody(requestBody) + " but it was already cancelled in another tab");
- return;
- }
-
- // We don't want to wait for the timer, so we send it
- // immediately. (We might actually end up racing with the timer,
- // but that's ok: even if we make the request twice, we'll do it
- // with the same transaction_id, so only one message will get
- // sent).
- //
- // (We also don't want to wait for the response from the server
- // here, as it will slow down processing of received keys if we
- // do.)
- this.sendOutgoingRoomKeyRequestCancellation(updatedReq).catch(e => {
- _logger.logger.error("Error sending room key request cancellation;" + " will retry later.", e);
- this.startTimer();
- });
- });
- }
- default:
- throw new Error("unhandled state: " + req.state);
- }
- });
- }
-
- /**
- * Look for room key requests by target device and state
- *
- * @param userId - Target user ID
- * @param deviceId - Target device ID
- *
- * @returns resolves to a list of all the {@link OutgoingRoomKeyRequest}
- */
- getOutgoingSentRoomKeyRequest(userId, deviceId) {
- return this.cryptoStore.getOutgoingRoomKeyRequestsByTarget(userId, deviceId, [RoomKeyRequestState.Sent]);
- }
-
- /**
- * Find anything in `sent` state, and kick it around the loop again.
- * This is intended for situations where something substantial has changed, and we
- * don't really expect the other end to even care about the cancellation.
- * For example, after initialization or self-verification.
- * @returns An array of `queueRoomKeyRequest` outputs.
- */
- async cancelAndResendAllOutgoingRequests() {
- const outgoings = await this.cryptoStore.getAllOutgoingRoomKeyRequestsByState(RoomKeyRequestState.Sent);
- return Promise.all(outgoings.map(({
- requestBody,
- recipients
- }) => this.queueRoomKeyRequest(requestBody, recipients, true)));
- }
-
- // start the background timer to send queued requests, if the timer isn't
- // already running
- startTimer() {
- if (this.sendOutgoingRoomKeyRequestsTimer) {
- return;
- }
- const startSendingOutgoingRoomKeyRequests = () => {
- if (this.sendOutgoingRoomKeyRequestsRunning) {
- throw new Error("RoomKeyRequestSend already in progress!");
- }
- this.sendOutgoingRoomKeyRequestsRunning = true;
- this.sendOutgoingRoomKeyRequests().finally(() => {
- this.sendOutgoingRoomKeyRequestsRunning = false;
- }).catch(e => {
- // this should only happen if there is an indexeddb error,
- // in which case we're a bit stuffed anyway.
- _logger.logger.warn(`error in OutgoingRoomKeyRequestManager: ${e}`);
- });
- };
- this.sendOutgoingRoomKeyRequestsTimer = setTimeout(startSendingOutgoingRoomKeyRequests, SEND_KEY_REQUESTS_DELAY_MS);
- }
-
- // look for and send any queued requests. Runs itself recursively until
- // there are no more requests, or there is an error (in which case, the
- // timer will be restarted before the promise resolves).
- async sendOutgoingRoomKeyRequests() {
- if (!this.clientRunning) {
- this.sendOutgoingRoomKeyRequestsTimer = undefined;
- return;
- }
- const req = await this.cryptoStore.getOutgoingRoomKeyRequestByState([RoomKeyRequestState.CancellationPending, RoomKeyRequestState.CancellationPendingAndWillResend, RoomKeyRequestState.Unsent]);
- if (!req) {
- this.sendOutgoingRoomKeyRequestsTimer = undefined;
- return;
- }
- try {
- switch (req.state) {
- case RoomKeyRequestState.Unsent:
- await this.sendOutgoingRoomKeyRequest(req);
- break;
- case RoomKeyRequestState.CancellationPending:
- await this.sendOutgoingRoomKeyRequestCancellation(req);
- break;
- case RoomKeyRequestState.CancellationPendingAndWillResend:
- await this.sendOutgoingRoomKeyRequestCancellation(req, true);
- break;
- }
-
- // go around the loop again
- return this.sendOutgoingRoomKeyRequests();
- } catch (e) {
- _logger.logger.error("Error sending room key request; will retry later.", e);
- this.sendOutgoingRoomKeyRequestsTimer = undefined;
- }
- }
-
- // given a RoomKeyRequest, send it and update the request record
- sendOutgoingRoomKeyRequest(req) {
- _logger.logger.log(`Requesting keys for ${stringifyRequestBody(req.requestBody)}` + ` from ${stringifyRecipientList(req.recipients)}` + `(id ${req.requestId})`);
- const requestMessage = {
- action: "request",
- requesting_device_id: this.deviceId,
- request_id: req.requestId,
- body: req.requestBody
- };
- return this.sendMessageToDevices(requestMessage, req.recipients, req.requestTxnId || req.requestId).then(() => {
- return this.cryptoStore.updateOutgoingRoomKeyRequest(req.requestId, RoomKeyRequestState.Unsent, {
- state: RoomKeyRequestState.Sent
- });
- });
- }
-
- // Given a RoomKeyRequest, cancel it and delete the request record unless
- // andResend is set, in which case transition to UNSENT.
- sendOutgoingRoomKeyRequestCancellation(req, andResend = false) {
- _logger.logger.log(`Sending cancellation for key request for ` + `${stringifyRequestBody(req.requestBody)} to ` + `${stringifyRecipientList(req.recipients)} ` + `(cancellation id ${req.cancellationTxnId})`);
- const requestMessage = {
- action: "request_cancellation",
- requesting_device_id: this.deviceId,
- request_id: req.requestId
- };
- return this.sendMessageToDevices(requestMessage, req.recipients, req.cancellationTxnId).then(() => {
- if (andResend) {
- // We want to resend, so transition to UNSENT
- return this.cryptoStore.updateOutgoingRoomKeyRequest(req.requestId, RoomKeyRequestState.CancellationPendingAndWillResend, {
- state: RoomKeyRequestState.Unsent
- });
- }
- return this.cryptoStore.deleteOutgoingRoomKeyRequest(req.requestId, RoomKeyRequestState.CancellationPending);
- });
- }
-
- // send a RoomKeyRequest to a list of recipients
- sendMessageToDevices(message, recipients, txnId) {
- const contentMap = new _utils.MapWithDefault(() => new Map());
- for (const recip of recipients) {
- const userDeviceMap = contentMap.getOrCreate(recip.userId);
- userDeviceMap.set(recip.deviceId, _objectSpread(_objectSpread({}, message), {}, {
- [_event.ToDeviceMessageId]: (0, _uuid.v4)()
- }));
- }
- return this.baseApis.sendToDevice(_event.EventType.RoomKeyRequest, contentMap, txnId);
- }
-}
-exports.OutgoingRoomKeyRequestManager = OutgoingRoomKeyRequestManager;
-function stringifyRequestBody(requestBody) {
- // we assume that the request is for megolm keys, which are identified by
- // room id and session id
- return requestBody.room_id + " / " + requestBody.session_id;
-}
-function stringifyRecipientList(recipients) {
- return `[${recipients.map(r => `${r.userId}:${r.deviceId}`).join(",")}]`;
-}
-//# sourceMappingURL=OutgoingRoomKeyRequestManager.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/OutgoingRoomKeyRequestManager.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/OutgoingRoomKeyRequestManager.js.map
deleted file mode 100644
index ef87212..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/OutgoingRoomKeyRequestManager.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"OutgoingRoomKeyRequestManager.js","names":["_uuid","require","_logger","_event","_utils","ownKeys","object","enumerableOnly","keys","Object","getOwnPropertySymbols","symbols","filter","sym","getOwnPropertyDescriptor","enumerable","push","apply","_objectSpread","target","i","arguments","length","source","forEach","key","_defineProperty2","default","getOwnPropertyDescriptors","defineProperties","defineProperty","SEND_KEY_REQUESTS_DELAY_MS","RoomKeyRequestState","exports","OutgoingRoomKeyRequestManager","constructor","baseApis","deviceId","cryptoStore","stop","logger","log","clientRunning","sendQueuedRequests","startTimer","queueRoomKeyRequest","requestBody","recipients","resend","req","getOutgoingRoomKeyRequest","getOrAddOutgoingRoomKeyRequest","requestId","makeTxnId","state","Unsent","CancellationPendingAndWillResend","CancellationPending","Sent","updateOutgoingRoomKeyRequest","cancellationTxnId","updatedReq","requestTxnId","sendOutgoingRoomKeyRequestCancellation","e","error","Error","cancelRoomKeyRequest","then","stringifyRequestBody","deleteOutgoingRoomKeyRequest","catch","getOutgoingSentRoomKeyRequest","userId","getOutgoingRoomKeyRequestsByTarget","cancelAndResendAllOutgoingRequests","outgoings","getAllOutgoingRoomKeyRequestsByState","Promise","all","map","sendOutgoingRoomKeyRequestsTimer","startSendingOutgoingRoomKeyRequests","sendOutgoingRoomKeyRequestsRunning","sendOutgoingRoomKeyRequests","finally","warn","setTimeout","undefined","getOutgoingRoomKeyRequestByState","sendOutgoingRoomKeyRequest","stringifyRecipientList","requestMessage","action","requesting_device_id","request_id","body","sendMessageToDevices","andResend","message","txnId","contentMap","MapWithDefault","Map","recip","userDeviceMap","getOrCreate","set","ToDeviceMessageId","uuidv4","sendToDevice","EventType","RoomKeyRequest","room_id","session_id","r","join"],"sources":["../../src/crypto/OutgoingRoomKeyRequestManager.ts"],"sourcesContent":["/*\nCopyright 2017 - 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { v4 as uuidv4 } from \"uuid\";\n\nimport { logger } from \"../logger\";\nimport { MatrixClient } from \"../client\";\nimport { IRoomKeyRequestBody, IRoomKeyRequestRecipient } from \"./index\";\nimport { CryptoStore, OutgoingRoomKeyRequest } from \"./store/base\";\nimport { EventType, ToDeviceMessageId } from \"../@types/event\";\nimport { MapWithDefault } from \"../utils\";\n\n/**\n * Internal module. Management of outgoing room key requests.\n *\n * See https://docs.google.com/document/d/1m4gQkcnJkxNuBmb5NoFCIadIY-DyqqNAS3lloE73BlQ\n * for draft documentation on what we're supposed to be implementing here.\n */\n\n// delay between deciding we want some keys, and sending out the request, to\n// allow for (a) it turning up anyway, (b) grouping requests together\nconst SEND_KEY_REQUESTS_DELAY_MS = 500;\n\n/**\n * possible states for a room key request\n *\n * The state machine looks like:\n * ```\n *\n * | (cancellation sent)\n * | .-------------------------------------------------.\n * | | |\n * V V (cancellation requested) |\n * UNSENT -----------------------------+ |\n * | | |\n * | | |\n * | (send successful) | CANCELLATION_PENDING_AND_WILL_RESEND\n * V | Λ\n * SENT | |\n * |-------------------------------- | --------------'\n * | | (cancellation requested with intent\n * | | to resend the original request)\n * | |\n * | (cancellation requested) |\n * V |\n * CANCELLATION_PENDING |\n * | |\n * | (cancellation sent) |\n * V |\n * (deleted) <---------------------------+\n * ```\n */\nexport enum RoomKeyRequestState {\n /** request not yet sent */\n Unsent,\n /** request sent, awaiting reply */\n Sent,\n /** reply received, cancellation not yet sent */\n CancellationPending,\n /**\n * Cancellation not yet sent and will transition to UNSENT instead of\n * being deleted once the cancellation has been sent.\n */\n CancellationPendingAndWillResend,\n}\n\ninterface RequestMessageBase {\n requesting_device_id: string;\n request_id: string;\n}\n\ninterface RequestMessageRequest extends RequestMessageBase {\n action: \"request\";\n body: IRoomKeyRequestBody;\n}\n\ninterface RequestMessageCancellation extends RequestMessageBase {\n action: \"request_cancellation\";\n}\n\ntype RequestMessage = RequestMessageRequest | RequestMessageCancellation;\n\nexport class OutgoingRoomKeyRequestManager {\n // handle for the delayed call to sendOutgoingRoomKeyRequests. Non-null\n // if the callback has been set, or if it is still running.\n private sendOutgoingRoomKeyRequestsTimer?: ReturnType<typeof setTimeout>;\n\n // sanity check to ensure that we don't end up with two concurrent runs\n // of sendOutgoingRoomKeyRequests\n private sendOutgoingRoomKeyRequestsRunning = false;\n\n private clientRunning = true;\n\n public constructor(\n private readonly baseApis: MatrixClient,\n private readonly deviceId: string,\n private readonly cryptoStore: CryptoStore,\n ) {}\n\n /**\n * Called when the client is stopped. Stops any running background processes.\n */\n public stop(): void {\n logger.log(\"stopping OutgoingRoomKeyRequestManager\");\n // stop the timer on the next run\n this.clientRunning = false;\n }\n\n /**\n * Send any requests that have been queued\n */\n public sendQueuedRequests(): void {\n this.startTimer();\n }\n\n /**\n * Queue up a room key request, if we haven't already queued or sent one.\n *\n * The `requestBody` is compared (with a deep-equality check) against\n * previous queued or sent requests and if it matches, no change is made.\n * Otherwise, a request is added to the pending list, and a job is started\n * in the background to send it.\n *\n * @param resend - whether to resend the key request if there is\n * already one\n *\n * @returns resolves when the request has been added to the\n * pending list (or we have established that a similar request already\n * exists)\n */\n public async queueRoomKeyRequest(\n requestBody: IRoomKeyRequestBody,\n recipients: IRoomKeyRequestRecipient[],\n resend = false,\n ): Promise<void> {\n const req = await this.cryptoStore.getOutgoingRoomKeyRequest(requestBody);\n if (!req) {\n await this.cryptoStore.getOrAddOutgoingRoomKeyRequest({\n requestBody: requestBody,\n recipients: recipients,\n requestId: this.baseApis.makeTxnId(),\n state: RoomKeyRequestState.Unsent,\n });\n } else {\n switch (req.state) {\n case RoomKeyRequestState.CancellationPendingAndWillResend:\n case RoomKeyRequestState.Unsent:\n // nothing to do here, since we're going to send a request anyways\n return;\n\n case RoomKeyRequestState.CancellationPending: {\n // existing request is about to be cancelled. If we want to\n // resend, then change the state so that it resends after\n // cancelling. Otherwise, just cancel the cancellation.\n const state = resend\n ? RoomKeyRequestState.CancellationPendingAndWillResend\n : RoomKeyRequestState.Sent;\n await this.cryptoStore.updateOutgoingRoomKeyRequest(\n req.requestId,\n RoomKeyRequestState.CancellationPending,\n {\n state,\n cancellationTxnId: this.baseApis.makeTxnId(),\n },\n );\n break;\n }\n case RoomKeyRequestState.Sent: {\n // a request has already been sent. If we don't want to\n // resend, then do nothing. If we do want to, then cancel the\n // existing request and send a new one.\n if (resend) {\n const state = RoomKeyRequestState.CancellationPendingAndWillResend;\n const updatedReq = await this.cryptoStore.updateOutgoingRoomKeyRequest(\n req.requestId,\n RoomKeyRequestState.Sent,\n {\n state,\n cancellationTxnId: this.baseApis.makeTxnId(),\n // need to use a new transaction ID so that\n // the request gets sent\n requestTxnId: this.baseApis.makeTxnId(),\n },\n );\n if (!updatedReq) {\n // updateOutgoingRoomKeyRequest couldn't find the request\n // in state ROOM_KEY_REQUEST_STATES.SENT, so we must have\n // raced with another tab to mark the request cancelled.\n // Try again, to make sure the request is resent.\n return this.queueRoomKeyRequest(requestBody, recipients, resend);\n }\n\n // We don't want to wait for the timer, so we send it\n // immediately. (We might actually end up racing with the timer,\n // but that's ok: even if we make the request twice, we'll do it\n // with the same transaction_id, so only one message will get\n // sent).\n //\n // (We also don't want to wait for the response from the server\n // here, as it will slow down processing of received keys if we\n // do.)\n try {\n await this.sendOutgoingRoomKeyRequestCancellation(updatedReq, true);\n } catch (e) {\n logger.error(\"Error sending room key request cancellation;\" + \" will retry later.\", e);\n }\n // The request has transitioned from\n // CANCELLATION_PENDING_AND_WILL_RESEND to UNSENT. We\n // still need to resend the request which is now UNSENT, so\n // start the timer if it isn't already started.\n }\n break;\n }\n default:\n throw new Error(\"unhandled state: \" + req.state);\n }\n }\n }\n\n /**\n * Cancel room key requests, if any match the given requestBody\n *\n *\n * @returns resolves when the request has been updated in our\n * pending list.\n */\n public cancelRoomKeyRequest(requestBody: IRoomKeyRequestBody): Promise<unknown> {\n return this.cryptoStore.getOutgoingRoomKeyRequest(requestBody).then((req): unknown => {\n if (!req) {\n // no request was made for this key\n return;\n }\n switch (req.state) {\n case RoomKeyRequestState.CancellationPending:\n case RoomKeyRequestState.CancellationPendingAndWillResend:\n // nothing to do here\n return;\n\n case RoomKeyRequestState.Unsent:\n // just delete it\n\n // FIXME: ghahah we may have attempted to send it, and\n // not yet got a successful response. So the server\n // may have seen it, so we still need to send a cancellation\n // in that case :/\n\n logger.log(\"deleting unnecessary room key request for \" + stringifyRequestBody(requestBody));\n return this.cryptoStore.deleteOutgoingRoomKeyRequest(req.requestId, RoomKeyRequestState.Unsent);\n\n case RoomKeyRequestState.Sent: {\n // send a cancellation.\n return this.cryptoStore\n .updateOutgoingRoomKeyRequest(req.requestId, RoomKeyRequestState.Sent, {\n state: RoomKeyRequestState.CancellationPending,\n cancellationTxnId: this.baseApis.makeTxnId(),\n })\n .then((updatedReq) => {\n if (!updatedReq) {\n // updateOutgoingRoomKeyRequest couldn't find the\n // request in state ROOM_KEY_REQUEST_STATES.SENT,\n // so we must have raced with another tab to mark\n // the request cancelled. There is no point in\n // sending another cancellation since the other tab\n // will do it.\n logger.log(\n \"Tried to cancel room key request for \" +\n stringifyRequestBody(requestBody) +\n \" but it was already cancelled in another tab\",\n );\n return;\n }\n\n // We don't want to wait for the timer, so we send it\n // immediately. (We might actually end up racing with the timer,\n // but that's ok: even if we make the request twice, we'll do it\n // with the same transaction_id, so only one message will get\n // sent).\n //\n // (We also don't want to wait for the response from the server\n // here, as it will slow down processing of received keys if we\n // do.)\n this.sendOutgoingRoomKeyRequestCancellation(updatedReq).catch((e) => {\n logger.error(\"Error sending room key request cancellation;\" + \" will retry later.\", e);\n this.startTimer();\n });\n });\n }\n default:\n throw new Error(\"unhandled state: \" + req.state);\n }\n });\n }\n\n /**\n * Look for room key requests by target device and state\n *\n * @param userId - Target user ID\n * @param deviceId - Target device ID\n *\n * @returns resolves to a list of all the {@link OutgoingRoomKeyRequest}\n */\n public getOutgoingSentRoomKeyRequest(userId: string, deviceId: string): Promise<OutgoingRoomKeyRequest[]> {\n return this.cryptoStore.getOutgoingRoomKeyRequestsByTarget(userId, deviceId, [RoomKeyRequestState.Sent]);\n }\n\n /**\n * Find anything in `sent` state, and kick it around the loop again.\n * This is intended for situations where something substantial has changed, and we\n * don't really expect the other end to even care about the cancellation.\n * For example, after initialization or self-verification.\n * @returns An array of `queueRoomKeyRequest` outputs.\n */\n public async cancelAndResendAllOutgoingRequests(): Promise<void[]> {\n const outgoings = await this.cryptoStore.getAllOutgoingRoomKeyRequestsByState(RoomKeyRequestState.Sent);\n return Promise.all(\n outgoings.map(({ requestBody, recipients }) => this.queueRoomKeyRequest(requestBody, recipients, true)),\n );\n }\n\n // start the background timer to send queued requests, if the timer isn't\n // already running\n private startTimer(): void {\n if (this.sendOutgoingRoomKeyRequestsTimer) {\n return;\n }\n\n const startSendingOutgoingRoomKeyRequests = (): void => {\n if (this.sendOutgoingRoomKeyRequestsRunning) {\n throw new Error(\"RoomKeyRequestSend already in progress!\");\n }\n this.sendOutgoingRoomKeyRequestsRunning = true;\n\n this.sendOutgoingRoomKeyRequests()\n .finally(() => {\n this.sendOutgoingRoomKeyRequestsRunning = false;\n })\n .catch((e) => {\n // this should only happen if there is an indexeddb error,\n // in which case we're a bit stuffed anyway.\n logger.warn(`error in OutgoingRoomKeyRequestManager: ${e}`);\n });\n };\n\n this.sendOutgoingRoomKeyRequestsTimer = setTimeout(\n startSendingOutgoingRoomKeyRequests,\n SEND_KEY_REQUESTS_DELAY_MS,\n );\n }\n\n // look for and send any queued requests. Runs itself recursively until\n // there are no more requests, or there is an error (in which case, the\n // timer will be restarted before the promise resolves).\n private async sendOutgoingRoomKeyRequests(): Promise<void> {\n if (!this.clientRunning) {\n this.sendOutgoingRoomKeyRequestsTimer = undefined;\n return;\n }\n\n const req = await this.cryptoStore.getOutgoingRoomKeyRequestByState([\n RoomKeyRequestState.CancellationPending,\n RoomKeyRequestState.CancellationPendingAndWillResend,\n RoomKeyRequestState.Unsent,\n ]);\n\n if (!req) {\n this.sendOutgoingRoomKeyRequestsTimer = undefined;\n return;\n }\n\n try {\n switch (req.state) {\n case RoomKeyRequestState.Unsent:\n await this.sendOutgoingRoomKeyRequest(req);\n break;\n case RoomKeyRequestState.CancellationPending:\n await this.sendOutgoingRoomKeyRequestCancellation(req);\n break;\n case RoomKeyRequestState.CancellationPendingAndWillResend:\n await this.sendOutgoingRoomKeyRequestCancellation(req, true);\n break;\n }\n\n // go around the loop again\n return this.sendOutgoingRoomKeyRequests();\n } catch (e) {\n logger.error(\"Error sending room key request; will retry later.\", e);\n this.sendOutgoingRoomKeyRequestsTimer = undefined;\n }\n }\n\n // given a RoomKeyRequest, send it and update the request record\n private sendOutgoingRoomKeyRequest(req: OutgoingRoomKeyRequest): Promise<unknown> {\n logger.log(\n `Requesting keys for ${stringifyRequestBody(req.requestBody)}` +\n ` from ${stringifyRecipientList(req.recipients)}` +\n `(id ${req.requestId})`,\n );\n\n const requestMessage: RequestMessage = {\n action: \"request\",\n requesting_device_id: this.deviceId,\n request_id: req.requestId,\n body: req.requestBody,\n };\n\n return this.sendMessageToDevices(requestMessage, req.recipients, req.requestTxnId || req.requestId).then(() => {\n return this.cryptoStore.updateOutgoingRoomKeyRequest(req.requestId, RoomKeyRequestState.Unsent, {\n state: RoomKeyRequestState.Sent,\n });\n });\n }\n\n // Given a RoomKeyRequest, cancel it and delete the request record unless\n // andResend is set, in which case transition to UNSENT.\n private sendOutgoingRoomKeyRequestCancellation(req: OutgoingRoomKeyRequest, andResend = false): Promise<unknown> {\n logger.log(\n `Sending cancellation for key request for ` +\n `${stringifyRequestBody(req.requestBody)} to ` +\n `${stringifyRecipientList(req.recipients)} ` +\n `(cancellation id ${req.cancellationTxnId})`,\n );\n\n const requestMessage: RequestMessage = {\n action: \"request_cancellation\",\n requesting_device_id: this.deviceId,\n request_id: req.requestId,\n };\n\n return this.sendMessageToDevices(requestMessage, req.recipients, req.cancellationTxnId).then(() => {\n if (andResend) {\n // We want to resend, so transition to UNSENT\n return this.cryptoStore.updateOutgoingRoomKeyRequest(\n req.requestId,\n RoomKeyRequestState.CancellationPendingAndWillResend,\n { state: RoomKeyRequestState.Unsent },\n );\n }\n return this.cryptoStore.deleteOutgoingRoomKeyRequest(\n req.requestId,\n RoomKeyRequestState.CancellationPending,\n );\n });\n }\n\n // send a RoomKeyRequest to a list of recipients\n private sendMessageToDevices(\n message: RequestMessage,\n recipients: IRoomKeyRequestRecipient[],\n txnId?: string,\n ): Promise<{}> {\n const contentMap = new MapWithDefault<string, Map<string, Record<string, any>>>(() => new Map());\n for (const recip of recipients) {\n const userDeviceMap = contentMap.getOrCreate(recip.userId);\n userDeviceMap.set(recip.deviceId, {\n ...message,\n [ToDeviceMessageId]: uuidv4(),\n });\n }\n\n return this.baseApis.sendToDevice(EventType.RoomKeyRequest, contentMap, txnId);\n }\n}\n\nfunction stringifyRequestBody(requestBody: IRoomKeyRequestBody): string {\n // we assume that the request is for megolm keys, which are identified by\n // room id and session id\n return requestBody.room_id + \" / \" + requestBody.session_id;\n}\n\nfunction stringifyRecipientList(recipients: IRoomKeyRequestRecipient[]): string {\n return `[${recipients.map((r) => `${r.userId}:${r.deviceId}`).join(\",\")}]`;\n}\n"],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/RoomList.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/RoomList.d.ts
deleted file mode 100644
index f2cf687..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/RoomList.d.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Manages the list of encrypted rooms
- */
-import { CryptoStore } from "./store/base";
-export interface IRoomEncryption {
- algorithm: string;
- rotation_period_ms?: number;
- rotation_period_msgs?: number;
-}
-export declare class RoomList {
- private readonly cryptoStore?;
- private roomEncryption;
- constructor(cryptoStore?: CryptoStore | undefined);
- init(): Promise<void>;
- getRoomEncryption(roomId: string): IRoomEncryption;
- isRoomEncrypted(roomId: string): boolean;
- setRoomEncryption(roomId: string, roomInfo: IRoomEncryption): Promise<void>;
-}
-//# sourceMappingURL=RoomList.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/RoomList.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/RoomList.d.ts.map
deleted file mode 100644
index c28854b..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/RoomList.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"RoomList.d.ts","sourceRoot":"","sources":["../../src/crypto/RoomList.ts"],"names":[],"mappings":"AAgBA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAI3C,MAAM,WAAW,eAAe;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,oBAAoB,CAAC,EAAE,MAAM,CAAC;CACjC;AAGD,qBAAa,QAAQ;IAIE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC;IAFhD,OAAO,CAAC,cAAc,CAAuC;gBAEzB,WAAW,CAAC,yBAAa;IAEhD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ3B,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,eAAe;IAIlD,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAIlC,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;CAS3F"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/RoomList.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/RoomList.js
deleted file mode 100644
index 8fbc993..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/RoomList.js
+++ /dev/null
@@ -1,63 +0,0 @@
-"use strict";
-
-var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.RoomList = void 0;
-var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
-var _indexeddbCryptoStore = require("./store/indexeddb-crypto-store");
-/*
-Copyright 2018 - 2021 The Matrix.org Foundation C.I.C.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-/**
- * Manages the list of encrypted rooms
- */
-
-/* eslint-enable camelcase */
-
-class RoomList {
- // Object of roomId -> room e2e info object (body of the m.room.encryption event)
-
- constructor(cryptoStore) {
- this.cryptoStore = cryptoStore;
- (0, _defineProperty2.default)(this, "roomEncryption", {});
- }
- async init() {
- await this.cryptoStore.doTxn("readwrite", [_indexeddbCryptoStore.IndexedDBCryptoStore.STORE_ROOMS], txn => {
- this.cryptoStore.getEndToEndRooms(txn, result => {
- this.roomEncryption = result;
- });
- });
- }
- getRoomEncryption(roomId) {
- return this.roomEncryption[roomId] || null;
- }
- isRoomEncrypted(roomId) {
- return Boolean(this.getRoomEncryption(roomId));
- }
- async setRoomEncryption(roomId, roomInfo) {
- // important that this happens before calling into the store
- // as it prevents the Crypto::setRoomEncryption from calling
- // this twice for consecutive m.room.encryption events
- this.roomEncryption[roomId] = roomInfo;
- await this.cryptoStore.doTxn("readwrite", [_indexeddbCryptoStore.IndexedDBCryptoStore.STORE_ROOMS], txn => {
- this.cryptoStore.storeEndToEndRoom(roomId, roomInfo, txn);
- });
- }
-}
-exports.RoomList = RoomList;
-//# sourceMappingURL=RoomList.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/RoomList.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/RoomList.js.map
deleted file mode 100644
index d8edb35..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/RoomList.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"RoomList.js","names":["_indexeddbCryptoStore","require","RoomList","constructor","cryptoStore","_defineProperty2","default","init","doTxn","IndexedDBCryptoStore","STORE_ROOMS","txn","getEndToEndRooms","result","roomEncryption","getRoomEncryption","roomId","isRoomEncrypted","Boolean","setRoomEncryption","roomInfo","storeEndToEndRoom","exports"],"sources":["../../src/crypto/RoomList.ts"],"sourcesContent":["/*\nCopyright 2018 - 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n/**\n * Manages the list of encrypted rooms\n */\n\nimport { CryptoStore } from \"./store/base\";\nimport { IndexedDBCryptoStore } from \"./store/indexeddb-crypto-store\";\n\n/* eslint-disable camelcase */\nexport interface IRoomEncryption {\n algorithm: string;\n rotation_period_ms?: number;\n rotation_period_msgs?: number;\n}\n/* eslint-enable camelcase */\n\nexport class RoomList {\n // Object of roomId -> room e2e info object (body of the m.room.encryption event)\n private roomEncryption: Record<string, IRoomEncryption> = {};\n\n public constructor(private readonly cryptoStore?: CryptoStore) {}\n\n public async init(): Promise<void> {\n await this.cryptoStore!.doTxn(\"readwrite\", [IndexedDBCryptoStore.STORE_ROOMS], (txn) => {\n this.cryptoStore!.getEndToEndRooms(txn, (result) => {\n this.roomEncryption = result;\n });\n });\n }\n\n public getRoomEncryption(roomId: string): IRoomEncryption {\n return this.roomEncryption[roomId] || null;\n }\n\n public isRoomEncrypted(roomId: string): boolean {\n return Boolean(this.getRoomEncryption(roomId));\n }\n\n public async setRoomEncryption(roomId: string, roomInfo: IRoomEncryption): Promise<void> {\n // important that this happens before calling into the store\n // as it prevents the Crypto::setRoomEncryption from calling\n // this twice for consecutive m.room.encryption events\n this.roomEncryption[roomId] = roomInfo;\n await this.cryptoStore!.doTxn(\"readwrite\", [IndexedDBCryptoStore.STORE_ROOMS], (txn) => {\n this.cryptoStore!.storeEndToEndRoom(roomId, roomInfo, txn);\n });\n }\n}\n"],"mappings":";;;;;;;;AAqBA,IAAAA,qBAAA,GAAAC,OAAA;AArBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAWA;;AAEO,MAAMC,QAAQ,CAAC;EAClB;;EAGOC,WAAWA,CAAkBC,WAAyB,EAAE;IAAA,KAA3BA,WAAyB,GAAzBA,WAAyB;IAAA,IAAAC,gBAAA,CAAAC,OAAA,0BAFH,CAAC,CAAC;EAEI;EAEhE,MAAaC,IAAIA,CAAA,EAAkB;IAC/B,MAAM,IAAI,CAACH,WAAW,CAAEI,KAAK,CAAC,WAAW,EAAE,CAACC,0CAAoB,CAACC,WAAW,CAAC,EAAGC,GAAG,IAAK;MACpF,IAAI,CAACP,WAAW,CAAEQ,gBAAgB,CAACD,GAAG,EAAGE,MAAM,IAAK;QAChD,IAAI,CAACC,cAAc,GAAGD,MAAM;MAChC,CAAC,CAAC;IACN,CAAC,CAAC;EACN;EAEOE,iBAAiBA,CAACC,MAAc,EAAmB;IACtD,OAAO,IAAI,CAACF,cAAc,CAACE,MAAM,CAAC,IAAI,IAAI;EAC9C;EAEOC,eAAeA,CAACD,MAAc,EAAW;IAC5C,OAAOE,OAAO,CAAC,IAAI,CAACH,iBAAiB,CAACC,MAAM,CAAC,CAAC;EAClD;EAEA,MAAaG,iBAAiBA,CAACH,MAAc,EAAEI,QAAyB,EAAiB;IACrF;IACA;IACA;IACA,IAAI,CAACN,cAAc,CAACE,MAAM,CAAC,GAAGI,QAAQ;IACtC,MAAM,IAAI,CAAChB,WAAW,CAAEI,KAAK,CAAC,WAAW,EAAE,CAACC,0CAAoB,CAACC,WAAW,CAAC,EAAGC,GAAG,IAAK;MACpF,IAAI,CAACP,WAAW,CAAEiB,iBAAiB,CAACL,MAAM,EAAEI,QAAQ,EAAET,GAAG,CAAC;IAC9D,CAAC,CAAC;EACN;AACJ;AAACW,OAAA,CAAApB,QAAA,GAAAA,QAAA"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/SecretStorage.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/SecretStorage.d.ts
deleted file mode 100644
index 13729e2..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/SecretStorage.d.ts
+++ /dev/null
@@ -1,115 +0,0 @@
-import { ICryptoCallbacks } from ".";
-import { IContent, MatrixEvent } from "../models/event";
-import { ClientEvent, ClientEventHandlerMap, MatrixClient } from "../client";
-import { IAddSecretStorageKeyOpts } from "./api";
-import { TypedEventEmitter } from "../models/typed-event-emitter";
-import { SecretStorageKeyDescription } from "../secret-storage";
-export declare const SECRET_STORAGE_ALGORITHM_V1_AES = "m.secret_storage.v1.aes-hmac-sha2";
-export type SecretStorageKeyTuple = [keyId: string, keyInfo: SecretStorageKeyDescription];
-export type SecretStorageKeyObject = {
- keyId: string;
- keyInfo: SecretStorageKeyDescription;
-};
-export interface ISecretRequest {
- requestId: string;
- promise: Promise<string>;
- cancel: (reason: string) => void;
-}
-export interface IAccountDataClient extends TypedEventEmitter<ClientEvent.AccountData, ClientEventHandlerMap> {
- getAccountDataFromServer: <T extends {
- [k: string]: any;
- }>(eventType: string) => Promise<T>;
- getAccountData: (eventType: string) => IContent | null;
- setAccountData: (eventType: string, content: any) => Promise<{}>;
-}
-/**
- * Implements Secure Secret Storage and Sharing (MSC1946)
- */
-export declare class SecretStorage<B extends MatrixClient | undefined = MatrixClient> {
- private readonly accountDataAdapter;
- private readonly cryptoCallbacks;
- private readonly baseApis;
- private requests;
- constructor(accountDataAdapter: IAccountDataClient, cryptoCallbacks: ICryptoCallbacks, baseApis: B);
- getDefaultKeyId(): Promise<string | null>;
- setDefaultKeyId(keyId: string): Promise<void>;
- /**
- * Add a key for encrypting secrets.
- *
- * @param algorithm - the algorithm used by the key.
- * @param opts - the options for the algorithm. The properties used
- * depend on the algorithm given.
- * @param keyId - the ID of the key. If not given, a random
- * ID will be generated.
- *
- * @returns An object with:
- * keyId: the ID of the key
- * keyInfo: details about the key (iv, mac, passphrase)
- */
- addKey(algorithm: string, opts?: IAddSecretStorageKeyOpts, keyId?: string): Promise<SecretStorageKeyObject>;
- /**
- * Get the key information for a given ID.
- *
- * @param keyId - The ID of the key to check
- * for. Defaults to the default key ID if not provided.
- * @returns If the key was found, the return value is an array of
- * the form [keyId, keyInfo]. Otherwise, null is returned.
- * XXX: why is this an array when addKey returns an object?
- */
- getKey(keyId?: string | null): Promise<SecretStorageKeyTuple | null>;
- /**
- * Check whether we have a key with a given ID.
- *
- * @param keyId - The ID of the key to check
- * for. Defaults to the default key ID if not provided.
- * @returns Whether we have the key.
- */
- hasKey(keyId?: string): Promise<boolean>;
- /**
- * Check whether a key matches what we expect based on the key info
- *
- * @param key - the key to check
- * @param info - the key info
- *
- * @returns whether or not the key matches
- */
- checkKey(key: Uint8Array, info: SecretStorageKeyDescription): Promise<boolean>;
- /**
- * Store an encrypted secret on the server
- *
- * @param name - The name of the secret
- * @param secret - The secret contents.
- * @param keys - The IDs of the keys to use to encrypt the secret
- * or null/undefined to use the default key.
- */
- store(name: string, secret: string, keys?: string[] | null): Promise<void>;
- /**
- * Get a secret from storage.
- *
- * @param name - the name of the secret
- *
- * @returns the contents of the secret
- */
- get(name: string): Promise<string | undefined>;
- /**
- * Check if a secret is stored on the server.
- *
- * @param name - the name of the secret
- *
- * @returns map of key name to key info the secret is encrypted
- * with, or null if it is not present or not encrypted with a trusted
- * key
- */
- isStored(name: string): Promise<Record<string, SecretStorageKeyDescription> | null>;
- /**
- * Request a secret from another device
- *
- * @param name - the name of the secret to request
- * @param devices - the devices to request the secret from
- */
- request(this: SecretStorage<MatrixClient>, name: string, devices: string[]): ISecretRequest;
- onRequestReceived(this: SecretStorage<MatrixClient>, event: MatrixEvent): Promise<void>;
- onSecretReceived(this: SecretStorage<MatrixClient>, event: MatrixEvent): void;
- private getSecretStorageKey;
-}
-//# sourceMappingURL=SecretStorage.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/SecretStorage.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/SecretStorage.d.ts.map
deleted file mode 100644
index b322252..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/SecretStorage.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"SecretStorage.d.ts","sourceRoot":"","sources":["../../src/crypto/SecretStorage.ts"],"names":[],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/SecretStorage.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/SecretStorage.js
deleted file mode 100644
index 8e8d965..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/SecretStorage.js
+++ /dev/null
@@ -1,491 +0,0 @@
-"use strict";
-
-var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.SecretStorage = exports.SECRET_STORAGE_ALGORITHM_V1_AES = void 0;
-var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
-var _uuid = require("uuid");
-var _logger = require("../logger");
-var olmlib = _interopRequireWildcard(require("./olmlib"));
-var _randomstring = require("../randomstring");
-var _aes = require("./aes");
-var _client = require("../client");
-var _utils = require("../utils");
-var _event = require("../@types/event");
-function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
-function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
-/*
-Copyright 2019 - 2021 The Matrix.org Foundation C.I.C.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-const SECRET_STORAGE_ALGORITHM_V1_AES = "m.secret_storage.v1.aes-hmac-sha2";
-
-// Some of the key functions use a tuple and some use an object...
-exports.SECRET_STORAGE_ALGORITHM_V1_AES = SECRET_STORAGE_ALGORITHM_V1_AES;
-/**
- * Implements Secure Secret Storage and Sharing (MSC1946)
- */
-class SecretStorage {
- // In it's pure javascript days, this was relying on some proper Javascript-style
- // type-abuse where sometimes we'd pass in a fake client object with just the account
- // data methods implemented, which is all this class needs unless you use the secret
- // sharing code, so it was fine. As a low-touch TypeScript migration, this now has
- // an extra, optional param for a real matrix client, so you can not pass it as long
- // as you don't request any secrets.
- // A better solution would probably be to split this class up into secret storage and
- // secret sharing which are really two separate things, even though they share an MSC.
- constructor(accountDataAdapter, cryptoCallbacks, baseApis) {
- this.accountDataAdapter = accountDataAdapter;
- this.cryptoCallbacks = cryptoCallbacks;
- this.baseApis = baseApis;
- (0, _defineProperty2.default)(this, "requests", new Map());
- }
- async getDefaultKeyId() {
- const defaultKey = await this.accountDataAdapter.getAccountDataFromServer("m.secret_storage.default_key");
- if (!defaultKey) return null;
- return defaultKey.key;
- }
- setDefaultKeyId(keyId) {
- return new Promise((resolve, reject) => {
- const listener = ev => {
- if (ev.getType() === "m.secret_storage.default_key" && ev.getContent().key === keyId) {
- this.accountDataAdapter.removeListener(_client.ClientEvent.AccountData, listener);
- resolve();
- }
- };
- this.accountDataAdapter.on(_client.ClientEvent.AccountData, listener);
- this.accountDataAdapter.setAccountData("m.secret_storage.default_key", {
- key: keyId
- }).catch(e => {
- this.accountDataAdapter.removeListener(_client.ClientEvent.AccountData, listener);
- reject(e);
- });
- });
- }
-
- /**
- * Add a key for encrypting secrets.
- *
- * @param algorithm - the algorithm used by the key.
- * @param opts - the options for the algorithm. The properties used
- * depend on the algorithm given.
- * @param keyId - the ID of the key. If not given, a random
- * ID will be generated.
- *
- * @returns An object with:
- * keyId: the ID of the key
- * keyInfo: details about the key (iv, mac, passphrase)
- */
- async addKey(algorithm, opts = {}, keyId) {
- if (algorithm !== SECRET_STORAGE_ALGORITHM_V1_AES) {
- throw new Error(`Unknown key algorithm ${algorithm}`);
- }
- const keyInfo = {
- algorithm
- };
- if (opts.name) {
- keyInfo.name = opts.name;
- }
- if (opts.passphrase) {
- keyInfo.passphrase = opts.passphrase;
- }
- if (opts.key) {
- const {
- iv,
- mac
- } = await (0, _aes.calculateKeyCheck)(opts.key);
- keyInfo.iv = iv;
- keyInfo.mac = mac;
- }
- if (!keyId) {
- do {
- keyId = (0, _randomstring.randomString)(32);
- } while (await this.accountDataAdapter.getAccountDataFromServer(`m.secret_storage.key.${keyId}`));
- }
- await this.accountDataAdapter.setAccountData(`m.secret_storage.key.${keyId}`, keyInfo);
- return {
- keyId,
- keyInfo
- };
- }
-
- /**
- * Get the key information for a given ID.
- *
- * @param keyId - The ID of the key to check
- * for. Defaults to the default key ID if not provided.
- * @returns If the key was found, the return value is an array of
- * the form [keyId, keyInfo]. Otherwise, null is returned.
- * XXX: why is this an array when addKey returns an object?
- */
- async getKey(keyId) {
- if (!keyId) {
- keyId = await this.getDefaultKeyId();
- }
- if (!keyId) {
- return null;
- }
- const keyInfo = await this.accountDataAdapter.getAccountDataFromServer("m.secret_storage.key." + keyId);
- return keyInfo ? [keyId, keyInfo] : null;
- }
-
- /**
- * Check whether we have a key with a given ID.
- *
- * @param keyId - The ID of the key to check
- * for. Defaults to the default key ID if not provided.
- * @returns Whether we have the key.
- */
- async hasKey(keyId) {
- return Boolean(await this.getKey(keyId));
- }
-
- /**
- * Check whether a key matches what we expect based on the key info
- *
- * @param key - the key to check
- * @param info - the key info
- *
- * @returns whether or not the key matches
- */
- async checkKey(key, info) {
- if (info.algorithm === SECRET_STORAGE_ALGORITHM_V1_AES) {
- if (info.mac) {
- const {
- mac
- } = await (0, _aes.calculateKeyCheck)(key, info.iv);
- return info.mac.replace(/=+$/g, "") === mac.replace(/=+$/g, "");
- } else {
- // if we have no information, we have to assume the key is right
- return true;
- }
- } else {
- throw new Error("Unknown algorithm");
- }
- }
-
- /**
- * Store an encrypted secret on the server
- *
- * @param name - The name of the secret
- * @param secret - The secret contents.
- * @param keys - The IDs of the keys to use to encrypt the secret
- * or null/undefined to use the default key.
- */
- async store(name, secret, keys) {
- const encrypted = {};
- if (!keys) {
- const defaultKeyId = await this.getDefaultKeyId();
- if (!defaultKeyId) {
- throw new Error("No keys specified and no default key present");
- }
- keys = [defaultKeyId];
- }
- if (keys.length === 0) {
- throw new Error("Zero keys given to encrypt with!");
- }
- for (const keyId of keys) {
- // get key information from key storage
- const keyInfo = await this.accountDataAdapter.getAccountDataFromServer("m.secret_storage.key." + keyId);
- if (!keyInfo) {
- throw new Error("Unknown key: " + keyId);
- }
-
- // encrypt secret, based on the algorithm
- if (keyInfo.algorithm === SECRET_STORAGE_ALGORITHM_V1_AES) {
- const keys = {
- [keyId]: keyInfo
- };
- const [, encryption] = await this.getSecretStorageKey(keys, name);
- encrypted[keyId] = await encryption.encrypt(secret);
- } else {
- _logger.logger.warn("unknown algorithm for secret storage key " + keyId + ": " + keyInfo.algorithm);
- // do nothing if we don't understand the encryption algorithm
- }
- }
-
- // save encrypted secret
- await this.accountDataAdapter.setAccountData(name, {
- encrypted
- });
- }
-
- /**
- * Get a secret from storage.
- *
- * @param name - the name of the secret
- *
- * @returns the contents of the secret
- */
- async get(name) {
- const secretInfo = await this.accountDataAdapter.getAccountDataFromServer(name);
- if (!secretInfo) {
- return;
- }
- if (!secretInfo.encrypted) {
- throw new Error("Content is not encrypted!");
- }
-
- // get possible keys to decrypt
- const keys = {};
- for (const keyId of Object.keys(secretInfo.encrypted)) {
- // get key information from key storage
- const keyInfo = await this.accountDataAdapter.getAccountDataFromServer("m.secret_storage.key." + keyId);
- const encInfo = secretInfo.encrypted[keyId];
- // only use keys we understand the encryption algorithm of
- if (keyInfo.algorithm === SECRET_STORAGE_ALGORITHM_V1_AES) {
- if (encInfo.iv && encInfo.ciphertext && encInfo.mac) {
- keys[keyId] = keyInfo;
- }
- }
- }
- if (Object.keys(keys).length === 0) {
- throw new Error(`Could not decrypt ${name} because none of ` + `the keys it is encrypted with are for a supported algorithm`);
- }
-
- // fetch private key from app
- const [keyId, decryption] = await this.getSecretStorageKey(keys, name);
- const encInfo = secretInfo.encrypted[keyId];
- return decryption.decrypt(encInfo);
- }
-
- /**
- * Check if a secret is stored on the server.
- *
- * @param name - the name of the secret
- *
- * @returns map of key name to key info the secret is encrypted
- * with, or null if it is not present or not encrypted with a trusted
- * key
- */
- async isStored(name) {
- // check if secret exists
- const secretInfo = await this.accountDataAdapter.getAccountDataFromServer(name);
- if (!(secretInfo !== null && secretInfo !== void 0 && secretInfo.encrypted)) return null;
- const ret = {};
-
- // filter secret encryption keys with supported algorithm
- for (const keyId of Object.keys(secretInfo.encrypted)) {
- // get key information from key storage
- const keyInfo = await this.accountDataAdapter.getAccountDataFromServer("m.secret_storage.key." + keyId);
- if (!keyInfo) continue;
- const encInfo = secretInfo.encrypted[keyId];
-
- // only use keys we understand the encryption algorithm of
- if (keyInfo.algorithm === SECRET_STORAGE_ALGORITHM_V1_AES) {
- if (encInfo.iv && encInfo.ciphertext && encInfo.mac) {
- ret[keyId] = keyInfo;
- }
- }
- }
- return Object.keys(ret).length ? ret : null;
- }
-
- /**
- * Request a secret from another device
- *
- * @param name - the name of the secret to request
- * @param devices - the devices to request the secret from
- */
- request(name, devices) {
- const requestId = this.baseApis.makeTxnId();
- const deferred = (0, _utils.defer)();
- this.requests.set(requestId, {
- name,
- devices,
- deferred
- });
- const cancel = reason => {
- // send cancellation event
- const cancelData = {
- action: "request_cancellation",
- requesting_device_id: this.baseApis.deviceId,
- request_id: requestId
- };
- const toDevice = new Map();
- for (const device of devices) {
- toDevice.set(device, cancelData);
- }
- this.baseApis.sendToDevice("m.secret.request", new Map([[this.baseApis.getUserId(), toDevice]]));
-
- // and reject the promise so that anyone waiting on it will be
- // notified
- deferred.reject(new Error(reason || "Cancelled"));
- };
-
- // send request to devices
- const requestData = {
- name,
- action: "request",
- requesting_device_id: this.baseApis.deviceId,
- request_id: requestId,
- [_event.ToDeviceMessageId]: (0, _uuid.v4)()
- };
- const toDevice = new Map();
- for (const device of devices) {
- toDevice.set(device, requestData);
- }
- _logger.logger.info(`Request secret ${name} from ${devices}, id ${requestId}`);
- this.baseApis.sendToDevice("m.secret.request", new Map([[this.baseApis.getUserId(), toDevice]]));
- return {
- requestId,
- promise: deferred.promise,
- cancel
- };
- }
- async onRequestReceived(event) {
- const sender = event.getSender();
- const content = event.getContent();
- if (sender !== this.baseApis.getUserId() || !(content.name && content.action && content.requesting_device_id && content.request_id)) {
- // ignore requests from anyone else, for now
- return;
- }
- const deviceId = content.requesting_device_id;
- // check if it's a cancel
- if (content.action === "request_cancellation") {
- /*
- Looks like we intended to emit events when we got cancelations, but
- we never put anything in the _incomingRequests object, and the request
- itself doesn't use events anyway so if we were to wire up cancellations,
- they probably ought to use the same callback interface. I'm leaving them
- disabled for now while converting this file to typescript.
- if (this._incomingRequests[deviceId]
- && this._incomingRequests[deviceId][content.request_id]) {
- logger.info(
- "received request cancellation for secret (" + sender +
- ", " + deviceId + ", " + content.request_id + ")",
- );
- this.baseApis.emit("crypto.secrets.requestCancelled", {
- user_id: sender,
- device_id: deviceId,
- request_id: content.request_id,
- });
- }
- */
- } else if (content.action === "request") {
- if (deviceId === this.baseApis.deviceId) {
- // no point in trying to send ourself the secret
- return;
- }
-
- // check if we have the secret
- _logger.logger.info("received request for secret (" + sender + ", " + deviceId + ", " + content.request_id + ")");
- if (!this.cryptoCallbacks.onSecretRequested) {
- return;
- }
- const secret = await this.cryptoCallbacks.onSecretRequested(sender, deviceId, content.request_id, content.name, this.baseApis.checkDeviceTrust(sender, deviceId));
- if (secret) {
- _logger.logger.info(`Preparing ${content.name} secret for ${deviceId}`);
- const payload = {
- type: "m.secret.send",
- content: {
- request_id: content.request_id,
- secret: secret
- }
- };
- const encryptedContent = {
- algorithm: olmlib.OLM_ALGORITHM,
- sender_key: this.baseApis.crypto.olmDevice.deviceCurve25519Key,
- ciphertext: {},
- [_event.ToDeviceMessageId]: (0, _uuid.v4)()
- };
- await olmlib.ensureOlmSessionsForDevices(this.baseApis.crypto.olmDevice, this.baseApis, new Map([[sender, [this.baseApis.getStoredDevice(sender, deviceId)]]]));
- await olmlib.encryptMessageForDevice(encryptedContent.ciphertext, this.baseApis.getUserId(), this.baseApis.deviceId, this.baseApis.crypto.olmDevice, sender, this.baseApis.getStoredDevice(sender, deviceId), payload);
- const contentMap = new Map([[sender, new Map([[deviceId, encryptedContent]])]]);
- _logger.logger.info(`Sending ${content.name} secret for ${deviceId}`);
- this.baseApis.sendToDevice("m.room.encrypted", contentMap);
- } else {
- _logger.logger.info(`Request denied for ${content.name} secret for ${deviceId}`);
- }
- }
- }
- onSecretReceived(event) {
- if (event.getSender() !== this.baseApis.getUserId()) {
- // we shouldn't be receiving secrets from anyone else, so ignore
- // because someone could be trying to send us bogus data
- return;
- }
- if (!olmlib.isOlmEncrypted(event)) {
- _logger.logger.error("secret event not properly encrypted");
- return;
- }
- const content = event.getContent();
- const senderKeyUser = this.baseApis.crypto.deviceList.getUserByIdentityKey(olmlib.OLM_ALGORITHM, event.getSenderKey() || "");
- if (senderKeyUser !== event.getSender()) {
- _logger.logger.error("sending device does not belong to the user it claims to be from");
- return;
- }
- _logger.logger.log("got secret share for request", content.request_id);
- const requestControl = this.requests.get(content.request_id);
- if (requestControl) {
- // make sure that the device that sent it is one of the devices that
- // we requested from
- const deviceInfo = this.baseApis.crypto.deviceList.getDeviceByIdentityKey(olmlib.OLM_ALGORITHM, event.getSenderKey());
- if (!deviceInfo) {
- _logger.logger.log("secret share from unknown device with key", event.getSenderKey());
- return;
- }
- if (!requestControl.devices.includes(deviceInfo.deviceId)) {
- _logger.logger.log("unsolicited secret share from device", deviceInfo.deviceId);
- return;
- }
- // unsure that the sender is trusted. In theory, this check is
- // unnecessary since we only accept secret shares from devices that
- // we requested from, but it doesn't hurt.
- const deviceTrust = this.baseApis.crypto.checkDeviceInfoTrust(event.getSender(), deviceInfo);
- if (!deviceTrust.isVerified()) {
- _logger.logger.log("secret share from unverified device");
- return;
- }
- _logger.logger.log(`Successfully received secret ${requestControl.name} ` + `from ${deviceInfo.deviceId}`);
- requestControl.deferred.resolve(content.secret);
- }
- }
- async getSecretStorageKey(keys, name) {
- if (!this.cryptoCallbacks.getSecretStorageKey) {
- throw new Error("No getSecretStorageKey callback supplied");
- }
- const returned = await this.cryptoCallbacks.getSecretStorageKey({
- keys
- }, name);
- if (!returned) {
- throw new Error("getSecretStorageKey callback returned falsey");
- }
- if (returned.length < 2) {
- throw new Error("getSecretStorageKey callback returned invalid data");
- }
- const [keyId, privateKey] = returned;
- if (!keys[keyId]) {
- throw new Error("App returned unknown key from getSecretStorageKey!");
- }
- if (keys[keyId].algorithm === SECRET_STORAGE_ALGORITHM_V1_AES) {
- const decryption = {
- encrypt: function (secret) {
- return (0, _aes.encryptAES)(secret, privateKey, name);
- },
- decrypt: function (encInfo) {
- return (0, _aes.decryptAES)(encInfo, privateKey, name);
- }
- };
- return [keyId, decryption];
- } else {
- throw new Error("Unknown key type: " + keys[keyId].algorithm);
- }
- }
-}
-exports.SecretStorage = SecretStorage;
-//# sourceMappingURL=SecretStorage.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/SecretStorage.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/SecretStorage.js.map
deleted file mode 100644
index 5852b67..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/SecretStorage.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"SecretStorage.js","names":["_uuid","require","_logger","olmlib","_interopRequireWildcard","_randomstring","_aes","_client","_utils","_event","_getRequireWildcardCache","nodeInterop","WeakMap","cacheBabelInterop","cacheNodeInterop","obj","__esModule","default","cache","has","get","newObj","hasPropertyDescriptor","Object","defineProperty","getOwnPropertyDescriptor","key","prototype","hasOwnProperty","call","desc","set","SECRET_STORAGE_ALGORITHM_V1_AES","exports","SecretStorage","constructor","accountDataAdapter","cryptoCallbacks","baseApis","_defineProperty2","Map","getDefaultKeyId","defaultKey","getAccountDataFromServer","setDefaultKeyId","keyId","Promise","resolve","reject","listener","ev","getType","getContent","removeListener","ClientEvent","AccountData","on","setAccountData","catch","e","addKey","algorithm","opts","Error","keyInfo","name","passphrase","iv","mac","calculateKeyCheck","randomString","getKey","hasKey","Boolean","checkKey","info","replace","store","secret","keys","encrypted","defaultKeyId","length","encryption","getSecretStorageKey","encrypt","logger","warn","secretInfo","encInfo","ciphertext","decryption","decrypt","isStored","ret","request","devices","requestId","makeTxnId","deferred","defer","requests","cancel","reason","cancelData","action","requesting_device_id","deviceId","request_id","toDevice","device","sendToDevice","getUserId","requestData","ToDeviceMessageId","uuidv4","promise","onRequestReceived","event","sender","getSender","content","onSecretRequested","checkDeviceTrust","payload","type","encryptedContent","OLM_ALGORITHM","sender_key","crypto","olmDevice","deviceCurve25519Key","ensureOlmSessionsForDevices","getStoredDevice","encryptMessageForDevice","contentMap","onSecretReceived","isOlmEncrypted","error","senderKeyUser","deviceList","getUserByIdentityKey","getSenderKey","log","requestControl","deviceInfo","getDeviceByIdentityKey","includes","deviceTrust","checkDeviceInfoTrust","isVerified","returned","privateKey","encryptAES","decryptAES"],"sources":["../../src/crypto/SecretStorage.ts"],"sourcesContent":["/*\nCopyright 2019 - 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { v4 as uuidv4 } from \"uuid\";\n\nimport { logger } from \"../logger\";\nimport * as olmlib from \"./olmlib\";\nimport { randomString } from \"../randomstring\";\nimport { calculateKeyCheck, decryptAES, encryptAES, IEncryptedPayload } from \"./aes\";\nimport { ICryptoCallbacks, IEncryptedContent } from \".\";\nimport { IContent, MatrixEvent } from \"../models/event\";\nimport { ClientEvent, ClientEventHandlerMap, MatrixClient } from \"../client\";\nimport { IAddSecretStorageKeyOpts } from \"./api\";\nimport { TypedEventEmitter } from \"../models/typed-event-emitter\";\nimport { defer, IDeferred } from \"../utils\";\nimport { ToDeviceMessageId } from \"../@types/event\";\nimport { SecretStorageKeyDescription, SecretStorageKeyDescriptionAesV1 } from \"../secret-storage\";\n\nexport const SECRET_STORAGE_ALGORITHM_V1_AES = \"m.secret_storage.v1.aes-hmac-sha2\";\n\n// Some of the key functions use a tuple and some use an object...\nexport type SecretStorageKeyTuple = [keyId: string, keyInfo: SecretStorageKeyDescription];\nexport type SecretStorageKeyObject = { keyId: string; keyInfo: SecretStorageKeyDescription };\n\nexport interface ISecretRequest {\n requestId: string;\n promise: Promise<string>;\n cancel: (reason: string) => void;\n}\n\nexport interface IAccountDataClient extends TypedEventEmitter<ClientEvent.AccountData, ClientEventHandlerMap> {\n // Subset of MatrixClient (which also uses any for the event content)\n getAccountDataFromServer: <T extends { [k: string]: any }>(eventType: string) => Promise<T>;\n getAccountData: (eventType: string) => IContent | null;\n setAccountData: (eventType: string, content: any) => Promise<{}>;\n}\n\ninterface ISecretRequestInternal {\n name: string;\n devices: string[];\n deferred: IDeferred<string>;\n}\n\ninterface IDecryptors {\n encrypt: (plaintext: string) => Promise<IEncryptedPayload>;\n decrypt: (ciphertext: IEncryptedPayload) => Promise<string>;\n}\n\ninterface ISecretInfo {\n encrypted: {\n [keyId: string]: IEncryptedPayload;\n };\n}\n\n/**\n * Implements Secure Secret Storage and Sharing (MSC1946)\n */\nexport class SecretStorage<B extends MatrixClient | undefined = MatrixClient> {\n private requests = new Map<string, ISecretRequestInternal>();\n\n // In it's pure javascript days, this was relying on some proper Javascript-style\n // type-abuse where sometimes we'd pass in a fake client object with just the account\n // data methods implemented, which is all this class needs unless you use the secret\n // sharing code, so it was fine. As a low-touch TypeScript migration, this now has\n // an extra, optional param for a real matrix client, so you can not pass it as long\n // as you don't request any secrets.\n // A better solution would probably be to split this class up into secret storage and\n // secret sharing which are really two separate things, even though they share an MSC.\n public constructor(\n private readonly accountDataAdapter: IAccountDataClient,\n private readonly cryptoCallbacks: ICryptoCallbacks,\n private readonly baseApis: B,\n ) {}\n\n public async getDefaultKeyId(): Promise<string | null> {\n const defaultKey = await this.accountDataAdapter.getAccountDataFromServer<{ key: string }>(\n \"m.secret_storage.default_key\",\n );\n if (!defaultKey) return null;\n return defaultKey.key;\n }\n\n public setDefaultKeyId(keyId: string): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n const listener = (ev: MatrixEvent): void => {\n if (ev.getType() === \"m.secret_storage.default_key\" && ev.getContent().key === keyId) {\n this.accountDataAdapter.removeListener(ClientEvent.AccountData, listener);\n resolve();\n }\n };\n this.accountDataAdapter.on(ClientEvent.AccountData, listener);\n\n this.accountDataAdapter.setAccountData(\"m.secret_storage.default_key\", { key: keyId }).catch((e) => {\n this.accountDataAdapter.removeListener(ClientEvent.AccountData, listener);\n reject(e);\n });\n });\n }\n\n /**\n * Add a key for encrypting secrets.\n *\n * @param algorithm - the algorithm used by the key.\n * @param opts - the options for the algorithm. The properties used\n * depend on the algorithm given.\n * @param keyId - the ID of the key. If not given, a random\n * ID will be generated.\n *\n * @returns An object with:\n * keyId: the ID of the key\n * keyInfo: details about the key (iv, mac, passphrase)\n */\n public async addKey(\n algorithm: string,\n opts: IAddSecretStorageKeyOpts = {},\n keyId?: string,\n ): Promise<SecretStorageKeyObject> {\n if (algorithm !== SECRET_STORAGE_ALGORITHM_V1_AES) {\n throw new Error(`Unknown key algorithm ${algorithm}`);\n }\n\n const keyInfo = { algorithm } as SecretStorageKeyDescriptionAesV1;\n\n if (opts.name) {\n keyInfo.name = opts.name;\n }\n\n if (opts.passphrase) {\n keyInfo.passphrase = opts.passphrase;\n }\n if (opts.key) {\n const { iv, mac } = await calculateKeyCheck(opts.key);\n keyInfo.iv = iv;\n keyInfo.mac = mac;\n }\n\n if (!keyId) {\n do {\n keyId = randomString(32);\n } while (\n await this.accountDataAdapter.getAccountDataFromServer<SecretStorageKeyDescription>(\n `m.secret_storage.key.${keyId}`,\n )\n );\n }\n\n await this.accountDataAdapter.setAccountData(`m.secret_storage.key.${keyId}`, keyInfo);\n\n return {\n keyId,\n keyInfo,\n };\n }\n\n /**\n * Get the key information for a given ID.\n *\n * @param keyId - The ID of the key to check\n * for. Defaults to the default key ID if not provided.\n * @returns If the key was found, the return value is an array of\n * the form [keyId, keyInfo]. Otherwise, null is returned.\n * XXX: why is this an array when addKey returns an object?\n */\n public async getKey(keyId?: string | null): Promise<SecretStorageKeyTuple | null> {\n if (!keyId) {\n keyId = await this.getDefaultKeyId();\n }\n if (!keyId) {\n return null;\n }\n\n const keyInfo = await this.accountDataAdapter.getAccountDataFromServer<SecretStorageKeyDescription>(\n \"m.secret_storage.key.\" + keyId,\n );\n return keyInfo ? [keyId, keyInfo] : null;\n }\n\n /**\n * Check whether we have a key with a given ID.\n *\n * @param keyId - The ID of the key to check\n * for. Defaults to the default key ID if not provided.\n * @returns Whether we have the key.\n */\n public async hasKey(keyId?: string): Promise<boolean> {\n return Boolean(await this.getKey(keyId));\n }\n\n /**\n * Check whether a key matches what we expect based on the key info\n *\n * @param key - the key to check\n * @param info - the key info\n *\n * @returns whether or not the key matches\n */\n public async checkKey(key: Uint8Array, info: SecretStorageKeyDescription): Promise<boolean> {\n if (info.algorithm === SECRET_STORAGE_ALGORITHM_V1_AES) {\n if (info.mac) {\n const { mac } = await calculateKeyCheck(key, info.iv);\n return info.mac.replace(/=+$/g, \"\") === mac.replace(/=+$/g, \"\");\n } else {\n // if we have no information, we have to assume the key is right\n return true;\n }\n } else {\n throw new Error(\"Unknown algorithm\");\n }\n }\n\n /**\n * Store an encrypted secret on the server\n *\n * @param name - The name of the secret\n * @param secret - The secret contents.\n * @param keys - The IDs of the keys to use to encrypt the secret\n * or null/undefined to use the default key.\n */\n public async store(name: string, secret: string, keys?: string[] | null): Promise<void> {\n const encrypted: Record<string, IEncryptedPayload> = {};\n\n if (!keys) {\n const defaultKeyId = await this.getDefaultKeyId();\n if (!defaultKeyId) {\n throw new Error(\"No keys specified and no default key present\");\n }\n keys = [defaultKeyId];\n }\n\n if (keys.length === 0) {\n throw new Error(\"Zero keys given to encrypt with!\");\n }\n\n for (const keyId of keys) {\n // get key information from key storage\n const keyInfo = await this.accountDataAdapter.getAccountDataFromServer<SecretStorageKeyDescription>(\n \"m.secret_storage.key.\" + keyId,\n );\n if (!keyInfo) {\n throw new Error(\"Unknown key: \" + keyId);\n }\n\n // encrypt secret, based on the algorithm\n if (keyInfo.algorithm === SECRET_STORAGE_ALGORITHM_V1_AES) {\n const keys = { [keyId]: keyInfo };\n const [, encryption] = await this.getSecretStorageKey(keys, name);\n encrypted[keyId] = await encryption.encrypt(secret);\n } else {\n logger.warn(\"unknown algorithm for secret storage key \" + keyId + \": \" + keyInfo.algorithm);\n // do nothing if we don't understand the encryption algorithm\n }\n }\n\n // save encrypted secret\n await this.accountDataAdapter.setAccountData(name, { encrypted });\n }\n\n /**\n * Get a secret from storage.\n *\n * @param name - the name of the secret\n *\n * @returns the contents of the secret\n */\n public async get(name: string): Promise<string | undefined> {\n const secretInfo = await this.accountDataAdapter.getAccountDataFromServer<ISecretInfo>(name);\n if (!secretInfo) {\n return;\n }\n if (!secretInfo.encrypted) {\n throw new Error(\"Content is not encrypted!\");\n }\n\n // get possible keys to decrypt\n const keys: Record<string, SecretStorageKeyDescription> = {};\n for (const keyId of Object.keys(secretInfo.encrypted)) {\n // get key information from key storage\n const keyInfo = await this.accountDataAdapter.getAccountDataFromServer<SecretStorageKeyDescription>(\n \"m.secret_storage.key.\" + keyId,\n );\n const encInfo = secretInfo.encrypted[keyId];\n // only use keys we understand the encryption algorithm of\n if (keyInfo.algorithm === SECRET_STORAGE_ALGORITHM_V1_AES) {\n if (encInfo.iv && encInfo.ciphertext && encInfo.mac) {\n keys[keyId] = keyInfo;\n }\n }\n }\n\n if (Object.keys(keys).length === 0) {\n throw new Error(\n `Could not decrypt ${name} because none of ` +\n `the keys it is encrypted with are for a supported algorithm`,\n );\n }\n\n // fetch private key from app\n const [keyId, decryption] = await this.getSecretStorageKey(keys, name);\n const encInfo = secretInfo.encrypted[keyId];\n\n return decryption.decrypt(encInfo);\n }\n\n /**\n * Check if a secret is stored on the server.\n *\n * @param name - the name of the secret\n *\n * @returns map of key name to key info the secret is encrypted\n * with, or null if it is not present or not encrypted with a trusted\n * key\n */\n public async isStored(name: string): Promise<Record<string, SecretStorageKeyDescription> | null> {\n // check if secret exists\n const secretInfo = await this.accountDataAdapter.getAccountDataFromServer<ISecretInfo>(name);\n if (!secretInfo?.encrypted) return null;\n\n const ret: Record<string, SecretStorageKeyDescription> = {};\n\n // filter secret encryption keys with supported algorithm\n for (const keyId of Object.keys(secretInfo.encrypted)) {\n // get key information from key storage\n const keyInfo = await this.accountDataAdapter.getAccountDataFromServer<SecretStorageKeyDescription>(\n \"m.secret_storage.key.\" + keyId,\n );\n if (!keyInfo) continue;\n const encInfo = secretInfo.encrypted[keyId];\n\n // only use keys we understand the encryption algorithm of\n if (keyInfo.algorithm === SECRET_STORAGE_ALGORITHM_V1_AES) {\n if (encInfo.iv && encInfo.ciphertext && encInfo.mac) {\n ret[keyId] = keyInfo;\n }\n }\n }\n return Object.keys(ret).length ? ret : null;\n }\n\n /**\n * Request a secret from another device\n *\n * @param name - the name of the secret to request\n * @param devices - the devices to request the secret from\n */\n public request(this: SecretStorage<MatrixClient>, name: string, devices: string[]): ISecretRequest {\n const requestId = this.baseApis.makeTxnId();\n\n const deferred = defer<string>();\n this.requests.set(requestId, { name, devices, deferred });\n\n const cancel = (reason: string): void => {\n // send cancellation event\n const cancelData = {\n action: \"request_cancellation\",\n requesting_device_id: this.baseApis.deviceId,\n request_id: requestId,\n };\n const toDevice: Map<string, typeof cancelData> = new Map();\n for (const device of devices) {\n toDevice.set(device, cancelData);\n }\n this.baseApis.sendToDevice(\"m.secret.request\", new Map([[this.baseApis.getUserId()!, toDevice]]));\n\n // and reject the promise so that anyone waiting on it will be\n // notified\n deferred.reject(new Error(reason || \"Cancelled\"));\n };\n\n // send request to devices\n const requestData = {\n name,\n action: \"request\",\n requesting_device_id: this.baseApis.deviceId,\n request_id: requestId,\n [ToDeviceMessageId]: uuidv4(),\n };\n const toDevice: Map<string, typeof requestData> = new Map();\n for (const device of devices) {\n toDevice.set(device, requestData);\n }\n logger.info(`Request secret ${name} from ${devices}, id ${requestId}`);\n this.baseApis.sendToDevice(\"m.secret.request\", new Map([[this.baseApis.getUserId()!, toDevice]]));\n\n return {\n requestId,\n promise: deferred.promise,\n cancel,\n };\n }\n\n public async onRequestReceived(this: SecretStorage<MatrixClient>, event: MatrixEvent): Promise<void> {\n const sender = event.getSender();\n const content = event.getContent();\n if (\n sender !== this.baseApis.getUserId() ||\n !(content.name && content.action && content.requesting_device_id && content.request_id)\n ) {\n // ignore requests from anyone else, for now\n return;\n }\n const deviceId = content.requesting_device_id;\n // check if it's a cancel\n if (content.action === \"request_cancellation\") {\n /*\n Looks like we intended to emit events when we got cancelations, but\n we never put anything in the _incomingRequests object, and the request\n itself doesn't use events anyway so if we were to wire up cancellations,\n they probably ought to use the same callback interface. I'm leaving them\n disabled for now while converting this file to typescript.\n if (this._incomingRequests[deviceId]\n && this._incomingRequests[deviceId][content.request_id]) {\n logger.info(\n \"received request cancellation for secret (\" + sender +\n \", \" + deviceId + \", \" + content.request_id + \")\",\n );\n this.baseApis.emit(\"crypto.secrets.requestCancelled\", {\n user_id: sender,\n device_id: deviceId,\n request_id: content.request_id,\n });\n }\n */\n } else if (content.action === \"request\") {\n if (deviceId === this.baseApis.deviceId) {\n // no point in trying to send ourself the secret\n return;\n }\n\n // check if we have the secret\n logger.info(\"received request for secret (\" + sender + \", \" + deviceId + \", \" + content.request_id + \")\");\n if (!this.cryptoCallbacks.onSecretRequested) {\n return;\n }\n const secret = await this.cryptoCallbacks.onSecretRequested(\n sender,\n deviceId,\n content.request_id,\n content.name,\n this.baseApis.checkDeviceTrust(sender, deviceId),\n );\n if (secret) {\n logger.info(`Preparing ${content.name} secret for ${deviceId}`);\n const payload = {\n type: \"m.secret.send\",\n content: {\n request_id: content.request_id,\n secret: secret,\n },\n };\n const encryptedContent: IEncryptedContent = {\n algorithm: olmlib.OLM_ALGORITHM,\n sender_key: this.baseApis.crypto!.olmDevice.deviceCurve25519Key!,\n ciphertext: {},\n [ToDeviceMessageId]: uuidv4(),\n };\n await olmlib.ensureOlmSessionsForDevices(\n this.baseApis.crypto!.olmDevice,\n this.baseApis,\n new Map([[sender, [this.baseApis.getStoredDevice(sender, deviceId)!]]]),\n );\n await olmlib.encryptMessageForDevice(\n encryptedContent.ciphertext,\n this.baseApis.getUserId()!,\n this.baseApis.deviceId!,\n this.baseApis.crypto!.olmDevice,\n sender,\n this.baseApis.getStoredDevice(sender, deviceId)!,\n payload,\n );\n const contentMap = new Map([[sender, new Map([[deviceId, encryptedContent]])]]);\n\n logger.info(`Sending ${content.name} secret for ${deviceId}`);\n this.baseApis.sendToDevice(\"m.room.encrypted\", contentMap);\n } else {\n logger.info(`Request denied for ${content.name} secret for ${deviceId}`);\n }\n }\n }\n\n public onSecretReceived(this: SecretStorage<MatrixClient>, event: MatrixEvent): void {\n if (event.getSender() !== this.baseApis.getUserId()) {\n // we shouldn't be receiving secrets from anyone else, so ignore\n // because someone could be trying to send us bogus data\n return;\n }\n\n if (!olmlib.isOlmEncrypted(event)) {\n logger.error(\"secret event not properly encrypted\");\n return;\n }\n\n const content = event.getContent();\n\n const senderKeyUser = this.baseApis.crypto!.deviceList.getUserByIdentityKey(\n olmlib.OLM_ALGORITHM,\n event.getSenderKey() || \"\",\n );\n if (senderKeyUser !== event.getSender()) {\n logger.error(\"sending device does not belong to the user it claims to be from\");\n return;\n }\n\n logger.log(\"got secret share for request\", content.request_id);\n const requestControl = this.requests.get(content.request_id);\n if (requestControl) {\n // make sure that the device that sent it is one of the devices that\n // we requested from\n const deviceInfo = this.baseApis.crypto!.deviceList.getDeviceByIdentityKey(\n olmlib.OLM_ALGORITHM,\n event.getSenderKey()!,\n );\n if (!deviceInfo) {\n logger.log(\"secret share from unknown device with key\", event.getSenderKey());\n return;\n }\n if (!requestControl.devices.includes(deviceInfo.deviceId)) {\n logger.log(\"unsolicited secret share from device\", deviceInfo.deviceId);\n return;\n }\n // unsure that the sender is trusted. In theory, this check is\n // unnecessary since we only accept secret shares from devices that\n // we requested from, but it doesn't hurt.\n const deviceTrust = this.baseApis.crypto!.checkDeviceInfoTrust(event.getSender()!, deviceInfo);\n if (!deviceTrust.isVerified()) {\n logger.log(\"secret share from unverified device\");\n return;\n }\n\n logger.log(`Successfully received secret ${requestControl.name} ` + `from ${deviceInfo.deviceId}`);\n requestControl.deferred.resolve(content.secret);\n }\n }\n\n private async getSecretStorageKey(\n keys: Record<string, SecretStorageKeyDescription>,\n name: string,\n ): Promise<[string, IDecryptors]> {\n if (!this.cryptoCallbacks.getSecretStorageKey) {\n throw new Error(\"No getSecretStorageKey callback supplied\");\n }\n\n const returned = await this.cryptoCallbacks.getSecretStorageKey({ keys }, name);\n\n if (!returned) {\n throw new Error(\"getSecretStorageKey callback returned falsey\");\n }\n if (returned.length < 2) {\n throw new Error(\"getSecretStorageKey callback returned invalid data\");\n }\n\n const [keyId, privateKey] = returned;\n if (!keys[keyId]) {\n throw new Error(\"App returned unknown key from getSecretStorageKey!\");\n }\n\n if (keys[keyId].algorithm === SECRET_STORAGE_ALGORITHM_V1_AES) {\n const decryption = {\n encrypt: function (secret: string): Promise<IEncryptedPayload> {\n return encryptAES(secret, privateKey, name);\n },\n decrypt: function (encInfo: IEncryptedPayload): Promise<string> {\n return decryptAES(encInfo, privateKey, name);\n },\n };\n return [keyId, decryption];\n } else {\n throw new Error(\"Unknown key type: \" + keys[keyId].algorithm);\n }\n }\n}\n"],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/aes.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/aes.d.ts
deleted file mode 100644
index 30ab08a..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/aes.d.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-export interface IEncryptedPayload {
- [key: string]: any;
- /** the initialization vector in base64 */
- iv: string;
- /** the ciphertext in base64 */
- ciphertext: string;
- /** the HMAC in base64 */
- mac: string;
-}
-/**
- * encrypt a string
- *
- * @param data - the plaintext to encrypt
- * @param key - the encryption key to use
- * @param name - the name of the secret
- * @param ivStr - the initialization vector to use
- */
-export declare function encryptAES(data: string, key: Uint8Array, name: string, ivStr?: string): Promise<IEncryptedPayload>;
-/**
- * decrypt a string
- *
- * @param data - the encrypted data
- * @param key - the encryption key to use
- * @param name - the name of the secret
- */
-export declare function decryptAES(data: IEncryptedPayload, key: Uint8Array, name: string): Promise<string>;
-/** Calculate the MAC for checking the key.
- *
- * @param key - the key to use
- * @param iv - The initialization vector as a base64-encoded string.
- * If omitted, a random initialization vector will be created.
- * @returns An object that contains, `mac` and `iv` properties.
- */
-export declare function calculateKeyCheck(key: Uint8Array, iv?: string): Promise<IEncryptedPayload>;
-//# sourceMappingURL=aes.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/aes.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/aes.d.ts.map
deleted file mode 100644
index ed3d0b5..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/aes.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"aes.d.ts","sourceRoot":"","sources":["../../src/crypto/aes.ts"],"names":[],"mappings":"AAsBA,MAAM,WAAW,iBAAiB;IAC9B,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;IACnB,0CAA0C;IAC1C,EAAE,EAAE,MAAM,CAAC;IACX,+BAA+B;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,yBAAyB;IACzB,GAAG,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAC5B,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,UAAU,EACf,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,iBAAiB,CAAC,CAkC5B;AAED;;;;;;GAMG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,iBAAiB,EAAE,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAoBxG;AAuCD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,UAAU,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAE1F"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/aes.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/aes.js
deleted file mode 100644
index 97181df..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/aes.js
+++ /dev/null
@@ -1,128 +0,0 @@
-"use strict";
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.calculateKeyCheck = calculateKeyCheck;
-exports.decryptAES = decryptAES;
-exports.encryptAES = encryptAES;
-var _olmlib = require("./olmlib");
-var _crypto = require("./crypto");
-/*
-Copyright 2020 - 2021 The Matrix.org Foundation C.I.C.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-// salt for HKDF, with 8 bytes of zeros
-const zeroSalt = new Uint8Array(8);
-/**
- * encrypt a string
- *
- * @param data - the plaintext to encrypt
- * @param key - the encryption key to use
- * @param name - the name of the secret
- * @param ivStr - the initialization vector to use
- */
-async function encryptAES(data, key, name, ivStr) {
- let iv;
- if (ivStr) {
- iv = (0, _olmlib.decodeBase64)(ivStr);
- } else {
- iv = new Uint8Array(16);
- _crypto.crypto.getRandomValues(iv);
-
- // clear bit 63 of the IV to stop us hitting the 64-bit counter boundary
- // (which would mean we wouldn't be able to decrypt on Android). The loss
- // of a single bit of iv is a price we have to pay.
- iv[8] &= 0x7f;
- }
- const [aesKey, hmacKey] = await deriveKeys(key, name);
- const encodedData = new _crypto.TextEncoder().encode(data);
- const ciphertext = await _crypto.subtleCrypto.encrypt({
- name: "AES-CTR",
- counter: iv,
- length: 64
- }, aesKey, encodedData);
- const hmac = await _crypto.subtleCrypto.sign({
- name: "HMAC"
- }, hmacKey, ciphertext);
- return {
- iv: (0, _olmlib.encodeBase64)(iv),
- ciphertext: (0, _olmlib.encodeBase64)(ciphertext),
- mac: (0, _olmlib.encodeBase64)(hmac)
- };
-}
-
-/**
- * decrypt a string
- *
- * @param data - the encrypted data
- * @param key - the encryption key to use
- * @param name - the name of the secret
- */
-async function decryptAES(data, key, name) {
- const [aesKey, hmacKey] = await deriveKeys(key, name);
- const ciphertext = (0, _olmlib.decodeBase64)(data.ciphertext);
- if (!(await _crypto.subtleCrypto.verify({
- name: "HMAC"
- }, hmacKey, (0, _olmlib.decodeBase64)(data.mac), ciphertext))) {
- throw new Error(`Error decrypting secret ${name}: bad MAC`);
- }
- const plaintext = await _crypto.subtleCrypto.decrypt({
- name: "AES-CTR",
- counter: (0, _olmlib.decodeBase64)(data.iv),
- length: 64
- }, aesKey, ciphertext);
- return new TextDecoder().decode(new Uint8Array(plaintext));
-}
-async function deriveKeys(key, name) {
- const hkdfkey = await _crypto.subtleCrypto.importKey("raw", key, {
- name: "HKDF"
- }, false, ["deriveBits"]);
- const keybits = await _crypto.subtleCrypto.deriveBits({
- name: "HKDF",
- salt: zeroSalt,
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
- // @ts-ignore: https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/879
- info: new _crypto.TextEncoder().encode(name),
- hash: "SHA-256"
- }, hkdfkey, 512);
- const aesKey = keybits.slice(0, 32);
- const hmacKey = keybits.slice(32);
- const aesProm = _crypto.subtleCrypto.importKey("raw", aesKey, {
- name: "AES-CTR"
- }, false, ["encrypt", "decrypt"]);
- const hmacProm = _crypto.subtleCrypto.importKey("raw", hmacKey, {
- name: "HMAC",
- hash: {
- name: "SHA-256"
- }
- }, false, ["sign", "verify"]);
- return Promise.all([aesProm, hmacProm]);
-}
-
-// string of zeroes, for calculating the key check
-const ZERO_STR = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
-
-/** Calculate the MAC for checking the key.
- *
- * @param key - the key to use
- * @param iv - The initialization vector as a base64-encoded string.
- * If omitted, a random initialization vector will be created.
- * @returns An object that contains, `mac` and `iv` properties.
- */
-function calculateKeyCheck(key, iv) {
- return encryptAES(ZERO_STR, key, "", iv);
-}
-//# sourceMappingURL=aes.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/aes.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/aes.js.map
deleted file mode 100644
index 3b8f88c..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/aes.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"aes.js","names":["_olmlib","require","_crypto","zeroSalt","Uint8Array","encryptAES","data","key","name","ivStr","iv","decodeBase64","crypto","getRandomValues","aesKey","hmacKey","deriveKeys","encodedData","TextEncoder","encode","ciphertext","subtleCrypto","encrypt","counter","length","hmac","sign","encodeBase64","mac","decryptAES","verify","Error","plaintext","decrypt","TextDecoder","decode","hkdfkey","importKey","keybits","deriveBits","salt","info","hash","slice","aesProm","hmacProm","Promise","all","ZERO_STR","calculateKeyCheck"],"sources":["../../src/crypto/aes.ts"],"sourcesContent":["/*\nCopyright 2020 - 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { decodeBase64, encodeBase64 } from \"./olmlib\";\nimport { subtleCrypto, crypto, TextEncoder } from \"./crypto\";\n\n// salt for HKDF, with 8 bytes of zeros\nconst zeroSalt = new Uint8Array(8);\n\nexport interface IEncryptedPayload {\n [key: string]: any; // extensible\n /** the initialization vector in base64 */\n iv: string;\n /** the ciphertext in base64 */\n ciphertext: string;\n /** the HMAC in base64 */\n mac: string;\n}\n\n/**\n * encrypt a string\n *\n * @param data - the plaintext to encrypt\n * @param key - the encryption key to use\n * @param name - the name of the secret\n * @param ivStr - the initialization vector to use\n */\nexport async function encryptAES(\n data: string,\n key: Uint8Array,\n name: string,\n ivStr?: string,\n): Promise<IEncryptedPayload> {\n let iv: Uint8Array;\n if (ivStr) {\n iv = decodeBase64(ivStr);\n } else {\n iv = new Uint8Array(16);\n crypto.getRandomValues(iv);\n\n // clear bit 63 of the IV to stop us hitting the 64-bit counter boundary\n // (which would mean we wouldn't be able to decrypt on Android). The loss\n // of a single bit of iv is a price we have to pay.\n iv[8] &= 0x7f;\n }\n\n const [aesKey, hmacKey] = await deriveKeys(key, name);\n const encodedData = new TextEncoder().encode(data);\n\n const ciphertext = await subtleCrypto.encrypt(\n {\n name: \"AES-CTR\",\n counter: iv,\n length: 64,\n },\n aesKey,\n encodedData,\n );\n\n const hmac = await subtleCrypto.sign({ name: \"HMAC\" }, hmacKey, ciphertext);\n\n return {\n iv: encodeBase64(iv),\n ciphertext: encodeBase64(ciphertext),\n mac: encodeBase64(hmac),\n };\n}\n\n/**\n * decrypt a string\n *\n * @param data - the encrypted data\n * @param key - the encryption key to use\n * @param name - the name of the secret\n */\nexport async function decryptAES(data: IEncryptedPayload, key: Uint8Array, name: string): Promise<string> {\n const [aesKey, hmacKey] = await deriveKeys(key, name);\n\n const ciphertext = decodeBase64(data.ciphertext);\n\n if (!(await subtleCrypto.verify({ name: \"HMAC\" }, hmacKey, decodeBase64(data.mac), ciphertext))) {\n throw new Error(`Error decrypting secret ${name}: bad MAC`);\n }\n\n const plaintext = await subtleCrypto.decrypt(\n {\n name: \"AES-CTR\",\n counter: decodeBase64(data.iv),\n length: 64,\n },\n aesKey,\n ciphertext,\n );\n\n return new TextDecoder().decode(new Uint8Array(plaintext));\n}\n\nasync function deriveKeys(key: Uint8Array, name: string): Promise<[CryptoKey, CryptoKey]> {\n const hkdfkey = await subtleCrypto.importKey(\"raw\", key, { name: \"HKDF\" }, false, [\"deriveBits\"]);\n const keybits = await subtleCrypto.deriveBits(\n {\n name: \"HKDF\",\n salt: zeroSalt,\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore: https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/879\n info: new TextEncoder().encode(name),\n hash: \"SHA-256\",\n },\n hkdfkey,\n 512,\n );\n\n const aesKey = keybits.slice(0, 32);\n const hmacKey = keybits.slice(32);\n\n const aesProm = subtleCrypto.importKey(\"raw\", aesKey, { name: \"AES-CTR\" }, false, [\"encrypt\", \"decrypt\"]);\n\n const hmacProm = subtleCrypto.importKey(\n \"raw\",\n hmacKey,\n {\n name: \"HMAC\",\n hash: { name: \"SHA-256\" },\n },\n false,\n [\"sign\", \"verify\"],\n );\n\n return Promise.all([aesProm, hmacProm]);\n}\n\n// string of zeroes, for calculating the key check\nconst ZERO_STR = \"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\";\n\n/** Calculate the MAC for checking the key.\n *\n * @param key - the key to use\n * @param iv - The initialization vector as a base64-encoded string.\n * If omitted, a random initialization vector will be created.\n * @returns An object that contains, `mac` and `iv` properties.\n */\nexport function calculateKeyCheck(key: Uint8Array, iv?: string): Promise<IEncryptedPayload> {\n return encryptAES(ZERO_STR, key, \"\", iv);\n}\n"],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/base.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/base.d.ts
deleted file mode 100644
index adf2715..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/base.d.ts
+++ /dev/null
@@ -1,170 +0,0 @@
-/**
- * Internal module. Defines the base classes of the encryption implementations
- */
-import type { IMegolmSessionData } from "../../@types/crypto";
-import { MatrixClient } from "../../client";
-import { Room } from "../../models/room";
-import { OlmDevice } from "../OlmDevice";
-import { IContent, MatrixEvent, RoomMember } from "../../matrix";
-import { Crypto, IEncryptedContent, IEventDecryptionResult, IncomingRoomKeyRequest } from "..";
-import { DeviceInfo } from "../deviceinfo";
-import { IRoomEncryption } from "../RoomList";
-import { DeviceInfoMap } from "../DeviceList";
-/**
- * Map of registered encryption algorithm classes. A map from string to {@link EncryptionAlgorithm} class
- */
-export declare const ENCRYPTION_CLASSES: Map<string, new (params: IParams) => EncryptionAlgorithm>;
-export type DecryptionClassParams<P extends IParams = IParams> = Omit<P, "deviceId" | "config">;
-/**
- * map of registered encryption algorithm classes. Map from string to {@link DecryptionAlgorithm} class
- */
-export declare const DECRYPTION_CLASSES: Map<string, new (params: DecryptionClassParams) => DecryptionAlgorithm>;
-export interface IParams {
- /** The UserID for the local user */
- userId: string;
- /** The identifier for this device. */
- deviceId: string;
- /** crypto core */
- crypto: Crypto;
- /** olm.js wrapper */
- olmDevice: OlmDevice;
- /** base matrix api interface */
- baseApis: MatrixClient;
- /** The ID of the room we will be sending to */
- roomId?: string;
- /** The body of the m.room.encryption event */
- config: IRoomEncryption & object;
-}
-/**
- * base type for encryption implementations
- */
-export declare abstract class EncryptionAlgorithm {
- protected readonly userId: string;
- protected readonly deviceId: string;
- protected readonly crypto: Crypto;
- protected readonly olmDevice: OlmDevice;
- protected readonly baseApis: MatrixClient;
- protected readonly roomId?: string;
- /**
- * @param params - parameters
- */
- constructor(params: IParams);
- /**
- * Perform any background tasks that can be done before a message is ready to
- * send, in order to speed up sending of the message.
- *
- * @param room - the room the event is in
- */
- prepareToEncrypt(room: Room): void;
- /**
- * Encrypt a message event
- *
- * @public
- *
- * @param content - event content
- *
- * @returns Promise which resolves to the new event body
- */
- abstract encryptMessage(room: Room, eventType: string, content: IContent): Promise<IEncryptedContent>;
- /**
- * Called when the membership of a member of the room changes.
- *
- * @param event - event causing the change
- * @param member - user whose membership changed
- * @param oldMembership - previous membership
- * @public
- */
- onRoomMembership(event: MatrixEvent, member: RoomMember, oldMembership?: string): void;
- reshareKeyWithDevice?(senderKey: string, sessionId: string, userId: string, device: DeviceInfo): Promise<void>;
- forceDiscardSession?(): void;
-}
-/**
- * base type for decryption implementations
- */
-export declare abstract class DecryptionAlgorithm {
- protected readonly userId: string;
- protected readonly crypto: Crypto;
- protected readonly olmDevice: OlmDevice;
- protected readonly baseApis: MatrixClient;
- protected readonly roomId?: string;
- constructor(params: DecryptionClassParams);
- /**
- * Decrypt an event
- *
- * @param event - undecrypted event
- *
- * @returns promise which
- * resolves once we have finished decrypting. Rejects with an
- * `algorithms.DecryptionError` if there is a problem decrypting the event.
- */
- abstract decryptEvent(event: MatrixEvent): Promise<IEventDecryptionResult>;
- /**
- * Handle a key event
- *
- * @param params - event key event
- */
- onRoomKeyEvent(params: MatrixEvent): Promise<void>;
- /**
- * Import a room key
- *
- * @param opts - object
- */
- importRoomKey(session: IMegolmSessionData, opts: object): Promise<void>;
- /**
- * Determine if we have the keys necessary to respond to a room key request
- *
- * @returns true if we have the keys and could (theoretically) share
- * them; else false.
- */
- hasKeysForKeyRequest(keyRequest: IncomingRoomKeyRequest): Promise<boolean>;
- /**
- * Send the response to a room key request
- *
- */
- shareKeysWithDevice(keyRequest: IncomingRoomKeyRequest): void;
- /**
- * Retry decrypting all the events from a sender that haven't been
- * decrypted yet.
- *
- * @param senderKey - the sender's key
- */
- retryDecryptionFromSender(senderKey: string): Promise<boolean>;
- onRoomKeyWithheldEvent?(event: MatrixEvent): Promise<void>;
- sendSharedHistoryInboundSessions?(devicesByUser: Map<string, DeviceInfo[]>): Promise<void>;
-}
-/**
- * Exception thrown when decryption fails
- *
- * @param msg - user-visible message describing the problem
- *
- * @param details - key/value pairs reported in the logs but not shown
- * to the user.
- */
-export declare class DecryptionError extends Error {
- readonly code: string;
- readonly detailedString: string;
- constructor(code: string, msg: string, details?: Record<string, string | Error>);
-}
-export declare class UnknownDeviceError extends Error {
- readonly devices: DeviceInfoMap;
- event?: MatrixEvent | undefined;
- /**
- * Exception thrown specifically when we want to warn the user to consider
- * the security of their conversation before continuing
- *
- * @param msg - message describing the problem
- * @param devices - set of unknown devices per user we're warning about
- */
- constructor(msg: string, devices: DeviceInfoMap, event?: MatrixEvent | undefined);
-}
-/**
- * Registers an encryption/decryption class for a particular algorithm
- *
- * @param algorithm - algorithm tag to register for
- *
- * @param encryptor - {@link EncryptionAlgorithm} implementation
- *
- * @param decryptor - {@link DecryptionAlgorithm} implementation
- */
-export declare function registerAlgorithm<P extends IParams = IParams>(algorithm: string, encryptor: new (params: P) => EncryptionAlgorithm, decryptor: new (params: DecryptionClassParams<P>) => DecryptionAlgorithm): void;
-//# sourceMappingURL=base.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/base.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/base.d.ts.map
deleted file mode 100644
index c4c177a..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/base.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../src/crypto/algorithms/base.ts"],"names":[],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/base.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/base.js
deleted file mode 100644
index 9c5bd8f..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/base.js
+++ /dev/null
@@ -1,226 +0,0 @@
-"use strict";
-
-var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.UnknownDeviceError = exports.EncryptionAlgorithm = exports.ENCRYPTION_CLASSES = exports.DecryptionError = exports.DecryptionAlgorithm = exports.DECRYPTION_CLASSES = void 0;
-exports.registerAlgorithm = registerAlgorithm;
-var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
-/*
-Copyright 2016 - 2021 The Matrix.org Foundation C.I.C.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-/**
- * Internal module. Defines the base classes of the encryption implementations
- */
-
-/**
- * Map of registered encryption algorithm classes. A map from string to {@link EncryptionAlgorithm} class
- */
-const ENCRYPTION_CLASSES = new Map();
-exports.ENCRYPTION_CLASSES = ENCRYPTION_CLASSES;
-/**
- * map of registered encryption algorithm classes. Map from string to {@link DecryptionAlgorithm} class
- */
-const DECRYPTION_CLASSES = new Map();
-exports.DECRYPTION_CLASSES = DECRYPTION_CLASSES;
-/**
- * base type for encryption implementations
- */
-class EncryptionAlgorithm {
- /**
- * @param params - parameters
- */
- constructor(params) {
- (0, _defineProperty2.default)(this, "userId", void 0);
- (0, _defineProperty2.default)(this, "deviceId", void 0);
- (0, _defineProperty2.default)(this, "crypto", void 0);
- (0, _defineProperty2.default)(this, "olmDevice", void 0);
- (0, _defineProperty2.default)(this, "baseApis", void 0);
- (0, _defineProperty2.default)(this, "roomId", void 0);
- this.userId = params.userId;
- this.deviceId = params.deviceId;
- this.crypto = params.crypto;
- this.olmDevice = params.olmDevice;
- this.baseApis = params.baseApis;
- this.roomId = params.roomId;
- }
-
- /**
- * Perform any background tasks that can be done before a message is ready to
- * send, in order to speed up sending of the message.
- *
- * @param room - the room the event is in
- */
- prepareToEncrypt(room) {}
-
- /**
- * Encrypt a message event
- *
- * @public
- *
- * @param content - event content
- *
- * @returns Promise which resolves to the new event body
- */
-
- /**
- * Called when the membership of a member of the room changes.
- *
- * @param event - event causing the change
- * @param member - user whose membership changed
- * @param oldMembership - previous membership
- * @public
- */
- onRoomMembership(event, member, oldMembership) {}
-}
-
-/**
- * base type for decryption implementations
- */
-exports.EncryptionAlgorithm = EncryptionAlgorithm;
-class DecryptionAlgorithm {
- constructor(params) {
- (0, _defineProperty2.default)(this, "userId", void 0);
- (0, _defineProperty2.default)(this, "crypto", void 0);
- (0, _defineProperty2.default)(this, "olmDevice", void 0);
- (0, _defineProperty2.default)(this, "baseApis", void 0);
- (0, _defineProperty2.default)(this, "roomId", void 0);
- this.userId = params.userId;
- this.crypto = params.crypto;
- this.olmDevice = params.olmDevice;
- this.baseApis = params.baseApis;
- this.roomId = params.roomId;
- }
-
- /**
- * Decrypt an event
- *
- * @param event - undecrypted event
- *
- * @returns promise which
- * resolves once we have finished decrypting. Rejects with an
- * `algorithms.DecryptionError` if there is a problem decrypting the event.
- */
-
- /**
- * Handle a key event
- *
- * @param params - event key event
- */
- async onRoomKeyEvent(params) {
- // ignore by default
- }
-
- /**
- * Import a room key
- *
- * @param opts - object
- */
- async importRoomKey(session, opts) {
- // ignore by default
- }
-
- /**
- * Determine if we have the keys necessary to respond to a room key request
- *
- * @returns true if we have the keys and could (theoretically) share
- * them; else false.
- */
- hasKeysForKeyRequest(keyRequest) {
- return Promise.resolve(false);
- }
-
- /**
- * Send the response to a room key request
- *
- */
- shareKeysWithDevice(keyRequest) {
- throw new Error("shareKeysWithDevice not supported for this DecryptionAlgorithm");
- }
-
- /**
- * Retry decrypting all the events from a sender that haven't been
- * decrypted yet.
- *
- * @param senderKey - the sender's key
- */
- async retryDecryptionFromSender(senderKey) {
- // ignore by default
- return false;
- }
-}
-
-/**
- * Exception thrown when decryption fails
- *
- * @param msg - user-visible message describing the problem
- *
- * @param details - key/value pairs reported in the logs but not shown
- * to the user.
- */
-exports.DecryptionAlgorithm = DecryptionAlgorithm;
-class DecryptionError extends Error {
- constructor(code, msg, details) {
- super(msg);
- this.code = code;
- (0, _defineProperty2.default)(this, "detailedString", void 0);
- this.code = code;
- this.name = "DecryptionError";
- this.detailedString = detailedStringForDecryptionError(this, details);
- }
-}
-exports.DecryptionError = DecryptionError;
-function detailedStringForDecryptionError(err, details) {
- let result = err.name + "[msg: " + err.message;
- if (details) {
- result += ", " + Object.keys(details).map(k => k + ": " + details[k]).join(", ");
- }
- result += "]";
- return result;
-}
-class UnknownDeviceError extends Error {
- /**
- * Exception thrown specifically when we want to warn the user to consider
- * the security of their conversation before continuing
- *
- * @param msg - message describing the problem
- * @param devices - set of unknown devices per user we're warning about
- */
- constructor(msg, devices, event) {
- super(msg);
- this.devices = devices;
- this.event = event;
- this.name = "UnknownDeviceError";
- this.devices = devices;
- }
-}
-
-/**
- * Registers an encryption/decryption class for a particular algorithm
- *
- * @param algorithm - algorithm tag to register for
- *
- * @param encryptor - {@link EncryptionAlgorithm} implementation
- *
- * @param decryptor - {@link DecryptionAlgorithm} implementation
- */
-exports.UnknownDeviceError = UnknownDeviceError;
-function registerAlgorithm(algorithm, encryptor, decryptor) {
- ENCRYPTION_CLASSES.set(algorithm, encryptor);
- DECRYPTION_CLASSES.set(algorithm, decryptor);
-}
-//# sourceMappingURL=base.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/base.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/base.js.map
deleted file mode 100644
index 3a4d930..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/base.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"base.js","names":["ENCRYPTION_CLASSES","Map","exports","DECRYPTION_CLASSES","EncryptionAlgorithm","constructor","params","_defineProperty2","default","userId","deviceId","crypto","olmDevice","baseApis","roomId","prepareToEncrypt","room","onRoomMembership","event","member","oldMembership","DecryptionAlgorithm","onRoomKeyEvent","importRoomKey","session","opts","hasKeysForKeyRequest","keyRequest","Promise","resolve","shareKeysWithDevice","Error","retryDecryptionFromSender","senderKey","DecryptionError","code","msg","details","name","detailedString","detailedStringForDecryptionError","err","result","message","Object","keys","map","k","join","UnknownDeviceError","devices","registerAlgorithm","algorithm","encryptor","decryptor","set"],"sources":["../../../src/crypto/algorithms/base.ts"],"sourcesContent":["/*\nCopyright 2016 - 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n/**\n * Internal module. Defines the base classes of the encryption implementations\n */\n\nimport type { IMegolmSessionData } from \"../../@types/crypto\";\nimport { MatrixClient } from \"../../client\";\nimport { Room } from \"../../models/room\";\nimport { OlmDevice } from \"../OlmDevice\";\nimport { IContent, MatrixEvent, RoomMember } from \"../../matrix\";\nimport { Crypto, IEncryptedContent, IEventDecryptionResult, IncomingRoomKeyRequest } from \"..\";\nimport { DeviceInfo } from \"../deviceinfo\";\nimport { IRoomEncryption } from \"../RoomList\";\nimport { DeviceInfoMap } from \"../DeviceList\";\n\n/**\n * Map of registered encryption algorithm classes. A map from string to {@link EncryptionAlgorithm} class\n */\nexport const ENCRYPTION_CLASSES = new Map<string, new (params: IParams) => EncryptionAlgorithm>();\n\nexport type DecryptionClassParams<P extends IParams = IParams> = Omit<P, \"deviceId\" | \"config\">;\n\n/**\n * map of registered encryption algorithm classes. Map from string to {@link DecryptionAlgorithm} class\n */\nexport const DECRYPTION_CLASSES = new Map<string, new (params: DecryptionClassParams) => DecryptionAlgorithm>();\n\nexport interface IParams {\n /** The UserID for the local user */\n userId: string;\n /** The identifier for this device. */\n deviceId: string;\n /** crypto core */\n crypto: Crypto;\n /** olm.js wrapper */\n olmDevice: OlmDevice;\n /** base matrix api interface */\n baseApis: MatrixClient;\n /** The ID of the room we will be sending to */\n roomId?: string;\n /** The body of the m.room.encryption event */\n config: IRoomEncryption & object;\n}\n\n/**\n * base type for encryption implementations\n */\nexport abstract class EncryptionAlgorithm {\n protected readonly userId: string;\n protected readonly deviceId: string;\n protected readonly crypto: Crypto;\n protected readonly olmDevice: OlmDevice;\n protected readonly baseApis: MatrixClient;\n protected readonly roomId?: string;\n\n /**\n * @param params - parameters\n */\n public constructor(params: IParams) {\n this.userId = params.userId;\n this.deviceId = params.deviceId;\n this.crypto = params.crypto;\n this.olmDevice = params.olmDevice;\n this.baseApis = params.baseApis;\n this.roomId = params.roomId;\n }\n\n /**\n * Perform any background tasks that can be done before a message is ready to\n * send, in order to speed up sending of the message.\n *\n * @param room - the room the event is in\n */\n public prepareToEncrypt(room: Room): void {}\n\n /**\n * Encrypt a message event\n *\n * @public\n *\n * @param content - event content\n *\n * @returns Promise which resolves to the new event body\n */\n public abstract encryptMessage(room: Room, eventType: string, content: IContent): Promise<IEncryptedContent>;\n\n /**\n * Called when the membership of a member of the room changes.\n *\n * @param event - event causing the change\n * @param member - user whose membership changed\n * @param oldMembership - previous membership\n * @public\n */\n public onRoomMembership(event: MatrixEvent, member: RoomMember, oldMembership?: string): void {}\n\n public reshareKeyWithDevice?(\n senderKey: string,\n sessionId: string,\n userId: string,\n device: DeviceInfo,\n ): Promise<void>;\n\n public forceDiscardSession?(): void;\n}\n\n/**\n * base type for decryption implementations\n */\nexport abstract class DecryptionAlgorithm {\n protected readonly userId: string;\n protected readonly crypto: Crypto;\n protected readonly olmDevice: OlmDevice;\n protected readonly baseApis: MatrixClient;\n protected readonly roomId?: string;\n\n public constructor(params: DecryptionClassParams) {\n this.userId = params.userId;\n this.crypto = params.crypto;\n this.olmDevice = params.olmDevice;\n this.baseApis = params.baseApis;\n this.roomId = params.roomId;\n }\n\n /**\n * Decrypt an event\n *\n * @param event - undecrypted event\n *\n * @returns promise which\n * resolves once we have finished decrypting. Rejects with an\n * `algorithms.DecryptionError` if there is a problem decrypting the event.\n */\n public abstract decryptEvent(event: MatrixEvent): Promise<IEventDecryptionResult>;\n\n /**\n * Handle a key event\n *\n * @param params - event key event\n */\n public async onRoomKeyEvent(params: MatrixEvent): Promise<void> {\n // ignore by default\n }\n\n /**\n * Import a room key\n *\n * @param opts - object\n */\n public async importRoomKey(session: IMegolmSessionData, opts: object): Promise<void> {\n // ignore by default\n }\n\n /**\n * Determine if we have the keys necessary to respond to a room key request\n *\n * @returns true if we have the keys and could (theoretically) share\n * them; else false.\n */\n public hasKeysForKeyRequest(keyRequest: IncomingRoomKeyRequest): Promise<boolean> {\n return Promise.resolve(false);\n }\n\n /**\n * Send the response to a room key request\n *\n */\n public shareKeysWithDevice(keyRequest: IncomingRoomKeyRequest): void {\n throw new Error(\"shareKeysWithDevice not supported for this DecryptionAlgorithm\");\n }\n\n /**\n * Retry decrypting all the events from a sender that haven't been\n * decrypted yet.\n *\n * @param senderKey - the sender's key\n */\n public async retryDecryptionFromSender(senderKey: string): Promise<boolean> {\n // ignore by default\n return false;\n }\n\n public onRoomKeyWithheldEvent?(event: MatrixEvent): Promise<void>;\n public sendSharedHistoryInboundSessions?(devicesByUser: Map<string, DeviceInfo[]>): Promise<void>;\n}\n\n/**\n * Exception thrown when decryption fails\n *\n * @param msg - user-visible message describing the problem\n *\n * @param details - key/value pairs reported in the logs but not shown\n * to the user.\n */\nexport class DecryptionError extends Error {\n public readonly detailedString: string;\n\n public constructor(public readonly code: string, msg: string, details?: Record<string, string | Error>) {\n super(msg);\n this.code = code;\n this.name = \"DecryptionError\";\n this.detailedString = detailedStringForDecryptionError(this, details);\n }\n}\n\nfunction detailedStringForDecryptionError(err: DecryptionError, details?: Record<string, string | Error>): string {\n let result = err.name + \"[msg: \" + err.message;\n\n if (details) {\n result +=\n \", \" +\n Object.keys(details)\n .map((k) => k + \": \" + details[k])\n .join(\", \");\n }\n\n result += \"]\";\n\n return result;\n}\n\nexport class UnknownDeviceError extends Error {\n /**\n * Exception thrown specifically when we want to warn the user to consider\n * the security of their conversation before continuing\n *\n * @param msg - message describing the problem\n * @param devices - set of unknown devices per user we're warning about\n */\n public constructor(msg: string, public readonly devices: DeviceInfoMap, public event?: MatrixEvent) {\n super(msg);\n this.name = \"UnknownDeviceError\";\n this.devices = devices;\n }\n}\n\n/**\n * Registers an encryption/decryption class for a particular algorithm\n *\n * @param algorithm - algorithm tag to register for\n *\n * @param encryptor - {@link EncryptionAlgorithm} implementation\n *\n * @param decryptor - {@link DecryptionAlgorithm} implementation\n */\nexport function registerAlgorithm<P extends IParams = IParams>(\n algorithm: string,\n encryptor: new (params: P) => EncryptionAlgorithm,\n decryptor: new (params: DecryptionClassParams<P>) => DecryptionAlgorithm,\n): void {\n ENCRYPTION_CLASSES.set(algorithm, encryptor as new (params: IParams) => EncryptionAlgorithm);\n DECRYPTION_CLASSES.set(algorithm, decryptor as new (params: DecryptionClassParams) => DecryptionAlgorithm);\n}\n"],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/index.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/index.d.ts
deleted file mode 100644
index e380e5f..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/index.d.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-import "./olm";
-import "./megolm";
-export * from "./base";
-//# sourceMappingURL=index.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/index.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/index.d.ts.map
deleted file mode 100644
index fe86a77..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/index.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/crypto/algorithms/index.ts"],"names":[],"mappings":"AAgBA,OAAO,OAAO,CAAC;AACf,OAAO,UAAU,CAAC;AAElB,cAAc,QAAQ,CAAC"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/index.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/index.js
deleted file mode 100644
index 1b8540e..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/index.js
+++ /dev/null
@@ -1,19 +0,0 @@
-"use strict";
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-require("./olm");
-require("./megolm");
-var _base = require("./base");
-Object.keys(_base).forEach(function (key) {
- if (key === "default" || key === "__esModule") return;
- if (key in exports && exports[key] === _base[key]) return;
- Object.defineProperty(exports, key, {
- enumerable: true,
- get: function () {
- return _base[key];
- }
- });
-});
-//# sourceMappingURL=index.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/index.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/index.js.map
deleted file mode 100644
index 84ccb86..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/index.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"index.js","names":["require","_base","Object","keys","forEach","key","exports","defineProperty","enumerable","get"],"sources":["../../../src/crypto/algorithms/index.ts"],"sourcesContent":["/*\nCopyright 2016 - 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport \"./olm\";\nimport \"./megolm\";\n\nexport * from \"./base\";\n"],"mappings":";;;;;AAgBAA,OAAA;AACAA,OAAA;AAEA,IAAAC,KAAA,GAAAD,OAAA;AAAAE,MAAA,CAAAC,IAAA,CAAAF,KAAA,EAAAG,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAJ,KAAA,CAAAI,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAR,KAAA,CAAAI,GAAA;IAAA;EAAA;AAAA"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/megolm.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/megolm.d.ts
deleted file mode 100644
index cfc9abb..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/megolm.d.ts
+++ /dev/null
@@ -1,385 +0,0 @@
-import type { IEventDecryptionResult, IMegolmSessionData } from "../../@types/crypto";
-import { DecryptionAlgorithm, DecryptionClassParams, EncryptionAlgorithm, IParams } from "./base";
-import { Room } from "../../models/room";
-import { DeviceInfo } from "../deviceinfo";
-import { IContent, MatrixEvent } from "../../models/event";
-import { IMegolmEncryptedContent, IncomingRoomKeyRequest } from "../index";
-export declare function isRoomSharedHistory(room: Room): boolean;
-export interface IOlmDevice<T = DeviceInfo> {
- userId: string;
- deviceInfo: T;
-}
-export interface IOutboundGroupSessionKey {
- chain_index: number;
- key: string;
-}
-/**
- * Megolm encryption implementation
- *
- * @param params - parameters, as per {@link EncryptionAlgorithm}
- */
-export declare class MegolmEncryption extends EncryptionAlgorithm {
- private setupPromise;
- private outboundSessions;
- private readonly sessionRotationPeriodMsgs;
- private readonly sessionRotationPeriodMs;
- private encryptionPreparation?;
- protected readonly roomId: string;
- private readonly prefixedLogger;
- constructor(params: IParams & Required<Pick<IParams, "roomId">>);
- /**
- * @internal
- *
- * @param devicesInRoom - The devices in this room, indexed by user ID
- * @param blocked - The devices that are blocked, indexed by user ID
- * @param singleOlmCreationPhase - Only perform one round of olm
- * session creation
- *
- * This method updates the setupPromise field of the class by chaining a new
- * call on top of the existing promise, and then catching and discarding any
- * errors that might happen while setting up the outbound group session. This
- * is done to ensure that `setupPromise` always resolves to `null` or the
- * `OutboundSessionInfo`.
- *
- * Using `>>=` to represent the promise chaining operation, it does the
- * following:
- *
- * ```
- * setupPromise = previousSetupPromise >>= setup >>= discardErrors
- * ```
- *
- * The initial value for the `setupPromise` is a promise that resolves to
- * `null`. The forceDiscardSession() resets setupPromise to this initial
- * promise.
- *
- * @returns Promise which resolves to the
- * OutboundSessionInfo when setup is complete.
- */
- private ensureOutboundSession;
- private prepareSession;
- private shareSession;
- /**
- * @internal
- *
- *
- * @returns session
- */
- private prepareNewSession;
- /**
- * Determines what devices in devicesByUser don't have an olm session as given
- * in devicemap.
- *
- * @internal
- *
- * @param deviceMap - the devices that have olm sessions, as returned by
- * olmlib.ensureOlmSessionsForDevices.
- * @param devicesByUser - a map of user IDs to array of deviceInfo
- * @param noOlmDevices - an array to fill with devices that don't have
- * olm sessions
- *
- * @returns an array of devices that don't have olm sessions. If
- * noOlmDevices is specified, then noOlmDevices will be returned.
- */
- private getDevicesWithoutSessions;
- /**
- * Splits the user device map into multiple chunks to reduce the number of
- * devices we encrypt to per API call.
- *
- * @internal
- *
- * @param devicesByUser - map from userid to list of devices
- *
- * @returns the blocked devices, split into chunks
- */
- private splitDevices;
- /**
- * @internal
- *
- *
- * @param chainIndex - current chain index
- *
- * @param userDeviceMap - mapping from userId to deviceInfo
- *
- * @param payload - fields to include in the encrypted payload
- *
- * @returns Promise which resolves once the key sharing
- * for the given userDeviceMap is generated and has been sent.
- */
- private encryptAndSendKeysToDevices;
- /**
- * @internal
- *
- *
- * @param userDeviceMap - list of blocked devices to notify
- *
- * @param payload - fields to include in the notification payload
- *
- * @returns Promise which resolves once the notifications
- * for the given userDeviceMap is generated and has been sent.
- */
- private sendBlockedNotificationsToDevices;
- /**
- * Re-shares a megolm session key with devices if the key has already been
- * sent to them.
- *
- * @param senderKey - The key of the originating device for the session
- * @param sessionId - ID of the outbound session to share
- * @param userId - ID of the user who owns the target device
- * @param device - The target device
- */
- reshareKeyWithDevice(senderKey: string, sessionId: string, userId: string, device: DeviceInfo): Promise<void>;
- /**
- * @internal
- *
- *
- * @param key - the session key as returned by
- * OlmDevice.getOutboundGroupSessionKey
- *
- * @param payload - the base to-device message payload for sharing keys
- *
- * @param devicesByUser - map from userid to list of devices
- *
- * @param errorDevices - array that will be populated with the devices that we can't get an
- * olm session for
- *
- * @param otkTimeout - The timeout in milliseconds when requesting
- * one-time keys for establishing new olm sessions.
- *
- * @param failedServers - An array to fill with remote servers that
- * failed to respond to one-time-key requests.
- */
- private shareKeyWithDevices;
- private shareKeyWithOlmSessions;
- /**
- * Notify devices that we weren't able to create olm sessions.
- *
- *
- *
- * @param failedDevices - the devices that we were unable to
- * create olm sessions for, as returned by shareKeyWithDevices
- */
- private notifyFailedOlmDevices;
- /**
- * Notify blocked devices that they have been blocked.
- *
- *
- * @param devicesByUser - map from userid to device ID to blocked data
- */
- private notifyBlockedDevices;
- /**
- * Perform any background tasks that can be done before a message is ready to
- * send, in order to speed up sending of the message.
- *
- * @param room - the room the event is in
- * @returns A function that, when called, will stop the preparation
- */
- prepareToEncrypt(room: Room): () => void;
- /**
- * @param content - plaintext event content
- *
- * @returns Promise which resolves to the new event body
- */
- encryptMessage(room: Room, eventType: string, content: IContent): Promise<IMegolmEncryptedContent>;
- private isVerificationEvent;
- /**
- * Forces the current outbound group session to be discarded such
- * that another one will be created next time an event is sent.
- *
- * This should not normally be necessary.
- */
- forceDiscardSession(): void;
- /**
- * Checks the devices we're about to send to and see if any are entirely
- * unknown to the user. If so, warn the user, and mark them as known to
- * give the user a chance to go verify them before re-sending this message.
- *
- * @param devicesInRoom - `userId -> {deviceId -> object}`
- * devices we should shared the session with.
- */
- private checkForUnknownDevices;
- /**
- * Remove unknown devices from a set of devices. The devicesInRoom parameter
- * will be modified.
- *
- * @param devicesInRoom - `userId -> {deviceId -> object}`
- * devices we should shared the session with.
- */
- private removeUnknownDevices;
- /**
- * Get the list of unblocked devices for all users in the room
- *
- * @param forceDistributeToUnverified - if set to true will include the unverified devices
- * even if setting is set to block them (useful for verification)
- * @param isCancelled - will cause the procedure to abort early if and when it starts
- * returning `true`. If omitted, cancellation won't happen.
- *
- * @returns Promise which resolves to `null`, or an array whose
- * first element is a {@link DeviceInfoMap} indicating
- * the devices that messages should be encrypted to, and whose second
- * element is a map from userId to deviceId to data indicating the devices
- * that are in the room but that have been blocked.
- * If `isCancelled` is provided and returns `true` while processing, `null`
- * will be returned.
- * If `isCancelled` is not provided, the Promise will never resolve to `null`.
- */
- private getDevicesInRoom;
-}
-/**
- * Megolm decryption implementation
- *
- * @param params - parameters, as per {@link DecryptionAlgorithm}
- */
-export declare class MegolmDecryption extends DecryptionAlgorithm {
- private pendingEvents;
- private olmlib;
- protected readonly roomId: string;
- private readonly prefixedLogger;
- constructor(params: DecryptionClassParams<IParams & Required<Pick<IParams, "roomId">>>);
- /**
- * returns a promise which resolves to a
- * {@link EventDecryptionResult} once we have finished
- * decrypting, or rejects with an `algorithms.DecryptionError` if there is a
- * problem decrypting the event.
- */
- decryptEvent(event: MatrixEvent): Promise<IEventDecryptionResult>;
- private requestKeysForEvent;
- /**
- * Add an event to the list of those awaiting their session keys.
- *
- * @internal
- *
- */
- private addEventToPendingList;
- /**
- * Remove an event from the list of those awaiting their session keys.
- *
- * @internal
- *
- */
- private removeEventFromPendingList;
- /**
- * Parse a RoomKey out of an `m.room_key` event.
- *
- * @param event - the event containing the room key.
- *
- * @returns The `RoomKey` if it could be successfully parsed out of the
- * event.
- *
- * @internal
- *
- */
- private roomKeyFromEvent;
- /**
- * Parse a RoomKey out of an `m.forwarded_room_key` event.
- *
- * @param event - the event containing the forwarded room key.
- *
- * @returns The `RoomKey` if it could be successfully parsed out of the
- * event.
- *
- * @internal
- *
- */
- private forwardedRoomKeyFromEvent;
- /**
- * Determine if we should accept the forwarded room key that was found in the given
- * event.
- *
- * @param event - An `m.forwarded_room_key` event.
- * @param roomKey - The room key that was found in the event.
- *
- * @returns promise that will resolve to a boolean telling us if it's ok to
- * accept the given forwarded room key.
- *
- * @internal
- *
- */
- private shouldAcceptForwardedKey;
- /**
- * Did we ever request the given room key from the event sender and its
- * accompanying device.
- *
- * @param event - An `m.forwarded_room_key` event.
- * @param roomKey - The room key that was found in the event.
- *
- * @internal
- *
- */
- private wasRoomKeyRequested;
- private wasRoomKeyForwardedByInviter;
- private wasRoomKeyForwardedAsHistory;
- /**
- * Check if a forwarded room key should be parked.
- *
- * A forwarded room key should be parked if it's a key for a room we're not
- * in. We park the forwarded room key in case *this sender* invites us to
- * that room later.
- */
- private shouldParkForwardedKey;
- /**
- * Park the given room key to our store.
- *
- * @param event - An `m.forwarded_room_key` event.
- * @param roomKey - The room key that was found in the event.
- *
- * @internal
- *
- */
- private parkForwardedKey;
- /**
- * Add the given room key to our store.
- *
- * @param roomKey - The room key that should be added to the store.
- *
- * @internal
- *
- */
- private addRoomKey;
- /**
- * Handle room keys that have been forwarded to us as an
- * `m.forwarded_room_key` event.
- *
- * Forwarded room keys need special handling since we have no way of knowing
- * who the original creator of the room key was. This naturally means that
- * forwarded room keys are always untrusted and should only be accepted in
- * some cases.
- *
- * @param event - An `m.forwarded_room_key` event.
- *
- * @internal
- *
- */
- private onForwardedRoomKey;
- onRoomKeyEvent(event: MatrixEvent): Promise<void>;
- /**
- * @param event - key event
- */
- onRoomKeyWithheldEvent(event: MatrixEvent): Promise<void>;
- private onNoOlmWithheldEvent;
- hasKeysForKeyRequest(keyRequest: IncomingRoomKeyRequest): Promise<boolean>;
- shareKeysWithDevice(keyRequest: IncomingRoomKeyRequest): void;
- private buildKeyForwardingMessage;
- /**
- * @param untrusted - whether the key should be considered as untrusted
- * @param source - where the key came from
- */
- importRoomKey(session: IMegolmSessionData, { untrusted, source }?: {
- untrusted?: boolean;
- source?: string;
- }): Promise<void>;
- /**
- * Have another go at decrypting events after we receive a key. Resolves once
- * decryption has been re-attempted on all events.
- *
- * @internal
- * @param forceRedecryptIfUntrusted - whether messages that were already
- * successfully decrypted using untrusted keys should be re-decrypted
- *
- * @returns whether all messages were successfully
- * decrypted with trusted keys
- */
- private retryDecryption;
- retryDecryptionFromSender(senderKey: string): Promise<boolean>;
- sendSharedHistoryInboundSessions(devicesByUser: Map<string, DeviceInfo[]>): Promise<void>;
-}
-//# sourceMappingURL=megolm.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/megolm.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/megolm.d.ts.map
deleted file mode 100644
index 5282d8b..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/megolm.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"megolm.d.ts","sourceRoot":"","sources":["../../../src/crypto/algorithms/megolm.ts"],"names":[],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/megolm.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/megolm.js
deleted file mode 100644
index 28b25ac..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/megolm.js
+++ /dev/null
@@ -1,1682 +0,0 @@
-"use strict";
-
-var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.MegolmEncryption = exports.MegolmDecryption = void 0;
-exports.isRoomSharedHistory = isRoomSharedHistory;
-var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
-var _uuid = require("uuid");
-var _logger = require("../../logger");
-var olmlib = _interopRequireWildcard(require("../olmlib"));
-var _base = require("./base");
-var _OlmDevice = require("../OlmDevice");
-var _event = require("../../@types/event");
-var _OutgoingRoomKeyRequestManager = require("../OutgoingRoomKeyRequestManager");
-var _utils = require("../../utils");
-function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
-function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
-function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
-function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
-// determine whether the key can be shared with invitees
-function isRoomSharedHistory(room) {
- var _room$currentState, _visibilityEvent$getC;
- const visibilityEvent = room === null || room === void 0 ? void 0 : (_room$currentState = room.currentState) === null || _room$currentState === void 0 ? void 0 : _room$currentState.getStateEvents("m.room.history_visibility", "");
- // NOTE: if the room visibility is unset, it would normally default to
- // "world_readable".
- // (https://spec.matrix.org/unstable/client-server-api/#server-behaviour-5)
- // But we will be paranoid here, and treat it as a situation where the room
- // is not shared-history
- const visibility = visibilityEvent === null || visibilityEvent === void 0 ? void 0 : (_visibilityEvent$getC = visibilityEvent.getContent()) === null || _visibilityEvent$getC === void 0 ? void 0 : _visibilityEvent$getC.history_visibility;
- return ["world_readable", "shared"].includes(visibility);
-}
-/**
- * Tests whether an encrypted content has a ciphertext.
- * Ciphertext can be a string or object depending on the content type {@link IEncryptedContent}.
- *
- * @param content - Encrypted content
- * @returns true: has ciphertext, else false
- */
-const hasCiphertext = content => {
- return typeof content.ciphertext === "string" ? !!content.ciphertext.length : !!Object.keys(content.ciphertext).length;
-};
-
-/** The result of parsing the an `m.room_key` or `m.forwarded_room_key` to-device event */
-
-/**
- * @internal
- */
-class OutboundSessionInfo {
- /** number of times this session has been used */
-
- /** when the session was created (ms since the epoch) */
-
- /** devices with which we have shared the session key `userId -> {deviceId -> SharedWithData}` */
-
- /**
- * @param sharedHistory - whether the session can be freely shared with
- * other group members, according to the room history visibility settings
- */
- constructor(sessionId, sharedHistory = false) {
- this.sessionId = sessionId;
- this.sharedHistory = sharedHistory;
- (0, _defineProperty2.default)(this, "useCount", 0);
- (0, _defineProperty2.default)(this, "creationTime", void 0);
- (0, _defineProperty2.default)(this, "sharedWithDevices", new _utils.MapWithDefault(() => new Map()));
- (0, _defineProperty2.default)(this, "blockedDevicesNotified", new _utils.MapWithDefault(() => new Map()));
- this.creationTime = new Date().getTime();
- }
-
- /**
- * Check if it's time to rotate the session
- */
- needsRotation(rotationPeriodMsgs, rotationPeriodMs) {
- const sessionLifetime = new Date().getTime() - this.creationTime;
- if (this.useCount >= rotationPeriodMsgs || sessionLifetime >= rotationPeriodMs) {
- _logger.logger.log("Rotating megolm session after " + this.useCount + " messages, " + sessionLifetime + "ms");
- return true;
- }
- return false;
- }
- markSharedWithDevice(userId, deviceId, deviceKey, chainIndex) {
- this.sharedWithDevices.getOrCreate(userId).set(deviceId, {
- deviceKey,
- messageIndex: chainIndex
- });
- }
- markNotifiedBlockedDevice(userId, deviceId) {
- this.blockedDevicesNotified.getOrCreate(userId).set(deviceId, true);
- }
-
- /**
- * Determine if this session has been shared with devices which it shouldn't
- * have been.
- *
- * @param devicesInRoom - `userId -> {deviceId -> object}`
- * devices we should shared the session with.
- *
- * @returns true if we have shared the session with devices which aren't
- * in devicesInRoom.
- */
- sharedWithTooManyDevices(devicesInRoom) {
- for (const [userId, devices] of this.sharedWithDevices) {
- if (!devicesInRoom.has(userId)) {
- _logger.logger.log("Starting new megolm session because we shared with " + userId);
- return true;
- }
- for (const [deviceId] of devices) {
- var _devicesInRoom$get;
- if (!((_devicesInRoom$get = devicesInRoom.get(userId)) !== null && _devicesInRoom$get !== void 0 && _devicesInRoom$get.get(deviceId))) {
- _logger.logger.log("Starting new megolm session because we shared with " + userId + ":" + deviceId);
- return true;
- }
- }
- }
- return false;
- }
-}
-
-/**
- * Megolm encryption implementation
- *
- * @param params - parameters, as per {@link EncryptionAlgorithm}
- */
-class MegolmEncryption extends _base.EncryptionAlgorithm {
- // the most recent attempt to set up a session. This is used to serialise
- // the session setups, so that we have a race-free view of which session we
- // are using, and which devices we have shared the keys with. It resolves
- // with an OutboundSessionInfo (or undefined, for the first message in the
- // room).
-
- // Map of outbound sessions by sessions ID. Used if we need a particular
- // session (the session we're currently using to send is always obtained
- // using setupPromise).
-
- constructor(params) {
- var _params$config$rotati, _params$config, _params$config$rotati2, _params$config2;
- super(params);
- (0, _defineProperty2.default)(this, "setupPromise", Promise.resolve(null));
- (0, _defineProperty2.default)(this, "outboundSessions", {});
- (0, _defineProperty2.default)(this, "sessionRotationPeriodMsgs", void 0);
- (0, _defineProperty2.default)(this, "sessionRotationPeriodMs", void 0);
- (0, _defineProperty2.default)(this, "encryptionPreparation", void 0);
- (0, _defineProperty2.default)(this, "roomId", void 0);
- (0, _defineProperty2.default)(this, "prefixedLogger", void 0);
- this.roomId = params.roomId;
- this.prefixedLogger = _logger.logger.withPrefix(`[${this.roomId} encryption]`);
- this.sessionRotationPeriodMsgs = (_params$config$rotati = (_params$config = params.config) === null || _params$config === void 0 ? void 0 : _params$config.rotation_period_msgs) !== null && _params$config$rotati !== void 0 ? _params$config$rotati : 100;
- this.sessionRotationPeriodMs = (_params$config$rotati2 = (_params$config2 = params.config) === null || _params$config2 === void 0 ? void 0 : _params$config2.rotation_period_ms) !== null && _params$config$rotati2 !== void 0 ? _params$config$rotati2 : 7 * 24 * 3600 * 1000;
- }
-
- /**
- * @internal
- *
- * @param devicesInRoom - The devices in this room, indexed by user ID
- * @param blocked - The devices that are blocked, indexed by user ID
- * @param singleOlmCreationPhase - Only perform one round of olm
- * session creation
- *
- * This method updates the setupPromise field of the class by chaining a new
- * call on top of the existing promise, and then catching and discarding any
- * errors that might happen while setting up the outbound group session. This
- * is done to ensure that `setupPromise` always resolves to `null` or the
- * `OutboundSessionInfo`.
- *
- * Using `>>=` to represent the promise chaining operation, it does the
- * following:
- *
- * ```
- * setupPromise = previousSetupPromise >>= setup >>= discardErrors
- * ```
- *
- * The initial value for the `setupPromise` is a promise that resolves to
- * `null`. The forceDiscardSession() resets setupPromise to this initial
- * promise.
- *
- * @returns Promise which resolves to the
- * OutboundSessionInfo when setup is complete.
- */
- async ensureOutboundSession(room, devicesInRoom, blocked, singleOlmCreationPhase = false) {
- // takes the previous OutboundSessionInfo, and considers whether to create
- // a new one. Also shares the key with any (new) devices in the room.
- //
- // returns a promise which resolves once the keyshare is successful.
- const setup = async oldSession => {
- const sharedHistory = isRoomSharedHistory(room);
- const session = await this.prepareSession(devicesInRoom, sharedHistory, oldSession);
- await this.shareSession(devicesInRoom, sharedHistory, singleOlmCreationPhase, blocked, session);
- return session;
- };
-
- // first wait for the previous share to complete
- const fallible = this.setupPromise.then(setup);
-
- // Ensure any failures are logged for debugging and make sure that the
- // promise chain remains unbroken
- //
- // setupPromise resolves to `null` or the `OutboundSessionInfo` whether
- // or not the share succeeds
- this.setupPromise = fallible.catch(e => {
- this.prefixedLogger.error(`Failed to setup outbound session`, e);
- return null;
- });
-
- // but we return a promise which only resolves if the share was successful.
- return fallible;
- }
- async prepareSession(devicesInRoom, sharedHistory, session) {
- var _session, _session2;
- // history visibility changed
- if (session && sharedHistory !== session.sharedHistory) {
- session = null;
- }
-
- // need to make a brand new session?
- if ((_session = session) !== null && _session !== void 0 && _session.needsRotation(this.sessionRotationPeriodMsgs, this.sessionRotationPeriodMs)) {
- this.prefixedLogger.log("Starting new megolm session because we need to rotate.");
- session = null;
- }
-
- // determine if we have shared with anyone we shouldn't have
- if ((_session2 = session) !== null && _session2 !== void 0 && _session2.sharedWithTooManyDevices(devicesInRoom)) {
- session = null;
- }
- if (!session) {
- this.prefixedLogger.log("Starting new megolm session");
- session = await this.prepareNewSession(sharedHistory);
- this.prefixedLogger.log(`Started new megolm session ${session.sessionId}`);
- this.outboundSessions[session.sessionId] = session;
- }
- return session;
- }
- async shareSession(devicesInRoom, sharedHistory, singleOlmCreationPhase, blocked, session) {
- // now check if we need to share with any devices
- const shareMap = {};
- for (const [userId, userDevices] of devicesInRoom) {
- for (const [deviceId, deviceInfo] of userDevices) {
- var _session$sharedWithDe;
- const key = deviceInfo.getIdentityKey();
- if (key == this.olmDevice.deviceCurve25519Key) {
- // don't bother sending to ourself
- continue;
- }
- if (!((_session$sharedWithDe = session.sharedWithDevices.get(userId)) !== null && _session$sharedWithDe !== void 0 && _session$sharedWithDe.get(deviceId))) {
- shareMap[userId] = shareMap[userId] || [];
- shareMap[userId].push(deviceInfo);
- }
- }
- }
- const key = this.olmDevice.getOutboundGroupSessionKey(session.sessionId);
- const payload = {
- type: "m.room_key",
- content: {
- "algorithm": olmlib.MEGOLM_ALGORITHM,
- "room_id": this.roomId,
- "session_id": session.sessionId,
- "session_key": key.key,
- "chain_index": key.chain_index,
- "org.matrix.msc3061.shared_history": sharedHistory
- }
- };
- const [devicesWithoutSession, olmSessions] = await olmlib.getExistingOlmSessions(this.olmDevice, this.baseApis, shareMap);
- await Promise.all([(async () => {
- // share keys with devices that we already have a session for
- const olmSessionList = Array.from(olmSessions.entries()).map(([userId, sessionsByUser]) => Array.from(sessionsByUser.entries()).map(([deviceId, session]) => `${userId}/${deviceId}: ${session.sessionId}`)).flat(1);
- this.prefixedLogger.debug("Sharing keys with devices with existing Olm sessions:", olmSessionList);
- await this.shareKeyWithOlmSessions(session, key, payload, olmSessions);
- this.prefixedLogger.debug("Shared keys with existing Olm sessions");
- })(), (async () => {
- const deviceList = Array.from(devicesWithoutSession.entries()).map(([userId, devicesByUser]) => devicesByUser.map(device => `${userId}/${device.deviceId}`)).flat(1);
- this.prefixedLogger.debug("Sharing keys (start phase 1) with devices without existing Olm sessions:", deviceList);
- const errorDevices = [];
-
- // meanwhile, establish olm sessions for devices that we don't
- // already have a session for, and share keys with them. If
- // we're doing two phases of olm session creation, use a
- // shorter timeout when fetching one-time keys for the first
- // phase.
- const start = Date.now();
- const failedServers = [];
- await this.shareKeyWithDevices(session, key, payload, devicesWithoutSession, errorDevices, singleOlmCreationPhase ? 10000 : 2000, failedServers);
- this.prefixedLogger.debug("Shared keys (end phase 1) with devices without existing Olm sessions");
- if (!singleOlmCreationPhase && Date.now() - start < 10000) {
- // perform the second phase of olm session creation if requested,
- // and if the first phase didn't take too long
- (async () => {
- // Retry sending keys to devices that we were unable to establish
- // an olm session for. This time, we use a longer timeout, but we
- // do this in the background and don't block anything else while we
- // do this. We only need to retry users from servers that didn't
- // respond the first time.
- const retryDevices = new _utils.MapWithDefault(() => []);
- const failedServerMap = new Set();
- for (const server of failedServers) {
- failedServerMap.add(server);
- }
- const failedDevices = [];
- for (const {
- userId,
- deviceInfo
- } of errorDevices) {
- const userHS = userId.slice(userId.indexOf(":") + 1);
- if (failedServerMap.has(userHS)) {
- retryDevices.getOrCreate(userId).push(deviceInfo);
- } else {
- // if we aren't going to retry, then handle it
- // as a failed device
- failedDevices.push({
- userId,
- deviceInfo
- });
- }
- }
- const retryDeviceList = Array.from(retryDevices.entries()).map(([userId, devicesByUser]) => devicesByUser.map(device => `${userId}/${device.deviceId}`)).flat(1);
- if (retryDeviceList.length > 0) {
- this.prefixedLogger.debug("Sharing keys (start phase 2) with devices without existing Olm sessions:", retryDeviceList);
- await this.shareKeyWithDevices(session, key, payload, retryDevices, failedDevices, 30000);
- this.prefixedLogger.debug("Shared keys (end phase 2) with devices without existing Olm sessions");
- }
- await this.notifyFailedOlmDevices(session, key, failedDevices);
- })();
- } else {
- await this.notifyFailedOlmDevices(session, key, errorDevices);
- }
- })(), (async () => {
- this.prefixedLogger.debug(`There are ${blocked.size} blocked devices:`, Array.from(blocked.entries()).map(([userId, blockedByUser]) => Array.from(blockedByUser.entries()).map(([deviceId, _deviceInfo]) => `${userId}/${deviceId}`)).flat(1));
-
- // also, notify newly blocked devices that they're blocked
- const blockedMap = new _utils.MapWithDefault(() => new Map());
- let blockedCount = 0;
- for (const [userId, userBlockedDevices] of blocked) {
- for (const [deviceId, device] of userBlockedDevices) {
- var _session$blockedDevic;
- if (((_session$blockedDevic = session.blockedDevicesNotified.get(userId)) === null || _session$blockedDevic === void 0 ? void 0 : _session$blockedDevic.get(deviceId)) === undefined) {
- blockedMap.getOrCreate(userId).set(deviceId, {
- device
- });
- blockedCount++;
- }
- }
- }
- if (blockedCount) {
- this.prefixedLogger.debug(`Notifying ${blockedCount} newly blocked devices:`, Array.from(blockedMap.entries()).map(([userId, blockedByUser]) => Object.entries(blockedByUser).map(([deviceId, _deviceInfo]) => `${userId}/${deviceId}`)).flat(1));
- await this.notifyBlockedDevices(session, blockedMap);
- this.prefixedLogger.debug(`Notified ${blockedCount} newly blocked devices`);
- }
- })()]);
- }
-
- /**
- * @internal
- *
- *
- * @returns session
- */
- async prepareNewSession(sharedHistory) {
- const sessionId = this.olmDevice.createOutboundGroupSession();
- const key = this.olmDevice.getOutboundGroupSessionKey(sessionId);
- await this.olmDevice.addInboundGroupSession(this.roomId, this.olmDevice.deviceCurve25519Key, [], sessionId, key.key, {
- ed25519: this.olmDevice.deviceEd25519Key
- }, false, {
- sharedHistory
- });
-
- // don't wait for it to complete
- this.crypto.backupManager.backupGroupSession(this.olmDevice.deviceCurve25519Key, sessionId);
- return new OutboundSessionInfo(sessionId, sharedHistory);
- }
-
- /**
- * Determines what devices in devicesByUser don't have an olm session as given
- * in devicemap.
- *
- * @internal
- *
- * @param deviceMap - the devices that have olm sessions, as returned by
- * olmlib.ensureOlmSessionsForDevices.
- * @param devicesByUser - a map of user IDs to array of deviceInfo
- * @param noOlmDevices - an array to fill with devices that don't have
- * olm sessions
- *
- * @returns an array of devices that don't have olm sessions. If
- * noOlmDevices is specified, then noOlmDevices will be returned.
- */
- getDevicesWithoutSessions(deviceMap, devicesByUser, noOlmDevices = []) {
- for (const [userId, devicesToShareWith] of devicesByUser) {
- const sessionResults = deviceMap.get(userId);
- for (const deviceInfo of devicesToShareWith) {
- const deviceId = deviceInfo.deviceId;
- const sessionResult = sessionResults === null || sessionResults === void 0 ? void 0 : sessionResults.get(deviceId);
- if (!(sessionResult !== null && sessionResult !== void 0 && sessionResult.sessionId)) {
- // no session with this device, probably because there
- // were no one-time keys.
-
- noOlmDevices.push({
- userId,
- deviceInfo
- });
- sessionResults === null || sessionResults === void 0 ? void 0 : sessionResults.delete(deviceId);
-
- // ensureOlmSessionsForUsers has already done the logging,
- // so just skip it.
- continue;
- }
- }
- }
- return noOlmDevices;
- }
-
- /**
- * Splits the user device map into multiple chunks to reduce the number of
- * devices we encrypt to per API call.
- *
- * @internal
- *
- * @param devicesByUser - map from userid to list of devices
- *
- * @returns the blocked devices, split into chunks
- */
- splitDevices(devicesByUser) {
- const maxDevicesPerRequest = 20;
-
- // use an array where the slices of a content map gets stored
- let currentSlice = [];
- const mapSlices = [currentSlice];
- for (const [userId, userDevices] of devicesByUser) {
- for (const deviceInfo of userDevices.values()) {
- currentSlice.push({
- userId: userId,
- deviceInfo: deviceInfo.device
- });
- }
-
- // We do this in the per-user loop as we prefer that all messages to the
- // same user end up in the same API call to make it easier for the
- // server (e.g. only have to send one EDU if a remote user, etc). This
- // does mean that if a user has many devices we may go over the desired
- // limit, but its not a hard limit so that is fine.
- if (currentSlice.length > maxDevicesPerRequest) {
- // the current slice is filled up. Start inserting into the next slice
- currentSlice = [];
- mapSlices.push(currentSlice);
- }
- }
- if (currentSlice.length === 0) {
- mapSlices.pop();
- }
- return mapSlices;
- }
-
- /**
- * @internal
- *
- *
- * @param chainIndex - current chain index
- *
- * @param userDeviceMap - mapping from userId to deviceInfo
- *
- * @param payload - fields to include in the encrypted payload
- *
- * @returns Promise which resolves once the key sharing
- * for the given userDeviceMap is generated and has been sent.
- */
- encryptAndSendKeysToDevices(session, chainIndex, devices, payload) {
- return this.crypto.encryptAndSendToDevices(devices, payload).then(() => {
- // store that we successfully uploaded the keys of the current slice
- for (const device of devices) {
- session.markSharedWithDevice(device.userId, device.deviceInfo.deviceId, device.deviceInfo.getIdentityKey(), chainIndex);
- }
- }).catch(error => {
- this.prefixedLogger.error("failed to encryptAndSendToDevices", error);
- throw error;
- });
- }
-
- /**
- * @internal
- *
- *
- * @param userDeviceMap - list of blocked devices to notify
- *
- * @param payload - fields to include in the notification payload
- *
- * @returns Promise which resolves once the notifications
- * for the given userDeviceMap is generated and has been sent.
- */
- async sendBlockedNotificationsToDevices(session, userDeviceMap, payload) {
- const contentMap = new _utils.MapWithDefault(() => new Map());
- for (const val of userDeviceMap) {
- const userId = val.userId;
- const blockedInfo = val.deviceInfo;
- const deviceInfo = blockedInfo.deviceInfo;
- const deviceId = deviceInfo.deviceId;
- const message = _objectSpread(_objectSpread({}, payload), {}, {
- code: blockedInfo.code,
- reason: blockedInfo.reason,
- [_event.ToDeviceMessageId]: (0, _uuid.v4)()
- });
- if (message.code === "m.no_olm") {
- delete message.room_id;
- delete message.session_id;
- }
- contentMap.getOrCreate(userId).set(deviceId, message);
- }
- await this.baseApis.sendToDevice("m.room_key.withheld", contentMap);
-
- // record the fact that we notified these blocked devices
- for (const [userId, userDeviceMap] of contentMap) {
- for (const deviceId of userDeviceMap.keys()) {
- session.markNotifiedBlockedDevice(userId, deviceId);
- }
- }
- }
-
- /**
- * Re-shares a megolm session key with devices if the key has already been
- * sent to them.
- *
- * @param senderKey - The key of the originating device for the session
- * @param sessionId - ID of the outbound session to share
- * @param userId - ID of the user who owns the target device
- * @param device - The target device
- */
- async reshareKeyWithDevice(senderKey, sessionId, userId, device) {
- var _obSessionInfo$shared;
- const obSessionInfo = this.outboundSessions[sessionId];
- if (!obSessionInfo) {
- this.prefixedLogger.debug(`megolm session ${senderKey}|${sessionId} not found: not re-sharing keys`);
- return;
- }
-
- // The chain index of the key we previously sent this device
- if (!obSessionInfo.sharedWithDevices.has(userId)) {
- this.prefixedLogger.debug(`megolm session ${senderKey}|${sessionId} never shared with user ${userId}`);
- return;
- }
- const sessionSharedData = (_obSessionInfo$shared = obSessionInfo.sharedWithDevices.get(userId)) === null || _obSessionInfo$shared === void 0 ? void 0 : _obSessionInfo$shared.get(device.deviceId);
- if (sessionSharedData === undefined) {
- this.prefixedLogger.debug(`megolm session ${senderKey}|${sessionId} never shared with device ${userId}:${device.deviceId}`);
- return;
- }
- if (sessionSharedData.deviceKey !== device.getIdentityKey()) {
- this.prefixedLogger.warn(`Megolm session ${senderKey}|${sessionId} has been shared with device ${device.deviceId} but ` + `with identity key ${sessionSharedData.deviceKey}. Key is now ${device.getIdentityKey()}!`);
- return;
- }
-
- // get the key from the inbound session: the outbound one will already
- // have been ratcheted to the next chain index.
- const key = await this.olmDevice.getInboundGroupSessionKey(this.roomId, senderKey, sessionId, sessionSharedData.messageIndex);
- if (!key) {
- this.prefixedLogger.warn(`No inbound session key found for megolm session ${senderKey}|${sessionId}: not re-sharing keys`);
- return;
- }
- await olmlib.ensureOlmSessionsForDevices(this.olmDevice, this.baseApis, new Map([[userId, [device]]]));
- const payload = {
- type: "m.forwarded_room_key",
- content: {
- "algorithm": olmlib.MEGOLM_ALGORITHM,
- "room_id": this.roomId,
- "session_id": sessionId,
- "session_key": key.key,
- "chain_index": key.chain_index,
- "sender_key": senderKey,
- "sender_claimed_ed25519_key": key.sender_claimed_ed25519_key,
- "forwarding_curve25519_key_chain": key.forwarding_curve25519_key_chain,
- "org.matrix.msc3061.shared_history": key.shared_history || false
- }
- };
- const encryptedContent = {
- algorithm: olmlib.OLM_ALGORITHM,
- sender_key: this.olmDevice.deviceCurve25519Key,
- ciphertext: {},
- [_event.ToDeviceMessageId]: (0, _uuid.v4)()
- };
- await olmlib.encryptMessageForDevice(encryptedContent.ciphertext, this.userId, this.deviceId, this.olmDevice, userId, device, payload);
- await this.baseApis.sendToDevice("m.room.encrypted", new Map([[userId, new Map([[device.deviceId, encryptedContent]])]]));
- this.prefixedLogger.debug(`Re-shared key for megolm session ${senderKey}|${sessionId} with ${userId}:${device.deviceId}`);
- }
-
- /**
- * @internal
- *
- *
- * @param key - the session key as returned by
- * OlmDevice.getOutboundGroupSessionKey
- *
- * @param payload - the base to-device message payload for sharing keys
- *
- * @param devicesByUser - map from userid to list of devices
- *
- * @param errorDevices - array that will be populated with the devices that we can't get an
- * olm session for
- *
- * @param otkTimeout - The timeout in milliseconds when requesting
- * one-time keys for establishing new olm sessions.
- *
- * @param failedServers - An array to fill with remote servers that
- * failed to respond to one-time-key requests.
- */
- async shareKeyWithDevices(session, key, payload, devicesByUser, errorDevices, otkTimeout, failedServers) {
- const devicemap = await olmlib.ensureOlmSessionsForDevices(this.olmDevice, this.baseApis, devicesByUser, false, otkTimeout, failedServers, this.prefixedLogger);
- this.getDevicesWithoutSessions(devicemap, devicesByUser, errorDevices);
- await this.shareKeyWithOlmSessions(session, key, payload, devicemap);
- }
- async shareKeyWithOlmSessions(session, key, payload, deviceMap) {
- const userDeviceMaps = this.splitDevices(deviceMap);
- for (let i = 0; i < userDeviceMaps.length; i++) {
- const taskDetail = `megolm keys for ${session.sessionId} (slice ${i + 1}/${userDeviceMaps.length})`;
- try {
- this.prefixedLogger.debug(`Sharing ${taskDetail}`, userDeviceMaps[i].map(d => `${d.userId}/${d.deviceInfo.deviceId}`));
- await this.encryptAndSendKeysToDevices(session, key.chain_index, userDeviceMaps[i], payload);
- this.prefixedLogger.debug(`Shared ${taskDetail}`);
- } catch (e) {
- this.prefixedLogger.error(`Failed to share ${taskDetail}`);
- throw e;
- }
- }
- }
-
- /**
- * Notify devices that we weren't able to create olm sessions.
- *
- *
- *
- * @param failedDevices - the devices that we were unable to
- * create olm sessions for, as returned by shareKeyWithDevices
- */
- async notifyFailedOlmDevices(session, key, failedDevices) {
- this.prefixedLogger.debug(`Notifying ${failedDevices.length} devices we failed to create Olm sessions`);
-
- // mark the devices that failed as "handled" because we don't want to try
- // to claim a one-time-key for dead devices on every message.
- for (const {
- userId,
- deviceInfo
- } of failedDevices) {
- const deviceId = deviceInfo.deviceId;
- session.markSharedWithDevice(userId, deviceId, deviceInfo.getIdentityKey(), key.chain_index);
- }
- const unnotifiedFailedDevices = await this.olmDevice.filterOutNotifiedErrorDevices(failedDevices);
- this.prefixedLogger.debug(`Need to notify ${unnotifiedFailedDevices.length} failed devices which haven't been notified before`);
- const blockedMap = new _utils.MapWithDefault(() => new Map());
- for (const {
- userId,
- deviceInfo
- } of unnotifiedFailedDevices) {
- // we use a similar format to what
- // olmlib.ensureOlmSessionsForDevices returns, so that
- // we can use the same function to split
- blockedMap.getOrCreate(userId).set(deviceInfo.deviceId, {
- device: {
- code: "m.no_olm",
- reason: _OlmDevice.WITHHELD_MESSAGES["m.no_olm"],
- deviceInfo
- }
- });
- }
-
- // send the notifications
- await this.notifyBlockedDevices(session, blockedMap);
- this.prefixedLogger.debug(`Notified ${unnotifiedFailedDevices.length} devices we failed to create Olm sessions`);
- }
-
- /**
- * Notify blocked devices that they have been blocked.
- *
- *
- * @param devicesByUser - map from userid to device ID to blocked data
- */
- async notifyBlockedDevices(session, devicesByUser) {
- const payload = {
- room_id: this.roomId,
- session_id: session.sessionId,
- algorithm: olmlib.MEGOLM_ALGORITHM,
- sender_key: this.olmDevice.deviceCurve25519Key
- };
- const userDeviceMaps = this.splitDevices(devicesByUser);
- for (let i = 0; i < userDeviceMaps.length; i++) {
- try {
- await this.sendBlockedNotificationsToDevices(session, userDeviceMaps[i], payload);
- this.prefixedLogger.log(`Completed blacklist notification for ${session.sessionId} ` + `(slice ${i + 1}/${userDeviceMaps.length})`);
- } catch (e) {
- this.prefixedLogger.log(`blacklist notification for ${session.sessionId} ` + `(slice ${i + 1}/${userDeviceMaps.length}) failed`);
- throw e;
- }
- }
- }
-
- /**
- * Perform any background tasks that can be done before a message is ready to
- * send, in order to speed up sending of the message.
- *
- * @param room - the room the event is in
- * @returns A function that, when called, will stop the preparation
- */
- prepareToEncrypt(room) {
- if (room.roomId !== this.roomId) {
- throw new Error("MegolmEncryption.prepareToEncrypt called on unexpected room");
- }
- if (this.encryptionPreparation != null) {
- // We're already preparing something, so don't do anything else.
- const elapsedTime = Date.now() - this.encryptionPreparation.startTime;
- this.prefixedLogger.debug(`Already started preparing to encrypt for this room ${elapsedTime}ms ago, skipping`);
- return this.encryptionPreparation.cancel;
- }
- this.prefixedLogger.debug("Preparing to encrypt events");
- let cancelled = false;
- const isCancelled = () => cancelled;
- this.encryptionPreparation = {
- startTime: Date.now(),
- promise: (async () => {
- try {
- // Attempt to enumerate the devices in room, and gracefully
- // handle cancellation if it occurs.
- const getDevicesResult = await this.getDevicesInRoom(room, false, isCancelled);
- if (getDevicesResult === null) return;
- const [devicesInRoom, blocked] = getDevicesResult;
- if (this.crypto.globalErrorOnUnknownDevices) {
- // Drop unknown devices for now. When the message gets sent, we'll
- // throw an error, but we'll still be prepared to send to the known
- // devices.
- this.removeUnknownDevices(devicesInRoom);
- }
- this.prefixedLogger.debug("Ensuring outbound megolm session");
- await this.ensureOutboundSession(room, devicesInRoom, blocked, true);
- this.prefixedLogger.debug("Ready to encrypt events");
- } catch (e) {
- this.prefixedLogger.error("Failed to prepare to encrypt events", e);
- } finally {
- delete this.encryptionPreparation;
- }
- })(),
- cancel: () => {
- // The caller has indicated that the process should be cancelled,
- // so tell the promise that we'd like to halt, and reset the preparation state.
- cancelled = true;
- delete this.encryptionPreparation;
- }
- };
- return this.encryptionPreparation.cancel;
- }
-
- /**
- * @param content - plaintext event content
- *
- * @returns Promise which resolves to the new event body
- */
- async encryptMessage(room, eventType, content) {
- this.prefixedLogger.log("Starting to encrypt event");
- if (this.encryptionPreparation != null) {
- // If we started sending keys, wait for it to be done.
- // FIXME: check if we need to cancel
- // (https://github.com/matrix-org/matrix-js-sdk/issues/1255)
- try {
- await this.encryptionPreparation.promise;
- } catch (e) {
- // ignore any errors -- if the preparation failed, we'll just
- // restart everything here
- }
- }
-
- /**
- * When using in-room messages and the room has encryption enabled,
- * clients should ensure that encryption does not hinder the verification.
- */
- const forceDistributeToUnverified = this.isVerificationEvent(eventType, content);
- const [devicesInRoom, blocked] = await this.getDevicesInRoom(room, forceDistributeToUnverified);
-
- // check if any of these devices are not yet known to the user.
- // if so, warn the user so they can verify or ignore.
- if (this.crypto.globalErrorOnUnknownDevices) {
- this.checkForUnknownDevices(devicesInRoom);
- }
- const session = await this.ensureOutboundSession(room, devicesInRoom, blocked);
- const payloadJson = {
- room_id: this.roomId,
- type: eventType,
- content: content
- };
- const ciphertext = this.olmDevice.encryptGroupMessage(session.sessionId, JSON.stringify(payloadJson));
- const encryptedContent = {
- algorithm: olmlib.MEGOLM_ALGORITHM,
- sender_key: this.olmDevice.deviceCurve25519Key,
- ciphertext: ciphertext,
- session_id: session.sessionId,
- // Include our device ID so that recipients can send us a
- // m.new_device message if they don't have our session key.
- // XXX: Do we still need this now that m.new_device messages
- // no longer exist since #483?
- device_id: this.deviceId
- };
- session.useCount++;
- return encryptedContent;
- }
- isVerificationEvent(eventType, content) {
- switch (eventType) {
- case _event.EventType.KeyVerificationCancel:
- case _event.EventType.KeyVerificationDone:
- case _event.EventType.KeyVerificationMac:
- case _event.EventType.KeyVerificationStart:
- case _event.EventType.KeyVerificationKey:
- case _event.EventType.KeyVerificationReady:
- case _event.EventType.KeyVerificationAccept:
- {
- return true;
- }
- case _event.EventType.RoomMessage:
- {
- return content["msgtype"] === _event.MsgType.KeyVerificationRequest;
- }
- default:
- {
- return false;
- }
- }
- }
-
- /**
- * Forces the current outbound group session to be discarded such
- * that another one will be created next time an event is sent.
- *
- * This should not normally be necessary.
- */
- forceDiscardSession() {
- this.setupPromise = this.setupPromise.then(() => null);
- }
-
- /**
- * Checks the devices we're about to send to and see if any are entirely
- * unknown to the user. If so, warn the user, and mark them as known to
- * give the user a chance to go verify them before re-sending this message.
- *
- * @param devicesInRoom - `userId -> {deviceId -> object}`
- * devices we should shared the session with.
- */
- checkForUnknownDevices(devicesInRoom) {
- const unknownDevices = new _utils.MapWithDefault(() => new Map());
- for (const [userId, userDevices] of devicesInRoom) {
- for (const [deviceId, device] of userDevices) {
- if (device.isUnverified() && !device.isKnown()) {
- unknownDevices.getOrCreate(userId).set(deviceId, device);
- }
- }
- }
- if (unknownDevices.size) {
- // it'd be kind to pass unknownDevices up to the user in this error
- throw new _base.UnknownDeviceError("This room contains unknown devices which have not been verified. " + "We strongly recommend you verify them before continuing.", unknownDevices);
- }
- }
-
- /**
- * Remove unknown devices from a set of devices. The devicesInRoom parameter
- * will be modified.
- *
- * @param devicesInRoom - `userId -> {deviceId -> object}`
- * devices we should shared the session with.
- */
- removeUnknownDevices(devicesInRoom) {
- for (const [userId, userDevices] of devicesInRoom) {
- for (const [deviceId, device] of userDevices) {
- if (device.isUnverified() && !device.isKnown()) {
- userDevices.delete(deviceId);
- }
- }
- if (userDevices.size === 0) {
- devicesInRoom.delete(userId);
- }
- }
- }
-
- /**
- * Get the list of unblocked devices for all users in the room
- *
- * @param forceDistributeToUnverified - if set to true will include the unverified devices
- * even if setting is set to block them (useful for verification)
- * @param isCancelled - will cause the procedure to abort early if and when it starts
- * returning `true`. If omitted, cancellation won't happen.
- *
- * @returns Promise which resolves to `null`, or an array whose
- * first element is a {@link DeviceInfoMap} indicating
- * the devices that messages should be encrypted to, and whose second
- * element is a map from userId to deviceId to data indicating the devices
- * that are in the room but that have been blocked.
- * If `isCancelled` is provided and returns `true` while processing, `null`
- * will be returned.
- * If `isCancelled` is not provided, the Promise will never resolve to `null`.
- */
-
- async getDevicesInRoom(room, forceDistributeToUnverified = false, isCancelled) {
- const members = await room.getEncryptionTargetMembers();
- this.prefixedLogger.debug(`Encrypting for users (shouldEncryptForInvitedMembers: ${room.shouldEncryptForInvitedMembers()}):`, members.map(u => `${u.userId} (${u.membership})`));
- const roomMembers = members.map(function (u) {
- return u.userId;
- });
-
- // The global value is treated as a default for when rooms don't specify a value.
- let isBlacklisting = this.crypto.globalBlacklistUnverifiedDevices;
- const isRoomBlacklisting = room.getBlacklistUnverifiedDevices();
- if (typeof isRoomBlacklisting === "boolean") {
- isBlacklisting = isRoomBlacklisting;
- }
-
- // We are happy to use a cached version here: we assume that if we already
- // have a list of the user's devices, then we already share an e2e room
- // with them, which means that they will have announced any new devices via
- // device_lists in their /sync response. This cache should then be maintained
- // using all the device_lists changes and left fields.
- // See https://github.com/vector-im/element-web/issues/2305 for details.
- const devices = await this.crypto.downloadKeys(roomMembers, false);
- if ((isCancelled === null || isCancelled === void 0 ? void 0 : isCancelled()) === true) {
- return null;
- }
- const blocked = new _utils.MapWithDefault(() => new Map());
- // remove any blocked devices
- for (const [userId, userDevices] of devices) {
- for (const [deviceId, userDevice] of userDevices) {
- // Yield prior to checking each device so that we don't block
- // updating/rendering for too long.
- // See https://github.com/vector-im/element-web/issues/21612
- if (isCancelled !== undefined) await (0, _utils.immediate)();
- if ((isCancelled === null || isCancelled === void 0 ? void 0 : isCancelled()) === true) return null;
- const deviceTrust = this.crypto.checkDeviceTrust(userId, deviceId);
- if (userDevice.isBlocked() || !deviceTrust.isVerified() && isBlacklisting && !forceDistributeToUnverified) {
- const blockedDevices = blocked.getOrCreate(userId);
- const isBlocked = userDevice.isBlocked();
- blockedDevices.set(deviceId, {
- code: isBlocked ? "m.blacklisted" : "m.unverified",
- reason: _OlmDevice.WITHHELD_MESSAGES[isBlocked ? "m.blacklisted" : "m.unverified"],
- deviceInfo: userDevice
- });
- userDevices.delete(deviceId);
- }
- }
- }
- return [devices, blocked];
- }
-}
-
-/**
- * Megolm decryption implementation
- *
- * @param params - parameters, as per {@link DecryptionAlgorithm}
- */
-exports.MegolmEncryption = MegolmEncryption;
-class MegolmDecryption extends _base.DecryptionAlgorithm {
- // events which we couldn't decrypt due to unknown sessions /
- // indexes, or which we could only decrypt with untrusted keys:
- // map from senderKey|sessionId to Set of MatrixEvents
-
- // this gets stubbed out by the unit tests.
-
- constructor(params) {
- super(params);
- (0, _defineProperty2.default)(this, "pendingEvents", new Map());
- (0, _defineProperty2.default)(this, "olmlib", olmlib);
- (0, _defineProperty2.default)(this, "roomId", void 0);
- (0, _defineProperty2.default)(this, "prefixedLogger", void 0);
- this.roomId = params.roomId;
- this.prefixedLogger = _logger.logger.withPrefix(`[${this.roomId} decryption]`);
- }
-
- /**
- * returns a promise which resolves to a
- * {@link EventDecryptionResult} once we have finished
- * decrypting, or rejects with an `algorithms.DecryptionError` if there is a
- * problem decrypting the event.
- */
- async decryptEvent(event) {
- const content = event.getWireContent();
- if (!content.sender_key || !content.session_id || !content.ciphertext) {
- throw new _base.DecryptionError("MEGOLM_MISSING_FIELDS", "Missing fields in input");
- }
-
- // we add the event to the pending list *before* we start decryption.
- //
- // then, if the key turns up while decryption is in progress (and
- // decryption fails), we will schedule a retry.
- // (fixes https://github.com/vector-im/element-web/issues/5001)
- this.addEventToPendingList(event);
- let res;
- try {
- res = await this.olmDevice.decryptGroupMessage(event.getRoomId(), content.sender_key, content.session_id, content.ciphertext, event.getId(), event.getTs());
- } catch (e) {
- if (e.name === "DecryptionError") {
- // re-throw decryption errors as-is
- throw e;
- }
- let errorCode = "OLM_DECRYPT_GROUP_MESSAGE_ERROR";
- if ((e === null || e === void 0 ? void 0 : e.message) === "OLM.UNKNOWN_MESSAGE_INDEX") {
- this.requestKeysForEvent(event);
- errorCode = "OLM_UNKNOWN_MESSAGE_INDEX";
- }
- throw new _base.DecryptionError(errorCode, e instanceof Error ? e.message : "Unknown Error: Error is undefined", {
- session: content.sender_key + "|" + content.session_id
- });
- }
- if (res === null) {
- // We've got a message for a session we don't have.
- // try and get the missing key from the backup first
- this.crypto.backupManager.queryKeyBackupRateLimited(event.getRoomId(), content.session_id).catch(() => {});
-
- // (XXX: We might actually have received this key since we started
- // decrypting, in which case we'll have scheduled a retry, and this
- // request will be redundant. We could probably check to see if the
- // event is still in the pending list; if not, a retry will have been
- // scheduled, so we needn't send out the request here.)
- this.requestKeysForEvent(event);
-
- // See if there was a problem with the olm session at the time the
- // event was sent. Use a fuzz factor of 2 minutes.
- const problem = await this.olmDevice.sessionMayHaveProblems(content.sender_key, event.getTs() - 120000);
- if (problem) {
- this.prefixedLogger.info(`When handling UISI from ${event.getSender()} (sender key ${content.sender_key}): ` + `recent session problem with that sender:`, problem);
- let problemDescription = PROBLEM_DESCRIPTIONS[problem.type] || PROBLEM_DESCRIPTIONS.unknown;
- if (problem.fixed) {
- problemDescription += " Trying to create a new secure channel and re-requesting the keys.";
- }
- throw new _base.DecryptionError("MEGOLM_UNKNOWN_INBOUND_SESSION_ID", problemDescription, {
- session: content.sender_key + "|" + content.session_id
- });
- }
- throw new _base.DecryptionError("MEGOLM_UNKNOWN_INBOUND_SESSION_ID", "The sender's device has not sent us the keys for this message.", {
- session: content.sender_key + "|" + content.session_id
- });
- }
-
- // Success. We can remove the event from the pending list, if
- // that hasn't already happened. However, if the event was
- // decrypted with an untrusted key, leave it on the pending
- // list so it will be retried if we find a trusted key later.
- if (!res.untrusted) {
- this.removeEventFromPendingList(event);
- }
- const payload = JSON.parse(res.result);
-
- // belt-and-braces check that the room id matches that indicated by the HS
- // (this is somewhat redundant, since the megolm session is scoped to the
- // room, so neither the sender nor a MITM can lie about the room_id).
- if (payload.room_id !== event.getRoomId()) {
- throw new _base.DecryptionError("MEGOLM_BAD_ROOM", "Message intended for room " + payload.room_id);
- }
- return {
- clearEvent: payload,
- senderCurve25519Key: res.senderKey,
- claimedEd25519Key: res.keysClaimed.ed25519,
- forwardingCurve25519KeyChain: res.forwardingCurve25519KeyChain,
- untrusted: res.untrusted
- };
- }
- requestKeysForEvent(event) {
- const wireContent = event.getWireContent();
- const recipients = event.getKeyRequestRecipients(this.userId);
- this.crypto.requestRoomKey({
- room_id: event.getRoomId(),
- algorithm: wireContent.algorithm,
- sender_key: wireContent.sender_key,
- session_id: wireContent.session_id
- }, recipients);
- }
-
- /**
- * Add an event to the list of those awaiting their session keys.
- *
- * @internal
- *
- */
- addEventToPendingList(event) {
- var _senderPendingEvents$;
- const content = event.getWireContent();
- const senderKey = content.sender_key;
- const sessionId = content.session_id;
- if (!this.pendingEvents.has(senderKey)) {
- this.pendingEvents.set(senderKey, new Map());
- }
- const senderPendingEvents = this.pendingEvents.get(senderKey);
- if (!senderPendingEvents.has(sessionId)) {
- senderPendingEvents.set(sessionId, new Set());
- }
- (_senderPendingEvents$ = senderPendingEvents.get(sessionId)) === null || _senderPendingEvents$ === void 0 ? void 0 : _senderPendingEvents$.add(event);
- }
-
- /**
- * Remove an event from the list of those awaiting their session keys.
- *
- * @internal
- *
- */
- removeEventFromPendingList(event) {
- const content = event.getWireContent();
- const senderKey = content.sender_key;
- const sessionId = content.session_id;
- const senderPendingEvents = this.pendingEvents.get(senderKey);
- const pendingEvents = senderPendingEvents === null || senderPendingEvents === void 0 ? void 0 : senderPendingEvents.get(sessionId);
- if (!pendingEvents) {
- return;
- }
- pendingEvents.delete(event);
- if (pendingEvents.size === 0) {
- senderPendingEvents.delete(sessionId);
- }
- if (senderPendingEvents.size === 0) {
- this.pendingEvents.delete(senderKey);
- }
- }
-
- /**
- * Parse a RoomKey out of an `m.room_key` event.
- *
- * @param event - the event containing the room key.
- *
- * @returns The `RoomKey` if it could be successfully parsed out of the
- * event.
- *
- * @internal
- *
- */
- roomKeyFromEvent(event) {
- const senderKey = event.getSenderKey();
- const content = event.getContent();
- const extraSessionData = {};
- if (!content.room_id || !content.session_key || !content.session_id || !content.algorithm) {
- this.prefixedLogger.error("key event is missing fields");
- return;
- }
- if (!olmlib.isOlmEncrypted(event)) {
- this.prefixedLogger.error("key event not properly encrypted");
- return;
- }
- if (content["org.matrix.msc3061.shared_history"]) {
- extraSessionData.sharedHistory = true;
- }
- const roomKey = {
- senderKey: senderKey,
- sessionId: content.session_id,
- sessionKey: content.session_key,
- extraSessionData,
- exportFormat: false,
- roomId: content.room_id,
- algorithm: content.algorithm,
- forwardingKeyChain: [],
- keysClaimed: event.getKeysClaimed()
- };
- return roomKey;
- }
-
- /**
- * Parse a RoomKey out of an `m.forwarded_room_key` event.
- *
- * @param event - the event containing the forwarded room key.
- *
- * @returns The `RoomKey` if it could be successfully parsed out of the
- * event.
- *
- * @internal
- *
- */
- forwardedRoomKeyFromEvent(event) {
- // the properties in m.forwarded_room_key are a superset of those in m.room_key, so
- // start by parsing the m.room_key fields.
- const roomKey = this.roomKeyFromEvent(event);
- if (!roomKey) {
- return;
- }
- const senderKey = event.getSenderKey();
- const content = event.getContent();
- const senderKeyUser = this.baseApis.crypto.deviceList.getUserByIdentityKey(olmlib.OLM_ALGORITHM, senderKey);
-
- // We received this to-device event from event.getSenderKey(), but the original
- // creator of the room key is claimed in the content.
- const claimedCurve25519Key = content.sender_key;
- const claimedEd25519Key = content.sender_claimed_ed25519_key;
- let forwardingKeyChain = Array.isArray(content.forwarding_curve25519_key_chain) ? content.forwarding_curve25519_key_chain : [];
-
- // copy content before we modify it
- forwardingKeyChain = forwardingKeyChain.slice();
- forwardingKeyChain.push(senderKey);
-
- // Check if we have all the fields we need.
- if (senderKeyUser !== event.getSender()) {
- this.prefixedLogger.error("sending device does not belong to the user it claims to be from");
- return;
- }
- if (!claimedCurve25519Key) {
- this.prefixedLogger.error("forwarded_room_key event is missing sender_key field");
- return;
- }
- if (!claimedEd25519Key) {
- this.prefixedLogger.error(`forwarded_room_key_event is missing sender_claimed_ed25519_key field`);
- return;
- }
- const keysClaimed = {
- ed25519: claimedEd25519Key
- };
-
- // FIXME: We're reusing the same field to track both:
- //
- // 1. The Olm identity we've received this room key from.
- // 2. The Olm identity deduced (in the trusted case) or claiming (in the
- // untrusted case) to be the original creator of this room key.
- //
- // We now overwrite the value tracking usage 1 with the value tracking usage 2.
- roomKey.senderKey = claimedCurve25519Key;
- // Replace our keysClaimed as well.
- roomKey.keysClaimed = keysClaimed;
- roomKey.exportFormat = true;
- roomKey.forwardingKeyChain = forwardingKeyChain;
- // forwarded keys are always untrusted
- roomKey.extraSessionData.untrusted = true;
- return roomKey;
- }
-
- /**
- * Determine if we should accept the forwarded room key that was found in the given
- * event.
- *
- * @param event - An `m.forwarded_room_key` event.
- * @param roomKey - The room key that was found in the event.
- *
- * @returns promise that will resolve to a boolean telling us if it's ok to
- * accept the given forwarded room key.
- *
- * @internal
- *
- */
- async shouldAcceptForwardedKey(event, roomKey) {
- var _this$crypto$deviceLi;
- const senderKey = event.getSenderKey();
- const sendingDevice = (_this$crypto$deviceLi = this.crypto.deviceList.getDeviceByIdentityKey(olmlib.OLM_ALGORITHM, senderKey)) !== null && _this$crypto$deviceLi !== void 0 ? _this$crypto$deviceLi : undefined;
- const deviceTrust = this.crypto.checkDeviceInfoTrust(event.getSender(), sendingDevice);
-
- // Using the plaintext sender here is fine since we checked that the
- // sender matches to the user id in the device keys when this event was
- // originally decrypted. This can obviously only happen if the device
- // keys have been downloaded, but if they haven't the
- // `deviceTrust.isVerified()` flag would be false as well.
- //
- // It would still be far nicer if the `sendingDevice` had a user ID
- // attached to it that went through signature checks.
- const fromUs = event.getSender() === this.baseApis.getUserId();
- const keyFromOurVerifiedDevice = deviceTrust.isVerified() && fromUs;
- const weRequested = await this.wasRoomKeyRequested(event, roomKey);
- const fromInviter = this.wasRoomKeyForwardedByInviter(event, roomKey);
- const sharedAsHistory = this.wasRoomKeyForwardedAsHistory(roomKey);
- return weRequested && keyFromOurVerifiedDevice || fromInviter && sharedAsHistory;
- }
-
- /**
- * Did we ever request the given room key from the event sender and its
- * accompanying device.
- *
- * @param event - An `m.forwarded_room_key` event.
- * @param roomKey - The room key that was found in the event.
- *
- * @internal
- *
- */
- async wasRoomKeyRequested(event, roomKey) {
- // We send the `m.room_key_request` out as a wildcard to-device request,
- // otherwise we would have to duplicate the same content for each
- // device. This is why we need to pass in "*" as the device id here.
- const outgoingRequests = await this.crypto.cryptoStore.getOutgoingRoomKeyRequestsByTarget(event.getSender(), "*", [_OutgoingRoomKeyRequestManager.RoomKeyRequestState.Sent]);
- return outgoingRequests.some(req => req.requestBody.room_id === roomKey.roomId && req.requestBody.session_id === roomKey.sessionId);
- }
- wasRoomKeyForwardedByInviter(event, roomKey) {
- var _room$getMember, _memberEvent$getUnsig, _memberEvent$getPrevC;
- // TODO: This is supposed to have a time limit. We should only accept
- // such keys if we happen to receive them for a recently joined room.
- const room = this.baseApis.getRoom(roomKey.roomId);
- const senderKey = event.getSenderKey();
- if (!senderKey) {
- return false;
- }
- const senderKeyUser = this.crypto.deviceList.getUserByIdentityKey(olmlib.OLM_ALGORITHM, senderKey);
- if (!senderKeyUser) {
- return false;
- }
- const memberEvent = room === null || room === void 0 ? void 0 : (_room$getMember = room.getMember(this.userId)) === null || _room$getMember === void 0 ? void 0 : _room$getMember.events.member;
- const fromInviter = (memberEvent === null || memberEvent === void 0 ? void 0 : memberEvent.getSender()) === senderKeyUser || (memberEvent === null || memberEvent === void 0 ? void 0 : (_memberEvent$getUnsig = memberEvent.getUnsigned()) === null || _memberEvent$getUnsig === void 0 ? void 0 : _memberEvent$getUnsig.prev_sender) === senderKeyUser && (memberEvent === null || memberEvent === void 0 ? void 0 : (_memberEvent$getPrevC = memberEvent.getPrevContent()) === null || _memberEvent$getPrevC === void 0 ? void 0 : _memberEvent$getPrevC.membership) === "invite";
- if (room && fromInviter) {
- return true;
- } else {
- return false;
- }
- }
- wasRoomKeyForwardedAsHistory(roomKey) {
- const room = this.baseApis.getRoom(roomKey.roomId);
-
- // If the key is not for a known room, then something fishy is going on,
- // so we reject the key out of caution. In practice, this is a bit moot
- // because we'll only accept shared_history forwarded by the inviter, and
- // we won't know who was the inviter for an unknown room, so we'll reject
- // it anyway.
- if (room && roomKey.extraSessionData.sharedHistory) {
- return true;
- } else {
- return false;
- }
- }
-
- /**
- * Check if a forwarded room key should be parked.
- *
- * A forwarded room key should be parked if it's a key for a room we're not
- * in. We park the forwarded room key in case *this sender* invites us to
- * that room later.
- */
- shouldParkForwardedKey(roomKey) {
- const room = this.baseApis.getRoom(roomKey.roomId);
- if (!room && roomKey.extraSessionData.sharedHistory) {
- return true;
- } else {
- return false;
- }
- }
-
- /**
- * Park the given room key to our store.
- *
- * @param event - An `m.forwarded_room_key` event.
- * @param roomKey - The room key that was found in the event.
- *
- * @internal
- *
- */
- async parkForwardedKey(event, roomKey) {
- const parkedData = {
- senderId: event.getSender(),
- senderKey: roomKey.senderKey,
- sessionId: roomKey.sessionId,
- sessionKey: roomKey.sessionKey,
- keysClaimed: roomKey.keysClaimed,
- forwardingCurve25519KeyChain: roomKey.forwardingKeyChain
- };
- await this.crypto.cryptoStore.doTxn("readwrite", ["parked_shared_history"], txn => this.crypto.cryptoStore.addParkedSharedHistory(roomKey.roomId, parkedData, txn), _logger.logger.withPrefix("[addParkedSharedHistory]"));
- }
-
- /**
- * Add the given room key to our store.
- *
- * @param roomKey - The room key that should be added to the store.
- *
- * @internal
- *
- */
- async addRoomKey(roomKey) {
- try {
- await this.olmDevice.addInboundGroupSession(roomKey.roomId, roomKey.senderKey, roomKey.forwardingKeyChain, roomKey.sessionId, roomKey.sessionKey, roomKey.keysClaimed, roomKey.exportFormat, roomKey.extraSessionData);
-
- // have another go at decrypting events sent with this session.
- if (await this.retryDecryption(roomKey.senderKey, roomKey.sessionId, !roomKey.extraSessionData.untrusted)) {
- // cancel any outstanding room key requests for this session.
- // Only do this if we managed to decrypt every message in the
- // session, because if we didn't, we leave the other key
- // requests in the hopes that someone sends us a key that
- // includes an earlier index.
- this.crypto.cancelRoomKeyRequest({
- algorithm: roomKey.algorithm,
- room_id: roomKey.roomId,
- session_id: roomKey.sessionId,
- sender_key: roomKey.senderKey
- });
- }
-
- // don't wait for the keys to be backed up for the server
- await this.crypto.backupManager.backupGroupSession(roomKey.senderKey, roomKey.sessionId);
- } catch (e) {
- this.prefixedLogger.error(`Error handling m.room_key_event: ${e}`);
- }
- }
-
- /**
- * Handle room keys that have been forwarded to us as an
- * `m.forwarded_room_key` event.
- *
- * Forwarded room keys need special handling since we have no way of knowing
- * who the original creator of the room key was. This naturally means that
- * forwarded room keys are always untrusted and should only be accepted in
- * some cases.
- *
- * @param event - An `m.forwarded_room_key` event.
- *
- * @internal
- *
- */
- async onForwardedRoomKey(event) {
- const roomKey = this.forwardedRoomKeyFromEvent(event);
- if (!roomKey) {
- return;
- }
- if (await this.shouldAcceptForwardedKey(event, roomKey)) {
- await this.addRoomKey(roomKey);
- } else if (this.shouldParkForwardedKey(roomKey)) {
- await this.parkForwardedKey(event, roomKey);
- }
- }
- async onRoomKeyEvent(event) {
- if (event.getType() == "m.forwarded_room_key") {
- await this.onForwardedRoomKey(event);
- } else {
- const roomKey = this.roomKeyFromEvent(event);
- if (!roomKey) {
- return;
- }
- await this.addRoomKey(roomKey);
- }
- }
-
- /**
- * @param event - key event
- */
- async onRoomKeyWithheldEvent(event) {
- const content = event.getContent();
- const senderKey = content.sender_key;
- if (content.code === "m.no_olm") {
- await this.onNoOlmWithheldEvent(event);
- } else if (content.code === "m.unavailable") {
- // this simply means that the other device didn't have the key, which isn't very useful information. Don't
- // record it in the storage
- } else {
- await this.olmDevice.addInboundGroupSessionWithheld(content.room_id, senderKey, content.session_id, content.code, content.reason);
- }
-
- // Having recorded the problem, retry decryption on any affected messages.
- // It's unlikely we'll be able to decrypt sucessfully now, but this will
- // update the error message.
- //
- if (content.session_id) {
- await this.retryDecryption(senderKey, content.session_id);
- } else {
- // no_olm messages aren't specific to a given megolm session, so
- // we trigger retrying decryption for all the messages from the sender's
- // key, so that we can update the error message to indicate the olm
- // session problem.
- await this.retryDecryptionFromSender(senderKey);
- }
- }
- async onNoOlmWithheldEvent(event) {
- const content = event.getContent();
- const senderKey = content.sender_key;
- const sender = event.getSender();
- this.prefixedLogger.warn(`${sender}:${senderKey} was unable to establish an olm session with us`);
- // if the sender says that they haven't been able to establish an olm
- // session, let's proactively establish one
-
- if (await this.olmDevice.getSessionIdForDevice(senderKey)) {
- // a session has already been established, so we don't need to
- // create a new one.
- this.prefixedLogger.debug("New session already created. Not creating a new one.");
- await this.olmDevice.recordSessionProblem(senderKey, "no_olm", true);
- return;
- }
- let device = this.crypto.deviceList.getDeviceByIdentityKey(content.algorithm, senderKey);
- if (!device) {
- // if we don't know about the device, fetch the user's devices again
- // and retry before giving up
- await this.crypto.downloadKeys([sender], false);
- device = this.crypto.deviceList.getDeviceByIdentityKey(content.algorithm, senderKey);
- if (!device) {
- this.prefixedLogger.info("Couldn't find device for identity key " + senderKey + ": not establishing session");
- await this.olmDevice.recordSessionProblem(senderKey, "no_olm", false);
- return;
- }
- }
-
- // XXX: switch this to use encryptAndSendToDevices() rather than duplicating it?
-
- await olmlib.ensureOlmSessionsForDevices(this.olmDevice, this.baseApis, new Map([[sender, [device]]]), false);
- const encryptedContent = {
- algorithm: olmlib.OLM_ALGORITHM,
- sender_key: this.olmDevice.deviceCurve25519Key,
- ciphertext: {},
- [_event.ToDeviceMessageId]: (0, _uuid.v4)()
- };
- await olmlib.encryptMessageForDevice(encryptedContent.ciphertext, this.userId, undefined, this.olmDevice, sender, device, {
- type: "m.dummy"
- });
- await this.olmDevice.recordSessionProblem(senderKey, "no_olm", true);
- await this.baseApis.sendToDevice("m.room.encrypted", new Map([[sender, new Map([[device.deviceId, encryptedContent]])]]));
- }
- hasKeysForKeyRequest(keyRequest) {
- const body = keyRequest.requestBody;
- return this.olmDevice.hasInboundSessionKeys(body.room_id, body.sender_key, body.session_id
- // TODO: ratchet index
- );
- }
-
- shareKeysWithDevice(keyRequest) {
- const userId = keyRequest.userId;
- const deviceId = keyRequest.deviceId;
- const deviceInfo = this.crypto.getStoredDevice(userId, deviceId);
- const body = keyRequest.requestBody;
-
- // XXX: switch this to use encryptAndSendToDevices()?
-
- this.olmlib.ensureOlmSessionsForDevices(this.olmDevice, this.baseApis, new Map([[userId, [deviceInfo]]])).then(devicemap => {
- var _devicemap$get;
- const olmSessionResult = (_devicemap$get = devicemap.get(userId)) === null || _devicemap$get === void 0 ? void 0 : _devicemap$get.get(deviceId);
- if (!(olmSessionResult !== null && olmSessionResult !== void 0 && olmSessionResult.sessionId)) {
- // no session with this device, probably because there
- // were no one-time keys.
- //
- // ensureOlmSessionsForUsers has already done the logging,
- // so just skip it.
- return null;
- }
- this.prefixedLogger.log("sharing keys for session " + body.sender_key + "|" + body.session_id + " with device " + userId + ":" + deviceId);
- return this.buildKeyForwardingMessage(body.room_id, body.sender_key, body.session_id);
- }).then(payload => {
- const encryptedContent = {
- algorithm: olmlib.OLM_ALGORITHM,
- sender_key: this.olmDevice.deviceCurve25519Key,
- ciphertext: {},
- [_event.ToDeviceMessageId]: (0, _uuid.v4)()
- };
- return this.olmlib.encryptMessageForDevice(encryptedContent.ciphertext, this.userId, undefined, this.olmDevice, userId, deviceInfo, payload).then(() => {
- // TODO: retries
- return this.baseApis.sendToDevice("m.room.encrypted", new Map([[userId, new Map([[deviceId, encryptedContent]])]]));
- });
- });
- }
- async buildKeyForwardingMessage(roomId, senderKey, sessionId) {
- const key = await this.olmDevice.getInboundGroupSessionKey(roomId, senderKey, sessionId);
- return {
- type: "m.forwarded_room_key",
- content: {
- "algorithm": olmlib.MEGOLM_ALGORITHM,
- "room_id": roomId,
- "sender_key": senderKey,
- "sender_claimed_ed25519_key": key.sender_claimed_ed25519_key,
- "session_id": sessionId,
- "session_key": key.key,
- "chain_index": key.chain_index,
- "forwarding_curve25519_key_chain": key.forwarding_curve25519_key_chain,
- "org.matrix.msc3061.shared_history": key.shared_history || false
- }
- };
- }
-
- /**
- * @param untrusted - whether the key should be considered as untrusted
- * @param source - where the key came from
- */
- importRoomKey(session, {
- untrusted,
- source
- } = {}) {
- const extraSessionData = {};
- if (untrusted || session.untrusted) {
- extraSessionData.untrusted = true;
- }
- if (session["org.matrix.msc3061.shared_history"]) {
- extraSessionData.sharedHistory = true;
- }
- return this.olmDevice.addInboundGroupSession(session.room_id, session.sender_key, session.forwarding_curve25519_key_chain, session.session_id, session.session_key, session.sender_claimed_keys, true, extraSessionData).then(() => {
- if (source !== "backup") {
- // don't wait for it to complete
- this.crypto.backupManager.backupGroupSession(session.sender_key, session.session_id).catch(e => {
- // This throws if the upload failed, but this is fine
- // since it will have written it to the db and will retry.
- this.prefixedLogger.log("Failed to back up megolm session", e);
- });
- }
- // have another go at decrypting events sent with this session.
- this.retryDecryption(session.sender_key, session.session_id, !extraSessionData.untrusted);
- });
- }
-
- /**
- * Have another go at decrypting events after we receive a key. Resolves once
- * decryption has been re-attempted on all events.
- *
- * @internal
- * @param forceRedecryptIfUntrusted - whether messages that were already
- * successfully decrypted using untrusted keys should be re-decrypted
- *
- * @returns whether all messages were successfully
- * decrypted with trusted keys
- */
- async retryDecryption(senderKey, sessionId, forceRedecryptIfUntrusted) {
- var _this$pendingEvents$g;
- const senderPendingEvents = this.pendingEvents.get(senderKey);
- if (!senderPendingEvents) {
- return true;
- }
- const pending = senderPendingEvents.get(sessionId);
- if (!pending) {
- return true;
- }
- const pendingList = [...pending];
- this.prefixedLogger.debug("Retrying decryption on events:", pendingList.map(e => `${e.getId()}`));
- await Promise.all(pendingList.map(async ev => {
- try {
- await ev.attemptDecryption(this.crypto, {
- isRetry: true,
- forceRedecryptIfUntrusted
- });
- } catch (e) {
- // don't die if something goes wrong
- }
- }));
-
- // If decrypted successfully with trusted keys, they'll have
- // been removed from pendingEvents
- return !((_this$pendingEvents$g = this.pendingEvents.get(senderKey)) !== null && _this$pendingEvents$g !== void 0 && _this$pendingEvents$g.has(sessionId));
- }
- async retryDecryptionFromSender(senderKey) {
- const senderPendingEvents = this.pendingEvents.get(senderKey);
- if (!senderPendingEvents) {
- return true;
- }
- this.pendingEvents.delete(senderKey);
- await Promise.all([...senderPendingEvents].map(async ([_sessionId, pending]) => {
- await Promise.all([...pending].map(async ev => {
- try {
- await ev.attemptDecryption(this.crypto);
- } catch (e) {
- // don't die if something goes wrong
- }
- }));
- }));
- return !this.pendingEvents.has(senderKey);
- }
- async sendSharedHistoryInboundSessions(devicesByUser) {
- await olmlib.ensureOlmSessionsForDevices(this.olmDevice, this.baseApis, devicesByUser);
- const sharedHistorySessions = await this.olmDevice.getSharedHistoryInboundGroupSessions(this.roomId);
- this.prefixedLogger.log(`Sharing history in with users ${Array.from(devicesByUser.keys())}`, sharedHistorySessions.map(([senderKey, sessionId]) => `${senderKey}|${sessionId}`));
- for (const [senderKey, sessionId] of sharedHistorySessions) {
- const payload = await this.buildKeyForwardingMessage(this.roomId, senderKey, sessionId);
-
- // FIXME: use encryptAndSendToDevices() rather than duplicating it here.
- const promises = [];
- const contentMap = new Map();
- for (const [userId, devices] of devicesByUser) {
- const deviceMessages = new Map();
- contentMap.set(userId, deviceMessages);
- for (const deviceInfo of devices) {
- const encryptedContent = {
- algorithm: olmlib.OLM_ALGORITHM,
- sender_key: this.olmDevice.deviceCurve25519Key,
- ciphertext: {},
- [_event.ToDeviceMessageId]: (0, _uuid.v4)()
- };
- deviceMessages.set(deviceInfo.deviceId, encryptedContent);
- promises.push(olmlib.encryptMessageForDevice(encryptedContent.ciphertext, this.userId, undefined, this.olmDevice, userId, deviceInfo, payload));
- }
- }
- await Promise.all(promises);
-
- // prune out any devices that encryptMessageForDevice could not encrypt for,
- // in which case it will have just not added anything to the ciphertext object.
- // There's no point sending messages to devices if we couldn't encrypt to them,
- // since that's effectively a blank message.
- for (const [userId, deviceMessages] of contentMap) {
- for (const [deviceId, content] of deviceMessages) {
- if (!hasCiphertext(content)) {
- this.prefixedLogger.log("No ciphertext for device " + userId + ":" + deviceId + ": pruning");
- deviceMessages.delete(deviceId);
- }
- }
- // No devices left for that user? Strip that too.
- if (deviceMessages.size === 0) {
- this.prefixedLogger.log("Pruned all devices for user " + userId);
- contentMap.delete(userId);
- }
- }
-
- // Is there anything left?
- if (contentMap.size === 0) {
- this.prefixedLogger.log("No users left to send to: aborting");
- return;
- }
- await this.baseApis.sendToDevice("m.room.encrypted", contentMap);
- }
- }
-}
-exports.MegolmDecryption = MegolmDecryption;
-const PROBLEM_DESCRIPTIONS = {
- no_olm: "The sender was unable to establish a secure channel.",
- unknown: "The secure channel with the sender was corrupted."
-};
-(0, _base.registerAlgorithm)(olmlib.MEGOLM_ALGORITHM, MegolmEncryption, MegolmDecryption);
-//# sourceMappingURL=megolm.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/megolm.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/megolm.js.map
deleted file mode 100644
index 27edd8b..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/megolm.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"megolm.js","names":["_uuid","require","_logger","olmlib","_interopRequireWildcard","_base","_OlmDevice","_event","_OutgoingRoomKeyRequestManager","_utils","_getRequireWildcardCache","nodeInterop","WeakMap","cacheBabelInterop","cacheNodeInterop","obj","__esModule","default","cache","has","get","newObj","hasPropertyDescriptor","Object","defineProperty","getOwnPropertyDescriptor","key","prototype","hasOwnProperty","call","desc","set","ownKeys","object","enumerableOnly","keys","getOwnPropertySymbols","symbols","filter","sym","enumerable","push","apply","_objectSpread","target","i","arguments","length","source","forEach","_defineProperty2","getOwnPropertyDescriptors","defineProperties","isRoomSharedHistory","room","_room$currentState","_visibilityEvent$getC","visibilityEvent","currentState","getStateEvents","visibility","getContent","history_visibility","includes","hasCiphertext","content","ciphertext","OutboundSessionInfo","constructor","sessionId","sharedHistory","MapWithDefault","Map","creationTime","Date","getTime","needsRotation","rotationPeriodMsgs","rotationPeriodMs","sessionLifetime","useCount","logger","log","markSharedWithDevice","userId","deviceId","deviceKey","chainIndex","sharedWithDevices","getOrCreate","messageIndex","markNotifiedBlockedDevice","blockedDevicesNotified","sharedWithTooManyDevices","devicesInRoom","devices","_devicesInRoom$get","MegolmEncryption","EncryptionAlgorithm","params","_params$config$rotati","_params$config","_params$config$rotati2","_params$config2","Promise","resolve","roomId","prefixedLogger","withPrefix","sessionRotationPeriodMsgs","config","rotation_period_msgs","sessionRotationPeriodMs","rotation_period_ms","ensureOutboundSession","blocked","singleOlmCreationPhase","setup","oldSession","session","prepareSession","shareSession","fallible","setupPromise","then","catch","e","error","_session","_session2","prepareNewSession","outboundSessions","shareMap","userDevices","deviceInfo","_session$sharedWithDe","getIdentityKey","olmDevice","deviceCurve25519Key","getOutboundGroupSessionKey","payload","type","MEGOLM_ALGORITHM","chain_index","devicesWithoutSession","olmSessions","getExistingOlmSessions","baseApis","all","olmSessionList","Array","from","entries","map","sessionsByUser","flat","debug","shareKeyWithOlmSessions","deviceList","devicesByUser","device","errorDevices","start","now","failedServers","shareKeyWithDevices","retryDevices","failedServerMap","Set","server","add","failedDevices","userHS","slice","indexOf","retryDeviceList","notifyFailedOlmDevices","size","blockedByUser","_deviceInfo","blockedMap","blockedCount","userBlockedDevices","_session$blockedDevic","undefined","notifyBlockedDevices","createOutboundGroupSession","addInboundGroupSession","ed25519","deviceEd25519Key","crypto","backupManager","backupGroupSession","getDevicesWithoutSessions","deviceMap","noOlmDevices","devicesToShareWith","sessionResults","sessionResult","delete","splitDevices","maxDevicesPerRequest","currentSlice","mapSlices","values","pop","encryptAndSendKeysToDevices","encryptAndSendToDevices","sendBlockedNotificationsToDevices","userDeviceMap","contentMap","val","blockedInfo","message","code","reason","ToDeviceMessageId","uuidv4","room_id","session_id","sendToDevice","reshareKeyWithDevice","senderKey","_obSessionInfo$shared","obSessionInfo","sessionSharedData","warn","getInboundGroupSessionKey","ensureOlmSessionsForDevices","sender_claimed_ed25519_key","forwarding_curve25519_key_chain","shared_history","encryptedContent","algorithm","OLM_ALGORITHM","sender_key","encryptMessageForDevice","otkTimeout","devicemap","userDeviceMaps","taskDetail","d","unnotifiedFailedDevices","filterOutNotifiedErrorDevices","WITHHELD_MESSAGES","prepareToEncrypt","Error","encryptionPreparation","elapsedTime","startTime","cancel","cancelled","isCancelled","promise","getDevicesResult","getDevicesInRoom","globalErrorOnUnknownDevices","removeUnknownDevices","encryptMessage","eventType","forceDistributeToUnverified","isVerificationEvent","checkForUnknownDevices","payloadJson","encryptGroupMessage","JSON","stringify","device_id","EventType","KeyVerificationCancel","KeyVerificationDone","KeyVerificationMac","KeyVerificationStart","KeyVerificationKey","KeyVerificationReady","KeyVerificationAccept","RoomMessage","MsgType","KeyVerificationRequest","forceDiscardSession","unknownDevices","isUnverified","isKnown","UnknownDeviceError","members","getEncryptionTargetMembers","shouldEncryptForInvitedMembers","u","membership","roomMembers","isBlacklisting","globalBlacklistUnverifiedDevices","isRoomBlacklisting","getBlacklistUnverifiedDevices","downloadKeys","userDevice","immediate","deviceTrust","checkDeviceTrust","isBlocked","isVerified","blockedDevices","exports","MegolmDecryption","DecryptionAlgorithm","decryptEvent","event","getWireContent","DecryptionError","addEventToPendingList","res","decryptGroupMessage","getRoomId","getId","getTs","name","errorCode","requestKeysForEvent","queryKeyBackupRateLimited","problem","sessionMayHaveProblems","info","getSender","problemDescription","PROBLEM_DESCRIPTIONS","unknown","fixed","untrusted","removeEventFromPendingList","parse","result","clearEvent","senderCurve25519Key","claimedEd25519Key","keysClaimed","forwardingCurve25519KeyChain","wireContent","recipients","getKeyRequestRecipients","requestRoomKey","_senderPendingEvents$","pendingEvents","senderPendingEvents","roomKeyFromEvent","getSenderKey","extraSessionData","session_key","isOlmEncrypted","roomKey","sessionKey","exportFormat","forwardingKeyChain","getKeysClaimed","forwardedRoomKeyFromEvent","senderKeyUser","getUserByIdentityKey","claimedCurve25519Key","isArray","shouldAcceptForwardedKey","_this$crypto$deviceLi","sendingDevice","getDeviceByIdentityKey","checkDeviceInfoTrust","fromUs","getUserId","keyFromOurVerifiedDevice","weRequested","wasRoomKeyRequested","fromInviter","wasRoomKeyForwardedByInviter","sharedAsHistory","wasRoomKeyForwardedAsHistory","outgoingRequests","cryptoStore","getOutgoingRoomKeyRequestsByTarget","RoomKeyRequestState","Sent","some","req","requestBody","_room$getMember","_memberEvent$getUnsig","_memberEvent$getPrevC","getRoom","memberEvent","getMember","events","member","getUnsigned","prev_sender","getPrevContent","shouldParkForwardedKey","parkForwardedKey","parkedData","senderId","doTxn","txn","addParkedSharedHistory","addRoomKey","retryDecryption","cancelRoomKeyRequest","onForwardedRoomKey","onRoomKeyEvent","getType","onRoomKeyWithheldEvent","onNoOlmWithheldEvent","addInboundGroupSessionWithheld","retryDecryptionFromSender","sender","getSessionIdForDevice","recordSessionProblem","hasKeysForKeyRequest","keyRequest","body","hasInboundSessionKeys","shareKeysWithDevice","getStoredDevice","_devicemap$get","olmSessionResult","buildKeyForwardingMessage","importRoomKey","sender_claimed_keys","forceRedecryptIfUntrusted","_this$pendingEvents$g","pending","pendingList","ev","attemptDecryption","isRetry","_sessionId","sendSharedHistoryInboundSessions","sharedHistorySessions","getSharedHistoryInboundGroupSessions","promises","deviceMessages","no_olm","registerAlgorithm"],"sources":["../../../src/crypto/algorithms/megolm.ts"],"sourcesContent":["/*\nCopyright 2015 - 2021, 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n/**\n * Defines m.olm encryption/decryption\n */\n\nimport { v4 as uuidv4 } from \"uuid\";\n\nimport type { IEventDecryptionResult, IMegolmSessionData } from \"../../@types/crypto\";\nimport { logger, PrefixedLogger } from \"../../logger\";\nimport * as olmlib from \"../olmlib\";\nimport {\n DecryptionAlgorithm,\n DecryptionClassParams,\n DecryptionError,\n EncryptionAlgorithm,\n IParams,\n registerAlgorithm,\n UnknownDeviceError,\n} from \"./base\";\nimport { IDecryptedGroupMessage, WITHHELD_MESSAGES } from \"../OlmDevice\";\nimport { Room } from \"../../models/room\";\nimport { DeviceInfo } from \"../deviceinfo\";\nimport { IOlmSessionResult } from \"../olmlib\";\nimport { DeviceInfoMap } from \"../DeviceList\";\nimport { IContent, MatrixEvent } from \"../../models/event\";\nimport { EventType, MsgType, ToDeviceMessageId } from \"../../@types/event\";\nimport { IMegolmEncryptedContent, IncomingRoomKeyRequest, IEncryptedContent } from \"../index\";\nimport { RoomKeyRequestState } from \"../OutgoingRoomKeyRequestManager\";\nimport { OlmGroupSessionExtraData } from \"../../@types/crypto\";\nimport { MatrixError } from \"../../http-api\";\nimport { immediate, MapWithDefault } from \"../../utils\";\n\n// determine whether the key can be shared with invitees\nexport function isRoomSharedHistory(room: Room): boolean {\n const visibilityEvent = room?.currentState?.getStateEvents(\"m.room.history_visibility\", \"\");\n // NOTE: if the room visibility is unset, it would normally default to\n // \"world_readable\".\n // (https://spec.matrix.org/unstable/client-server-api/#server-behaviour-5)\n // But we will be paranoid here, and treat it as a situation where the room\n // is not shared-history\n const visibility = visibilityEvent?.getContent()?.history_visibility;\n return [\"world_readable\", \"shared\"].includes(visibility);\n}\n\ninterface IBlockedDevice {\n code: string;\n reason: string;\n deviceInfo: DeviceInfo;\n}\n\n// map user Id → device Id → IBlockedDevice\ntype BlockedMap = Map<string, Map<string, IBlockedDevice>>;\n\nexport interface IOlmDevice<T = DeviceInfo> {\n userId: string;\n deviceInfo: T;\n}\n\n/**\n * Tests whether an encrypted content has a ciphertext.\n * Ciphertext can be a string or object depending on the content type {@link IEncryptedContent}.\n *\n * @param content - Encrypted content\n * @returns true: has ciphertext, else false\n */\nconst hasCiphertext = (content: IEncryptedContent): boolean => {\n return typeof content.ciphertext === \"string\"\n ? !!content.ciphertext.length\n : !!Object.keys(content.ciphertext).length;\n};\n\n/** The result of parsing the an `m.room_key` or `m.forwarded_room_key` to-device event */\ninterface RoomKey {\n /**\n * The Curve25519 key of the megolm session creator.\n *\n * For `m.room_key`, this is also the sender of the `m.room_key` to-device event.\n * For `m.forwarded_room_key`, the two are different (and the key of the sender of the\n * `m.forwarded_room_key` event is included in `forwardingKeyChain`)\n */\n senderKey: string;\n sessionId: string;\n sessionKey: string;\n exportFormat: boolean;\n roomId: string;\n algorithm: string;\n /**\n * A list of the curve25519 keys of the users involved in forwarding this key, most recent last.\n * For `m.room_key` events, this is empty.\n */\n forwardingKeyChain: string[];\n keysClaimed: Partial<Record<\"ed25519\", string>>;\n extraSessionData: OlmGroupSessionExtraData;\n}\n\nexport interface IOutboundGroupSessionKey {\n chain_index: number;\n key: string;\n}\n\ninterface IMessage {\n type: string;\n content: {\n \"algorithm\": string;\n \"room_id\": string;\n \"sender_key\"?: string;\n \"sender_claimed_ed25519_key\"?: string;\n \"session_id\": string;\n \"session_key\": string;\n \"chain_index\": number;\n \"forwarding_curve25519_key_chain\"?: string[];\n \"org.matrix.msc3061.shared_history\": boolean;\n };\n}\n\ninterface IKeyForwardingMessage extends IMessage {\n type: \"m.forwarded_room_key\";\n}\n\ninterface IPayload extends Partial<IMessage> {\n code?: string;\n reason?: string;\n room_id?: string;\n session_id?: string;\n algorithm?: string;\n sender_key?: string;\n}\n\ninterface SharedWithData {\n // The identity key of the device we shared with\n deviceKey: string;\n // The message index of the ratchet we shared with that device\n messageIndex: number;\n}\n\n/**\n * @internal\n */\nclass OutboundSessionInfo {\n /** number of times this session has been used */\n public useCount = 0;\n /** when the session was created (ms since the epoch) */\n public creationTime: number;\n /** devices with which we have shared the session key `userId -> {deviceId -> SharedWithData}` */\n public sharedWithDevices: MapWithDefault<string, Map<string, SharedWithData>> = new MapWithDefault(() => new Map());\n public blockedDevicesNotified: MapWithDefault<string, Map<string, boolean>> = new MapWithDefault(() => new Map());\n\n /**\n * @param sharedHistory - whether the session can be freely shared with\n * other group members, according to the room history visibility settings\n */\n public constructor(public readonly sessionId: string, public readonly sharedHistory = false) {\n this.creationTime = new Date().getTime();\n }\n\n /**\n * Check if it's time to rotate the session\n */\n public needsRotation(rotationPeriodMsgs: number, rotationPeriodMs: number): boolean {\n const sessionLifetime = new Date().getTime() - this.creationTime;\n\n if (this.useCount >= rotationPeriodMsgs || sessionLifetime >= rotationPeriodMs) {\n logger.log(\"Rotating megolm session after \" + this.useCount + \" messages, \" + sessionLifetime + \"ms\");\n return true;\n }\n\n return false;\n }\n\n public markSharedWithDevice(userId: string, deviceId: string, deviceKey: string, chainIndex: number): void {\n this.sharedWithDevices.getOrCreate(userId).set(deviceId, { deviceKey, messageIndex: chainIndex });\n }\n\n public markNotifiedBlockedDevice(userId: string, deviceId: string): void {\n this.blockedDevicesNotified.getOrCreate(userId).set(deviceId, true);\n }\n\n /**\n * Determine if this session has been shared with devices which it shouldn't\n * have been.\n *\n * @param devicesInRoom - `userId -> {deviceId -> object}`\n * devices we should shared the session with.\n *\n * @returns true if we have shared the session with devices which aren't\n * in devicesInRoom.\n */\n public sharedWithTooManyDevices(devicesInRoom: DeviceInfoMap): boolean {\n for (const [userId, devices] of this.sharedWithDevices) {\n if (!devicesInRoom.has(userId)) {\n logger.log(\"Starting new megolm session because we shared with \" + userId);\n return true;\n }\n\n for (const [deviceId] of devices) {\n if (!devicesInRoom.get(userId)?.get(deviceId)) {\n logger.log(\"Starting new megolm session because we shared with \" + userId + \":\" + deviceId);\n return true;\n }\n }\n }\n\n return false;\n }\n}\n\n/**\n * Megolm encryption implementation\n *\n * @param params - parameters, as per {@link EncryptionAlgorithm}\n */\nexport class MegolmEncryption extends EncryptionAlgorithm {\n // the most recent attempt to set up a session. This is used to serialise\n // the session setups, so that we have a race-free view of which session we\n // are using, and which devices we have shared the keys with. It resolves\n // with an OutboundSessionInfo (or undefined, for the first message in the\n // room).\n private setupPromise = Promise.resolve<OutboundSessionInfo | null>(null);\n\n // Map of outbound sessions by sessions ID. Used if we need a particular\n // session (the session we're currently using to send is always obtained\n // using setupPromise).\n private outboundSessions: Record<string, OutboundSessionInfo> = {};\n\n private readonly sessionRotationPeriodMsgs: number;\n private readonly sessionRotationPeriodMs: number;\n private encryptionPreparation?: {\n promise: Promise<void>;\n startTime: number;\n cancel: () => void;\n };\n\n protected readonly roomId: string;\n private readonly prefixedLogger: PrefixedLogger;\n\n public constructor(params: IParams & Required<Pick<IParams, \"roomId\">>) {\n super(params);\n this.roomId = params.roomId;\n this.prefixedLogger = logger.withPrefix(`[${this.roomId} encryption]`);\n\n this.sessionRotationPeriodMsgs = params.config?.rotation_period_msgs ?? 100;\n this.sessionRotationPeriodMs = params.config?.rotation_period_ms ?? 7 * 24 * 3600 * 1000;\n }\n\n /**\n * @internal\n *\n * @param devicesInRoom - The devices in this room, indexed by user ID\n * @param blocked - The devices that are blocked, indexed by user ID\n * @param singleOlmCreationPhase - Only perform one round of olm\n * session creation\n *\n * This method updates the setupPromise field of the class by chaining a new\n * call on top of the existing promise, and then catching and discarding any\n * errors that might happen while setting up the outbound group session. This\n * is done to ensure that `setupPromise` always resolves to `null` or the\n * `OutboundSessionInfo`.\n *\n * Using `>>=` to represent the promise chaining operation, it does the\n * following:\n *\n * ```\n * setupPromise = previousSetupPromise >>= setup >>= discardErrors\n * ```\n *\n * The initial value for the `setupPromise` is a promise that resolves to\n * `null`. The forceDiscardSession() resets setupPromise to this initial\n * promise.\n *\n * @returns Promise which resolves to the\n * OutboundSessionInfo when setup is complete.\n */\n private async ensureOutboundSession(\n room: Room,\n devicesInRoom: DeviceInfoMap,\n blocked: BlockedMap,\n singleOlmCreationPhase = false,\n ): Promise<OutboundSessionInfo> {\n // takes the previous OutboundSessionInfo, and considers whether to create\n // a new one. Also shares the key with any (new) devices in the room.\n //\n // returns a promise which resolves once the keyshare is successful.\n const setup = async (oldSession: OutboundSessionInfo | null): Promise<OutboundSessionInfo> => {\n const sharedHistory = isRoomSharedHistory(room);\n const session = await this.prepareSession(devicesInRoom, sharedHistory, oldSession);\n\n await this.shareSession(devicesInRoom, sharedHistory, singleOlmCreationPhase, blocked, session);\n\n return session;\n };\n\n // first wait for the previous share to complete\n const fallible = this.setupPromise.then(setup);\n\n // Ensure any failures are logged for debugging and make sure that the\n // promise chain remains unbroken\n //\n // setupPromise resolves to `null` or the `OutboundSessionInfo` whether\n // or not the share succeeds\n this.setupPromise = fallible.catch((e) => {\n this.prefixedLogger.error(`Failed to setup outbound session`, e);\n return null;\n });\n\n // but we return a promise which only resolves if the share was successful.\n return fallible;\n }\n\n private async prepareSession(\n devicesInRoom: DeviceInfoMap,\n sharedHistory: boolean,\n session: OutboundSessionInfo | null,\n ): Promise<OutboundSessionInfo> {\n // history visibility changed\n if (session && sharedHistory !== session.sharedHistory) {\n session = null;\n }\n\n // need to make a brand new session?\n if (session?.needsRotation(this.sessionRotationPeriodMsgs, this.sessionRotationPeriodMs)) {\n this.prefixedLogger.log(\"Starting new megolm session because we need to rotate.\");\n session = null;\n }\n\n // determine if we have shared with anyone we shouldn't have\n if (session?.sharedWithTooManyDevices(devicesInRoom)) {\n session = null;\n }\n\n if (!session) {\n this.prefixedLogger.log(\"Starting new megolm session\");\n session = await this.prepareNewSession(sharedHistory);\n this.prefixedLogger.log(`Started new megolm session ${session.sessionId}`);\n this.outboundSessions[session.sessionId] = session;\n }\n\n return session;\n }\n\n private async shareSession(\n devicesInRoom: DeviceInfoMap,\n sharedHistory: boolean,\n singleOlmCreationPhase: boolean,\n blocked: BlockedMap,\n session: OutboundSessionInfo,\n ): Promise<void> {\n // now check if we need to share with any devices\n const shareMap: Record<string, DeviceInfo[]> = {};\n\n for (const [userId, userDevices] of devicesInRoom) {\n for (const [deviceId, deviceInfo] of userDevices) {\n const key = deviceInfo.getIdentityKey();\n if (key == this.olmDevice.deviceCurve25519Key) {\n // don't bother sending to ourself\n continue;\n }\n\n if (!session.sharedWithDevices.get(userId)?.get(deviceId)) {\n shareMap[userId] = shareMap[userId] || [];\n shareMap[userId].push(deviceInfo);\n }\n }\n }\n\n const key = this.olmDevice.getOutboundGroupSessionKey(session.sessionId);\n const payload: IPayload = {\n type: \"m.room_key\",\n content: {\n \"algorithm\": olmlib.MEGOLM_ALGORITHM,\n \"room_id\": this.roomId,\n \"session_id\": session.sessionId,\n \"session_key\": key.key,\n \"chain_index\": key.chain_index,\n \"org.matrix.msc3061.shared_history\": sharedHistory,\n },\n };\n const [devicesWithoutSession, olmSessions] = await olmlib.getExistingOlmSessions(\n this.olmDevice,\n this.baseApis,\n shareMap,\n );\n\n await Promise.all([\n (async (): Promise<void> => {\n // share keys with devices that we already have a session for\n const olmSessionList = Array.from(olmSessions.entries())\n .map(([userId, sessionsByUser]) =>\n Array.from(sessionsByUser.entries()).map(\n ([deviceId, session]) => `${userId}/${deviceId}: ${session.sessionId}`,\n ),\n )\n .flat(1);\n this.prefixedLogger.debug(\"Sharing keys with devices with existing Olm sessions:\", olmSessionList);\n await this.shareKeyWithOlmSessions(session, key, payload, olmSessions);\n this.prefixedLogger.debug(\"Shared keys with existing Olm sessions\");\n })(),\n (async (): Promise<void> => {\n const deviceList = Array.from(devicesWithoutSession.entries())\n .map(([userId, devicesByUser]) => devicesByUser.map((device) => `${userId}/${device.deviceId}`))\n .flat(1);\n this.prefixedLogger.debug(\n \"Sharing keys (start phase 1) with devices without existing Olm sessions:\",\n deviceList,\n );\n const errorDevices: IOlmDevice[] = [];\n\n // meanwhile, establish olm sessions for devices that we don't\n // already have a session for, and share keys with them. If\n // we're doing two phases of olm session creation, use a\n // shorter timeout when fetching one-time keys for the first\n // phase.\n const start = Date.now();\n const failedServers: string[] = [];\n await this.shareKeyWithDevices(\n session,\n key,\n payload,\n devicesWithoutSession,\n errorDevices,\n singleOlmCreationPhase ? 10000 : 2000,\n failedServers,\n );\n this.prefixedLogger.debug(\"Shared keys (end phase 1) with devices without existing Olm sessions\");\n\n if (!singleOlmCreationPhase && Date.now() - start < 10000) {\n // perform the second phase of olm session creation if requested,\n // and if the first phase didn't take too long\n (async (): Promise<void> => {\n // Retry sending keys to devices that we were unable to establish\n // an olm session for. This time, we use a longer timeout, but we\n // do this in the background and don't block anything else while we\n // do this. We only need to retry users from servers that didn't\n // respond the first time.\n const retryDevices: MapWithDefault<string, DeviceInfo[]> = new MapWithDefault(() => []);\n const failedServerMap = new Set();\n for (const server of failedServers) {\n failedServerMap.add(server);\n }\n const failedDevices: IOlmDevice[] = [];\n for (const { userId, deviceInfo } of errorDevices) {\n const userHS = userId.slice(userId.indexOf(\":\") + 1);\n if (failedServerMap.has(userHS)) {\n retryDevices.getOrCreate(userId).push(deviceInfo);\n } else {\n // if we aren't going to retry, then handle it\n // as a failed device\n failedDevices.push({ userId, deviceInfo });\n }\n }\n\n const retryDeviceList = Array.from(retryDevices.entries())\n .map(([userId, devicesByUser]) =>\n devicesByUser.map((device) => `${userId}/${device.deviceId}`),\n )\n .flat(1);\n\n if (retryDeviceList.length > 0) {\n this.prefixedLogger.debug(\n \"Sharing keys (start phase 2) with devices without existing Olm sessions:\",\n retryDeviceList,\n );\n await this.shareKeyWithDevices(session, key, payload, retryDevices, failedDevices, 30000);\n this.prefixedLogger.debug(\n \"Shared keys (end phase 2) with devices without existing Olm sessions\",\n );\n }\n\n await this.notifyFailedOlmDevices(session, key, failedDevices);\n })();\n } else {\n await this.notifyFailedOlmDevices(session, key, errorDevices);\n }\n })(),\n (async (): Promise<void> => {\n this.prefixedLogger.debug(\n `There are ${blocked.size} blocked devices:`,\n Array.from(blocked.entries())\n .map(([userId, blockedByUser]) =>\n Array.from(blockedByUser.entries()).map(\n ([deviceId, _deviceInfo]) => `${userId}/${deviceId}`,\n ),\n )\n .flat(1),\n );\n\n // also, notify newly blocked devices that they're blocked\n const blockedMap: MapWithDefault<string, Map<string, { device: IBlockedDevice }>> = new MapWithDefault(\n () => new Map(),\n );\n let blockedCount = 0;\n for (const [userId, userBlockedDevices] of blocked) {\n for (const [deviceId, device] of userBlockedDevices) {\n if (session.blockedDevicesNotified.get(userId)?.get(deviceId) === undefined) {\n blockedMap.getOrCreate(userId).set(deviceId, { device });\n blockedCount++;\n }\n }\n }\n\n if (blockedCount) {\n this.prefixedLogger.debug(\n `Notifying ${blockedCount} newly blocked devices:`,\n Array.from(blockedMap.entries())\n .map(([userId, blockedByUser]) =>\n Object.entries(blockedByUser).map(([deviceId, _deviceInfo]) => `${userId}/${deviceId}`),\n )\n .flat(1),\n );\n await this.notifyBlockedDevices(session, blockedMap);\n this.prefixedLogger.debug(`Notified ${blockedCount} newly blocked devices`);\n }\n })(),\n ]);\n }\n\n /**\n * @internal\n *\n *\n * @returns session\n */\n private async prepareNewSession(sharedHistory: boolean): Promise<OutboundSessionInfo> {\n const sessionId = this.olmDevice.createOutboundGroupSession();\n const key = this.olmDevice.getOutboundGroupSessionKey(sessionId);\n\n await this.olmDevice.addInboundGroupSession(\n this.roomId,\n this.olmDevice.deviceCurve25519Key!,\n [],\n sessionId,\n key.key,\n { ed25519: this.olmDevice.deviceEd25519Key! },\n false,\n { sharedHistory },\n );\n\n // don't wait for it to complete\n this.crypto.backupManager.backupGroupSession(this.olmDevice.deviceCurve25519Key!, sessionId);\n\n return new OutboundSessionInfo(sessionId, sharedHistory);\n }\n\n /**\n * Determines what devices in devicesByUser don't have an olm session as given\n * in devicemap.\n *\n * @internal\n *\n * @param deviceMap - the devices that have olm sessions, as returned by\n * olmlib.ensureOlmSessionsForDevices.\n * @param devicesByUser - a map of user IDs to array of deviceInfo\n * @param noOlmDevices - an array to fill with devices that don't have\n * olm sessions\n *\n * @returns an array of devices that don't have olm sessions. If\n * noOlmDevices is specified, then noOlmDevices will be returned.\n */\n private getDevicesWithoutSessions(\n deviceMap: Map<string, Map<string, IOlmSessionResult>>,\n devicesByUser: Map<string, DeviceInfo[]>,\n noOlmDevices: IOlmDevice[] = [],\n ): IOlmDevice[] {\n for (const [userId, devicesToShareWith] of devicesByUser) {\n const sessionResults = deviceMap.get(userId);\n\n for (const deviceInfo of devicesToShareWith) {\n const deviceId = deviceInfo.deviceId;\n\n const sessionResult = sessionResults?.get(deviceId);\n if (!sessionResult?.sessionId) {\n // no session with this device, probably because there\n // were no one-time keys.\n\n noOlmDevices.push({ userId, deviceInfo });\n sessionResults?.delete(deviceId);\n\n // ensureOlmSessionsForUsers has already done the logging,\n // so just skip it.\n continue;\n }\n }\n }\n\n return noOlmDevices;\n }\n\n /**\n * Splits the user device map into multiple chunks to reduce the number of\n * devices we encrypt to per API call.\n *\n * @internal\n *\n * @param devicesByUser - map from userid to list of devices\n *\n * @returns the blocked devices, split into chunks\n */\n private splitDevices<T extends DeviceInfo | IBlockedDevice>(\n devicesByUser: Map<string, Map<string, { device: T }>>,\n ): IOlmDevice<T>[][] {\n const maxDevicesPerRequest = 20;\n\n // use an array where the slices of a content map gets stored\n let currentSlice: IOlmDevice<T>[] = [];\n const mapSlices = [currentSlice];\n\n for (const [userId, userDevices] of devicesByUser) {\n for (const deviceInfo of userDevices.values()) {\n currentSlice.push({\n userId: userId,\n deviceInfo: deviceInfo.device,\n });\n }\n\n // We do this in the per-user loop as we prefer that all messages to the\n // same user end up in the same API call to make it easier for the\n // server (e.g. only have to send one EDU if a remote user, etc). This\n // does mean that if a user has many devices we may go over the desired\n // limit, but its not a hard limit so that is fine.\n if (currentSlice.length > maxDevicesPerRequest) {\n // the current slice is filled up. Start inserting into the next slice\n currentSlice = [];\n mapSlices.push(currentSlice);\n }\n }\n if (currentSlice.length === 0) {\n mapSlices.pop();\n }\n return mapSlices;\n }\n\n /**\n * @internal\n *\n *\n * @param chainIndex - current chain index\n *\n * @param userDeviceMap - mapping from userId to deviceInfo\n *\n * @param payload - fields to include in the encrypted payload\n *\n * @returns Promise which resolves once the key sharing\n * for the given userDeviceMap is generated and has been sent.\n */\n private encryptAndSendKeysToDevices(\n session: OutboundSessionInfo,\n chainIndex: number,\n devices: IOlmDevice[],\n payload: IPayload,\n ): Promise<void> {\n return this.crypto\n .encryptAndSendToDevices(devices, payload)\n .then(() => {\n // store that we successfully uploaded the keys of the current slice\n for (const device of devices) {\n session.markSharedWithDevice(\n device.userId,\n device.deviceInfo.deviceId,\n device.deviceInfo.getIdentityKey(),\n chainIndex,\n );\n }\n })\n .catch((error) => {\n this.prefixedLogger.error(\"failed to encryptAndSendToDevices\", error);\n throw error;\n });\n }\n\n /**\n * @internal\n *\n *\n * @param userDeviceMap - list of blocked devices to notify\n *\n * @param payload - fields to include in the notification payload\n *\n * @returns Promise which resolves once the notifications\n * for the given userDeviceMap is generated and has been sent.\n */\n private async sendBlockedNotificationsToDevices(\n session: OutboundSessionInfo,\n userDeviceMap: IOlmDevice<IBlockedDevice>[],\n payload: IPayload,\n ): Promise<void> {\n const contentMap: MapWithDefault<string, Map<string, IPayload>> = new MapWithDefault(() => new Map());\n\n for (const val of userDeviceMap) {\n const userId = val.userId;\n const blockedInfo = val.deviceInfo;\n const deviceInfo = blockedInfo.deviceInfo;\n const deviceId = deviceInfo.deviceId;\n\n const message = {\n ...payload,\n code: blockedInfo.code,\n reason: blockedInfo.reason,\n [ToDeviceMessageId]: uuidv4(),\n };\n\n if (message.code === \"m.no_olm\") {\n delete message.room_id;\n delete message.session_id;\n }\n\n contentMap.getOrCreate(userId).set(deviceId, message);\n }\n\n await this.baseApis.sendToDevice(\"m.room_key.withheld\", contentMap);\n\n // record the fact that we notified these blocked devices\n for (const [userId, userDeviceMap] of contentMap) {\n for (const deviceId of userDeviceMap.keys()) {\n session.markNotifiedBlockedDevice(userId, deviceId);\n }\n }\n }\n\n /**\n * Re-shares a megolm session key with devices if the key has already been\n * sent to them.\n *\n * @param senderKey - The key of the originating device for the session\n * @param sessionId - ID of the outbound session to share\n * @param userId - ID of the user who owns the target device\n * @param device - The target device\n */\n public async reshareKeyWithDevice(\n senderKey: string,\n sessionId: string,\n userId: string,\n device: DeviceInfo,\n ): Promise<void> {\n const obSessionInfo = this.outboundSessions[sessionId];\n if (!obSessionInfo) {\n this.prefixedLogger.debug(`megolm session ${senderKey}|${sessionId} not found: not re-sharing keys`);\n return;\n }\n\n // The chain index of the key we previously sent this device\n if (!obSessionInfo.sharedWithDevices.has(userId)) {\n this.prefixedLogger.debug(`megolm session ${senderKey}|${sessionId} never shared with user ${userId}`);\n return;\n }\n const sessionSharedData = obSessionInfo.sharedWithDevices.get(userId)?.get(device.deviceId);\n if (sessionSharedData === undefined) {\n this.prefixedLogger.debug(\n `megolm session ${senderKey}|${sessionId} never shared with device ${userId}:${device.deviceId}`,\n );\n return;\n }\n\n if (sessionSharedData.deviceKey !== device.getIdentityKey()) {\n this.prefixedLogger.warn(\n `Megolm session ${senderKey}|${sessionId} has been shared with device ${device.deviceId} but ` +\n `with identity key ${sessionSharedData.deviceKey}. Key is now ${device.getIdentityKey()}!`,\n );\n return;\n }\n\n // get the key from the inbound session: the outbound one will already\n // have been ratcheted to the next chain index.\n const key = await this.olmDevice.getInboundGroupSessionKey(\n this.roomId,\n senderKey,\n sessionId,\n sessionSharedData.messageIndex,\n );\n\n if (!key) {\n this.prefixedLogger.warn(\n `No inbound session key found for megolm session ${senderKey}|${sessionId}: not re-sharing keys`,\n );\n return;\n }\n\n await olmlib.ensureOlmSessionsForDevices(this.olmDevice, this.baseApis, new Map([[userId, [device]]]));\n\n const payload = {\n type: \"m.forwarded_room_key\",\n content: {\n \"algorithm\": olmlib.MEGOLM_ALGORITHM,\n \"room_id\": this.roomId,\n \"session_id\": sessionId,\n \"session_key\": key.key,\n \"chain_index\": key.chain_index,\n \"sender_key\": senderKey,\n \"sender_claimed_ed25519_key\": key.sender_claimed_ed25519_key,\n \"forwarding_curve25519_key_chain\": key.forwarding_curve25519_key_chain,\n \"org.matrix.msc3061.shared_history\": key.shared_history || false,\n },\n };\n\n const encryptedContent: IEncryptedContent = {\n algorithm: olmlib.OLM_ALGORITHM,\n sender_key: this.olmDevice.deviceCurve25519Key!,\n ciphertext: {},\n [ToDeviceMessageId]: uuidv4(),\n };\n await olmlib.encryptMessageForDevice(\n encryptedContent.ciphertext,\n this.userId,\n this.deviceId,\n this.olmDevice,\n userId,\n device,\n payload,\n );\n\n await this.baseApis.sendToDevice(\n \"m.room.encrypted\",\n new Map([[userId, new Map([[device.deviceId, encryptedContent]])]]),\n );\n this.prefixedLogger.debug(\n `Re-shared key for megolm session ${senderKey}|${sessionId} with ${userId}:${device.deviceId}`,\n );\n }\n\n /**\n * @internal\n *\n *\n * @param key - the session key as returned by\n * OlmDevice.getOutboundGroupSessionKey\n *\n * @param payload - the base to-device message payload for sharing keys\n *\n * @param devicesByUser - map from userid to list of devices\n *\n * @param errorDevices - array that will be populated with the devices that we can't get an\n * olm session for\n *\n * @param otkTimeout - The timeout in milliseconds when requesting\n * one-time keys for establishing new olm sessions.\n *\n * @param failedServers - An array to fill with remote servers that\n * failed to respond to one-time-key requests.\n */\n private async shareKeyWithDevices(\n session: OutboundSessionInfo,\n key: IOutboundGroupSessionKey,\n payload: IPayload,\n devicesByUser: Map<string, DeviceInfo[]>,\n errorDevices: IOlmDevice[],\n otkTimeout: number,\n failedServers?: string[],\n ): Promise<void> {\n const devicemap = await olmlib.ensureOlmSessionsForDevices(\n this.olmDevice,\n this.baseApis,\n devicesByUser,\n false,\n otkTimeout,\n failedServers,\n this.prefixedLogger,\n );\n this.getDevicesWithoutSessions(devicemap, devicesByUser, errorDevices);\n await this.shareKeyWithOlmSessions(session, key, payload, devicemap);\n }\n\n private async shareKeyWithOlmSessions(\n session: OutboundSessionInfo,\n key: IOutboundGroupSessionKey,\n payload: IPayload,\n deviceMap: Map<string, Map<string, IOlmSessionResult>>,\n ): Promise<void> {\n const userDeviceMaps = this.splitDevices(deviceMap);\n\n for (let i = 0; i < userDeviceMaps.length; i++) {\n const taskDetail = `megolm keys for ${session.sessionId} (slice ${i + 1}/${userDeviceMaps.length})`;\n try {\n this.prefixedLogger.debug(\n `Sharing ${taskDetail}`,\n userDeviceMaps[i].map((d) => `${d.userId}/${d.deviceInfo.deviceId}`),\n );\n await this.encryptAndSendKeysToDevices(session, key.chain_index, userDeviceMaps[i], payload);\n this.prefixedLogger.debug(`Shared ${taskDetail}`);\n } catch (e) {\n this.prefixedLogger.error(`Failed to share ${taskDetail}`);\n throw e;\n }\n }\n }\n\n /**\n * Notify devices that we weren't able to create olm sessions.\n *\n *\n *\n * @param failedDevices - the devices that we were unable to\n * create olm sessions for, as returned by shareKeyWithDevices\n */\n private async notifyFailedOlmDevices(\n session: OutboundSessionInfo,\n key: IOutboundGroupSessionKey,\n failedDevices: IOlmDevice[],\n ): Promise<void> {\n this.prefixedLogger.debug(`Notifying ${failedDevices.length} devices we failed to create Olm sessions`);\n\n // mark the devices that failed as \"handled\" because we don't want to try\n // to claim a one-time-key for dead devices on every message.\n for (const { userId, deviceInfo } of failedDevices) {\n const deviceId = deviceInfo.deviceId;\n\n session.markSharedWithDevice(userId, deviceId, deviceInfo.getIdentityKey(), key.chain_index);\n }\n\n const unnotifiedFailedDevices = await this.olmDevice.filterOutNotifiedErrorDevices(failedDevices);\n this.prefixedLogger.debug(\n `Need to notify ${unnotifiedFailedDevices.length} failed devices which haven't been notified before`,\n );\n const blockedMap: MapWithDefault<string, Map<string, { device: IBlockedDevice }>> = new MapWithDefault(\n () => new Map(),\n );\n for (const { userId, deviceInfo } of unnotifiedFailedDevices) {\n // we use a similar format to what\n // olmlib.ensureOlmSessionsForDevices returns, so that\n // we can use the same function to split\n blockedMap.getOrCreate(userId).set(deviceInfo.deviceId, {\n device: {\n code: \"m.no_olm\",\n reason: WITHHELD_MESSAGES[\"m.no_olm\"],\n deviceInfo,\n },\n });\n }\n\n // send the notifications\n await this.notifyBlockedDevices(session, blockedMap);\n this.prefixedLogger.debug(\n `Notified ${unnotifiedFailedDevices.length} devices we failed to create Olm sessions`,\n );\n }\n\n /**\n * Notify blocked devices that they have been blocked.\n *\n *\n * @param devicesByUser - map from userid to device ID to blocked data\n */\n private async notifyBlockedDevices(\n session: OutboundSessionInfo,\n devicesByUser: Map<string, Map<string, { device: IBlockedDevice }>>,\n ): Promise<void> {\n const payload: IPayload = {\n room_id: this.roomId,\n session_id: session.sessionId,\n algorithm: olmlib.MEGOLM_ALGORITHM,\n sender_key: this.olmDevice.deviceCurve25519Key!,\n };\n\n const userDeviceMaps = this.splitDevices(devicesByUser);\n\n for (let i = 0; i < userDeviceMaps.length; i++) {\n try {\n await this.sendBlockedNotificationsToDevices(session, userDeviceMaps[i], payload);\n this.prefixedLogger.log(\n `Completed blacklist notification for ${session.sessionId} ` +\n `(slice ${i + 1}/${userDeviceMaps.length})`,\n );\n } catch (e) {\n this.prefixedLogger.log(\n `blacklist notification for ${session.sessionId} ` +\n `(slice ${i + 1}/${userDeviceMaps.length}) failed`,\n );\n\n throw e;\n }\n }\n }\n\n /**\n * Perform any background tasks that can be done before a message is ready to\n * send, in order to speed up sending of the message.\n *\n * @param room - the room the event is in\n * @returns A function that, when called, will stop the preparation\n */\n public prepareToEncrypt(room: Room): () => void {\n if (room.roomId !== this.roomId) {\n throw new Error(\"MegolmEncryption.prepareToEncrypt called on unexpected room\");\n }\n\n if (this.encryptionPreparation != null) {\n // We're already preparing something, so don't do anything else.\n const elapsedTime = Date.now() - this.encryptionPreparation.startTime;\n this.prefixedLogger.debug(\n `Already started preparing to encrypt for this room ${elapsedTime}ms ago, skipping`,\n );\n return this.encryptionPreparation.cancel;\n }\n\n this.prefixedLogger.debug(\"Preparing to encrypt events\");\n\n let cancelled = false;\n const isCancelled = (): boolean => cancelled;\n\n this.encryptionPreparation = {\n startTime: Date.now(),\n promise: (async (): Promise<void> => {\n try {\n // Attempt to enumerate the devices in room, and gracefully\n // handle cancellation if it occurs.\n const getDevicesResult = await this.getDevicesInRoom(room, false, isCancelled);\n if (getDevicesResult === null) return;\n const [devicesInRoom, blocked] = getDevicesResult;\n\n if (this.crypto.globalErrorOnUnknownDevices) {\n // Drop unknown devices for now. When the message gets sent, we'll\n // throw an error, but we'll still be prepared to send to the known\n // devices.\n this.removeUnknownDevices(devicesInRoom);\n }\n\n this.prefixedLogger.debug(\"Ensuring outbound megolm session\");\n await this.ensureOutboundSession(room, devicesInRoom, blocked, true);\n\n this.prefixedLogger.debug(\"Ready to encrypt events\");\n } catch (e) {\n this.prefixedLogger.error(\"Failed to prepare to encrypt events\", e);\n } finally {\n delete this.encryptionPreparation;\n }\n })(),\n\n cancel: (): void => {\n // The caller has indicated that the process should be cancelled,\n // so tell the promise that we'd like to halt, and reset the preparation state.\n cancelled = true;\n delete this.encryptionPreparation;\n },\n };\n\n return this.encryptionPreparation.cancel;\n }\n\n /**\n * @param content - plaintext event content\n *\n * @returns Promise which resolves to the new event body\n */\n public async encryptMessage(room: Room, eventType: string, content: IContent): Promise<IMegolmEncryptedContent> {\n this.prefixedLogger.log(\"Starting to encrypt event\");\n\n if (this.encryptionPreparation != null) {\n // If we started sending keys, wait for it to be done.\n // FIXME: check if we need to cancel\n // (https://github.com/matrix-org/matrix-js-sdk/issues/1255)\n try {\n await this.encryptionPreparation.promise;\n } catch (e) {\n // ignore any errors -- if the preparation failed, we'll just\n // restart everything here\n }\n }\n\n /**\n * When using in-room messages and the room has encryption enabled,\n * clients should ensure that encryption does not hinder the verification.\n */\n const forceDistributeToUnverified = this.isVerificationEvent(eventType, content);\n const [devicesInRoom, blocked] = await this.getDevicesInRoom(room, forceDistributeToUnverified);\n\n // check if any of these devices are not yet known to the user.\n // if so, warn the user so they can verify or ignore.\n if (this.crypto.globalErrorOnUnknownDevices) {\n this.checkForUnknownDevices(devicesInRoom);\n }\n\n const session = await this.ensureOutboundSession(room, devicesInRoom, blocked);\n const payloadJson = {\n room_id: this.roomId,\n type: eventType,\n content: content,\n };\n\n const ciphertext = this.olmDevice.encryptGroupMessage(session.sessionId, JSON.stringify(payloadJson));\n const encryptedContent: IEncryptedContent = {\n algorithm: olmlib.MEGOLM_ALGORITHM,\n sender_key: this.olmDevice.deviceCurve25519Key!,\n ciphertext: ciphertext,\n session_id: session.sessionId,\n // Include our device ID so that recipients can send us a\n // m.new_device message if they don't have our session key.\n // XXX: Do we still need this now that m.new_device messages\n // no longer exist since #483?\n device_id: this.deviceId,\n };\n\n session.useCount++;\n return encryptedContent;\n }\n\n private isVerificationEvent(eventType: string, content: IContent): boolean {\n switch (eventType) {\n case EventType.KeyVerificationCancel:\n case EventType.KeyVerificationDone:\n case EventType.KeyVerificationMac:\n case EventType.KeyVerificationStart:\n case EventType.KeyVerificationKey:\n case EventType.KeyVerificationReady:\n case EventType.KeyVerificationAccept: {\n return true;\n }\n case EventType.RoomMessage: {\n return content[\"msgtype\"] === MsgType.KeyVerificationRequest;\n }\n default: {\n return false;\n }\n }\n }\n\n /**\n * Forces the current outbound group session to be discarded such\n * that another one will be created next time an event is sent.\n *\n * This should not normally be necessary.\n */\n public forceDiscardSession(): void {\n this.setupPromise = this.setupPromise.then(() => null);\n }\n\n /**\n * Checks the devices we're about to send to and see if any are entirely\n * unknown to the user. If so, warn the user, and mark them as known to\n * give the user a chance to go verify them before re-sending this message.\n *\n * @param devicesInRoom - `userId -> {deviceId -> object}`\n * devices we should shared the session with.\n */\n private checkForUnknownDevices(devicesInRoom: DeviceInfoMap): void {\n const unknownDevices: MapWithDefault<string, Map<string, DeviceInfo>> = new MapWithDefault(() => new Map());\n\n for (const [userId, userDevices] of devicesInRoom) {\n for (const [deviceId, device] of userDevices) {\n if (device.isUnverified() && !device.isKnown()) {\n unknownDevices.getOrCreate(userId).set(deviceId, device);\n }\n }\n }\n\n if (unknownDevices.size) {\n // it'd be kind to pass unknownDevices up to the user in this error\n throw new UnknownDeviceError(\n \"This room contains unknown devices which have not been verified. \" +\n \"We strongly recommend you verify them before continuing.\",\n unknownDevices,\n );\n }\n }\n\n /**\n * Remove unknown devices from a set of devices. The devicesInRoom parameter\n * will be modified.\n *\n * @param devicesInRoom - `userId -> {deviceId -> object}`\n * devices we should shared the session with.\n */\n private removeUnknownDevices(devicesInRoom: DeviceInfoMap): void {\n for (const [userId, userDevices] of devicesInRoom) {\n for (const [deviceId, device] of userDevices) {\n if (device.isUnverified() && !device.isKnown()) {\n userDevices.delete(deviceId);\n }\n }\n\n if (userDevices.size === 0) {\n devicesInRoom.delete(userId);\n }\n }\n }\n\n /**\n * Get the list of unblocked devices for all users in the room\n *\n * @param forceDistributeToUnverified - if set to true will include the unverified devices\n * even if setting is set to block them (useful for verification)\n * @param isCancelled - will cause the procedure to abort early if and when it starts\n * returning `true`. If omitted, cancellation won't happen.\n *\n * @returns Promise which resolves to `null`, or an array whose\n * first element is a {@link DeviceInfoMap} indicating\n * the devices that messages should be encrypted to, and whose second\n * element is a map from userId to deviceId to data indicating the devices\n * that are in the room but that have been blocked.\n * If `isCancelled` is provided and returns `true` while processing, `null`\n * will be returned.\n * If `isCancelled` is not provided, the Promise will never resolve to `null`.\n */\n private async getDevicesInRoom(\n room: Room,\n forceDistributeToUnverified?: boolean,\n ): Promise<[DeviceInfoMap, BlockedMap]>;\n private async getDevicesInRoom(\n room: Room,\n forceDistributeToUnverified?: boolean,\n isCancelled?: () => boolean,\n ): Promise<null | [DeviceInfoMap, BlockedMap]>;\n private async getDevicesInRoom(\n room: Room,\n forceDistributeToUnverified = false,\n isCancelled?: () => boolean,\n ): Promise<null | [DeviceInfoMap, BlockedMap]> {\n const members = await room.getEncryptionTargetMembers();\n this.prefixedLogger.debug(\n `Encrypting for users (shouldEncryptForInvitedMembers: ${room.shouldEncryptForInvitedMembers()}):`,\n members.map((u) => `${u.userId} (${u.membership})`),\n );\n\n const roomMembers = members.map(function (u) {\n return u.userId;\n });\n\n // The global value is treated as a default for when rooms don't specify a value.\n let isBlacklisting = this.crypto.globalBlacklistUnverifiedDevices;\n const isRoomBlacklisting = room.getBlacklistUnverifiedDevices();\n if (typeof isRoomBlacklisting === \"boolean\") {\n isBlacklisting = isRoomBlacklisting;\n }\n\n // We are happy to use a cached version here: we assume that if we already\n // have a list of the user's devices, then we already share an e2e room\n // with them, which means that they will have announced any new devices via\n // device_lists in their /sync response. This cache should then be maintained\n // using all the device_lists changes and left fields.\n // See https://github.com/vector-im/element-web/issues/2305 for details.\n const devices = await this.crypto.downloadKeys(roomMembers, false);\n\n if (isCancelled?.() === true) {\n return null;\n }\n\n const blocked = new MapWithDefault<string, Map<string, IBlockedDevice>>(() => new Map());\n // remove any blocked devices\n for (const [userId, userDevices] of devices) {\n for (const [deviceId, userDevice] of userDevices) {\n // Yield prior to checking each device so that we don't block\n // updating/rendering for too long.\n // See https://github.com/vector-im/element-web/issues/21612\n if (isCancelled !== undefined) await immediate();\n if (isCancelled?.() === true) return null;\n const deviceTrust = this.crypto.checkDeviceTrust(userId, deviceId);\n\n if (\n userDevice.isBlocked() ||\n (!deviceTrust.isVerified() && isBlacklisting && !forceDistributeToUnverified)\n ) {\n const blockedDevices = blocked.getOrCreate(userId);\n const isBlocked = userDevice.isBlocked();\n blockedDevices.set(deviceId, {\n code: isBlocked ? \"m.blacklisted\" : \"m.unverified\",\n reason: WITHHELD_MESSAGES[isBlocked ? \"m.blacklisted\" : \"m.unverified\"],\n deviceInfo: userDevice,\n });\n userDevices.delete(deviceId);\n }\n }\n }\n\n return [devices, blocked];\n }\n}\n\n/**\n * Megolm decryption implementation\n *\n * @param params - parameters, as per {@link DecryptionAlgorithm}\n */\nexport class MegolmDecryption extends DecryptionAlgorithm {\n // events which we couldn't decrypt due to unknown sessions /\n // indexes, or which we could only decrypt with untrusted keys:\n // map from senderKey|sessionId to Set of MatrixEvents\n private pendingEvents = new Map<string, Map<string, Set<MatrixEvent>>>();\n\n // this gets stubbed out by the unit tests.\n private olmlib = olmlib;\n\n protected readonly roomId: string;\n private readonly prefixedLogger: PrefixedLogger;\n\n public constructor(params: DecryptionClassParams<IParams & Required<Pick<IParams, \"roomId\">>>) {\n super(params);\n this.roomId = params.roomId;\n this.prefixedLogger = logger.withPrefix(`[${this.roomId} decryption]`);\n }\n\n /**\n * returns a promise which resolves to a\n * {@link EventDecryptionResult} once we have finished\n * decrypting, or rejects with an `algorithms.DecryptionError` if there is a\n * problem decrypting the event.\n */\n public async decryptEvent(event: MatrixEvent): Promise<IEventDecryptionResult> {\n const content = event.getWireContent();\n\n if (!content.sender_key || !content.session_id || !content.ciphertext) {\n throw new DecryptionError(\"MEGOLM_MISSING_FIELDS\", \"Missing fields in input\");\n }\n\n // we add the event to the pending list *before* we start decryption.\n //\n // then, if the key turns up while decryption is in progress (and\n // decryption fails), we will schedule a retry.\n // (fixes https://github.com/vector-im/element-web/issues/5001)\n this.addEventToPendingList(event);\n\n let res: IDecryptedGroupMessage | null;\n try {\n res = await this.olmDevice.decryptGroupMessage(\n event.getRoomId()!,\n content.sender_key,\n content.session_id,\n content.ciphertext,\n event.getId()!,\n event.getTs(),\n );\n } catch (e) {\n if ((<Error>e).name === \"DecryptionError\") {\n // re-throw decryption errors as-is\n throw e;\n }\n\n let errorCode = \"OLM_DECRYPT_GROUP_MESSAGE_ERROR\";\n\n if ((<MatrixError>e)?.message === \"OLM.UNKNOWN_MESSAGE_INDEX\") {\n this.requestKeysForEvent(event);\n\n errorCode = \"OLM_UNKNOWN_MESSAGE_INDEX\";\n }\n\n throw new DecryptionError(errorCode, e instanceof Error ? e.message : \"Unknown Error: Error is undefined\", {\n session: content.sender_key + \"|\" + content.session_id,\n });\n }\n\n if (res === null) {\n // We've got a message for a session we don't have.\n // try and get the missing key from the backup first\n this.crypto.backupManager.queryKeyBackupRateLimited(event.getRoomId(), content.session_id).catch(() => {});\n\n // (XXX: We might actually have received this key since we started\n // decrypting, in which case we'll have scheduled a retry, and this\n // request will be redundant. We could probably check to see if the\n // event is still in the pending list; if not, a retry will have been\n // scheduled, so we needn't send out the request here.)\n this.requestKeysForEvent(event);\n\n // See if there was a problem with the olm session at the time the\n // event was sent. Use a fuzz factor of 2 minutes.\n const problem = await this.olmDevice.sessionMayHaveProblems(content.sender_key, event.getTs() - 120000);\n if (problem) {\n this.prefixedLogger.info(\n `When handling UISI from ${event.getSender()} (sender key ${content.sender_key}): ` +\n `recent session problem with that sender:`,\n problem,\n );\n let problemDescription = PROBLEM_DESCRIPTIONS[problem.type as \"no_olm\"] || PROBLEM_DESCRIPTIONS.unknown;\n if (problem.fixed) {\n problemDescription += \" Trying to create a new secure channel and re-requesting the keys.\";\n }\n throw new DecryptionError(\"MEGOLM_UNKNOWN_INBOUND_SESSION_ID\", problemDescription, {\n session: content.sender_key + \"|\" + content.session_id,\n });\n }\n\n throw new DecryptionError(\n \"MEGOLM_UNKNOWN_INBOUND_SESSION_ID\",\n \"The sender's device has not sent us the keys for this message.\",\n {\n session: content.sender_key + \"|\" + content.session_id,\n },\n );\n }\n\n // Success. We can remove the event from the pending list, if\n // that hasn't already happened. However, if the event was\n // decrypted with an untrusted key, leave it on the pending\n // list so it will be retried if we find a trusted key later.\n if (!res.untrusted) {\n this.removeEventFromPendingList(event);\n }\n\n const payload = JSON.parse(res.result);\n\n // belt-and-braces check that the room id matches that indicated by the HS\n // (this is somewhat redundant, since the megolm session is scoped to the\n // room, so neither the sender nor a MITM can lie about the room_id).\n if (payload.room_id !== event.getRoomId()) {\n throw new DecryptionError(\"MEGOLM_BAD_ROOM\", \"Message intended for room \" + payload.room_id);\n }\n\n return {\n clearEvent: payload,\n senderCurve25519Key: res.senderKey,\n claimedEd25519Key: res.keysClaimed.ed25519,\n forwardingCurve25519KeyChain: res.forwardingCurve25519KeyChain,\n untrusted: res.untrusted,\n };\n }\n\n private requestKeysForEvent(event: MatrixEvent): void {\n const wireContent = event.getWireContent();\n\n const recipients = event.getKeyRequestRecipients(this.userId);\n\n this.crypto.requestRoomKey(\n {\n room_id: event.getRoomId()!,\n algorithm: wireContent.algorithm,\n sender_key: wireContent.sender_key,\n session_id: wireContent.session_id,\n },\n recipients,\n );\n }\n\n /**\n * Add an event to the list of those awaiting their session keys.\n *\n * @internal\n *\n */\n private addEventToPendingList(event: MatrixEvent): void {\n const content = event.getWireContent();\n const senderKey = content.sender_key;\n const sessionId = content.session_id;\n if (!this.pendingEvents.has(senderKey)) {\n this.pendingEvents.set(senderKey, new Map<string, Set<MatrixEvent>>());\n }\n const senderPendingEvents = this.pendingEvents.get(senderKey)!;\n if (!senderPendingEvents.has(sessionId)) {\n senderPendingEvents.set(sessionId, new Set());\n }\n senderPendingEvents.get(sessionId)?.add(event);\n }\n\n /**\n * Remove an event from the list of those awaiting their session keys.\n *\n * @internal\n *\n */\n private removeEventFromPendingList(event: MatrixEvent): void {\n const content = event.getWireContent();\n const senderKey = content.sender_key;\n const sessionId = content.session_id;\n const senderPendingEvents = this.pendingEvents.get(senderKey);\n const pendingEvents = senderPendingEvents?.get(sessionId);\n if (!pendingEvents) {\n return;\n }\n\n pendingEvents.delete(event);\n if (pendingEvents.size === 0) {\n senderPendingEvents!.delete(sessionId);\n }\n if (senderPendingEvents!.size === 0) {\n this.pendingEvents.delete(senderKey);\n }\n }\n\n /**\n * Parse a RoomKey out of an `m.room_key` event.\n *\n * @param event - the event containing the room key.\n *\n * @returns The `RoomKey` if it could be successfully parsed out of the\n * event.\n *\n * @internal\n *\n */\n private roomKeyFromEvent(event: MatrixEvent): RoomKey | undefined {\n const senderKey = event.getSenderKey()!;\n const content = event.getContent<Partial<IMessage[\"content\"]>>();\n const extraSessionData: OlmGroupSessionExtraData = {};\n\n if (!content.room_id || !content.session_key || !content.session_id || !content.algorithm) {\n this.prefixedLogger.error(\"key event is missing fields\");\n return;\n }\n\n if (!olmlib.isOlmEncrypted(event)) {\n this.prefixedLogger.error(\"key event not properly encrypted\");\n return;\n }\n\n if (content[\"org.matrix.msc3061.shared_history\"]) {\n extraSessionData.sharedHistory = true;\n }\n\n const roomKey: RoomKey = {\n senderKey: senderKey,\n sessionId: content.session_id,\n sessionKey: content.session_key,\n extraSessionData,\n exportFormat: false,\n roomId: content.room_id,\n algorithm: content.algorithm,\n forwardingKeyChain: [],\n keysClaimed: event.getKeysClaimed(),\n };\n\n return roomKey;\n }\n\n /**\n * Parse a RoomKey out of an `m.forwarded_room_key` event.\n *\n * @param event - the event containing the forwarded room key.\n *\n * @returns The `RoomKey` if it could be successfully parsed out of the\n * event.\n *\n * @internal\n *\n */\n private forwardedRoomKeyFromEvent(event: MatrixEvent): RoomKey | undefined {\n // the properties in m.forwarded_room_key are a superset of those in m.room_key, so\n // start by parsing the m.room_key fields.\n const roomKey = this.roomKeyFromEvent(event);\n\n if (!roomKey) {\n return;\n }\n\n const senderKey = event.getSenderKey()!;\n const content = event.getContent<Partial<IMessage[\"content\"]>>();\n\n const senderKeyUser = this.baseApis.crypto!.deviceList.getUserByIdentityKey(olmlib.OLM_ALGORITHM, senderKey);\n\n // We received this to-device event from event.getSenderKey(), but the original\n // creator of the room key is claimed in the content.\n const claimedCurve25519Key = content.sender_key;\n const claimedEd25519Key = content.sender_claimed_ed25519_key;\n\n let forwardingKeyChain = Array.isArray(content.forwarding_curve25519_key_chain)\n ? content.forwarding_curve25519_key_chain\n : [];\n\n // copy content before we modify it\n forwardingKeyChain = forwardingKeyChain.slice();\n forwardingKeyChain.push(senderKey);\n\n // Check if we have all the fields we need.\n if (senderKeyUser !== event.getSender()) {\n this.prefixedLogger.error(\"sending device does not belong to the user it claims to be from\");\n return;\n }\n\n if (!claimedCurve25519Key) {\n this.prefixedLogger.error(\"forwarded_room_key event is missing sender_key field\");\n return;\n }\n\n if (!claimedEd25519Key) {\n this.prefixedLogger.error(`forwarded_room_key_event is missing sender_claimed_ed25519_key field`);\n return;\n }\n\n const keysClaimed = {\n ed25519: claimedEd25519Key,\n };\n\n // FIXME: We're reusing the same field to track both:\n //\n // 1. The Olm identity we've received this room key from.\n // 2. The Olm identity deduced (in the trusted case) or claiming (in the\n // untrusted case) to be the original creator of this room key.\n //\n // We now overwrite the value tracking usage 1 with the value tracking usage 2.\n roomKey.senderKey = claimedCurve25519Key;\n // Replace our keysClaimed as well.\n roomKey.keysClaimed = keysClaimed;\n roomKey.exportFormat = true;\n roomKey.forwardingKeyChain = forwardingKeyChain;\n // forwarded keys are always untrusted\n roomKey.extraSessionData.untrusted = true;\n\n return roomKey;\n }\n\n /**\n * Determine if we should accept the forwarded room key that was found in the given\n * event.\n *\n * @param event - An `m.forwarded_room_key` event.\n * @param roomKey - The room key that was found in the event.\n *\n * @returns promise that will resolve to a boolean telling us if it's ok to\n * accept the given forwarded room key.\n *\n * @internal\n *\n */\n private async shouldAcceptForwardedKey(event: MatrixEvent, roomKey: RoomKey): Promise<boolean> {\n const senderKey = event.getSenderKey()!;\n\n const sendingDevice =\n this.crypto.deviceList.getDeviceByIdentityKey(olmlib.OLM_ALGORITHM, senderKey) ?? undefined;\n const deviceTrust = this.crypto.checkDeviceInfoTrust(event.getSender()!, sendingDevice);\n\n // Using the plaintext sender here is fine since we checked that the\n // sender matches to the user id in the device keys when this event was\n // originally decrypted. This can obviously only happen if the device\n // keys have been downloaded, but if they haven't the\n // `deviceTrust.isVerified()` flag would be false as well.\n //\n // It would still be far nicer if the `sendingDevice` had a user ID\n // attached to it that went through signature checks.\n const fromUs = event.getSender() === this.baseApis.getUserId();\n const keyFromOurVerifiedDevice = deviceTrust.isVerified() && fromUs;\n const weRequested = await this.wasRoomKeyRequested(event, roomKey);\n const fromInviter = this.wasRoomKeyForwardedByInviter(event, roomKey);\n const sharedAsHistory = this.wasRoomKeyForwardedAsHistory(roomKey);\n\n return (weRequested && keyFromOurVerifiedDevice) || (fromInviter && sharedAsHistory);\n }\n\n /**\n * Did we ever request the given room key from the event sender and its\n * accompanying device.\n *\n * @param event - An `m.forwarded_room_key` event.\n * @param roomKey - The room key that was found in the event.\n *\n * @internal\n *\n */\n private async wasRoomKeyRequested(event: MatrixEvent, roomKey: RoomKey): Promise<boolean> {\n // We send the `m.room_key_request` out as a wildcard to-device request,\n // otherwise we would have to duplicate the same content for each\n // device. This is why we need to pass in \"*\" as the device id here.\n const outgoingRequests = await this.crypto.cryptoStore.getOutgoingRoomKeyRequestsByTarget(\n event.getSender()!,\n \"*\",\n [RoomKeyRequestState.Sent],\n );\n\n return outgoingRequests.some(\n (req) => req.requestBody.room_id === roomKey.roomId && req.requestBody.session_id === roomKey.sessionId,\n );\n }\n\n private wasRoomKeyForwardedByInviter(event: MatrixEvent, roomKey: RoomKey): boolean {\n // TODO: This is supposed to have a time limit. We should only accept\n // such keys if we happen to receive them for a recently joined room.\n const room = this.baseApis.getRoom(roomKey.roomId);\n const senderKey = event.getSenderKey();\n\n if (!senderKey) {\n return false;\n }\n\n const senderKeyUser = this.crypto.deviceList.getUserByIdentityKey(olmlib.OLM_ALGORITHM, senderKey);\n\n if (!senderKeyUser) {\n return false;\n }\n\n const memberEvent = room?.getMember(this.userId)?.events.member;\n const fromInviter =\n memberEvent?.getSender() === senderKeyUser ||\n (memberEvent?.getUnsigned()?.prev_sender === senderKeyUser &&\n memberEvent?.getPrevContent()?.membership === \"invite\");\n\n if (room && fromInviter) {\n return true;\n } else {\n return false;\n }\n }\n\n private wasRoomKeyForwardedAsHistory(roomKey: RoomKey): boolean {\n const room = this.baseApis.getRoom(roomKey.roomId);\n\n // If the key is not for a known room, then something fishy is going on,\n // so we reject the key out of caution. In practice, this is a bit moot\n // because we'll only accept shared_history forwarded by the inviter, and\n // we won't know who was the inviter for an unknown room, so we'll reject\n // it anyway.\n if (room && roomKey.extraSessionData.sharedHistory) {\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * Check if a forwarded room key should be parked.\n *\n * A forwarded room key should be parked if it's a key for a room we're not\n * in. We park the forwarded room key in case *this sender* invites us to\n * that room later.\n */\n private shouldParkForwardedKey(roomKey: RoomKey): boolean {\n const room = this.baseApis.getRoom(roomKey.roomId);\n\n if (!room && roomKey.extraSessionData.sharedHistory) {\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * Park the given room key to our store.\n *\n * @param event - An `m.forwarded_room_key` event.\n * @param roomKey - The room key that was found in the event.\n *\n * @internal\n *\n */\n private async parkForwardedKey(event: MatrixEvent, roomKey: RoomKey): Promise<void> {\n const parkedData = {\n senderId: event.getSender()!,\n senderKey: roomKey.senderKey,\n sessionId: roomKey.sessionId,\n sessionKey: roomKey.sessionKey,\n keysClaimed: roomKey.keysClaimed,\n forwardingCurve25519KeyChain: roomKey.forwardingKeyChain,\n };\n await this.crypto.cryptoStore.doTxn(\n \"readwrite\",\n [\"parked_shared_history\"],\n (txn) => this.crypto.cryptoStore.addParkedSharedHistory(roomKey.roomId, parkedData, txn),\n logger.withPrefix(\"[addParkedSharedHistory]\"),\n );\n }\n\n /**\n * Add the given room key to our store.\n *\n * @param roomKey - The room key that should be added to the store.\n *\n * @internal\n *\n */\n private async addRoomKey(roomKey: RoomKey): Promise<void> {\n try {\n await this.olmDevice.addInboundGroupSession(\n roomKey.roomId,\n roomKey.senderKey,\n roomKey.forwardingKeyChain,\n roomKey.sessionId,\n roomKey.sessionKey,\n roomKey.keysClaimed,\n roomKey.exportFormat,\n roomKey.extraSessionData,\n );\n\n // have another go at decrypting events sent with this session.\n if (await this.retryDecryption(roomKey.senderKey, roomKey.sessionId, !roomKey.extraSessionData.untrusted)) {\n // cancel any outstanding room key requests for this session.\n // Only do this if we managed to decrypt every message in the\n // session, because if we didn't, we leave the other key\n // requests in the hopes that someone sends us a key that\n // includes an earlier index.\n this.crypto.cancelRoomKeyRequest({\n algorithm: roomKey.algorithm,\n room_id: roomKey.roomId,\n session_id: roomKey.sessionId,\n sender_key: roomKey.senderKey,\n });\n }\n\n // don't wait for the keys to be backed up for the server\n await this.crypto.backupManager.backupGroupSession(roomKey.senderKey, roomKey.sessionId);\n } catch (e) {\n this.prefixedLogger.error(`Error handling m.room_key_event: ${e}`);\n }\n }\n\n /**\n * Handle room keys that have been forwarded to us as an\n * `m.forwarded_room_key` event.\n *\n * Forwarded room keys need special handling since we have no way of knowing\n * who the original creator of the room key was. This naturally means that\n * forwarded room keys are always untrusted and should only be accepted in\n * some cases.\n *\n * @param event - An `m.forwarded_room_key` event.\n *\n * @internal\n *\n */\n private async onForwardedRoomKey(event: MatrixEvent): Promise<void> {\n const roomKey = this.forwardedRoomKeyFromEvent(event);\n\n if (!roomKey) {\n return;\n }\n\n if (await this.shouldAcceptForwardedKey(event, roomKey)) {\n await this.addRoomKey(roomKey);\n } else if (this.shouldParkForwardedKey(roomKey)) {\n await this.parkForwardedKey(event, roomKey);\n }\n }\n\n public async onRoomKeyEvent(event: MatrixEvent): Promise<void> {\n if (event.getType() == \"m.forwarded_room_key\") {\n await this.onForwardedRoomKey(event);\n } else {\n const roomKey = this.roomKeyFromEvent(event);\n\n if (!roomKey) {\n return;\n }\n\n await this.addRoomKey(roomKey);\n }\n }\n\n /**\n * @param event - key event\n */\n public async onRoomKeyWithheldEvent(event: MatrixEvent): Promise<void> {\n const content = event.getContent();\n const senderKey = content.sender_key;\n\n if (content.code === \"m.no_olm\") {\n await this.onNoOlmWithheldEvent(event);\n } else if (content.code === \"m.unavailable\") {\n // this simply means that the other device didn't have the key, which isn't very useful information. Don't\n // record it in the storage\n } else {\n await this.olmDevice.addInboundGroupSessionWithheld(\n content.room_id,\n senderKey,\n content.session_id,\n content.code,\n content.reason,\n );\n }\n\n // Having recorded the problem, retry decryption on any affected messages.\n // It's unlikely we'll be able to decrypt sucessfully now, but this will\n // update the error message.\n //\n if (content.session_id) {\n await this.retryDecryption(senderKey, content.session_id);\n } else {\n // no_olm messages aren't specific to a given megolm session, so\n // we trigger retrying decryption for all the messages from the sender's\n // key, so that we can update the error message to indicate the olm\n // session problem.\n await this.retryDecryptionFromSender(senderKey);\n }\n }\n\n private async onNoOlmWithheldEvent(event: MatrixEvent): Promise<void> {\n const content = event.getContent();\n const senderKey = content.sender_key;\n const sender = event.getSender()!;\n this.prefixedLogger.warn(`${sender}:${senderKey} was unable to establish an olm session with us`);\n // if the sender says that they haven't been able to establish an olm\n // session, let's proactively establish one\n\n if (await this.olmDevice.getSessionIdForDevice(senderKey)) {\n // a session has already been established, so we don't need to\n // create a new one.\n this.prefixedLogger.debug(\"New session already created. Not creating a new one.\");\n await this.olmDevice.recordSessionProblem(senderKey, \"no_olm\", true);\n return;\n }\n let device = this.crypto.deviceList.getDeviceByIdentityKey(content.algorithm, senderKey);\n if (!device) {\n // if we don't know about the device, fetch the user's devices again\n // and retry before giving up\n await this.crypto.downloadKeys([sender], false);\n device = this.crypto.deviceList.getDeviceByIdentityKey(content.algorithm, senderKey);\n if (!device) {\n this.prefixedLogger.info(\n \"Couldn't find device for identity key \" + senderKey + \": not establishing session\",\n );\n await this.olmDevice.recordSessionProblem(senderKey, \"no_olm\", false);\n return;\n }\n }\n\n // XXX: switch this to use encryptAndSendToDevices() rather than duplicating it?\n\n await olmlib.ensureOlmSessionsForDevices(this.olmDevice, this.baseApis, new Map([[sender, [device]]]), false);\n const encryptedContent: IEncryptedContent = {\n algorithm: olmlib.OLM_ALGORITHM,\n sender_key: this.olmDevice.deviceCurve25519Key!,\n ciphertext: {},\n [ToDeviceMessageId]: uuidv4(),\n };\n await olmlib.encryptMessageForDevice(\n encryptedContent.ciphertext,\n this.userId,\n undefined,\n this.olmDevice,\n sender,\n device,\n { type: \"m.dummy\" },\n );\n\n await this.olmDevice.recordSessionProblem(senderKey, \"no_olm\", true);\n\n await this.baseApis.sendToDevice(\n \"m.room.encrypted\",\n new Map([[sender, new Map([[device.deviceId, encryptedContent]])]]),\n );\n }\n\n public hasKeysForKeyRequest(keyRequest: IncomingRoomKeyRequest): Promise<boolean> {\n const body = keyRequest.requestBody;\n\n return this.olmDevice.hasInboundSessionKeys(\n body.room_id,\n body.sender_key,\n body.session_id,\n // TODO: ratchet index\n );\n }\n\n public shareKeysWithDevice(keyRequest: IncomingRoomKeyRequest): void {\n const userId = keyRequest.userId;\n const deviceId = keyRequest.deviceId;\n const deviceInfo = this.crypto.getStoredDevice(userId, deviceId)!;\n const body = keyRequest.requestBody;\n\n // XXX: switch this to use encryptAndSendToDevices()?\n\n this.olmlib\n .ensureOlmSessionsForDevices(this.olmDevice, this.baseApis, new Map([[userId, [deviceInfo]]]))\n .then((devicemap) => {\n const olmSessionResult = devicemap.get(userId)?.get(deviceId);\n if (!olmSessionResult?.sessionId) {\n // no session with this device, probably because there\n // were no one-time keys.\n //\n // ensureOlmSessionsForUsers has already done the logging,\n // so just skip it.\n return null;\n }\n\n this.prefixedLogger.log(\n \"sharing keys for session \" +\n body.sender_key +\n \"|\" +\n body.session_id +\n \" with device \" +\n userId +\n \":\" +\n deviceId,\n );\n\n return this.buildKeyForwardingMessage(body.room_id, body.sender_key, body.session_id);\n })\n .then((payload) => {\n const encryptedContent: IEncryptedContent = {\n algorithm: olmlib.OLM_ALGORITHM,\n sender_key: this.olmDevice.deviceCurve25519Key!,\n ciphertext: {},\n [ToDeviceMessageId]: uuidv4(),\n };\n\n return this.olmlib\n .encryptMessageForDevice(\n encryptedContent.ciphertext,\n this.userId,\n undefined,\n this.olmDevice,\n userId,\n deviceInfo,\n payload!,\n )\n .then(() => {\n // TODO: retries\n return this.baseApis.sendToDevice(\n \"m.room.encrypted\",\n new Map([[userId, new Map([[deviceId, encryptedContent]])]]),\n );\n });\n });\n }\n\n private async buildKeyForwardingMessage(\n roomId: string,\n senderKey: string,\n sessionId: string,\n ): Promise<IKeyForwardingMessage> {\n const key = await this.olmDevice.getInboundGroupSessionKey(roomId, senderKey, sessionId);\n\n return {\n type: \"m.forwarded_room_key\",\n content: {\n \"algorithm\": olmlib.MEGOLM_ALGORITHM,\n \"room_id\": roomId,\n \"sender_key\": senderKey,\n \"sender_claimed_ed25519_key\": key!.sender_claimed_ed25519_key!,\n \"session_id\": sessionId,\n \"session_key\": key!.key,\n \"chain_index\": key!.chain_index,\n \"forwarding_curve25519_key_chain\": key!.forwarding_curve25519_key_chain,\n \"org.matrix.msc3061.shared_history\": key!.shared_history || false,\n },\n };\n }\n\n /**\n * @param untrusted - whether the key should be considered as untrusted\n * @param source - where the key came from\n */\n public importRoomKey(\n session: IMegolmSessionData,\n { untrusted, source }: { untrusted?: boolean; source?: string } = {},\n ): Promise<void> {\n const extraSessionData: OlmGroupSessionExtraData = {};\n if (untrusted || session.untrusted) {\n extraSessionData.untrusted = true;\n }\n if (session[\"org.matrix.msc3061.shared_history\"]) {\n extraSessionData.sharedHistory = true;\n }\n return this.olmDevice\n .addInboundGroupSession(\n session.room_id,\n session.sender_key,\n session.forwarding_curve25519_key_chain,\n session.session_id,\n session.session_key,\n session.sender_claimed_keys,\n true,\n extraSessionData,\n )\n .then(() => {\n if (source !== \"backup\") {\n // don't wait for it to complete\n this.crypto.backupManager.backupGroupSession(session.sender_key, session.session_id).catch((e) => {\n // This throws if the upload failed, but this is fine\n // since it will have written it to the db and will retry.\n this.prefixedLogger.log(\"Failed to back up megolm session\", e);\n });\n }\n // have another go at decrypting events sent with this session.\n this.retryDecryption(session.sender_key, session.session_id, !extraSessionData.untrusted);\n });\n }\n\n /**\n * Have another go at decrypting events after we receive a key. Resolves once\n * decryption has been re-attempted on all events.\n *\n * @internal\n * @param forceRedecryptIfUntrusted - whether messages that were already\n * successfully decrypted using untrusted keys should be re-decrypted\n *\n * @returns whether all messages were successfully\n * decrypted with trusted keys\n */\n private async retryDecryption(\n senderKey: string,\n sessionId: string,\n forceRedecryptIfUntrusted?: boolean,\n ): Promise<boolean> {\n const senderPendingEvents = this.pendingEvents.get(senderKey);\n if (!senderPendingEvents) {\n return true;\n }\n\n const pending = senderPendingEvents.get(sessionId);\n if (!pending) {\n return true;\n }\n\n const pendingList = [...pending];\n this.prefixedLogger.debug(\n \"Retrying decryption on events:\",\n pendingList.map((e) => `${e.getId()}`),\n );\n\n await Promise.all(\n pendingList.map(async (ev) => {\n try {\n await ev.attemptDecryption(this.crypto, { isRetry: true, forceRedecryptIfUntrusted });\n } catch (e) {\n // don't die if something goes wrong\n }\n }),\n );\n\n // If decrypted successfully with trusted keys, they'll have\n // been removed from pendingEvents\n return !this.pendingEvents.get(senderKey)?.has(sessionId);\n }\n\n public async retryDecryptionFromSender(senderKey: string): Promise<boolean> {\n const senderPendingEvents = this.pendingEvents.get(senderKey);\n if (!senderPendingEvents) {\n return true;\n }\n\n this.pendingEvents.delete(senderKey);\n\n await Promise.all(\n [...senderPendingEvents].map(async ([_sessionId, pending]) => {\n await Promise.all(\n [...pending].map(async (ev) => {\n try {\n await ev.attemptDecryption(this.crypto);\n } catch (e) {\n // don't die if something goes wrong\n }\n }),\n );\n }),\n );\n\n return !this.pendingEvents.has(senderKey);\n }\n\n public async sendSharedHistoryInboundSessions(devicesByUser: Map<string, DeviceInfo[]>): Promise<void> {\n await olmlib.ensureOlmSessionsForDevices(this.olmDevice, this.baseApis, devicesByUser);\n\n const sharedHistorySessions = await this.olmDevice.getSharedHistoryInboundGroupSessions(this.roomId);\n this.prefixedLogger.log(\n `Sharing history in with users ${Array.from(devicesByUser.keys())}`,\n sharedHistorySessions.map(([senderKey, sessionId]) => `${senderKey}|${sessionId}`),\n );\n for (const [senderKey, sessionId] of sharedHistorySessions) {\n const payload = await this.buildKeyForwardingMessage(this.roomId, senderKey, sessionId);\n\n // FIXME: use encryptAndSendToDevices() rather than duplicating it here.\n const promises: Promise<unknown>[] = [];\n const contentMap: Map<string, Map<string, IEncryptedContent>> = new Map();\n for (const [userId, devices] of devicesByUser) {\n const deviceMessages = new Map();\n contentMap.set(userId, deviceMessages);\n for (const deviceInfo of devices) {\n const encryptedContent: IEncryptedContent = {\n algorithm: olmlib.OLM_ALGORITHM,\n sender_key: this.olmDevice.deviceCurve25519Key!,\n ciphertext: {},\n [ToDeviceMessageId]: uuidv4(),\n };\n deviceMessages.set(deviceInfo.deviceId, encryptedContent);\n promises.push(\n olmlib.encryptMessageForDevice(\n encryptedContent.ciphertext,\n this.userId,\n undefined,\n this.olmDevice,\n userId,\n deviceInfo,\n payload,\n ),\n );\n }\n }\n await Promise.all(promises);\n\n // prune out any devices that encryptMessageForDevice could not encrypt for,\n // in which case it will have just not added anything to the ciphertext object.\n // There's no point sending messages to devices if we couldn't encrypt to them,\n // since that's effectively a blank message.\n for (const [userId, deviceMessages] of contentMap) {\n for (const [deviceId, content] of deviceMessages) {\n if (!hasCiphertext(content)) {\n this.prefixedLogger.log(\"No ciphertext for device \" + userId + \":\" + deviceId + \": pruning\");\n deviceMessages.delete(deviceId);\n }\n }\n // No devices left for that user? Strip that too.\n if (deviceMessages.size === 0) {\n this.prefixedLogger.log(\"Pruned all devices for user \" + userId);\n contentMap.delete(userId);\n }\n }\n\n // Is there anything left?\n if (contentMap.size === 0) {\n this.prefixedLogger.log(\"No users left to send to: aborting\");\n return;\n }\n\n await this.baseApis.sendToDevice(\"m.room.encrypted\", contentMap);\n }\n }\n}\n\nconst PROBLEM_DESCRIPTIONS = {\n no_olm: \"The sender was unable to establish a secure channel.\",\n unknown: \"The secure channel with the sender was corrupted.\",\n};\n\nregisterAlgorithm(olmlib.MEGOLM_ALGORITHM, MegolmEncryption, MegolmDecryption);\n"],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/olm.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/olm.d.ts
deleted file mode 100644
index 827a070..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/olm.d.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-export interface IMessage {
- type: number;
- body: string;
-}
-//# sourceMappingURL=olm.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/olm.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/olm.d.ts.map
deleted file mode 100644
index 803f3d9..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/olm.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"olm.d.ts","sourceRoot":"","sources":["../../../src/crypto/algorithms/olm.ts"],"names":[],"mappings":"AAgCA,MAAM,WAAW,QAAQ;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CAChB"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/olm.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/olm.js
deleted file mode 100644
index 3b1fb56..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/olm.js
+++ /dev/null
@@ -1,269 +0,0 @@
-"use strict";
-
-var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
-var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
-var _logger = require("../../logger");
-var olmlib = _interopRequireWildcard(require("../olmlib"));
-var _deviceinfo = require("../deviceinfo");
-var _base = require("./base");
-function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
-function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
-/*
-Copyright 2016 - 2021 The Matrix.org Foundation C.I.C.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-/**
- * Defines m.olm encryption/decryption
- */
-
-const DeviceVerification = _deviceinfo.DeviceInfo.DeviceVerification;
-/**
- * Olm encryption implementation
- *
- * @param params - parameters, as per {@link EncryptionAlgorithm}
- */
-class OlmEncryption extends _base.EncryptionAlgorithm {
- constructor(...args) {
- super(...args);
- (0, _defineProperty2.default)(this, "sessionPrepared", false);
- (0, _defineProperty2.default)(this, "prepPromise", null);
- }
- /**
- * @internal
- * @param roomMembers - list of currently-joined users in the room
- * @returns Promise which resolves when setup is complete
- */
- ensureSession(roomMembers) {
- if (this.prepPromise) {
- // prep already in progress
- return this.prepPromise;
- }
- if (this.sessionPrepared) {
- // prep already done
- return Promise.resolve();
- }
- this.prepPromise = this.crypto.downloadKeys(roomMembers).then(() => {
- return this.crypto.ensureOlmSessionsForUsers(roomMembers);
- }).then(() => {
- this.sessionPrepared = true;
- }).finally(() => {
- this.prepPromise = null;
- });
- return this.prepPromise;
- }
-
- /**
- * @param content - plaintext event content
- *
- * @returns Promise which resolves to the new event body
- */
- async encryptMessage(room, eventType, content) {
- // pick the list of recipients based on the membership list.
- //
- // TODO: there is a race condition here! What if a new user turns up
- // just as you are sending a secret message?
-
- const members = await room.getEncryptionTargetMembers();
- const users = members.map(function (u) {
- return u.userId;
- });
- await this.ensureSession(users);
- const payloadFields = {
- room_id: room.roomId,
- type: eventType,
- content: content
- };
- const encryptedContent = {
- algorithm: olmlib.OLM_ALGORITHM,
- sender_key: this.olmDevice.deviceCurve25519Key,
- ciphertext: {}
- };
- const promises = [];
- for (const userId of users) {
- const devices = this.crypto.getStoredDevicesForUser(userId) || [];
- for (const deviceInfo of devices) {
- const key = deviceInfo.getIdentityKey();
- if (key == this.olmDevice.deviceCurve25519Key) {
- // don't bother sending to ourself
- continue;
- }
- if (deviceInfo.verified == DeviceVerification.BLOCKED) {
- // don't bother setting up sessions with blocked users
- continue;
- }
- promises.push(olmlib.encryptMessageForDevice(encryptedContent.ciphertext, this.userId, this.deviceId, this.olmDevice, userId, deviceInfo, payloadFields));
- }
- }
- return Promise.all(promises).then(() => encryptedContent);
- }
-}
-
-/**
- * Olm decryption implementation
- *
- * @param params - parameters, as per {@link DecryptionAlgorithm}
- */
-class OlmDecryption extends _base.DecryptionAlgorithm {
- /**
- * returns a promise which resolves to a
- * {@link EventDecryptionResult} once we have finished
- * decrypting. Rejects with an `algorithms.DecryptionError` if there is a
- * problem decrypting the event.
- */
- async decryptEvent(event) {
- const content = event.getWireContent();
- const deviceKey = content.sender_key;
- const ciphertext = content.ciphertext;
- if (!ciphertext) {
- throw new _base.DecryptionError("OLM_MISSING_CIPHERTEXT", "Missing ciphertext");
- }
- if (!(this.olmDevice.deviceCurve25519Key in ciphertext)) {
- throw new _base.DecryptionError("OLM_NOT_INCLUDED_IN_RECIPIENTS", "Not included in recipients");
- }
- const message = ciphertext[this.olmDevice.deviceCurve25519Key];
- let payloadString;
- try {
- payloadString = await this.decryptMessage(deviceKey, message);
- } catch (e) {
- throw new _base.DecryptionError("OLM_BAD_ENCRYPTED_MESSAGE", "Bad Encrypted Message", {
- sender: deviceKey,
- err: e
- });
- }
- const payload = JSON.parse(payloadString);
-
- // check that we were the intended recipient, to avoid unknown-key attack
- // https://github.com/vector-im/vector-web/issues/2483
- if (payload.recipient != this.userId) {
- throw new _base.DecryptionError("OLM_BAD_RECIPIENT", "Message was intented for " + payload.recipient);
- }
- if (payload.recipient_keys.ed25519 != this.olmDevice.deviceEd25519Key) {
- throw new _base.DecryptionError("OLM_BAD_RECIPIENT_KEY", "Message not intended for this device", {
- intended: payload.recipient_keys.ed25519,
- our_key: this.olmDevice.deviceEd25519Key
- });
- }
-
- // check that the device that encrypted the event belongs to the user
- // that the event claims it's from. We need to make sure that our
- // device list is up-to-date. If the device is unknown, we can only
- // assume that the device logged out. Some event handlers, such as
- // secret sharing, may be more strict and reject events that come from
- // unknown devices.
- await this.crypto.deviceList.downloadKeys([event.getSender()], false);
- const senderKeyUser = this.crypto.deviceList.getUserByIdentityKey(olmlib.OLM_ALGORITHM, deviceKey);
- if (senderKeyUser !== event.getSender() && senderKeyUser != undefined) {
- throw new _base.DecryptionError("OLM_BAD_SENDER", "Message claimed to be from " + event.getSender(), {
- real_sender: senderKeyUser
- });
- }
-
- // check that the original sender matches what the homeserver told us, to
- // avoid people masquerading as others.
- // (this check is also provided via the sender's embedded ed25519 key,
- // which is checked elsewhere).
- if (payload.sender != event.getSender()) {
- throw new _base.DecryptionError("OLM_FORWARDED_MESSAGE", "Message forwarded from " + payload.sender, {
- reported_sender: event.getSender()
- });
- }
-
- // Olm events intended for a room have a room_id.
- if (payload.room_id !== event.getRoomId()) {
- throw new _base.DecryptionError("OLM_BAD_ROOM", "Message intended for room " + payload.room_id, {
- reported_room: event.getRoomId() || "ROOM_ID_UNDEFINED"
- });
- }
- const claimedKeys = payload.keys || {};
- return {
- clearEvent: payload,
- senderCurve25519Key: deviceKey,
- claimedEd25519Key: claimedKeys.ed25519 || null
- };
- }
-
- /**
- * Attempt to decrypt an Olm message
- *
- * @param theirDeviceIdentityKey - Curve25519 identity key of the sender
- * @param message - message object, with 'type' and 'body' fields
- *
- * @returns payload, if decrypted successfully.
- */
- decryptMessage(theirDeviceIdentityKey, message) {
- // This is a wrapper that serialises decryptions of prekey messages, because
- // otherwise we race between deciding we have no active sessions for the message
- // and creating a new one, which we can only do once because it removes the OTK.
- if (message.type !== 0) {
- // not a prekey message: we can safely just try & decrypt it
- return this.reallyDecryptMessage(theirDeviceIdentityKey, message);
- } else {
- const myPromise = this.olmDevice.olmPrekeyPromise.then(() => {
- return this.reallyDecryptMessage(theirDeviceIdentityKey, message);
- });
- // we want the error, but don't propagate it to the next decryption
- this.olmDevice.olmPrekeyPromise = myPromise.catch(() => {});
- return myPromise;
- }
- }
- async reallyDecryptMessage(theirDeviceIdentityKey, message) {
- const sessionIds = await this.olmDevice.getSessionIdsForDevice(theirDeviceIdentityKey);
-
- // try each session in turn.
- const decryptionErrors = {};
- for (const sessionId of sessionIds) {
- try {
- const payload = await this.olmDevice.decryptMessage(theirDeviceIdentityKey, sessionId, message.type, message.body);
- _logger.logger.log("Decrypted Olm message from " + theirDeviceIdentityKey + " with session " + sessionId);
- return payload;
- } catch (e) {
- const foundSession = await this.olmDevice.matchesSession(theirDeviceIdentityKey, sessionId, message.type, message.body);
- if (foundSession) {
- // decryption failed, but it was a prekey message matching this
- // session, so it should have worked.
- throw new Error("Error decrypting prekey message with existing session id " + sessionId + ": " + e.message);
- }
-
- // otherwise it's probably a message for another session; carry on, but
- // keep a record of the error
- decryptionErrors[sessionId] = e.message;
- }
- }
- if (message.type !== 0) {
- // not a prekey message, so it should have matched an existing session, but it
- // didn't work.
-
- if (sessionIds.length === 0) {
- throw new Error("No existing sessions");
- }
- throw new Error("Error decrypting non-prekey message with existing sessions: " + JSON.stringify(decryptionErrors));
- }
-
- // prekey message which doesn't match any existing sessions: make a new
- // session.
-
- let res;
- try {
- res = await this.olmDevice.createInboundSession(theirDeviceIdentityKey, message.type, message.body);
- } catch (e) {
- decryptionErrors["(new)"] = e.message;
- throw new Error("Error decrypting prekey message: " + JSON.stringify(decryptionErrors));
- }
- _logger.logger.log("created new inbound Olm session ID " + res.session_id + " with " + theirDeviceIdentityKey);
- return res.payload;
- }
-}
-(0, _base.registerAlgorithm)(olmlib.OLM_ALGORITHM, OlmEncryption, OlmDecryption);
-//# sourceMappingURL=olm.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/olm.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/olm.js.map
deleted file mode 100644
index a760ab6..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/algorithms/olm.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"olm.js","names":["_logger","require","olmlib","_interopRequireWildcard","_deviceinfo","_base","_getRequireWildcardCache","nodeInterop","WeakMap","cacheBabelInterop","cacheNodeInterop","obj","__esModule","default","cache","has","get","newObj","hasPropertyDescriptor","Object","defineProperty","getOwnPropertyDescriptor","key","prototype","hasOwnProperty","call","desc","set","DeviceVerification","DeviceInfo","OlmEncryption","EncryptionAlgorithm","constructor","args","_defineProperty2","ensureSession","roomMembers","prepPromise","sessionPrepared","Promise","resolve","crypto","downloadKeys","then","ensureOlmSessionsForUsers","finally","encryptMessage","room","eventType","content","members","getEncryptionTargetMembers","users","map","u","userId","payloadFields","room_id","roomId","type","encryptedContent","algorithm","OLM_ALGORITHM","sender_key","olmDevice","deviceCurve25519Key","ciphertext","promises","devices","getStoredDevicesForUser","deviceInfo","getIdentityKey","verified","BLOCKED","push","encryptMessageForDevice","deviceId","all","OlmDecryption","DecryptionAlgorithm","decryptEvent","event","getWireContent","deviceKey","DecryptionError","message","payloadString","decryptMessage","e","sender","err","payload","JSON","parse","recipient","recipient_keys","ed25519","deviceEd25519Key","intended","our_key","deviceList","getSender","senderKeyUser","getUserByIdentityKey","undefined","real_sender","reported_sender","getRoomId","reported_room","claimedKeys","keys","clearEvent","senderCurve25519Key","claimedEd25519Key","theirDeviceIdentityKey","reallyDecryptMessage","myPromise","olmPrekeyPromise","catch","sessionIds","getSessionIdsForDevice","decryptionErrors","sessionId","body","logger","log","foundSession","matchesSession","Error","length","stringify","res","createInboundSession","session_id","registerAlgorithm"],"sources":["../../../src/crypto/algorithms/olm.ts"],"sourcesContent":["/*\nCopyright 2016 - 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n/**\n * Defines m.olm encryption/decryption\n */\n\nimport type { IEventDecryptionResult } from \"../../@types/crypto\";\nimport { logger } from \"../../logger\";\nimport * as olmlib from \"../olmlib\";\nimport { DeviceInfo } from \"../deviceinfo\";\nimport { DecryptionAlgorithm, DecryptionError, EncryptionAlgorithm, registerAlgorithm } from \"./base\";\nimport { Room } from \"../../models/room\";\nimport { IContent, MatrixEvent } from \"../../models/event\";\nimport { IEncryptedContent, IOlmEncryptedContent } from \"../index\";\nimport { IInboundSession } from \"../OlmDevice\";\n\nconst DeviceVerification = DeviceInfo.DeviceVerification;\n\nexport interface IMessage {\n type: number;\n body: string;\n}\n\n/**\n * Olm encryption implementation\n *\n * @param params - parameters, as per {@link EncryptionAlgorithm}\n */\nclass OlmEncryption extends EncryptionAlgorithm {\n private sessionPrepared = false;\n private prepPromise: Promise<void> | null = null;\n\n /**\n * @internal\n\n * @param roomMembers - list of currently-joined users in the room\n * @returns Promise which resolves when setup is complete\n */\n private ensureSession(roomMembers: string[]): Promise<void> {\n if (this.prepPromise) {\n // prep already in progress\n return this.prepPromise;\n }\n\n if (this.sessionPrepared) {\n // prep already done\n return Promise.resolve();\n }\n\n this.prepPromise = this.crypto\n .downloadKeys(roomMembers)\n .then(() => {\n return this.crypto.ensureOlmSessionsForUsers(roomMembers);\n })\n .then(() => {\n this.sessionPrepared = true;\n })\n .finally(() => {\n this.prepPromise = null;\n });\n\n return this.prepPromise;\n }\n\n /**\n * @param content - plaintext event content\n *\n * @returns Promise which resolves to the new event body\n */\n public async encryptMessage(room: Room, eventType: string, content: IContent): Promise<IOlmEncryptedContent> {\n // pick the list of recipients based on the membership list.\n //\n // TODO: there is a race condition here! What if a new user turns up\n // just as you are sending a secret message?\n\n const members = await room.getEncryptionTargetMembers();\n\n const users = members.map(function (u) {\n return u.userId;\n });\n\n await this.ensureSession(users);\n\n const payloadFields = {\n room_id: room.roomId,\n type: eventType,\n content: content,\n };\n\n const encryptedContent: IEncryptedContent = {\n algorithm: olmlib.OLM_ALGORITHM,\n sender_key: this.olmDevice.deviceCurve25519Key!,\n ciphertext: {},\n };\n\n const promises: Promise<void>[] = [];\n\n for (const userId of users) {\n const devices = this.crypto.getStoredDevicesForUser(userId) || [];\n\n for (const deviceInfo of devices) {\n const key = deviceInfo.getIdentityKey();\n if (key == this.olmDevice.deviceCurve25519Key) {\n // don't bother sending to ourself\n continue;\n }\n if (deviceInfo.verified == DeviceVerification.BLOCKED) {\n // don't bother setting up sessions with blocked users\n continue;\n }\n\n promises.push(\n olmlib.encryptMessageForDevice(\n encryptedContent.ciphertext,\n this.userId,\n this.deviceId,\n this.olmDevice,\n userId,\n deviceInfo,\n payloadFields,\n ),\n );\n }\n }\n\n return Promise.all(promises).then(() => encryptedContent);\n }\n}\n\n/**\n * Olm decryption implementation\n *\n * @param params - parameters, as per {@link DecryptionAlgorithm}\n */\nclass OlmDecryption extends DecryptionAlgorithm {\n /**\n * returns a promise which resolves to a\n * {@link EventDecryptionResult} once we have finished\n * decrypting. Rejects with an `algorithms.DecryptionError` if there is a\n * problem decrypting the event.\n */\n public async decryptEvent(event: MatrixEvent): Promise<IEventDecryptionResult> {\n const content = event.getWireContent();\n const deviceKey = content.sender_key;\n const ciphertext = content.ciphertext;\n\n if (!ciphertext) {\n throw new DecryptionError(\"OLM_MISSING_CIPHERTEXT\", \"Missing ciphertext\");\n }\n\n if (!(this.olmDevice.deviceCurve25519Key! in ciphertext)) {\n throw new DecryptionError(\"OLM_NOT_INCLUDED_IN_RECIPIENTS\", \"Not included in recipients\");\n }\n const message = ciphertext[this.olmDevice.deviceCurve25519Key!];\n let payloadString: string;\n\n try {\n payloadString = await this.decryptMessage(deviceKey, message);\n } catch (e) {\n throw new DecryptionError(\"OLM_BAD_ENCRYPTED_MESSAGE\", \"Bad Encrypted Message\", {\n sender: deviceKey,\n err: e as Error,\n });\n }\n\n const payload = JSON.parse(payloadString);\n\n // check that we were the intended recipient, to avoid unknown-key attack\n // https://github.com/vector-im/vector-web/issues/2483\n if (payload.recipient != this.userId) {\n throw new DecryptionError(\"OLM_BAD_RECIPIENT\", \"Message was intented for \" + payload.recipient);\n }\n\n if (payload.recipient_keys.ed25519 != this.olmDevice.deviceEd25519Key) {\n throw new DecryptionError(\"OLM_BAD_RECIPIENT_KEY\", \"Message not intended for this device\", {\n intended: payload.recipient_keys.ed25519,\n our_key: this.olmDevice.deviceEd25519Key!,\n });\n }\n\n // check that the device that encrypted the event belongs to the user\n // that the event claims it's from. We need to make sure that our\n // device list is up-to-date. If the device is unknown, we can only\n // assume that the device logged out. Some event handlers, such as\n // secret sharing, may be more strict and reject events that come from\n // unknown devices.\n await this.crypto.deviceList.downloadKeys([event.getSender()!], false);\n const senderKeyUser = this.crypto.deviceList.getUserByIdentityKey(olmlib.OLM_ALGORITHM, deviceKey);\n if (senderKeyUser !== event.getSender() && senderKeyUser != undefined) {\n throw new DecryptionError(\"OLM_BAD_SENDER\", \"Message claimed to be from \" + event.getSender(), {\n real_sender: senderKeyUser,\n });\n }\n\n // check that the original sender matches what the homeserver told us, to\n // avoid people masquerading as others.\n // (this check is also provided via the sender's embedded ed25519 key,\n // which is checked elsewhere).\n if (payload.sender != event.getSender()) {\n throw new DecryptionError(\"OLM_FORWARDED_MESSAGE\", \"Message forwarded from \" + payload.sender, {\n reported_sender: event.getSender()!,\n });\n }\n\n // Olm events intended for a room have a room_id.\n if (payload.room_id !== event.getRoomId()) {\n throw new DecryptionError(\"OLM_BAD_ROOM\", \"Message intended for room \" + payload.room_id, {\n reported_room: event.getRoomId() || \"ROOM_ID_UNDEFINED\",\n });\n }\n\n const claimedKeys = payload.keys || {};\n\n return {\n clearEvent: payload,\n senderCurve25519Key: deviceKey,\n claimedEd25519Key: claimedKeys.ed25519 || null,\n };\n }\n\n /**\n * Attempt to decrypt an Olm message\n *\n * @param theirDeviceIdentityKey - Curve25519 identity key of the sender\n * @param message - message object, with 'type' and 'body' fields\n *\n * @returns payload, if decrypted successfully.\n */\n private decryptMessage(theirDeviceIdentityKey: string, message: IMessage): Promise<string> {\n // This is a wrapper that serialises decryptions of prekey messages, because\n // otherwise we race between deciding we have no active sessions for the message\n // and creating a new one, which we can only do once because it removes the OTK.\n if (message.type !== 0) {\n // not a prekey message: we can safely just try & decrypt it\n return this.reallyDecryptMessage(theirDeviceIdentityKey, message);\n } else {\n const myPromise = this.olmDevice.olmPrekeyPromise.then(() => {\n return this.reallyDecryptMessage(theirDeviceIdentityKey, message);\n });\n // we want the error, but don't propagate it to the next decryption\n this.olmDevice.olmPrekeyPromise = myPromise.catch(() => {});\n return myPromise;\n }\n }\n\n private async reallyDecryptMessage(theirDeviceIdentityKey: string, message: IMessage): Promise<string> {\n const sessionIds = await this.olmDevice.getSessionIdsForDevice(theirDeviceIdentityKey);\n\n // try each session in turn.\n const decryptionErrors: Record<string, string> = {};\n for (const sessionId of sessionIds) {\n try {\n const payload = await this.olmDevice.decryptMessage(\n theirDeviceIdentityKey,\n sessionId,\n message.type,\n message.body,\n );\n logger.log(\"Decrypted Olm message from \" + theirDeviceIdentityKey + \" with session \" + sessionId);\n return payload;\n } catch (e) {\n const foundSession = await this.olmDevice.matchesSession(\n theirDeviceIdentityKey,\n sessionId,\n message.type,\n message.body,\n );\n\n if (foundSession) {\n // decryption failed, but it was a prekey message matching this\n // session, so it should have worked.\n throw new Error(\n \"Error decrypting prekey message with existing session id \" +\n sessionId +\n \": \" +\n (<Error>e).message,\n );\n }\n\n // otherwise it's probably a message for another session; carry on, but\n // keep a record of the error\n decryptionErrors[sessionId] = (<Error>e).message;\n }\n }\n\n if (message.type !== 0) {\n // not a prekey message, so it should have matched an existing session, but it\n // didn't work.\n\n if (sessionIds.length === 0) {\n throw new Error(\"No existing sessions\");\n }\n\n throw new Error(\n \"Error decrypting non-prekey message with existing sessions: \" + JSON.stringify(decryptionErrors),\n );\n }\n\n // prekey message which doesn't match any existing sessions: make a new\n // session.\n\n let res: IInboundSession;\n try {\n res = await this.olmDevice.createInboundSession(theirDeviceIdentityKey, message.type, message.body);\n } catch (e) {\n decryptionErrors[\"(new)\"] = (<Error>e).message;\n throw new Error(\"Error decrypting prekey message: \" + JSON.stringify(decryptionErrors));\n }\n\n logger.log(\"created new inbound Olm session ID \" + res.session_id + \" with \" + theirDeviceIdentityKey);\n return res.payload;\n }\n}\n\nregisterAlgorithm(olmlib.OLM_ALGORITHM, OlmEncryption, OlmDecryption);\n"],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/api.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/api.d.ts
deleted file mode 100644
index a01a697..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/api.d.ts
+++ /dev/null
@@ -1,89 +0,0 @@
-import { DeviceInfo } from "./deviceinfo";
-import { IKeyBackupInfo } from "./keybackup";
-import { PassphraseInfo } from "../secret-storage";
-export { PassphraseInfo as IPassphraseInfo, SecretStorageKeyDescription as ISecretStorageKeyInfo, } from "../secret-storage";
-export declare enum CrossSigningKey {
- Master = "master",
- SelfSigning = "self_signing",
- UserSigning = "user_signing"
-}
-export interface IEncryptedEventInfo {
- /**
- * whether the event is encrypted (if not encrypted, some of the other properties may not be set)
- */
- encrypted: boolean;
- /**
- * the sender's key
- */
- senderKey: string;
- /**
- * the algorithm used to encrypt the event
- */
- algorithm: string;
- /**
- * whether we can be sure that the owner of the senderKey sent the event
- */
- authenticated: boolean;
- /**
- * the sender's device information, if available
- */
- sender?: DeviceInfo;
- /**
- * if the event's ed25519 and curve25519 keys don't match (only meaningful if `sender` is set)
- */
- mismatchedSender: boolean;
-}
-export interface IRecoveryKey {
- keyInfo?: IAddSecretStorageKeyOpts;
- privateKey: Uint8Array;
- encodedPrivateKey?: string;
-}
-export interface ICreateSecretStorageOpts {
- /**
- * Function called to await a secret storage key creation flow.
- * @returns Promise resolving to an object with public key metadata, encoded private
- * recovery key which should be disposed of after displaying to the user,
- * and raw private key to avoid round tripping if needed.
- */
- createSecretStorageKey?: () => Promise<IRecoveryKey>;
- /**
- * The current key backup object. If passed,
- * the passphrase and recovery key from this backup will be used.
- */
- keyBackupInfo?: IKeyBackupInfo;
- /**
- * If true, a new key backup version will be
- * created and the private key stored in the new SSSS store. Ignored if keyBackupInfo
- * is supplied.
- */
- setupNewKeyBackup?: boolean;
- /**
- * Reset even if keys already exist.
- */
- setupNewSecretStorage?: boolean;
- /**
- * Function called to get the user's
- * current key backup passphrase. Should return a promise that resolves with a Uint8Array
- * containing the key, or rejects if the key cannot be obtained.
- */
- getKeyBackupPassphrase?: () => Promise<Uint8Array>;
-}
-export interface IAddSecretStorageKeyOpts {
- pubkey?: string;
- passphrase?: PassphraseInfo;
- name?: string;
- key?: Uint8Array;
-}
-export interface IImportOpts {
- stage: string;
- successes: number;
- failures: number;
- total: number;
-}
-export interface IImportRoomKeysOpts {
- /** called with an object that has a "stage" param */
- progressCallback?: (stage: IImportOpts) => void;
- untrusted?: boolean;
- source?: string;
-}
-//# sourceMappingURL=api.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/api.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/api.d.ts.map
deleted file mode 100644
index ceeb45b..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/api.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/crypto/api.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGnD,OAAO,EACH,cAAc,IAAI,eAAe,EACjC,2BAA2B,IAAI,qBAAqB,GACvD,MAAM,mBAAmB,CAAC;AAI3B,oBAAY,eAAe;IACvB,MAAM,WAAW;IACjB,WAAW,iBAAiB;IAC5B,WAAW,iBAAiB;CAC/B;AAED,MAAM,WAAW,mBAAmB;IAChC;;OAEG;IACH,SAAS,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,aAAa,EAAE,OAAO,CAAC;IAEvB;;OAEG;IACH,MAAM,CAAC,EAAE,UAAU,CAAC;IAEpB;;OAEG;IACH,gBAAgB,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,YAAY;IACzB,OAAO,CAAC,EAAE,wBAAwB,CAAC;IACnC,UAAU,EAAE,UAAU,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,wBAAwB;IACrC;;;;;OAKG;IACH,sBAAsB,CAAC,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,CAAC;IAErD;;;OAGG;IACH,aAAa,CAAC,EAAE,cAAc,CAAC;IAE/B;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B;;OAEG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAEhC;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC;CACtD;AAED,MAAM,WAAW,wBAAwB;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,UAAU,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB;IAChC,qDAAqD;IACrD,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;IAChD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/api.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/api.js
deleted file mode 100644
index ac3ef1e..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/api.js
+++ /dev/null
@@ -1,44 +0,0 @@
-"use strict";
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.CrossSigningKey = void 0;
-Object.defineProperty(exports, "IPassphraseInfo", {
- enumerable: true,
- get: function () {
- return _secretStorage.PassphraseInfo;
- }
-});
-Object.defineProperty(exports, "ISecretStorageKeyInfo", {
- enumerable: true,
- get: function () {
- return _secretStorage.SecretStorageKeyDescription;
- }
-});
-var _secretStorage = require("../secret-storage");
-/*
-Copyright 2021 The Matrix.org Foundation C.I.C.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-/* re-exports for backwards compatibility. */
-// TODO: Merge this with crypto.js once converted
-let CrossSigningKey;
-exports.CrossSigningKey = CrossSigningKey;
-(function (CrossSigningKey) {
- CrossSigningKey["Master"] = "master";
- CrossSigningKey["SelfSigning"] = "self_signing";
- CrossSigningKey["UserSigning"] = "user_signing";
-})(CrossSigningKey || (exports.CrossSigningKey = CrossSigningKey = {}));
-//# sourceMappingURL=api.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/api.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/api.js.map
deleted file mode 100644
index 810699f..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/api.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"api.js","names":["_secretStorage","require","CrossSigningKey","exports"],"sources":["../../src/crypto/api.ts"],"sourcesContent":["/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { DeviceInfo } from \"./deviceinfo\";\nimport { IKeyBackupInfo } from \"./keybackup\";\nimport { PassphraseInfo } from \"../secret-storage\";\n\n/* re-exports for backwards compatibility. */\nexport {\n PassphraseInfo as IPassphraseInfo,\n SecretStorageKeyDescription as ISecretStorageKeyInfo,\n} from \"../secret-storage\";\n\n// TODO: Merge this with crypto.js once converted\n\nexport enum CrossSigningKey {\n Master = \"master\",\n SelfSigning = \"self_signing\",\n UserSigning = \"user_signing\",\n}\n\nexport interface IEncryptedEventInfo {\n /**\n * whether the event is encrypted (if not encrypted, some of the other properties may not be set)\n */\n encrypted: boolean;\n\n /**\n * the sender's key\n */\n senderKey: string;\n\n /**\n * the algorithm used to encrypt the event\n */\n algorithm: string;\n\n /**\n * whether we can be sure that the owner of the senderKey sent the event\n */\n authenticated: boolean;\n\n /**\n * the sender's device information, if available\n */\n sender?: DeviceInfo;\n\n /**\n * if the event's ed25519 and curve25519 keys don't match (only meaningful if `sender` is set)\n */\n mismatchedSender: boolean;\n}\n\nexport interface IRecoveryKey {\n keyInfo?: IAddSecretStorageKeyOpts;\n privateKey: Uint8Array;\n encodedPrivateKey?: string;\n}\n\nexport interface ICreateSecretStorageOpts {\n /**\n * Function called to await a secret storage key creation flow.\n * @returns Promise resolving to an object with public key metadata, encoded private\n * recovery key which should be disposed of after displaying to the user,\n * and raw private key to avoid round tripping if needed.\n */\n createSecretStorageKey?: () => Promise<IRecoveryKey>;\n\n /**\n * The current key backup object. If passed,\n * the passphrase and recovery key from this backup will be used.\n */\n keyBackupInfo?: IKeyBackupInfo;\n\n /**\n * If true, a new key backup version will be\n * created and the private key stored in the new SSSS store. Ignored if keyBackupInfo\n * is supplied.\n */\n setupNewKeyBackup?: boolean;\n\n /**\n * Reset even if keys already exist.\n */\n setupNewSecretStorage?: boolean;\n\n /**\n * Function called to get the user's\n * current key backup passphrase. Should return a promise that resolves with a Uint8Array\n * containing the key, or rejects if the key cannot be obtained.\n */\n getKeyBackupPassphrase?: () => Promise<Uint8Array>;\n}\n\nexport interface IAddSecretStorageKeyOpts {\n pubkey?: string;\n passphrase?: PassphraseInfo;\n name?: string;\n key?: Uint8Array;\n}\n\nexport interface IImportOpts {\n stage: string; // TODO: Enum\n successes: number;\n failures: number;\n total: number;\n}\n\nexport interface IImportRoomKeysOpts {\n /** called with an object that has a \"stage\" param */\n progressCallback?: (stage: IImportOpts) => void;\n untrusted?: boolean;\n source?: string; // TODO: Enum\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAqBA,IAAAA,cAAA,GAAAC,OAAA;AArBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AAMA;AAAA,IAEYC,eAAe;AAAAC,OAAA,CAAAD,eAAA,GAAAA,eAAA;AAAA,WAAfA,eAAe;EAAfA,eAAe;EAAfA,eAAe;EAAfA,eAAe;AAAA,GAAfA,eAAe,KAAAC,OAAA,CAAAD,eAAA,GAAfA,eAAe"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/backup.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/backup.d.ts
deleted file mode 100644
index 143b2bb..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/backup.d.ts
+++ /dev/null
@@ -1,184 +0,0 @@
-/**
- * Classes for dealing with key backup.
- */
-import type { IMegolmSessionData } from "../@types/crypto";
-import { MatrixClient } from "../client";
-import { DeviceInfo } from "./deviceinfo";
-import { DeviceTrustLevel } from "./CrossSigning";
-import { IEncryptedPayload } from "./aes";
-import { Curve25519SessionData, IAes256AuthData, ICurve25519AuthData, IKeyBackupInfo, IKeyBackupSession } from "./keybackup";
-type AuthData = IKeyBackupInfo["auth_data"];
-type SigInfo = {
- deviceId: string;
- valid?: boolean | null;
- device?: DeviceInfo | null;
- crossSigningId?: boolean;
- deviceTrust?: DeviceTrustLevel;
-};
-export type TrustInfo = {
- usable: boolean;
- sigs: SigInfo[];
- trusted_locally?: boolean;
-};
-export interface IKeyBackupCheck {
- backupInfo?: IKeyBackupInfo;
- trustInfo: TrustInfo;
-}
-export interface IPreparedKeyBackupVersion {
- algorithm: string;
- auth_data: AuthData;
- recovery_key: string;
- privateKey: Uint8Array;
-}
-/** A function used to get the secret key for a backup.
- */
-type GetKey = () => Promise<ArrayLike<number>>;
-interface BackupAlgorithmClass {
- algorithmName: string;
- init(authData: AuthData, getKey: GetKey): Promise<BackupAlgorithm>;
- prepare(key?: string | Uint8Array | null): Promise<[Uint8Array, AuthData]>;
- checkBackupVersion(info: IKeyBackupInfo): void;
-}
-interface BackupAlgorithm {
- untrusted: boolean;
- encryptSession(data: Record<string, any>): Promise<Curve25519SessionData | IEncryptedPayload>;
- decryptSessions(ciphertexts: Record<string, IKeyBackupSession>): Promise<IMegolmSessionData[]>;
- authData: AuthData;
- keyMatches(key: ArrayLike<number>): Promise<boolean>;
- free(): void;
-}
-export interface IKeyBackup {
- rooms: {
- [roomId: string]: {
- sessions: {
- [sessionId: string]: IKeyBackupSession;
- };
- };
- };
-}
-/**
- * Manages the key backup.
- */
-export declare class BackupManager {
- private readonly baseApis;
- readonly getKey: GetKey;
- private algorithm;
- backupInfo: IKeyBackupInfo | undefined;
- checkedForBackup: boolean;
- private sendingBackups;
- private sessionLastCheckAttemptedTime;
- constructor(baseApis: MatrixClient, getKey: GetKey);
- get version(): string | undefined;
- /**
- * Performs a quick check to ensure that the backup info looks sane.
- *
- * Throws an error if a problem is detected.
- *
- * @param info - the key backup info
- */
- static checkBackupVersion(info: IKeyBackupInfo): void;
- static makeAlgorithm(info: IKeyBackupInfo, getKey: GetKey): Promise<BackupAlgorithm>;
- enableKeyBackup(info: IKeyBackupInfo): Promise<void>;
- /**
- * Disable backing up of keys.
- */
- disableKeyBackup(): void;
- getKeyBackupEnabled(): boolean | null;
- prepareKeyBackupVersion(key?: string | Uint8Array | null, algorithm?: string | undefined): Promise<IPreparedKeyBackupVersion>;
- createKeyBackupVersion(info: IKeyBackupInfo): Promise<void>;
- /**
- * Check the server for an active key backup and
- * if one is present and has a valid signature from
- * one of the user's verified devices, start backing up
- * to it.
- */
- checkAndStart(): Promise<IKeyBackupCheck | null>;
- /**
- * Forces a re-check of the key backup and enables/disables it
- * as appropriate.
- *
- * @returns Object with backup info (as returned by
- * getKeyBackupVersion) in backupInfo and
- * trust information (as returned by isKeyBackupTrusted)
- * in trustInfo.
- */
- checkKeyBackup(): Promise<IKeyBackupCheck | null>;
- /**
- * Attempts to retrieve a session from a key backup, if enough time
- * has elapsed since the last check for this session id.
- */
- queryKeyBackupRateLimited(targetRoomId: string | undefined, targetSessionId: string | undefined): Promise<void>;
- /**
- * Check if the given backup info is trusted.
- *
- * @param backupInfo - key backup info dict from /room_keys/version
- */
- isKeyBackupTrusted(backupInfo?: IKeyBackupInfo): Promise<TrustInfo>;
- /**
- * Schedules sending all keys waiting to be sent to the backup, if not already
- * scheduled. Retries if necessary.
- *
- * @param maxDelay - Maximum delay to wait in ms. 0 means no delay.
- */
- scheduleKeyBackupSend(maxDelay?: number): Promise<void>;
- /**
- * Take some e2e keys waiting to be backed up and send them
- * to the backup.
- *
- * @param limit - Maximum number of keys to back up
- * @returns Number of sessions backed up
- */
- backupPendingKeys(limit: number): Promise<number>;
- backupGroupSession(senderKey: string, sessionId: string): Promise<void>;
- /**
- * Marks all group sessions as needing to be backed up and schedules them to
- * upload in the background as soon as possible.
- */
- scheduleAllGroupSessionsForBackup(): Promise<void>;
- /**
- * Marks all group sessions as needing to be backed up without scheduling
- * them to upload in the background.
- * @returns Promise which resolves to the number of sessions now requiring a backup
- * (which will be equal to the number of sessions in the store).
- */
- flagAllGroupSessionsForBackup(): Promise<number>;
- /**
- * Counts the number of end to end session keys that are waiting to be backed up
- * @returns Promise which resolves to the number of sessions requiring backup
- */
- countSessionsNeedingBackup(): Promise<number>;
-}
-export declare class Curve25519 implements BackupAlgorithm {
- authData: ICurve25519AuthData;
- private publicKey;
- private getKey;
- static algorithmName: string;
- constructor(authData: ICurve25519AuthData, publicKey: any, // FIXME: PkEncryption
- getKey: () => Promise<Uint8Array>);
- static init(authData: AuthData, getKey: () => Promise<Uint8Array>): Promise<Curve25519>;
- static prepare(key?: string | Uint8Array | null): Promise<[Uint8Array, AuthData]>;
- static checkBackupVersion(info: IKeyBackupInfo): void;
- get untrusted(): boolean;
- encryptSession(data: Record<string, any>): Promise<Curve25519SessionData>;
- decryptSessions(sessions: Record<string, IKeyBackupSession<Curve25519SessionData>>): Promise<IMegolmSessionData[]>;
- keyMatches(key: Uint8Array): Promise<boolean>;
- free(): void;
-}
-export declare class Aes256 implements BackupAlgorithm {
- readonly authData: IAes256AuthData;
- private readonly key;
- static algorithmName: "org.matrix.msc3270.v1.aes-hmac-sha2";
- constructor(authData: IAes256AuthData, key: Uint8Array);
- static init(authData: IAes256AuthData, getKey: () => Promise<Uint8Array>): Promise<Aes256>;
- static prepare(key?: string | Uint8Array | null): Promise<[Uint8Array, AuthData]>;
- static checkBackupVersion(info: IKeyBackupInfo): void;
- get untrusted(): boolean;
- encryptSession(data: Record<string, any>): Promise<IEncryptedPayload>;
- decryptSessions(sessions: Record<string, IKeyBackupSession<IEncryptedPayload>>): Promise<IMegolmSessionData[]>;
- keyMatches(key: Uint8Array): Promise<boolean>;
- free(): void;
-}
-export declare const algorithmsByName: Record<string, BackupAlgorithmClass>;
-export declare const DefaultAlgorithm: BackupAlgorithmClass;
-export {};
-//# sourceMappingURL=backup.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/backup.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/backup.d.ts.map
deleted file mode 100644
index 5161b6e..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/backup.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"backup.d.ts","sourceRoot":"","sources":["../../src/crypto/backup.ts"],"names":[],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/backup.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/backup.js
deleted file mode 100644
index ae42cce..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/backup.js
+++ /dev/null
@@ -1,654 +0,0 @@
-"use strict";
-
-var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.algorithmsByName = exports.DefaultAlgorithm = exports.Curve25519 = exports.BackupManager = exports.Aes256 = void 0;
-var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
-var _client = require("../client");
-var _logger = require("../logger");
-var _olmlib = require("./olmlib");
-var _key_passphrase = require("./key_passphrase");
-var _utils = require("../utils");
-var _indexeddbCryptoStore = require("./store/indexeddb-crypto-store");
-var _recoverykey = require("./recoverykey");
-var _aes = require("./aes");
-var _NamespacedValue = require("../NamespacedValue");
-var _index = require("./index");
-var _crypto = require("./crypto");
-var _httpApi = require("../http-api");
-/*
-Copyright 2021 The Matrix.org Foundation C.I.C.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-/**
- * Classes for dealing with key backup.
- */
-
-const KEY_BACKUP_KEYS_PER_REQUEST = 200;
-const KEY_BACKUP_CHECK_RATE_LIMIT = 5000; // ms
-
-/**
- * Manages the key backup.
- */
-class BackupManager {
- // The info dict from /room_keys/version
- // Have we checked the server for a backup we can use?
- // Are we currently sending backups?
- // When did we last try to check the server for a given session id?
-
- constructor(baseApis, getKey) {
- this.baseApis = baseApis;
- this.getKey = getKey;
- (0, _defineProperty2.default)(this, "algorithm", void 0);
- (0, _defineProperty2.default)(this, "backupInfo", void 0);
- (0, _defineProperty2.default)(this, "checkedForBackup", void 0);
- (0, _defineProperty2.default)(this, "sendingBackups", void 0);
- (0, _defineProperty2.default)(this, "sessionLastCheckAttemptedTime", {});
- this.checkedForBackup = false;
- this.sendingBackups = false;
- }
- get version() {
- return this.backupInfo && this.backupInfo.version;
- }
-
- /**
- * Performs a quick check to ensure that the backup info looks sane.
- *
- * Throws an error if a problem is detected.
- *
- * @param info - the key backup info
- */
- static checkBackupVersion(info) {
- const Algorithm = algorithmsByName[info.algorithm];
- if (!Algorithm) {
- throw new Error("Unknown backup algorithm: " + info.algorithm);
- }
- if (typeof info.auth_data !== "object") {
- throw new Error("Invalid backup data returned");
- }
- return Algorithm.checkBackupVersion(info);
- }
- static makeAlgorithm(info, getKey) {
- const Algorithm = algorithmsByName[info.algorithm];
- if (!Algorithm) {
- throw new Error("Unknown backup algorithm");
- }
- return Algorithm.init(info.auth_data, getKey);
- }
- async enableKeyBackup(info) {
- this.backupInfo = info;
- if (this.algorithm) {
- this.algorithm.free();
- }
- this.algorithm = await BackupManager.makeAlgorithm(info, this.getKey);
- this.baseApis.emit(_index.CryptoEvent.KeyBackupStatus, true);
-
- // There may be keys left over from a partially completed backup, so
- // schedule a send to check.
- this.scheduleKeyBackupSend();
- }
-
- /**
- * Disable backing up of keys.
- */
- disableKeyBackup() {
- if (this.algorithm) {
- this.algorithm.free();
- }
- this.algorithm = undefined;
- this.backupInfo = undefined;
- this.baseApis.emit(_index.CryptoEvent.KeyBackupStatus, false);
- }
- getKeyBackupEnabled() {
- if (!this.checkedForBackup) {
- return null;
- }
- return Boolean(this.algorithm);
- }
- async prepareKeyBackupVersion(key, algorithm) {
- const Algorithm = algorithm ? algorithmsByName[algorithm] : DefaultAlgorithm;
- if (!Algorithm) {
- throw new Error("Unknown backup algorithm");
- }
- const [privateKey, authData] = await Algorithm.prepare(key);
- const recoveryKey = (0, _recoverykey.encodeRecoveryKey)(privateKey);
- return {
- algorithm: Algorithm.algorithmName,
- auth_data: authData,
- recovery_key: recoveryKey,
- privateKey
- };
- }
- async createKeyBackupVersion(info) {
- this.algorithm = await BackupManager.makeAlgorithm(info, this.getKey);
- }
-
- /**
- * Check the server for an active key backup and
- * if one is present and has a valid signature from
- * one of the user's verified devices, start backing up
- * to it.
- */
- async checkAndStart() {
- _logger.logger.log("Checking key backup status...");
- if (this.baseApis.isGuest()) {
- _logger.logger.log("Skipping key backup check since user is guest");
- this.checkedForBackup = true;
- return null;
- }
- let backupInfo;
- try {
- var _await$this$baseApis$;
- backupInfo = (_await$this$baseApis$ = await this.baseApis.getKeyBackupVersion()) !== null && _await$this$baseApis$ !== void 0 ? _await$this$baseApis$ : undefined;
- } catch (e) {
- _logger.logger.log("Error checking for active key backup", e);
- if (e.httpStatus === 404) {
- // 404 is returned when the key backup does not exist, so that
- // counts as successfully checking.
- this.checkedForBackup = true;
- }
- return null;
- }
- this.checkedForBackup = true;
- const trustInfo = await this.isKeyBackupTrusted(backupInfo);
- if (trustInfo.usable && !this.backupInfo) {
- _logger.logger.log(`Found usable key backup v${backupInfo.version}: enabling key backups`);
- await this.enableKeyBackup(backupInfo);
- } else if (!trustInfo.usable && this.backupInfo) {
- _logger.logger.log("No usable key backup: disabling key backup");
- this.disableKeyBackup();
- } else if (!trustInfo.usable && !this.backupInfo) {
- _logger.logger.log("No usable key backup: not enabling key backup");
- } else if (trustInfo.usable && this.backupInfo) {
- // may not be the same version: if not, we should switch
- if (backupInfo.version !== this.backupInfo.version) {
- _logger.logger.log(`On backup version ${this.backupInfo.version} but ` + `found version ${backupInfo.version}: switching.`);
- this.disableKeyBackup();
- await this.enableKeyBackup(backupInfo);
- // We're now using a new backup, so schedule all the keys we have to be
- // uploaded to the new backup. This is a bit of a workaround to upload
- // keys to a new backup in *most* cases, but it won't cover all cases
- // because we don't remember what backup version we uploaded keys to:
- // see https://github.com/vector-im/element-web/issues/14833
- await this.scheduleAllGroupSessionsForBackup();
- } else {
- _logger.logger.log(`Backup version ${backupInfo.version} still current`);
- }
- }
- return {
- backupInfo,
- trustInfo
- };
- }
-
- /**
- * Forces a re-check of the key backup and enables/disables it
- * as appropriate.
- *
- * @returns Object with backup info (as returned by
- * getKeyBackupVersion) in backupInfo and
- * trust information (as returned by isKeyBackupTrusted)
- * in trustInfo.
- */
- async checkKeyBackup() {
- this.checkedForBackup = false;
- return this.checkAndStart();
- }
-
- /**
- * Attempts to retrieve a session from a key backup, if enough time
- * has elapsed since the last check for this session id.
- */
- async queryKeyBackupRateLimited(targetRoomId, targetSessionId) {
- if (!this.backupInfo) {
- return;
- }
- const now = new Date().getTime();
- if (!this.sessionLastCheckAttemptedTime[targetSessionId] || now - this.sessionLastCheckAttemptedTime[targetSessionId] > KEY_BACKUP_CHECK_RATE_LIMIT) {
- this.sessionLastCheckAttemptedTime[targetSessionId] = now;
- await this.baseApis.restoreKeyBackupWithCache(targetRoomId, targetSessionId, this.backupInfo, {});
- }
- }
-
- /**
- * Check if the given backup info is trusted.
- *
- * @param backupInfo - key backup info dict from /room_keys/version
- */
- async isKeyBackupTrusted(backupInfo) {
- const ret = {
- usable: false,
- trusted_locally: false,
- sigs: []
- };
- if (!backupInfo || !backupInfo.algorithm || !backupInfo.auth_data || !backupInfo.auth_data.signatures) {
- _logger.logger.info("Key backup is absent or missing required data");
- return ret;
- }
- const userId = this.baseApis.getUserId();
- const privKey = await this.baseApis.crypto.getSessionBackupPrivateKey();
- if (privKey) {
- let algorithm = null;
- try {
- algorithm = await BackupManager.makeAlgorithm(backupInfo, async () => privKey);
- if (await algorithm.keyMatches(privKey)) {
- _logger.logger.info("Backup is trusted locally");
- ret.trusted_locally = true;
- }
- } catch {
- // do nothing -- if we have an error, then we don't mark it as
- // locally trusted
- } finally {
- var _algorithm;
- (_algorithm = algorithm) === null || _algorithm === void 0 ? void 0 : _algorithm.free();
- }
- }
- const mySigs = backupInfo.auth_data.signatures[userId] || {};
- for (const keyId of Object.keys(mySigs)) {
- const keyIdParts = keyId.split(":");
- if (keyIdParts[0] !== "ed25519") {
- _logger.logger.log("Ignoring unknown signature type: " + keyIdParts[0]);
- continue;
- }
- // Could be a cross-signing master key, but just say this is the device
- // ID for backwards compat
- const sigInfo = {
- deviceId: keyIdParts[1]
- };
-
- // first check to see if it's from our cross-signing key
- const crossSigningId = this.baseApis.crypto.crossSigningInfo.getId();
- if (crossSigningId === sigInfo.deviceId) {
- sigInfo.crossSigningId = true;
- try {
- await (0, _olmlib.verifySignature)(this.baseApis.crypto.olmDevice, backupInfo.auth_data, userId, sigInfo.deviceId, crossSigningId);
- sigInfo.valid = true;
- } catch (e) {
- _logger.logger.warn("Bad signature from cross signing key " + crossSigningId, e);
- sigInfo.valid = false;
- }
- ret.sigs.push(sigInfo);
- continue;
- }
-
- // Now look for a sig from a device
- // At some point this can probably go away and we'll just support
- // it being signed by the cross-signing master key
- const device = this.baseApis.crypto.deviceList.getStoredDevice(userId, sigInfo.deviceId);
- if (device) {
- sigInfo.device = device;
- sigInfo.deviceTrust = this.baseApis.checkDeviceTrust(userId, sigInfo.deviceId);
- try {
- await (0, _olmlib.verifySignature)(this.baseApis.crypto.olmDevice, backupInfo.auth_data, userId, device.deviceId, device.getFingerprint());
- sigInfo.valid = true;
- } catch (e) {
- _logger.logger.info("Bad signature from key ID " + keyId + " userID " + this.baseApis.getUserId() + " device ID " + device.deviceId + " fingerprint: " + device.getFingerprint(), backupInfo.auth_data, e);
- sigInfo.valid = false;
- }
- } else {
- sigInfo.valid = null; // Can't determine validity because we don't have the signing device
- _logger.logger.info("Ignoring signature from unknown key " + keyId);
- }
- ret.sigs.push(sigInfo);
- }
- ret.usable = ret.sigs.some(s => {
- var _s$deviceTrust;
- return s.valid && (s.device && ((_s$deviceTrust = s.deviceTrust) === null || _s$deviceTrust === void 0 ? void 0 : _s$deviceTrust.isVerified()) || s.crossSigningId);
- });
- return ret;
- }
-
- /**
- * Schedules sending all keys waiting to be sent to the backup, if not already
- * scheduled. Retries if necessary.
- *
- * @param maxDelay - Maximum delay to wait in ms. 0 means no delay.
- */
- async scheduleKeyBackupSend(maxDelay = 10000) {
- if (this.sendingBackups) return;
- this.sendingBackups = true;
- try {
- // wait between 0 and `maxDelay` seconds, to avoid backup
- // requests from different clients hitting the server all at
- // the same time when a new key is sent
- const delay = Math.random() * maxDelay;
- await (0, _utils.sleep)(delay);
- let numFailures = 0; // number of consecutive failures
- for (;;) {
- if (!this.algorithm) {
- return;
- }
- try {
- const numBackedUp = await this.backupPendingKeys(KEY_BACKUP_KEYS_PER_REQUEST);
- if (numBackedUp === 0) {
- // no sessions left needing backup: we're done
- return;
- }
- numFailures = 0;
- } catch (err) {
- numFailures++;
- _logger.logger.log("Key backup request failed", err);
- if (err.data) {
- if (err.data.errcode == "M_NOT_FOUND" || err.data.errcode == "M_WRONG_ROOM_KEYS_VERSION") {
- // Re-check key backup status on error, so we can be
- // sure to present the current situation when asked.
- await this.checkKeyBackup();
- // Backup version has changed or this backup version
- // has been deleted
- this.baseApis.crypto.emit(_index.CryptoEvent.KeyBackupFailed, err.data.errcode);
- throw err;
- }
- }
- }
- if (numFailures) {
- // exponential backoff if we have failures
- await (0, _utils.sleep)(1000 * Math.pow(2, Math.min(numFailures - 1, 4)));
- }
- }
- } finally {
- this.sendingBackups = false;
- }
- }
-
- /**
- * Take some e2e keys waiting to be backed up and send them
- * to the backup.
- *
- * @param limit - Maximum number of keys to back up
- * @returns Number of sessions backed up
- */
- async backupPendingKeys(limit) {
- const sessions = await this.baseApis.crypto.cryptoStore.getSessionsNeedingBackup(limit);
- if (!sessions.length) {
- return 0;
- }
- let remaining = await this.baseApis.crypto.cryptoStore.countSessionsNeedingBackup();
- this.baseApis.crypto.emit(_index.CryptoEvent.KeyBackupSessionsRemaining, remaining);
- const rooms = {};
- for (const session of sessions) {
- var _deviceList$getDevice;
- const roomId = session.sessionData.room_id;
- (0, _utils.safeSet)(rooms, roomId, rooms[roomId] || {
- sessions: {}
- });
- const sessionData = this.baseApis.crypto.olmDevice.exportInboundGroupSession(session.senderKey, session.sessionId, session.sessionData);
- sessionData.algorithm = _olmlib.MEGOLM_ALGORITHM;
- const forwardedCount = (sessionData.forwarding_curve25519_key_chain || []).length;
- const userId = this.baseApis.crypto.deviceList.getUserByIdentityKey(_olmlib.MEGOLM_ALGORITHM, session.senderKey);
- const device = (_deviceList$getDevice = this.baseApis.crypto.deviceList.getDeviceByIdentityKey(_olmlib.MEGOLM_ALGORITHM, session.senderKey)) !== null && _deviceList$getDevice !== void 0 ? _deviceList$getDevice : undefined;
- const verified = this.baseApis.crypto.checkDeviceInfoTrust(userId, device).isVerified();
- (0, _utils.safeSet)(rooms[roomId]["sessions"], session.sessionId, {
- first_message_index: sessionData.first_known_index,
- forwarded_count: forwardedCount,
- is_verified: verified,
- session_data: await this.algorithm.encryptSession(sessionData)
- });
- }
- await this.baseApis.sendKeyBackup(undefined, undefined, this.backupInfo.version, {
- rooms
- });
- await this.baseApis.crypto.cryptoStore.unmarkSessionsNeedingBackup(sessions);
- remaining = await this.baseApis.crypto.cryptoStore.countSessionsNeedingBackup();
- this.baseApis.crypto.emit(_index.CryptoEvent.KeyBackupSessionsRemaining, remaining);
- return sessions.length;
- }
- async backupGroupSession(senderKey, sessionId) {
- await this.baseApis.crypto.cryptoStore.markSessionsNeedingBackup([{
- senderKey: senderKey,
- sessionId: sessionId
- }]);
- if (this.backupInfo) {
- // don't wait for this to complete: it will delay so
- // happens in the background
- this.scheduleKeyBackupSend();
- }
- // if this.backupInfo is not set, then the keys will be backed up when
- // this.enableKeyBackup is called
- }
-
- /**
- * Marks all group sessions as needing to be backed up and schedules them to
- * upload in the background as soon as possible.
- */
- async scheduleAllGroupSessionsForBackup() {
- await this.flagAllGroupSessionsForBackup();
-
- // Schedule keys to upload in the background as soon as possible.
- this.scheduleKeyBackupSend(0 /* maxDelay */);
- }
-
- /**
- * Marks all group sessions as needing to be backed up without scheduling
- * them to upload in the background.
- * @returns Promise which resolves to the number of sessions now requiring a backup
- * (which will be equal to the number of sessions in the store).
- */
- async flagAllGroupSessionsForBackup() {
- await this.baseApis.crypto.cryptoStore.doTxn("readwrite", [_indexeddbCryptoStore.IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS, _indexeddbCryptoStore.IndexedDBCryptoStore.STORE_BACKUP], txn => {
- this.baseApis.crypto.cryptoStore.getAllEndToEndInboundGroupSessions(txn, session => {
- if (session !== null) {
- this.baseApis.crypto.cryptoStore.markSessionsNeedingBackup([session], txn);
- }
- });
- });
- const remaining = await this.baseApis.crypto.cryptoStore.countSessionsNeedingBackup();
- this.baseApis.emit(_index.CryptoEvent.KeyBackupSessionsRemaining, remaining);
- return remaining;
- }
-
- /**
- * Counts the number of end to end session keys that are waiting to be backed up
- * @returns Promise which resolves to the number of sessions requiring backup
- */
- countSessionsNeedingBackup() {
- return this.baseApis.crypto.cryptoStore.countSessionsNeedingBackup();
- }
-}
-exports.BackupManager = BackupManager;
-class Curve25519 {
- constructor(authData, publicKey,
- // FIXME: PkEncryption
- getKey) {
- this.authData = authData;
- this.publicKey = publicKey;
- this.getKey = getKey;
- }
- static async init(authData, getKey) {
- if (!authData || !("public_key" in authData)) {
- throw new Error("auth_data missing required information");
- }
- const publicKey = new global.Olm.PkEncryption();
- publicKey.set_recipient_key(authData.public_key);
- return new Curve25519(authData, publicKey, getKey);
- }
- static async prepare(key) {
- const decryption = new global.Olm.PkDecryption();
- try {
- const authData = {};
- if (!key) {
- authData.public_key = decryption.generate_key();
- } else if (key instanceof Uint8Array) {
- authData.public_key = decryption.init_with_private_key(key);
- } else {
- const derivation = await (0, _key_passphrase.keyFromPassphrase)(key);
- authData.private_key_salt = derivation.salt;
- authData.private_key_iterations = derivation.iterations;
- authData.public_key = decryption.init_with_private_key(derivation.key);
- }
- const publicKey = new global.Olm.PkEncryption();
- publicKey.set_recipient_key(authData.public_key);
- return [decryption.get_private_key(), authData];
- } finally {
- decryption.free();
- }
- }
- static checkBackupVersion(info) {
- if (!("public_key" in info.auth_data)) {
- throw new Error("Invalid backup data returned");
- }
- }
- get untrusted() {
- return true;
- }
- async encryptSession(data) {
- const plainText = Object.assign({}, data);
- delete plainText.session_id;
- delete plainText.room_id;
- delete plainText.first_known_index;
- return this.publicKey.encrypt(JSON.stringify(plainText));
- }
- async decryptSessions(sessions) {
- const privKey = await this.getKey();
- const decryption = new global.Olm.PkDecryption();
- try {
- const backupPubKey = decryption.init_with_private_key(privKey);
- if (backupPubKey !== this.authData.public_key) {
- throw new _httpApi.MatrixError({
- errcode: _client.MatrixClient.RESTORE_BACKUP_ERROR_BAD_KEY
- });
- }
- const keys = [];
- for (const [sessionId, sessionData] of Object.entries(sessions)) {
- try {
- const decrypted = JSON.parse(decryption.decrypt(sessionData.session_data.ephemeral, sessionData.session_data.mac, sessionData.session_data.ciphertext));
- decrypted.session_id = sessionId;
- keys.push(decrypted);
- } catch (e) {
- _logger.logger.log("Failed to decrypt megolm session from backup", e, sessionData);
- }
- }
- return keys;
- } finally {
- decryption.free();
- }
- }
- async keyMatches(key) {
- const decryption = new global.Olm.PkDecryption();
- let pubKey;
- try {
- pubKey = decryption.init_with_private_key(key);
- } finally {
- decryption.free();
- }
- return pubKey === this.authData.public_key;
- }
- free() {
- this.publicKey.free();
- }
-}
-exports.Curve25519 = Curve25519;
-(0, _defineProperty2.default)(Curve25519, "algorithmName", "m.megolm_backup.v1.curve25519-aes-sha2");
-function randomBytes(size) {
- const buf = new Uint8Array(size);
- _crypto.crypto.getRandomValues(buf);
- return buf;
-}
-const UNSTABLE_MSC3270_NAME = new _NamespacedValue.UnstableValue("m.megolm_backup.v1.aes-hmac-sha2", "org.matrix.msc3270.v1.aes-hmac-sha2");
-class Aes256 {
- constructor(authData, key) {
- this.authData = authData;
- this.key = key;
- }
- static async init(authData, getKey) {
- if (!authData) {
- throw new Error("auth_data missing");
- }
- const key = await getKey();
- if (authData.mac) {
- const {
- mac
- } = await (0, _aes.calculateKeyCheck)(key, authData.iv);
- if (authData.mac.replace(/=+$/g, "") !== mac.replace(/=+/g, "")) {
- throw new Error("Key does not match");
- }
- }
- return new Aes256(authData, key);
- }
- static async prepare(key) {
- let outKey;
- const authData = {};
- if (!key) {
- outKey = randomBytes(32);
- } else if (key instanceof Uint8Array) {
- outKey = new Uint8Array(key);
- } else {
- const derivation = await (0, _key_passphrase.keyFromPassphrase)(key);
- authData.private_key_salt = derivation.salt;
- authData.private_key_iterations = derivation.iterations;
- outKey = derivation.key;
- }
- const {
- iv,
- mac
- } = await (0, _aes.calculateKeyCheck)(outKey);
- authData.iv = iv;
- authData.mac = mac;
- return [outKey, authData];
- }
- static checkBackupVersion(info) {
- if (!("iv" in info.auth_data && "mac" in info.auth_data)) {
- throw new Error("Invalid backup data returned");
- }
- }
- get untrusted() {
- return false;
- }
- encryptSession(data) {
- const plainText = Object.assign({}, data);
- delete plainText.session_id;
- delete plainText.room_id;
- delete plainText.first_known_index;
- return (0, _aes.encryptAES)(JSON.stringify(plainText), this.key, data.session_id);
- }
- async decryptSessions(sessions) {
- const keys = [];
- for (const [sessionId, sessionData] of Object.entries(sessions)) {
- try {
- const decrypted = JSON.parse(await (0, _aes.decryptAES)(sessionData.session_data, this.key, sessionId));
- decrypted.session_id = sessionId;
- keys.push(decrypted);
- } catch (e) {
- _logger.logger.log("Failed to decrypt megolm session from backup", e, sessionData);
- }
- }
- return keys;
- }
- async keyMatches(key) {
- if (this.authData.mac) {
- const {
- mac
- } = await (0, _aes.calculateKeyCheck)(key, this.authData.iv);
- return this.authData.mac.replace(/=+$/g, "") === mac.replace(/=+/g, "");
- } else {
- // if we have no information, we have to assume the key is right
- return true;
- }
- }
- free() {
- this.key.fill(0);
- }
-}
-exports.Aes256 = Aes256;
-(0, _defineProperty2.default)(Aes256, "algorithmName", UNSTABLE_MSC3270_NAME.name);
-const algorithmsByName = {
- [Curve25519.algorithmName]: Curve25519,
- [Aes256.algorithmName]: Aes256
-};
-exports.algorithmsByName = algorithmsByName;
-const DefaultAlgorithm = Curve25519;
-exports.DefaultAlgorithm = DefaultAlgorithm;
-//# sourceMappingURL=backup.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/backup.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/backup.js.map
deleted file mode 100644
index 970eea4..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/backup.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"backup.js","names":["_client","require","_logger","_olmlib","_key_passphrase","_utils","_indexeddbCryptoStore","_recoverykey","_aes","_NamespacedValue","_index","_crypto","_httpApi","KEY_BACKUP_KEYS_PER_REQUEST","KEY_BACKUP_CHECK_RATE_LIMIT","BackupManager","constructor","baseApis","getKey","_defineProperty2","default","checkedForBackup","sendingBackups","version","backupInfo","checkBackupVersion","info","Algorithm","algorithmsByName","algorithm","Error","auth_data","makeAlgorithm","init","enableKeyBackup","free","emit","CryptoEvent","KeyBackupStatus","scheduleKeyBackupSend","disableKeyBackup","undefined","getKeyBackupEnabled","Boolean","prepareKeyBackupVersion","key","DefaultAlgorithm","privateKey","authData","prepare","recoveryKey","encodeRecoveryKey","algorithmName","recovery_key","createKeyBackupVersion","checkAndStart","logger","log","isGuest","_await$this$baseApis$","getKeyBackupVersion","e","httpStatus","trustInfo","isKeyBackupTrusted","usable","scheduleAllGroupSessionsForBackup","checkKeyBackup","queryKeyBackupRateLimited","targetRoomId","targetSessionId","now","Date","getTime","sessionLastCheckAttemptedTime","restoreKeyBackupWithCache","ret","trusted_locally","sigs","signatures","userId","getUserId","privKey","crypto","getSessionBackupPrivateKey","keyMatches","_algorithm","mySigs","keyId","Object","keys","keyIdParts","split","sigInfo","deviceId","crossSigningId","crossSigningInfo","getId","verifySignature","olmDevice","valid","warn","push","device","deviceList","getStoredDevice","deviceTrust","checkDeviceTrust","getFingerprint","some","s","_s$deviceTrust","isVerified","maxDelay","delay","Math","random","sleep","numFailures","numBackedUp","backupPendingKeys","err","data","errcode","KeyBackupFailed","pow","min","limit","sessions","cryptoStore","getSessionsNeedingBackup","length","remaining","countSessionsNeedingBackup","KeyBackupSessionsRemaining","rooms","session","_deviceList$getDevice","roomId","sessionData","room_id","safeSet","exportInboundGroupSession","senderKey","sessionId","MEGOLM_ALGORITHM","forwardedCount","forwarding_curve25519_key_chain","getUserByIdentityKey","getDeviceByIdentityKey","verified","checkDeviceInfoTrust","first_message_index","first_known_index","forwarded_count","is_verified","session_data","encryptSession","sendKeyBackup","unmarkSessionsNeedingBackup","backupGroupSession","markSessionsNeedingBackup","flagAllGroupSessionsForBackup","doTxn","IndexedDBCryptoStore","STORE_INBOUND_GROUP_SESSIONS","STORE_BACKUP","txn","getAllEndToEndInboundGroupSessions","exports","Curve25519","publicKey","global","Olm","PkEncryption","set_recipient_key","public_key","decryption","PkDecryption","generate_key","Uint8Array","init_with_private_key","derivation","keyFromPassphrase","private_key_salt","salt","private_key_iterations","iterations","get_private_key","untrusted","plainText","assign","session_id","encrypt","JSON","stringify","decryptSessions","backupPubKey","MatrixError","MatrixClient","RESTORE_BACKUP_ERROR_BAD_KEY","entries","decrypted","parse","decrypt","ephemeral","mac","ciphertext","pubKey","randomBytes","size","buf","getRandomValues","UNSTABLE_MSC3270_NAME","UnstableValue","Aes256","calculateKeyCheck","iv","replace","outKey","encryptAES","decryptAES","fill","name"],"sources":["../../src/crypto/backup.ts"],"sourcesContent":["/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n/**\n * Classes for dealing with key backup.\n */\n\nimport type { IMegolmSessionData } from \"../@types/crypto\";\nimport { MatrixClient } from \"../client\";\nimport { logger } from \"../logger\";\nimport { MEGOLM_ALGORITHM, verifySignature } from \"./olmlib\";\nimport { DeviceInfo } from \"./deviceinfo\";\nimport { DeviceTrustLevel } from \"./CrossSigning\";\nimport { keyFromPassphrase } from \"./key_passphrase\";\nimport { safeSet, sleep } from \"../utils\";\nimport { IndexedDBCryptoStore } from \"./store/indexeddb-crypto-store\";\nimport { encodeRecoveryKey } from \"./recoverykey\";\nimport { calculateKeyCheck, decryptAES, encryptAES, IEncryptedPayload } from \"./aes\";\nimport {\n Curve25519SessionData,\n IAes256AuthData,\n ICurve25519AuthData,\n IKeyBackupInfo,\n IKeyBackupSession,\n} from \"./keybackup\";\nimport { UnstableValue } from \"../NamespacedValue\";\nimport { CryptoEvent } from \"./index\";\nimport { crypto } from \"./crypto\";\nimport { HTTPError, MatrixError } from \"../http-api\";\n\nconst KEY_BACKUP_KEYS_PER_REQUEST = 200;\nconst KEY_BACKUP_CHECK_RATE_LIMIT = 5000; // ms\n\ntype AuthData = IKeyBackupInfo[\"auth_data\"];\n\ntype SigInfo = {\n deviceId: string;\n valid?: boolean | null; // true: valid, false: invalid, null: cannot attempt validation\n device?: DeviceInfo | null;\n crossSigningId?: boolean;\n deviceTrust?: DeviceTrustLevel;\n};\n\nexport type TrustInfo = {\n usable: boolean; // is the backup trusted, true iff there is a sig that is valid & from a trusted device\n sigs: SigInfo[];\n // eslint-disable-next-line camelcase\n trusted_locally?: boolean;\n};\n\nexport interface IKeyBackupCheck {\n backupInfo?: IKeyBackupInfo;\n trustInfo: TrustInfo;\n}\n\n/* eslint-disable camelcase */\nexport interface IPreparedKeyBackupVersion {\n algorithm: string;\n auth_data: AuthData;\n recovery_key: string;\n privateKey: Uint8Array;\n}\n/* eslint-enable camelcase */\n\n/** A function used to get the secret key for a backup.\n */\ntype GetKey = () => Promise<ArrayLike<number>>;\n\ninterface BackupAlgorithmClass {\n algorithmName: string;\n // initialize from an existing backup\n init(authData: AuthData, getKey: GetKey): Promise<BackupAlgorithm>;\n\n // prepare a brand new backup\n prepare(key?: string | Uint8Array | null): Promise<[Uint8Array, AuthData]>;\n\n checkBackupVersion(info: IKeyBackupInfo): void;\n}\n\ninterface BackupAlgorithm {\n untrusted: boolean;\n encryptSession(data: Record<string, any>): Promise<Curve25519SessionData | IEncryptedPayload>;\n decryptSessions(ciphertexts: Record<string, IKeyBackupSession>): Promise<IMegolmSessionData[]>;\n authData: AuthData;\n keyMatches(key: ArrayLike<number>): Promise<boolean>;\n free(): void;\n}\n\nexport interface IKeyBackup {\n rooms: {\n [roomId: string]: {\n sessions: {\n [sessionId: string]: IKeyBackupSession;\n };\n };\n };\n}\n\n/**\n * Manages the key backup.\n */\nexport class BackupManager {\n private algorithm: BackupAlgorithm | undefined;\n public backupInfo: IKeyBackupInfo | undefined; // The info dict from /room_keys/version\n public checkedForBackup: boolean; // Have we checked the server for a backup we can use?\n private sendingBackups: boolean; // Are we currently sending backups?\n private sessionLastCheckAttemptedTime: Record<string, number> = {}; // When did we last try to check the server for a given session id?\n\n public constructor(private readonly baseApis: MatrixClient, public readonly getKey: GetKey) {\n this.checkedForBackup = false;\n this.sendingBackups = false;\n }\n\n public get version(): string | undefined {\n return this.backupInfo && this.backupInfo.version;\n }\n\n /**\n * Performs a quick check to ensure that the backup info looks sane.\n *\n * Throws an error if a problem is detected.\n *\n * @param info - the key backup info\n */\n public static checkBackupVersion(info: IKeyBackupInfo): void {\n const Algorithm = algorithmsByName[info.algorithm];\n if (!Algorithm) {\n throw new Error(\"Unknown backup algorithm: \" + info.algorithm);\n }\n if (typeof info.auth_data !== \"object\") {\n throw new Error(\"Invalid backup data returned\");\n }\n return Algorithm.checkBackupVersion(info);\n }\n\n public static makeAlgorithm(info: IKeyBackupInfo, getKey: GetKey): Promise<BackupAlgorithm> {\n const Algorithm = algorithmsByName[info.algorithm];\n if (!Algorithm) {\n throw new Error(\"Unknown backup algorithm\");\n }\n return Algorithm.init(info.auth_data, getKey);\n }\n\n public async enableKeyBackup(info: IKeyBackupInfo): Promise<void> {\n this.backupInfo = info;\n if (this.algorithm) {\n this.algorithm.free();\n }\n\n this.algorithm = await BackupManager.makeAlgorithm(info, this.getKey);\n\n this.baseApis.emit(CryptoEvent.KeyBackupStatus, true);\n\n // There may be keys left over from a partially completed backup, so\n // schedule a send to check.\n this.scheduleKeyBackupSend();\n }\n\n /**\n * Disable backing up of keys.\n */\n public disableKeyBackup(): void {\n if (this.algorithm) {\n this.algorithm.free();\n }\n this.algorithm = undefined;\n\n this.backupInfo = undefined;\n\n this.baseApis.emit(CryptoEvent.KeyBackupStatus, false);\n }\n\n public getKeyBackupEnabled(): boolean | null {\n if (!this.checkedForBackup) {\n return null;\n }\n return Boolean(this.algorithm);\n }\n\n public async prepareKeyBackupVersion(\n key?: string | Uint8Array | null,\n algorithm?: string | undefined,\n ): Promise<IPreparedKeyBackupVersion> {\n const Algorithm = algorithm ? algorithmsByName[algorithm] : DefaultAlgorithm;\n if (!Algorithm) {\n throw new Error(\"Unknown backup algorithm\");\n }\n\n const [privateKey, authData] = await Algorithm.prepare(key);\n const recoveryKey = encodeRecoveryKey(privateKey)!;\n return {\n algorithm: Algorithm.algorithmName,\n auth_data: authData,\n recovery_key: recoveryKey,\n privateKey,\n };\n }\n\n public async createKeyBackupVersion(info: IKeyBackupInfo): Promise<void> {\n this.algorithm = await BackupManager.makeAlgorithm(info, this.getKey);\n }\n\n /**\n * Check the server for an active key backup and\n * if one is present and has a valid signature from\n * one of the user's verified devices, start backing up\n * to it.\n */\n public async checkAndStart(): Promise<IKeyBackupCheck | null> {\n logger.log(\"Checking key backup status...\");\n if (this.baseApis.isGuest()) {\n logger.log(\"Skipping key backup check since user is guest\");\n this.checkedForBackup = true;\n return null;\n }\n let backupInfo: IKeyBackupInfo | undefined;\n try {\n backupInfo = (await this.baseApis.getKeyBackupVersion()) ?? undefined;\n } catch (e) {\n logger.log(\"Error checking for active key backup\", e);\n if ((<HTTPError>e).httpStatus === 404) {\n // 404 is returned when the key backup does not exist, so that\n // counts as successfully checking.\n this.checkedForBackup = true;\n }\n return null;\n }\n this.checkedForBackup = true;\n\n const trustInfo = await this.isKeyBackupTrusted(backupInfo);\n\n if (trustInfo.usable && !this.backupInfo) {\n logger.log(`Found usable key backup v${backupInfo!.version}: enabling key backups`);\n await this.enableKeyBackup(backupInfo!);\n } else if (!trustInfo.usable && this.backupInfo) {\n logger.log(\"No usable key backup: disabling key backup\");\n this.disableKeyBackup();\n } else if (!trustInfo.usable && !this.backupInfo) {\n logger.log(\"No usable key backup: not enabling key backup\");\n } else if (trustInfo.usable && this.backupInfo) {\n // may not be the same version: if not, we should switch\n if (backupInfo!.version !== this.backupInfo.version) {\n logger.log(\n `On backup version ${this.backupInfo.version} but ` +\n `found version ${backupInfo!.version}: switching.`,\n );\n this.disableKeyBackup();\n await this.enableKeyBackup(backupInfo!);\n // We're now using a new backup, so schedule all the keys we have to be\n // uploaded to the new backup. This is a bit of a workaround to upload\n // keys to a new backup in *most* cases, but it won't cover all cases\n // because we don't remember what backup version we uploaded keys to:\n // see https://github.com/vector-im/element-web/issues/14833\n await this.scheduleAllGroupSessionsForBackup();\n } else {\n logger.log(`Backup version ${backupInfo!.version} still current`);\n }\n }\n\n return { backupInfo, trustInfo };\n }\n\n /**\n * Forces a re-check of the key backup and enables/disables it\n * as appropriate.\n *\n * @returns Object with backup info (as returned by\n * getKeyBackupVersion) in backupInfo and\n * trust information (as returned by isKeyBackupTrusted)\n * in trustInfo.\n */\n public async checkKeyBackup(): Promise<IKeyBackupCheck | null> {\n this.checkedForBackup = false;\n return this.checkAndStart();\n }\n\n /**\n * Attempts to retrieve a session from a key backup, if enough time\n * has elapsed since the last check for this session id.\n */\n public async queryKeyBackupRateLimited(\n targetRoomId: string | undefined,\n targetSessionId: string | undefined,\n ): Promise<void> {\n if (!this.backupInfo) {\n return;\n }\n\n const now = new Date().getTime();\n if (\n !this.sessionLastCheckAttemptedTime[targetSessionId!] ||\n now - this.sessionLastCheckAttemptedTime[targetSessionId!] > KEY_BACKUP_CHECK_RATE_LIMIT\n ) {\n this.sessionLastCheckAttemptedTime[targetSessionId!] = now;\n await this.baseApis.restoreKeyBackupWithCache(targetRoomId!, targetSessionId!, this.backupInfo, {});\n }\n }\n\n /**\n * Check if the given backup info is trusted.\n *\n * @param backupInfo - key backup info dict from /room_keys/version\n */\n public async isKeyBackupTrusted(backupInfo?: IKeyBackupInfo): Promise<TrustInfo> {\n const ret = {\n usable: false,\n trusted_locally: false,\n sigs: [] as SigInfo[],\n };\n\n if (!backupInfo || !backupInfo.algorithm || !backupInfo.auth_data || !backupInfo.auth_data.signatures) {\n logger.info(\"Key backup is absent or missing required data\");\n return ret;\n }\n\n const userId = this.baseApis.getUserId()!;\n const privKey = await this.baseApis.crypto!.getSessionBackupPrivateKey();\n if (privKey) {\n let algorithm: BackupAlgorithm | null = null;\n try {\n algorithm = await BackupManager.makeAlgorithm(backupInfo, async () => privKey);\n\n if (await algorithm.keyMatches(privKey)) {\n logger.info(\"Backup is trusted locally\");\n ret.trusted_locally = true;\n }\n } catch {\n // do nothing -- if we have an error, then we don't mark it as\n // locally trusted\n } finally {\n algorithm?.free();\n }\n }\n\n const mySigs = backupInfo.auth_data.signatures[userId] || {};\n\n for (const keyId of Object.keys(mySigs)) {\n const keyIdParts = keyId.split(\":\");\n if (keyIdParts[0] !== \"ed25519\") {\n logger.log(\"Ignoring unknown signature type: \" + keyIdParts[0]);\n continue;\n }\n // Could be a cross-signing master key, but just say this is the device\n // ID for backwards compat\n const sigInfo: SigInfo = { deviceId: keyIdParts[1] };\n\n // first check to see if it's from our cross-signing key\n const crossSigningId = this.baseApis.crypto!.crossSigningInfo.getId();\n if (crossSigningId === sigInfo.deviceId) {\n sigInfo.crossSigningId = true;\n try {\n await verifySignature(\n this.baseApis.crypto!.olmDevice,\n backupInfo.auth_data,\n userId,\n sigInfo.deviceId,\n crossSigningId,\n );\n sigInfo.valid = true;\n } catch (e) {\n logger.warn(\"Bad signature from cross signing key \" + crossSigningId, e);\n sigInfo.valid = false;\n }\n ret.sigs.push(sigInfo);\n continue;\n }\n\n // Now look for a sig from a device\n // At some point this can probably go away and we'll just support\n // it being signed by the cross-signing master key\n const device = this.baseApis.crypto!.deviceList.getStoredDevice(userId, sigInfo.deviceId);\n if (device) {\n sigInfo.device = device;\n sigInfo.deviceTrust = this.baseApis.checkDeviceTrust(userId, sigInfo.deviceId);\n try {\n await verifySignature(\n this.baseApis.crypto!.olmDevice,\n backupInfo.auth_data,\n userId,\n device.deviceId,\n device.getFingerprint(),\n );\n sigInfo.valid = true;\n } catch (e) {\n logger.info(\n \"Bad signature from key ID \" +\n keyId +\n \" userID \" +\n this.baseApis.getUserId() +\n \" device ID \" +\n device.deviceId +\n \" fingerprint: \" +\n device.getFingerprint(),\n backupInfo.auth_data,\n e,\n );\n sigInfo.valid = false;\n }\n } else {\n sigInfo.valid = null; // Can't determine validity because we don't have the signing device\n logger.info(\"Ignoring signature from unknown key \" + keyId);\n }\n ret.sigs.push(sigInfo);\n }\n\n ret.usable = ret.sigs.some((s) => {\n return s.valid && ((s.device && s.deviceTrust?.isVerified()) || s.crossSigningId);\n });\n return ret;\n }\n\n /**\n * Schedules sending all keys waiting to be sent to the backup, if not already\n * scheduled. Retries if necessary.\n *\n * @param maxDelay - Maximum delay to wait in ms. 0 means no delay.\n */\n public async scheduleKeyBackupSend(maxDelay = 10000): Promise<void> {\n if (this.sendingBackups) return;\n\n this.sendingBackups = true;\n\n try {\n // wait between 0 and `maxDelay` seconds, to avoid backup\n // requests from different clients hitting the server all at\n // the same time when a new key is sent\n const delay = Math.random() * maxDelay;\n await sleep(delay);\n let numFailures = 0; // number of consecutive failures\n for (;;) {\n if (!this.algorithm) {\n return;\n }\n try {\n const numBackedUp = await this.backupPendingKeys(KEY_BACKUP_KEYS_PER_REQUEST);\n if (numBackedUp === 0) {\n // no sessions left needing backup: we're done\n return;\n }\n numFailures = 0;\n } catch (err) {\n numFailures++;\n logger.log(\"Key backup request failed\", err);\n if ((<MatrixError>err).data) {\n if (\n (<MatrixError>err).data.errcode == \"M_NOT_FOUND\" ||\n (<MatrixError>err).data.errcode == \"M_WRONG_ROOM_KEYS_VERSION\"\n ) {\n // Re-check key backup status on error, so we can be\n // sure to present the current situation when asked.\n await this.checkKeyBackup();\n // Backup version has changed or this backup version\n // has been deleted\n this.baseApis.crypto!.emit(CryptoEvent.KeyBackupFailed, (<MatrixError>err).data.errcode!);\n throw err;\n }\n }\n }\n if (numFailures) {\n // exponential backoff if we have failures\n await sleep(1000 * Math.pow(2, Math.min(numFailures - 1, 4)));\n }\n }\n } finally {\n this.sendingBackups = false;\n }\n }\n\n /**\n * Take some e2e keys waiting to be backed up and send them\n * to the backup.\n *\n * @param limit - Maximum number of keys to back up\n * @returns Number of sessions backed up\n */\n public async backupPendingKeys(limit: number): Promise<number> {\n const sessions = await this.baseApis.crypto!.cryptoStore.getSessionsNeedingBackup(limit);\n if (!sessions.length) {\n return 0;\n }\n\n let remaining = await this.baseApis.crypto!.cryptoStore.countSessionsNeedingBackup();\n this.baseApis.crypto!.emit(CryptoEvent.KeyBackupSessionsRemaining, remaining);\n\n const rooms: IKeyBackup[\"rooms\"] = {};\n for (const session of sessions) {\n const roomId = session.sessionData!.room_id;\n safeSet(rooms, roomId, rooms[roomId] || { sessions: {} });\n\n const sessionData = this.baseApis.crypto!.olmDevice.exportInboundGroupSession(\n session.senderKey,\n session.sessionId,\n session.sessionData!,\n );\n sessionData.algorithm = MEGOLM_ALGORITHM;\n\n const forwardedCount = (sessionData.forwarding_curve25519_key_chain || []).length;\n\n const userId = this.baseApis.crypto!.deviceList.getUserByIdentityKey(MEGOLM_ALGORITHM, session.senderKey);\n const device =\n this.baseApis.crypto!.deviceList.getDeviceByIdentityKey(MEGOLM_ALGORITHM, session.senderKey) ??\n undefined;\n const verified = this.baseApis.crypto!.checkDeviceInfoTrust(userId!, device).isVerified();\n\n safeSet(rooms[roomId][\"sessions\"], session.sessionId, {\n first_message_index: sessionData.first_known_index,\n forwarded_count: forwardedCount,\n is_verified: verified,\n session_data: await this.algorithm!.encryptSession(sessionData),\n });\n }\n\n await this.baseApis.sendKeyBackup(undefined, undefined, this.backupInfo!.version, { rooms });\n\n await this.baseApis.crypto!.cryptoStore.unmarkSessionsNeedingBackup(sessions);\n remaining = await this.baseApis.crypto!.cryptoStore.countSessionsNeedingBackup();\n this.baseApis.crypto!.emit(CryptoEvent.KeyBackupSessionsRemaining, remaining);\n\n return sessions.length;\n }\n\n public async backupGroupSession(senderKey: string, sessionId: string): Promise<void> {\n await this.baseApis.crypto!.cryptoStore.markSessionsNeedingBackup([\n {\n senderKey: senderKey,\n sessionId: sessionId,\n },\n ]);\n\n if (this.backupInfo) {\n // don't wait for this to complete: it will delay so\n // happens in the background\n this.scheduleKeyBackupSend();\n }\n // if this.backupInfo is not set, then the keys will be backed up when\n // this.enableKeyBackup is called\n }\n\n /**\n * Marks all group sessions as needing to be backed up and schedules them to\n * upload in the background as soon as possible.\n */\n public async scheduleAllGroupSessionsForBackup(): Promise<void> {\n await this.flagAllGroupSessionsForBackup();\n\n // Schedule keys to upload in the background as soon as possible.\n this.scheduleKeyBackupSend(0 /* maxDelay */);\n }\n\n /**\n * Marks all group sessions as needing to be backed up without scheduling\n * them to upload in the background.\n * @returns Promise which resolves to the number of sessions now requiring a backup\n * (which will be equal to the number of sessions in the store).\n */\n public async flagAllGroupSessionsForBackup(): Promise<number> {\n await this.baseApis.crypto!.cryptoStore.doTxn(\n \"readwrite\",\n [IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS, IndexedDBCryptoStore.STORE_BACKUP],\n (txn) => {\n this.baseApis.crypto!.cryptoStore.getAllEndToEndInboundGroupSessions(txn, (session) => {\n if (session !== null) {\n this.baseApis.crypto!.cryptoStore.markSessionsNeedingBackup([session], txn);\n }\n });\n },\n );\n\n const remaining = await this.baseApis.crypto!.cryptoStore.countSessionsNeedingBackup();\n this.baseApis.emit(CryptoEvent.KeyBackupSessionsRemaining, remaining);\n return remaining;\n }\n\n /**\n * Counts the number of end to end session keys that are waiting to be backed up\n * @returns Promise which resolves to the number of sessions requiring backup\n */\n public countSessionsNeedingBackup(): Promise<number> {\n return this.baseApis.crypto!.cryptoStore.countSessionsNeedingBackup();\n }\n}\n\nexport class Curve25519 implements BackupAlgorithm {\n public static algorithmName = \"m.megolm_backup.v1.curve25519-aes-sha2\";\n\n public constructor(\n public authData: ICurve25519AuthData,\n private publicKey: any, // FIXME: PkEncryption\n private getKey: () => Promise<Uint8Array>,\n ) {}\n\n public static async init(authData: AuthData, getKey: () => Promise<Uint8Array>): Promise<Curve25519> {\n if (!authData || !(\"public_key\" in authData)) {\n throw new Error(\"auth_data missing required information\");\n }\n const publicKey = new global.Olm.PkEncryption();\n publicKey.set_recipient_key(authData.public_key);\n return new Curve25519(authData as ICurve25519AuthData, publicKey, getKey);\n }\n\n public static async prepare(key?: string | Uint8Array | null): Promise<[Uint8Array, AuthData]> {\n const decryption = new global.Olm.PkDecryption();\n try {\n const authData: Partial<ICurve25519AuthData> = {};\n if (!key) {\n authData.public_key = decryption.generate_key();\n } else if (key instanceof Uint8Array) {\n authData.public_key = decryption.init_with_private_key(key);\n } else {\n const derivation = await keyFromPassphrase(key);\n authData.private_key_salt = derivation.salt;\n authData.private_key_iterations = derivation.iterations;\n authData.public_key = decryption.init_with_private_key(derivation.key);\n }\n const publicKey = new global.Olm.PkEncryption();\n publicKey.set_recipient_key(authData.public_key);\n\n return [decryption.get_private_key(), authData as AuthData];\n } finally {\n decryption.free();\n }\n }\n\n public static checkBackupVersion(info: IKeyBackupInfo): void {\n if (!(\"public_key\" in info.auth_data)) {\n throw new Error(\"Invalid backup data returned\");\n }\n }\n\n public get untrusted(): boolean {\n return true;\n }\n\n public async encryptSession(data: Record<string, any>): Promise<Curve25519SessionData> {\n const plainText: Record<string, any> = Object.assign({}, data);\n delete plainText.session_id;\n delete plainText.room_id;\n delete plainText.first_known_index;\n return this.publicKey.encrypt(JSON.stringify(plainText));\n }\n\n public async decryptSessions(\n sessions: Record<string, IKeyBackupSession<Curve25519SessionData>>,\n ): Promise<IMegolmSessionData[]> {\n const privKey = await this.getKey();\n const decryption = new global.Olm.PkDecryption();\n try {\n const backupPubKey = decryption.init_with_private_key(privKey);\n\n if (backupPubKey !== this.authData.public_key) {\n throw new MatrixError({ errcode: MatrixClient.RESTORE_BACKUP_ERROR_BAD_KEY });\n }\n\n const keys: IMegolmSessionData[] = [];\n\n for (const [sessionId, sessionData] of Object.entries(sessions)) {\n try {\n const decrypted = JSON.parse(\n decryption.decrypt(\n sessionData.session_data.ephemeral,\n sessionData.session_data.mac,\n sessionData.session_data.ciphertext,\n ),\n );\n decrypted.session_id = sessionId;\n keys.push(decrypted);\n } catch (e) {\n logger.log(\"Failed to decrypt megolm session from backup\", e, sessionData);\n }\n }\n return keys;\n } finally {\n decryption.free();\n }\n }\n\n public async keyMatches(key: Uint8Array): Promise<boolean> {\n const decryption = new global.Olm.PkDecryption();\n let pubKey: string;\n try {\n pubKey = decryption.init_with_private_key(key);\n } finally {\n decryption.free();\n }\n\n return pubKey === this.authData.public_key;\n }\n\n public free(): void {\n this.publicKey.free();\n }\n}\n\nfunction randomBytes(size: number): Uint8Array {\n const buf = new Uint8Array(size);\n crypto.getRandomValues(buf);\n return buf;\n}\n\nconst UNSTABLE_MSC3270_NAME = new UnstableValue(\n \"m.megolm_backup.v1.aes-hmac-sha2\",\n \"org.matrix.msc3270.v1.aes-hmac-sha2\",\n);\n\nexport class Aes256 implements BackupAlgorithm {\n public static algorithmName = UNSTABLE_MSC3270_NAME.name;\n\n public constructor(public readonly authData: IAes256AuthData, private readonly key: Uint8Array) {}\n\n public static async init(authData: IAes256AuthData, getKey: () => Promise<Uint8Array>): Promise<Aes256> {\n if (!authData) {\n throw new Error(\"auth_data missing\");\n }\n const key = await getKey();\n if (authData.mac) {\n const { mac } = await calculateKeyCheck(key, authData.iv);\n if (authData.mac.replace(/=+$/g, \"\") !== mac.replace(/=+/g, \"\")) {\n throw new Error(\"Key does not match\");\n }\n }\n return new Aes256(authData, key);\n }\n\n public static async prepare(key?: string | Uint8Array | null): Promise<[Uint8Array, AuthData]> {\n let outKey: Uint8Array;\n const authData: Partial<IAes256AuthData> = {};\n if (!key) {\n outKey = randomBytes(32);\n } else if (key instanceof Uint8Array) {\n outKey = new Uint8Array(key);\n } else {\n const derivation = await keyFromPassphrase(key);\n authData.private_key_salt = derivation.salt;\n authData.private_key_iterations = derivation.iterations;\n outKey = derivation.key;\n }\n\n const { iv, mac } = await calculateKeyCheck(outKey);\n authData.iv = iv;\n authData.mac = mac;\n\n return [outKey, authData as AuthData];\n }\n\n public static checkBackupVersion(info: IKeyBackupInfo): void {\n if (!(\"iv\" in info.auth_data && \"mac\" in info.auth_data)) {\n throw new Error(\"Invalid backup data returned\");\n }\n }\n\n public get untrusted(): boolean {\n return false;\n }\n\n public encryptSession(data: Record<string, any>): Promise<IEncryptedPayload> {\n const plainText: Record<string, any> = Object.assign({}, data);\n delete plainText.session_id;\n delete plainText.room_id;\n delete plainText.first_known_index;\n return encryptAES(JSON.stringify(plainText), this.key, data.session_id);\n }\n\n public async decryptSessions(\n sessions: Record<string, IKeyBackupSession<IEncryptedPayload>>,\n ): Promise<IMegolmSessionData[]> {\n const keys: IMegolmSessionData[] = [];\n\n for (const [sessionId, sessionData] of Object.entries(sessions)) {\n try {\n const decrypted = JSON.parse(await decryptAES(sessionData.session_data, this.key, sessionId));\n decrypted.session_id = sessionId;\n keys.push(decrypted);\n } catch (e) {\n logger.log(\"Failed to decrypt megolm session from backup\", e, sessionData);\n }\n }\n return keys;\n }\n\n public async keyMatches(key: Uint8Array): Promise<boolean> {\n if (this.authData.mac) {\n const { mac } = await calculateKeyCheck(key, this.authData.iv);\n return this.authData.mac.replace(/=+$/g, \"\") === mac.replace(/=+/g, \"\");\n } else {\n // if we have no information, we have to assume the key is right\n return true;\n }\n }\n\n public free(): void {\n this.key.fill(0);\n }\n}\n\nexport const algorithmsByName: Record<string, BackupAlgorithmClass> = {\n [Curve25519.algorithmName]: Curve25519,\n [Aes256.algorithmName]: Aes256,\n};\n\nexport const DefaultAlgorithm: BackupAlgorithmClass = Curve25519;\n"],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/crypto.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/crypto.d.ts
deleted file mode 100644
index 8078b5f..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/crypto.d.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-export declare let crypto: Crypto;
-export declare let subtleCrypto: SubtleCrypto;
-export declare let TextEncoder: {
- new (): TextEncoder;
- prototype: TextEncoder;
-};
-export declare function setCrypto(_crypto: Crypto): void;
-export declare function setTextEncoder(_TextEncoder: typeof TextEncoder): void;
-//# sourceMappingURL=crypto.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/crypto.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/crypto.d.ts.map
deleted file mode 100644
index c5a2d62..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/crypto.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../../src/crypto/crypto.ts"],"names":[],"mappings":"AAkBA,eAAO,IAAI,MAAM,QAAwB,CAAC;AAC1C,eAAO,IAAI,YAAY,cAAuE,CAAC;AAC/F,eAAO,IAAI,WAAW;;;CAA6B,CAAC;AAsBpD,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAG/C;AAED,wBAAgB,cAAc,CAAC,YAAY,EAAE,OAAO,WAAW,GAAG,IAAI,CAErE"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/crypto.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/crypto.js
deleted file mode 100644
index a622f2e..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/crypto.js
+++ /dev/null
@@ -1,48 +0,0 @@
-"use strict";
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.crypto = exports.TextEncoder = void 0;
-exports.setCrypto = setCrypto;
-exports.setTextEncoder = setTextEncoder;
-exports.subtleCrypto = void 0;
-var _logger = require("../logger");
-var _global$window, _global$window$crypto, _global$window2, _global$window2$crypt, _global$window3, _global$window3$crypt, _global$window4;
-let crypto = (_global$window = global.window) === null || _global$window === void 0 ? void 0 : _global$window.crypto;
-exports.crypto = crypto;
-let subtleCrypto = (_global$window$crypto = (_global$window2 = global.window) === null || _global$window2 === void 0 ? void 0 : (_global$window2$crypt = _global$window2.crypto) === null || _global$window2$crypt === void 0 ? void 0 : _global$window2$crypt.subtle) !== null && _global$window$crypto !== void 0 ? _global$window$crypto : (_global$window3 = global.window) === null || _global$window3 === void 0 ? void 0 : (_global$window3$crypt = _global$window3.crypto) === null || _global$window3$crypt === void 0 ? void 0 : _global$window3$crypt.webkitSubtle;
-exports.subtleCrypto = subtleCrypto;
-let TextEncoder = (_global$window4 = global.window) === null || _global$window4 === void 0 ? void 0 : _global$window4.TextEncoder;
-
-/* eslint-disable @typescript-eslint/no-var-requires */
-exports.TextEncoder = TextEncoder;
-if (!crypto) {
- try {
- exports.crypto = crypto = require("crypto").webcrypto;
- } catch (e) {
- _logger.logger.error("Failed to load webcrypto", e);
- }
-}
-if (!subtleCrypto) {
- var _crypto2;
- exports.subtleCrypto = subtleCrypto = (_crypto2 = crypto) === null || _crypto2 === void 0 ? void 0 : _crypto2.subtle;
-}
-if (!TextEncoder) {
- try {
- exports.TextEncoder = TextEncoder = require("util").TextEncoder;
- } catch (e) {
- _logger.logger.error("Failed to load TextEncoder util", e);
- }
-}
-/* eslint-enable @typescript-eslint/no-var-requires */
-
-function setCrypto(_crypto) {
- var _crypto$subtle;
- exports.crypto = crypto = _crypto;
- exports.subtleCrypto = subtleCrypto = (_crypto$subtle = _crypto.subtle) !== null && _crypto$subtle !== void 0 ? _crypto$subtle : _crypto.webkitSubtle;
-}
-function setTextEncoder(_TextEncoder) {
- exports.TextEncoder = TextEncoder = _TextEncoder;
-}
-//# sourceMappingURL=crypto.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/crypto.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/crypto.js.map
deleted file mode 100644
index 8dc5b69..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/crypto.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"crypto.js","names":["_logger","require","_global$window","_global$window$crypto","_global$window2","_global$window2$crypt","_global$window3","_global$window3$crypt","_global$window4","crypto","global","window","exports","subtleCrypto","subtle","webkitSubtle","TextEncoder","webcrypto","e","logger","error","_crypto2","setCrypto","_crypto","_crypto$subtle","setTextEncoder","_TextEncoder"],"sources":["../../src/crypto/crypto.ts"],"sourcesContent":["/*\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { logger } from \"../logger\";\n\nexport let crypto = global.window?.crypto;\nexport let subtleCrypto = global.window?.crypto?.subtle ?? global.window?.crypto?.webkitSubtle;\nexport let TextEncoder = global.window?.TextEncoder;\n\n/* eslint-disable @typescript-eslint/no-var-requires */\nif (!crypto) {\n try {\n crypto = require(\"crypto\").webcrypto;\n } catch (e) {\n logger.error(\"Failed to load webcrypto\", e);\n }\n}\nif (!subtleCrypto) {\n subtleCrypto = crypto?.subtle;\n}\nif (!TextEncoder) {\n try {\n TextEncoder = require(\"util\").TextEncoder;\n } catch (e) {\n logger.error(\"Failed to load TextEncoder util\", e);\n }\n}\n/* eslint-enable @typescript-eslint/no-var-requires */\n\nexport function setCrypto(_crypto: Crypto): void {\n crypto = _crypto;\n subtleCrypto = _crypto.subtle ?? _crypto.webkitSubtle;\n}\n\nexport function setTextEncoder(_TextEncoder: typeof TextEncoder): void {\n TextEncoder = _TextEncoder;\n}\n"],"mappings":";;;;;;;;;AAgBA,IAAAA,OAAA,GAAAC,OAAA;AAAmC,IAAAC,cAAA,EAAAC,qBAAA,EAAAC,eAAA,EAAAC,qBAAA,EAAAC,eAAA,EAAAC,qBAAA,EAAAC,eAAA;AAE5B,IAAIC,MAAM,IAAAP,cAAA,GAAGQ,MAAM,CAACC,MAAM,cAAAT,cAAA,uBAAbA,cAAA,CAAeO,MAAM;AAACG,OAAA,CAAAH,MAAA,GAAAA,MAAA;AACnC,IAAII,YAAY,IAAAV,qBAAA,IAAAC,eAAA,GAAGM,MAAM,CAACC,MAAM,cAAAP,eAAA,wBAAAC,qBAAA,GAAbD,eAAA,CAAeK,MAAM,cAAAJ,qBAAA,uBAArBA,qBAAA,CAAuBS,MAAM,cAAAX,qBAAA,cAAAA,qBAAA,IAAAG,eAAA,GAAII,MAAM,CAACC,MAAM,cAAAL,eAAA,wBAAAC,qBAAA,GAAbD,eAAA,CAAeG,MAAM,cAAAF,qBAAA,uBAArBA,qBAAA,CAAuBQ,YAAY;AAACH,OAAA,CAAAC,YAAA,GAAAA,YAAA;AACxF,IAAIG,WAAW,IAAAR,eAAA,GAAGE,MAAM,CAACC,MAAM,cAAAH,eAAA,uBAAbA,eAAA,CAAeQ,WAAW;;AAEnD;AAAAJ,OAAA,CAAAI,WAAA,GAAAA,WAAA;AACA,IAAI,CAACP,MAAM,EAAE;EACT,IAAI;IACAG,OAAA,CAAAH,MAAA,GAAAA,MAAM,GAAGR,OAAO,CAAC,QAAQ,CAAC,CAACgB,SAAS;EACxC,CAAC,CAAC,OAAOC,CAAC,EAAE;IACRC,cAAM,CAACC,KAAK,CAAC,0BAA0B,EAAEF,CAAC,CAAC;EAC/C;AACJ;AACA,IAAI,CAACL,YAAY,EAAE;EAAA,IAAAQ,QAAA;EACfT,OAAA,CAAAC,YAAA,GAAAA,YAAY,IAAAQ,QAAA,GAAGZ,MAAM,cAAAY,QAAA,uBAANA,QAAA,CAAQP,MAAM;AACjC;AACA,IAAI,CAACE,WAAW,EAAE;EACd,IAAI;IACAJ,OAAA,CAAAI,WAAA,GAAAA,WAAW,GAAGf,OAAO,CAAC,MAAM,CAAC,CAACe,WAAW;EAC7C,CAAC,CAAC,OAAOE,CAAC,EAAE;IACRC,cAAM,CAACC,KAAK,CAAC,iCAAiC,EAAEF,CAAC,CAAC;EACtD;AACJ;AACA;;AAEO,SAASI,SAASA,CAACC,OAAe,EAAQ;EAAA,IAAAC,cAAA;EAC7CZ,OAAA,CAAAH,MAAA,GAAAA,MAAM,GAAGc,OAAO;EAChBX,OAAA,CAAAC,YAAA,GAAAA,YAAY,IAAAW,cAAA,GAAGD,OAAO,CAACT,MAAM,cAAAU,cAAA,cAAAA,cAAA,GAAID,OAAO,CAACR,YAAY;AACzD;AAEO,SAASU,cAAcA,CAACC,YAAgC,EAAQ;EACnEd,OAAA,CAAAI,WAAA,GAAAA,WAAW,GAAGU,YAAY;AAC9B"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/dehydration.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/dehydration.d.ts
deleted file mode 100644
index 2087b6a..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/dehydration.d.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-import { Crypto } from "./index";
-import { SecretStorageKeyDescription } from "../secret-storage";
-export interface IDehydratedDevice {
- device_id: string;
- device_data: SecretStorageKeyDescription & {
- algorithm: string;
- account: string;
- };
-}
-export interface IDehydratedDeviceKeyInfo {
- passphrase?: string;
-}
-export declare const DEHYDRATION_ALGORITHM = "org.matrix.msc2697.v1.olm.libolm_pickle";
-export declare class DehydrationManager {
- private readonly crypto;
- private inProgress;
- private timeoutId;
- private key?;
- private keyInfo?;
- private deviceDisplayName?;
- constructor(crypto: Crypto);
- getDehydrationKeyFromCache(): Promise<void>;
- /** set the key, and queue periodic dehydration to the server in the background */
- setKeyAndQueueDehydration(key: Uint8Array, keyInfo?: {
- [props: string]: any;
- }, deviceDisplayName?: string): Promise<void>;
- setKey(key: Uint8Array, keyInfo?: {
- [props: string]: any;
- }, deviceDisplayName?: string): Promise<boolean | undefined>;
- /** returns the device id of the newly created dehydrated device */
- dehydrateDevice(): Promise<string | undefined>;
- stop(): void;
-}
-//# sourceMappingURL=dehydration.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/dehydration.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/dehydration.d.ts.map
deleted file mode 100644
index 1908ae6..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/dehydration.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"dehydration.d.ts","sourceRoot":"","sources":["../../src/crypto/dehydration.ts"],"names":[],"mappings":"AAuBA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEjC,OAAO,EAAE,2BAA2B,EAAE,MAAM,mBAAmB,CAAC;AAEhE,MAAM,WAAW,iBAAiB;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,2BAA2B,GAAG;QAEvC,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;KACnB,CAAC;CACL;AAED,MAAM,WAAW,wBAAwB;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,eAAO,MAAM,qBAAqB,4CAA4C,CAAC;AAI/E,qBAAa,kBAAkB;IAOR,OAAO,CAAC,QAAQ,CAAC,MAAM;IAN1C,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,SAAS,CAAM;IACvB,OAAO,CAAC,GAAG,CAAC,CAAa;IACzB,OAAO,CAAC,OAAO,CAAC,CAA2B;IAC3C,OAAO,CAAC,iBAAiB,CAAC,CAAS;gBAEC,MAAM,EAAE,MAAM;IAI3C,0BAA0B,IAAI,OAAO,CAAC,IAAI,CAAC;IAsBlD,kFAAkF;IACrE,yBAAyB,CAClC,GAAG,EAAE,UAAU,EACf,OAAO,GAAE;QAAE,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAAA;KAAO,EACtC,iBAAiB,CAAC,EAAE,MAAM,GAC3B,OAAO,CAAC,IAAI,CAAC;IAQH,MAAM,CACf,GAAG,EAAE,UAAU,EACf,OAAO,GAAE;QAAE,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAAA;KAAO,EACtC,iBAAiB,CAAC,EAAE,MAAM,GAC3B,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC;IAkC/B,mEAAmE;IACtD,eAAe,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAuIpD,IAAI,IAAI,IAAI;CAMtB"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/dehydration.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/dehydration.js
deleted file mode 100644
index 2a00aa7..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/dehydration.js
+++ /dev/null
@@ -1,238 +0,0 @@
-"use strict";
-
-var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.DehydrationManager = exports.DEHYDRATION_ALGORITHM = void 0;
-var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
-var _anotherJson = _interopRequireDefault(require("another-json"));
-var _olmlib = require("./olmlib");
-var _indexeddbCryptoStore = require("../crypto/store/indexeddb-crypto-store");
-var _aes = require("./aes");
-var _logger = require("../logger");
-var _httpApi = require("../http-api");
-/*
-Copyright 2020-2021 The Matrix.org Foundation C.I.C.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-const DEHYDRATION_ALGORITHM = "org.matrix.msc2697.v1.olm.libolm_pickle";
-exports.DEHYDRATION_ALGORITHM = DEHYDRATION_ALGORITHM;
-const oneweek = 7 * 24 * 60 * 60 * 1000;
-class DehydrationManager {
- constructor(crypto) {
- this.crypto = crypto;
- (0, _defineProperty2.default)(this, "inProgress", false);
- (0, _defineProperty2.default)(this, "timeoutId", void 0);
- (0, _defineProperty2.default)(this, "key", void 0);
- (0, _defineProperty2.default)(this, "keyInfo", void 0);
- (0, _defineProperty2.default)(this, "deviceDisplayName", void 0);
- this.getDehydrationKeyFromCache();
- }
- getDehydrationKeyFromCache() {
- return this.crypto.cryptoStore.doTxn("readonly", [_indexeddbCryptoStore.IndexedDBCryptoStore.STORE_ACCOUNT], txn => {
- this.crypto.cryptoStore.getSecretStorePrivateKey(txn, async result => {
- if (result) {
- const {
- key,
- keyInfo,
- deviceDisplayName,
- time
- } = result;
- const pickleKey = Buffer.from(this.crypto.olmDevice.pickleKey);
- const decrypted = await (0, _aes.decryptAES)(key, pickleKey, DEHYDRATION_ALGORITHM);
- this.key = (0, _olmlib.decodeBase64)(decrypted);
- this.keyInfo = keyInfo;
- this.deviceDisplayName = deviceDisplayName;
- const now = Date.now();
- const delay = Math.max(1, time + oneweek - now);
- this.timeoutId = global.setTimeout(this.dehydrateDevice.bind(this), delay);
- }
- }, "dehydration");
- });
- }
-
- /** set the key, and queue periodic dehydration to the server in the background */
- async setKeyAndQueueDehydration(key, keyInfo = {}, deviceDisplayName) {
- const matches = await this.setKey(key, keyInfo, deviceDisplayName);
- if (!matches) {
- // start dehydration in the background
- this.dehydrateDevice();
- }
- }
- async setKey(key, keyInfo = {}, deviceDisplayName) {
- if (!key) {
- // unsetting the key -- cancel any pending dehydration task
- if (this.timeoutId) {
- global.clearTimeout(this.timeoutId);
- this.timeoutId = undefined;
- }
- // clear storage
- await this.crypto.cryptoStore.doTxn("readwrite", [_indexeddbCryptoStore.IndexedDBCryptoStore.STORE_ACCOUNT], txn => {
- this.crypto.cryptoStore.storeSecretStorePrivateKey(txn, "dehydration", null);
- });
- this.key = undefined;
- this.keyInfo = undefined;
- return;
- }
-
- // Check to see if it's the same key as before. If it's different,
- // dehydrate a new device. If it's the same, we can keep the same
- // device. (Assume that keyInfo and deviceDisplayName will be the
- // same if the key is the same.)
- let matches = !!this.key && key.length == this.key.length;
- for (let i = 0; matches && i < key.length; i++) {
- if (key[i] != this.key[i]) {
- matches = false;
- }
- }
- if (!matches) {
- this.key = key;
- this.keyInfo = keyInfo;
- this.deviceDisplayName = deviceDisplayName;
- }
- return matches;
- }
-
- /** returns the device id of the newly created dehydrated device */
- async dehydrateDevice() {
- if (this.inProgress) {
- _logger.logger.log("Dehydration already in progress -- not starting new dehydration");
- return;
- }
- this.inProgress = true;
- if (this.timeoutId) {
- global.clearTimeout(this.timeoutId);
- this.timeoutId = undefined;
- }
- try {
- const pickleKey = Buffer.from(this.crypto.olmDevice.pickleKey);
-
- // update the crypto store with the timestamp
- const key = await (0, _aes.encryptAES)((0, _olmlib.encodeBase64)(this.key), pickleKey, DEHYDRATION_ALGORITHM);
- await this.crypto.cryptoStore.doTxn("readwrite", [_indexeddbCryptoStore.IndexedDBCryptoStore.STORE_ACCOUNT], txn => {
- this.crypto.cryptoStore.storeSecretStorePrivateKey(txn, "dehydration", {
- keyInfo: this.keyInfo,
- key,
- deviceDisplayName: this.deviceDisplayName,
- time: Date.now()
- });
- });
- _logger.logger.log("Attempting to dehydrate device");
- _logger.logger.log("Creating account");
- // create the account and all the necessary keys
- const account = new global.Olm.Account();
- account.create();
- const e2eKeys = JSON.parse(account.identity_keys());
- const maxKeys = account.max_number_of_one_time_keys();
- // FIXME: generate in small batches?
- account.generate_one_time_keys(maxKeys / 2);
- account.generate_fallback_key();
- const otks = JSON.parse(account.one_time_keys());
- const fallbacks = JSON.parse(account.fallback_key());
- account.mark_keys_as_published();
-
- // dehydrate the account and store it on the server
- const pickledAccount = account.pickle(new Uint8Array(this.key));
- const deviceData = {
- algorithm: DEHYDRATION_ALGORITHM,
- account: pickledAccount
- };
- if (this.keyInfo.passphrase) {
- deviceData.passphrase = this.keyInfo.passphrase;
- }
- _logger.logger.log("Uploading account to server");
- // eslint-disable-next-line camelcase
- const dehydrateResult = await this.crypto.baseApis.http.authedRequest(_httpApi.Method.Put, "/dehydrated_device", undefined, {
- device_data: deviceData,
- initial_device_display_name: this.deviceDisplayName
- }, {
- prefix: "/_matrix/client/unstable/org.matrix.msc2697.v2"
- });
-
- // send the keys to the server
- const deviceId = dehydrateResult.device_id;
- _logger.logger.log("Preparing device keys", deviceId);
- const deviceKeys = {
- algorithms: this.crypto.supportedAlgorithms,
- device_id: deviceId,
- user_id: this.crypto.userId,
- keys: {
- [`ed25519:${deviceId}`]: e2eKeys.ed25519,
- [`curve25519:${deviceId}`]: e2eKeys.curve25519
- }
- };
- const deviceSignature = account.sign(_anotherJson.default.stringify(deviceKeys));
- deviceKeys.signatures = {
- [this.crypto.userId]: {
- [`ed25519:${deviceId}`]: deviceSignature
- }
- };
- if (this.crypto.crossSigningInfo.getId("self_signing")) {
- await this.crypto.crossSigningInfo.signObject(deviceKeys, "self_signing");
- }
- _logger.logger.log("Preparing one-time keys");
- const oneTimeKeys = {};
- for (const [keyId, key] of Object.entries(otks.curve25519)) {
- const k = {
- key
- };
- const signature = account.sign(_anotherJson.default.stringify(k));
- k.signatures = {
- [this.crypto.userId]: {
- [`ed25519:${deviceId}`]: signature
- }
- };
- oneTimeKeys[`signed_curve25519:${keyId}`] = k;
- }
- _logger.logger.log("Preparing fallback keys");
- const fallbackKeys = {};
- for (const [keyId, key] of Object.entries(fallbacks.curve25519)) {
- const k = {
- key,
- fallback: true
- };
- const signature = account.sign(_anotherJson.default.stringify(k));
- k.signatures = {
- [this.crypto.userId]: {
- [`ed25519:${deviceId}`]: signature
- }
- };
- fallbackKeys[`signed_curve25519:${keyId}`] = k;
- }
- _logger.logger.log("Uploading keys to server");
- await this.crypto.baseApis.http.authedRequest(_httpApi.Method.Post, "/keys/upload/" + encodeURI(deviceId), undefined, {
- "device_keys": deviceKeys,
- "one_time_keys": oneTimeKeys,
- "org.matrix.msc2732.fallback_keys": fallbackKeys
- });
- _logger.logger.log("Done dehydrating");
-
- // dehydrate again in a week
- this.timeoutId = global.setTimeout(this.dehydrateDevice.bind(this), oneweek);
- return deviceId;
- } finally {
- this.inProgress = false;
- }
- }
- stop() {
- if (this.timeoutId) {
- global.clearTimeout(this.timeoutId);
- this.timeoutId = undefined;
- }
- }
-}
-exports.DehydrationManager = DehydrationManager;
-//# sourceMappingURL=dehydration.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/dehydration.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/dehydration.js.map
deleted file mode 100644
index 385d71f..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/dehydration.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"dehydration.js","names":["_anotherJson","_interopRequireDefault","require","_olmlib","_indexeddbCryptoStore","_aes","_logger","_httpApi","DEHYDRATION_ALGORITHM","exports","oneweek","DehydrationManager","constructor","crypto","_defineProperty2","default","getDehydrationKeyFromCache","cryptoStore","doTxn","IndexedDBCryptoStore","STORE_ACCOUNT","txn","getSecretStorePrivateKey","result","key","keyInfo","deviceDisplayName","time","pickleKey","Buffer","from","olmDevice","decrypted","decryptAES","decodeBase64","now","Date","delay","Math","max","timeoutId","global","setTimeout","dehydrateDevice","bind","setKeyAndQueueDehydration","matches","setKey","clearTimeout","undefined","storeSecretStorePrivateKey","length","i","inProgress","logger","log","encryptAES","encodeBase64","account","Olm","Account","create","e2eKeys","JSON","parse","identity_keys","maxKeys","max_number_of_one_time_keys","generate_one_time_keys","generate_fallback_key","otks","one_time_keys","fallbacks","fallback_key","mark_keys_as_published","pickledAccount","pickle","Uint8Array","deviceData","algorithm","passphrase","dehydrateResult","baseApis","http","authedRequest","Method","Put","device_data","initial_device_display_name","prefix","deviceId","device_id","deviceKeys","algorithms","supportedAlgorithms","user_id","userId","keys","ed25519","curve25519","deviceSignature","sign","anotherjson","stringify","signatures","crossSigningInfo","getId","signObject","oneTimeKeys","keyId","Object","entries","k","signature","fallbackKeys","fallback","Post","encodeURI","stop"],"sources":["../../src/crypto/dehydration.ts"],"sourcesContent":["/*\nCopyright 2020-2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport anotherjson from \"another-json\";\n\nimport type { IDeviceKeys, IOneTimeKey } from \"../@types/crypto\";\nimport { decodeBase64, encodeBase64 } from \"./olmlib\";\nimport { IndexedDBCryptoStore } from \"../crypto/store/indexeddb-crypto-store\";\nimport { decryptAES, encryptAES } from \"./aes\";\nimport { logger } from \"../logger\";\nimport { Crypto } from \"./index\";\nimport { Method } from \"../http-api\";\nimport { SecretStorageKeyDescription } from \"../secret-storage\";\n\nexport interface IDehydratedDevice {\n device_id: string; // eslint-disable-line camelcase\n device_data: SecretStorageKeyDescription & {\n // eslint-disable-line camelcase\n algorithm: string;\n account: string; // pickle\n };\n}\n\nexport interface IDehydratedDeviceKeyInfo {\n passphrase?: string;\n}\n\nexport const DEHYDRATION_ALGORITHM = \"org.matrix.msc2697.v1.olm.libolm_pickle\";\n\nconst oneweek = 7 * 24 * 60 * 60 * 1000;\n\nexport class DehydrationManager {\n private inProgress = false;\n private timeoutId: any;\n private key?: Uint8Array;\n private keyInfo?: { [props: string]: any };\n private deviceDisplayName?: string;\n\n public constructor(private readonly crypto: Crypto) {\n this.getDehydrationKeyFromCache();\n }\n\n public getDehydrationKeyFromCache(): Promise<void> {\n return this.crypto.cryptoStore.doTxn(\"readonly\", [IndexedDBCryptoStore.STORE_ACCOUNT], (txn) => {\n this.crypto.cryptoStore.getSecretStorePrivateKey(\n txn,\n async (result) => {\n if (result) {\n const { key, keyInfo, deviceDisplayName, time } = result;\n const pickleKey = Buffer.from(this.crypto.olmDevice.pickleKey);\n const decrypted = await decryptAES(key, pickleKey, DEHYDRATION_ALGORITHM);\n this.key = decodeBase64(decrypted);\n this.keyInfo = keyInfo;\n this.deviceDisplayName = deviceDisplayName;\n const now = Date.now();\n const delay = Math.max(1, time + oneweek - now);\n this.timeoutId = global.setTimeout(this.dehydrateDevice.bind(this), delay);\n }\n },\n \"dehydration\",\n );\n });\n }\n\n /** set the key, and queue periodic dehydration to the server in the background */\n public async setKeyAndQueueDehydration(\n key: Uint8Array,\n keyInfo: { [props: string]: any } = {},\n deviceDisplayName?: string,\n ): Promise<void> {\n const matches = await this.setKey(key, keyInfo, deviceDisplayName);\n if (!matches) {\n // start dehydration in the background\n this.dehydrateDevice();\n }\n }\n\n public async setKey(\n key: Uint8Array,\n keyInfo: { [props: string]: any } = {},\n deviceDisplayName?: string,\n ): Promise<boolean | undefined> {\n if (!key) {\n // unsetting the key -- cancel any pending dehydration task\n if (this.timeoutId) {\n global.clearTimeout(this.timeoutId);\n this.timeoutId = undefined;\n }\n // clear storage\n await this.crypto.cryptoStore.doTxn(\"readwrite\", [IndexedDBCryptoStore.STORE_ACCOUNT], (txn) => {\n this.crypto.cryptoStore.storeSecretStorePrivateKey(txn, \"dehydration\", null);\n });\n this.key = undefined;\n this.keyInfo = undefined;\n return;\n }\n\n // Check to see if it's the same key as before. If it's different,\n // dehydrate a new device. If it's the same, we can keep the same\n // device. (Assume that keyInfo and deviceDisplayName will be the\n // same if the key is the same.)\n let matches: boolean = !!this.key && key.length == this.key.length;\n for (let i = 0; matches && i < key.length; i++) {\n if (key[i] != this.key![i]) {\n matches = false;\n }\n }\n if (!matches) {\n this.key = key;\n this.keyInfo = keyInfo;\n this.deviceDisplayName = deviceDisplayName;\n }\n return matches;\n }\n\n /** returns the device id of the newly created dehydrated device */\n public async dehydrateDevice(): Promise<string | undefined> {\n if (this.inProgress) {\n logger.log(\"Dehydration already in progress -- not starting new dehydration\");\n return;\n }\n this.inProgress = true;\n if (this.timeoutId) {\n global.clearTimeout(this.timeoutId);\n this.timeoutId = undefined;\n }\n try {\n const pickleKey = Buffer.from(this.crypto.olmDevice.pickleKey);\n\n // update the crypto store with the timestamp\n const key = await encryptAES(encodeBase64(this.key!), pickleKey, DEHYDRATION_ALGORITHM);\n await this.crypto.cryptoStore.doTxn(\"readwrite\", [IndexedDBCryptoStore.STORE_ACCOUNT], (txn) => {\n this.crypto.cryptoStore.storeSecretStorePrivateKey(txn, \"dehydration\", {\n keyInfo: this.keyInfo,\n key,\n deviceDisplayName: this.deviceDisplayName!,\n time: Date.now(),\n });\n });\n logger.log(\"Attempting to dehydrate device\");\n\n logger.log(\"Creating account\");\n // create the account and all the necessary keys\n const account = new global.Olm.Account();\n account.create();\n const e2eKeys = JSON.parse(account.identity_keys());\n\n const maxKeys = account.max_number_of_one_time_keys();\n // FIXME: generate in small batches?\n account.generate_one_time_keys(maxKeys / 2);\n account.generate_fallback_key();\n const otks: Record<string, string> = JSON.parse(account.one_time_keys());\n const fallbacks: Record<string, string> = JSON.parse(account.fallback_key());\n account.mark_keys_as_published();\n\n // dehydrate the account and store it on the server\n const pickledAccount = account.pickle(new Uint8Array(this.key!));\n\n const deviceData: { [props: string]: any } = {\n algorithm: DEHYDRATION_ALGORITHM,\n account: pickledAccount,\n };\n if (this.keyInfo!.passphrase) {\n deviceData.passphrase = this.keyInfo!.passphrase;\n }\n\n logger.log(\"Uploading account to server\");\n // eslint-disable-next-line camelcase\n const dehydrateResult = await this.crypto.baseApis.http.authedRequest<{ device_id: string }>(\n Method.Put,\n \"/dehydrated_device\",\n undefined,\n {\n device_data: deviceData,\n initial_device_display_name: this.deviceDisplayName,\n },\n {\n prefix: \"/_matrix/client/unstable/org.matrix.msc2697.v2\",\n },\n );\n\n // send the keys to the server\n const deviceId = dehydrateResult.device_id;\n logger.log(\"Preparing device keys\", deviceId);\n const deviceKeys: IDeviceKeys = {\n algorithms: this.crypto.supportedAlgorithms,\n device_id: deviceId,\n user_id: this.crypto.userId,\n keys: {\n [`ed25519:${deviceId}`]: e2eKeys.ed25519,\n [`curve25519:${deviceId}`]: e2eKeys.curve25519,\n },\n };\n const deviceSignature = account.sign(anotherjson.stringify(deviceKeys));\n deviceKeys.signatures = {\n [this.crypto.userId]: {\n [`ed25519:${deviceId}`]: deviceSignature,\n },\n };\n if (this.crypto.crossSigningInfo.getId(\"self_signing\")) {\n await this.crypto.crossSigningInfo.signObject(deviceKeys, \"self_signing\");\n }\n\n logger.log(\"Preparing one-time keys\");\n const oneTimeKeys: Record<string, IOneTimeKey> = {};\n for (const [keyId, key] of Object.entries(otks.curve25519)) {\n const k: IOneTimeKey = { key };\n const signature = account.sign(anotherjson.stringify(k));\n k.signatures = {\n [this.crypto.userId]: {\n [`ed25519:${deviceId}`]: signature,\n },\n };\n oneTimeKeys[`signed_curve25519:${keyId}`] = k;\n }\n\n logger.log(\"Preparing fallback keys\");\n const fallbackKeys: Record<string, IOneTimeKey> = {};\n for (const [keyId, key] of Object.entries(fallbacks.curve25519)) {\n const k: IOneTimeKey = { key, fallback: true };\n const signature = account.sign(anotherjson.stringify(k));\n k.signatures = {\n [this.crypto.userId]: {\n [`ed25519:${deviceId}`]: signature,\n },\n };\n fallbackKeys[`signed_curve25519:${keyId}`] = k;\n }\n\n logger.log(\"Uploading keys to server\");\n await this.crypto.baseApis.http.authedRequest(\n Method.Post,\n \"/keys/upload/\" + encodeURI(deviceId),\n undefined,\n {\n \"device_keys\": deviceKeys,\n \"one_time_keys\": oneTimeKeys,\n \"org.matrix.msc2732.fallback_keys\": fallbackKeys,\n },\n );\n logger.log(\"Done dehydrating\");\n\n // dehydrate again in a week\n this.timeoutId = global.setTimeout(this.dehydrateDevice.bind(this), oneweek);\n\n return deviceId;\n } finally {\n this.inProgress = false;\n }\n }\n\n public stop(): void {\n if (this.timeoutId) {\n global.clearTimeout(this.timeoutId);\n this.timeoutId = undefined;\n }\n }\n}\n"],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/deviceinfo.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/deviceinfo.d.ts
deleted file mode 100644
index 2363761..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/deviceinfo.d.ts
+++ /dev/null
@@ -1,102 +0,0 @@
-import { ISignatures } from "../@types/signed";
-export interface IDevice {
- keys: Record<string, string>;
- algorithms: string[];
- verified: DeviceVerification;
- known: boolean;
- unsigned?: Record<string, any>;
- signatures?: ISignatures;
-}
-declare enum DeviceVerification {
- Blocked = -1,
- Unverified = 0,
- Verified = 1
-}
-/**
- * Information about a user's device
- */
-export declare class DeviceInfo {
- readonly deviceId: string;
- /**
- * rehydrate a DeviceInfo from the session store
- *
- * @param obj - raw object from session store
- * @param deviceId - id of the device
- *
- * @returns new DeviceInfo
- */
- static fromStorage(obj: Partial<IDevice>, deviceId: string): DeviceInfo;
- static DeviceVerification: {
- VERIFIED: DeviceVerification;
- UNVERIFIED: DeviceVerification;
- BLOCKED: DeviceVerification;
- };
- /** list of algorithms supported by this device */
- algorithms: string[];
- /** a map from `<key type>:<id> -> <base64-encoded key>` */
- keys: Record<string, string>;
- /** whether the device has been verified/blocked by the user */
- verified: DeviceVerification;
- /**
- * whether the user knows of this device's existence
- * (useful when warning the user that a user has added new devices)
- */
- known: boolean;
- /** additional data from the homeserver */
- unsigned: Record<string, any>;
- signatures: ISignatures;
- /**
- * @param deviceId - id of the device
- */
- constructor(deviceId: string);
- /**
- * Prepare a DeviceInfo for JSON serialisation in the session store
- *
- * @returns deviceinfo with non-serialised members removed
- */
- toStorage(): IDevice;
- /**
- * Get the fingerprint for this device (ie, the Ed25519 key)
- *
- * @returns base64-encoded fingerprint of this device
- */
- getFingerprint(): string;
- /**
- * Get the identity key for this device (ie, the Curve25519 key)
- *
- * @returns base64-encoded identity key of this device
- */
- getIdentityKey(): string;
- /**
- * Get the configured display name for this device, if any
- *
- * @returns displayname
- */
- getDisplayName(): string | null;
- /**
- * Returns true if this device is blocked
- *
- * @returns true if blocked
- */
- isBlocked(): boolean;
- /**
- * Returns true if this device is verified
- *
- * @returns true if verified
- */
- isVerified(): boolean;
- /**
- * Returns true if this device is unverified
- *
- * @returns true if unverified
- */
- isUnverified(): boolean;
- /**
- * Returns true if the user knows about this device's existence
- *
- * @returns true if known
- */
- isKnown(): boolean;
-}
-export {};
-//# sourceMappingURL=deviceinfo.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/deviceinfo.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/deviceinfo.d.ts.map
deleted file mode 100644
index 10a0011..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/deviceinfo.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"deviceinfo.d.ts","sourceRoot":"","sources":["../../src/crypto/deviceinfo.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,MAAM,WAAW,OAAO;IACpB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC/B,UAAU,CAAC,EAAE,WAAW,CAAC;CAC5B;AAED,aAAK,kBAAkB;IACnB,OAAO,KAAK;IACZ,UAAU,IAAI;IACd,QAAQ,IAAI;CACf;AAED;;GAEG;AACH,qBAAa,UAAU;aA4CgB,QAAQ,EAAE,MAAM;IA3CnD;;;;;;;OAOG;WACW,WAAW,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU;IAW9E,OAAc,kBAAkB;;;;MAI9B;IAEF,kDAAkD;IAC3C,UAAU,EAAE,MAAM,EAAE,CAAM;IACjC,2DAA2D;IACpD,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAM;IACzC,+DAA+D;IACxD,QAAQ,qBAAiC;IAChD;;;OAGG;IACI,KAAK,UAAS;IACrB,0CAA0C;IACnC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAM;IACnC,UAAU,EAAE,WAAW,CAAM;IAEpC;;OAEG;gBACgC,QAAQ,EAAE,MAAM;IAEnD;;;;OAIG;IACI,SAAS,IAAI,OAAO;IAW3B;;;;OAIG;IACI,cAAc,IAAI,MAAM;IAI/B;;;;OAIG;IACI,cAAc,IAAI,MAAM;IAI/B;;;;OAIG;IACI,cAAc,IAAI,MAAM,GAAG,IAAI;IAItC;;;;OAIG;IACI,SAAS,IAAI,OAAO;IAI3B;;;;OAIG;IACI,UAAU,IAAI,OAAO;IAI5B;;;;OAIG;IACI,YAAY,IAAI,OAAO;IAI9B;;;;OAIG;IACI,OAAO,IAAI,OAAO;CAG5B"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/deviceinfo.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/deviceinfo.js
deleted file mode 100644
index 42dc409..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/deviceinfo.js
+++ /dev/null
@@ -1,150 +0,0 @@
-"use strict";
-
-var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.DeviceInfo = void 0;
-var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
-/*
-Copyright 2016 - 2021 The Matrix.org Foundation C.I.C.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-var DeviceVerification;
-/**
- * Information about a user's device
- */
-(function (DeviceVerification) {
- DeviceVerification[DeviceVerification["Blocked"] = -1] = "Blocked";
- DeviceVerification[DeviceVerification["Unverified"] = 0] = "Unverified";
- DeviceVerification[DeviceVerification["Verified"] = 1] = "Verified";
-})(DeviceVerification || (DeviceVerification = {}));
-class DeviceInfo {
- /**
- * rehydrate a DeviceInfo from the session store
- *
- * @param obj - raw object from session store
- * @param deviceId - id of the device
- *
- * @returns new DeviceInfo
- */
- static fromStorage(obj, deviceId) {
- const res = new DeviceInfo(deviceId);
- for (const prop in obj) {
- if (obj.hasOwnProperty(prop)) {
- // @ts-ignore - this is messy and typescript doesn't like it
- res[prop] = obj[prop];
- }
- }
- return res;
- }
- /**
- * @param deviceId - id of the device
- */
- constructor(deviceId) {
- this.deviceId = deviceId;
- (0, _defineProperty2.default)(this, "algorithms", []);
- (0, _defineProperty2.default)(this, "keys", {});
- (0, _defineProperty2.default)(this, "verified", DeviceVerification.Unverified);
- (0, _defineProperty2.default)(this, "known", false);
- (0, _defineProperty2.default)(this, "unsigned", {});
- (0, _defineProperty2.default)(this, "signatures", {});
- }
-
- /**
- * Prepare a DeviceInfo for JSON serialisation in the session store
- *
- * @returns deviceinfo with non-serialised members removed
- */
- toStorage() {
- return {
- algorithms: this.algorithms,
- keys: this.keys,
- verified: this.verified,
- known: this.known,
- unsigned: this.unsigned,
- signatures: this.signatures
- };
- }
-
- /**
- * Get the fingerprint for this device (ie, the Ed25519 key)
- *
- * @returns base64-encoded fingerprint of this device
- */
- getFingerprint() {
- return this.keys["ed25519:" + this.deviceId];
- }
-
- /**
- * Get the identity key for this device (ie, the Curve25519 key)
- *
- * @returns base64-encoded identity key of this device
- */
- getIdentityKey() {
- return this.keys["curve25519:" + this.deviceId];
- }
-
- /**
- * Get the configured display name for this device, if any
- *
- * @returns displayname
- */
- getDisplayName() {
- return this.unsigned.device_display_name || null;
- }
-
- /**
- * Returns true if this device is blocked
- *
- * @returns true if blocked
- */
- isBlocked() {
- return this.verified == DeviceVerification.Blocked;
- }
-
- /**
- * Returns true if this device is verified
- *
- * @returns true if verified
- */
- isVerified() {
- return this.verified == DeviceVerification.Verified;
- }
-
- /**
- * Returns true if this device is unverified
- *
- * @returns true if unverified
- */
- isUnverified() {
- return this.verified == DeviceVerification.Unverified;
- }
-
- /**
- * Returns true if the user knows about this device's existence
- *
- * @returns true if known
- */
- isKnown() {
- return this.known === true;
- }
-}
-exports.DeviceInfo = DeviceInfo;
-(0, _defineProperty2.default)(DeviceInfo, "DeviceVerification", {
- VERIFIED: DeviceVerification.Verified,
- UNVERIFIED: DeviceVerification.Unverified,
- BLOCKED: DeviceVerification.Blocked
-});
-//# sourceMappingURL=deviceinfo.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/deviceinfo.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/deviceinfo.js.map
deleted file mode 100644
index 4ce37db..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/deviceinfo.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"deviceinfo.js","names":["DeviceVerification","DeviceInfo","fromStorage","obj","deviceId","res","prop","hasOwnProperty","constructor","_defineProperty2","default","Unverified","toStorage","algorithms","keys","verified","known","unsigned","signatures","getFingerprint","getIdentityKey","getDisplayName","device_display_name","isBlocked","Blocked","isVerified","Verified","isUnverified","isKnown","exports","VERIFIED","UNVERIFIED","BLOCKED"],"sources":["../../src/crypto/deviceinfo.ts"],"sourcesContent":["/*\nCopyright 2016 - 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { ISignatures } from \"../@types/signed\";\n\nexport interface IDevice {\n keys: Record<string, string>;\n algorithms: string[];\n verified: DeviceVerification;\n known: boolean;\n unsigned?: Record<string, any>;\n signatures?: ISignatures;\n}\n\nenum DeviceVerification {\n Blocked = -1,\n Unverified = 0,\n Verified = 1,\n}\n\n/**\n * Information about a user's device\n */\nexport class DeviceInfo {\n /**\n * rehydrate a DeviceInfo from the session store\n *\n * @param obj - raw object from session store\n * @param deviceId - id of the device\n *\n * @returns new DeviceInfo\n */\n public static fromStorage(obj: Partial<IDevice>, deviceId: string): DeviceInfo {\n const res = new DeviceInfo(deviceId);\n for (const prop in obj) {\n if (obj.hasOwnProperty(prop)) {\n // @ts-ignore - this is messy and typescript doesn't like it\n res[prop as keyof IDevice] = obj[prop as keyof IDevice];\n }\n }\n return res;\n }\n\n public static DeviceVerification = {\n VERIFIED: DeviceVerification.Verified,\n UNVERIFIED: DeviceVerification.Unverified,\n BLOCKED: DeviceVerification.Blocked,\n };\n\n /** list of algorithms supported by this device */\n public algorithms: string[] = [];\n /** a map from `<key type>:<id> -> <base64-encoded key>` */\n public keys: Record<string, string> = {};\n /** whether the device has been verified/blocked by the user */\n public verified = DeviceVerification.Unverified;\n /**\n * whether the user knows of this device's existence\n * (useful when warning the user that a user has added new devices)\n */\n public known = false;\n /** additional data from the homeserver */\n public unsigned: Record<string, any> = {};\n public signatures: ISignatures = {};\n\n /**\n * @param deviceId - id of the device\n */\n public constructor(public readonly deviceId: string) {}\n\n /**\n * Prepare a DeviceInfo for JSON serialisation in the session store\n *\n * @returns deviceinfo with non-serialised members removed\n */\n public toStorage(): IDevice {\n return {\n algorithms: this.algorithms,\n keys: this.keys,\n verified: this.verified,\n known: this.known,\n unsigned: this.unsigned,\n signatures: this.signatures,\n };\n }\n\n /**\n * Get the fingerprint for this device (ie, the Ed25519 key)\n *\n * @returns base64-encoded fingerprint of this device\n */\n public getFingerprint(): string {\n return this.keys[\"ed25519:\" + this.deviceId];\n }\n\n /**\n * Get the identity key for this device (ie, the Curve25519 key)\n *\n * @returns base64-encoded identity key of this device\n */\n public getIdentityKey(): string {\n return this.keys[\"curve25519:\" + this.deviceId];\n }\n\n /**\n * Get the configured display name for this device, if any\n *\n * @returns displayname\n */\n public getDisplayName(): string | null {\n return this.unsigned.device_display_name || null;\n }\n\n /**\n * Returns true if this device is blocked\n *\n * @returns true if blocked\n */\n public isBlocked(): boolean {\n return this.verified == DeviceVerification.Blocked;\n }\n\n /**\n * Returns true if this device is verified\n *\n * @returns true if verified\n */\n public isVerified(): boolean {\n return this.verified == DeviceVerification.Verified;\n }\n\n /**\n * Returns true if this device is unverified\n *\n * @returns true if unverified\n */\n public isUnverified(): boolean {\n return this.verified == DeviceVerification.Unverified;\n }\n\n /**\n * Returns true if the user knows about this device's existence\n *\n * @returns true if known\n */\n public isKnown(): boolean {\n return this.known === true;\n }\n}\n"],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/index.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/index.d.ts
deleted file mode 100644
index 8b0811d..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/index.d.ts
+++ /dev/null
@@ -1,1083 +0,0 @@
-import type { IEventDecryptionResult, IMegolmSessionData } from "../@types/crypto";
-import { ToDeviceMessageId } from "../@types/event";
-import { IExportedDevice, OlmDevice } from "./OlmDevice";
-import { IOlmDevice } from "./algorithms/megolm";
-import * as olmlib from "./olmlib";
-import { DeviceInfoMap, DeviceList } from "./DeviceList";
-import { DeviceInfo } from "./deviceinfo";
-import type { DecryptionAlgorithm } from "./algorithms";
-import { CrossSigningInfo, DeviceTrustLevel, UserTrustLevel } from "./CrossSigning";
-import { ISecretRequest, SecretStorage, SecretStorageKeyObject, SecretStorageKeyTuple } from "./SecretStorage";
-import { IAddSecretStorageKeyOpts, ICreateSecretStorageOpts, IEncryptedEventInfo, IImportRoomKeysOpts, IRecoveryKey } from "./api";
-import { VerificationBase } from "./verification/Base";
-import { VerificationRequest } from "./verification/request/VerificationRequest";
-import { InRoomRequests } from "./verification/request/InRoomChannel";
-import { DehydrationManager } from "./dehydration";
-import { BackupManager } from "./backup";
-import { IStore } from "../store";
-import { Room, RoomEvent } from "../models/room";
-import { RoomMemberEvent } from "../models/room-member";
-import { MatrixEvent, MatrixEventEvent } from "../models/event";
-import { ClientEvent, IKeysUploadResponse, IUploadKeySignaturesResponse, MatrixClient } from "../client";
-import type { IRoomEncryption, RoomList } from "./RoomList";
-import { ISyncStateData } from "../sync";
-import { CryptoStore } from "./store/base";
-import { IVerificationChannel } from "./verification/request/Channel";
-import { TypedEventEmitter } from "../models/typed-event-emitter";
-import { ISyncResponse, IToDeviceEvent } from "../sync-accumulator";
-import { ISignatures } from "../@types/signed";
-import { IMessage } from "./algorithms/olm";
-import { CryptoBackend, OnSyncCompletedData } from "../common-crypto/CryptoBackend";
-import { SecretStorageKeyDescription } from "../secret-storage";
-/**
- * verification method names
- */
-export declare const verificationMethods: {
- readonly RECIPROCATE_QR_CODE: string;
- readonly SAS: string;
-};
-export type VerificationMethod = keyof typeof verificationMethods | string;
-export declare function isCryptoAvailable(): boolean;
-interface IInitOpts {
- exportedOlmDevice?: IExportedDevice;
- pickleKey?: string;
-}
-export interface IBootstrapCrossSigningOpts {
- /** Optional. Reset even if keys already exist. */
- setupNewCrossSigning?: boolean;
- /**
- * A function that makes the request requiring auth. Receives the auth data as an object.
- * Can be called multiple times, first with an empty authDict, to obtain the flows.
- */
- authUploadDeviceSigningKeys?(makeRequest: (authData: any) => Promise<{}>): Promise<void>;
-}
-export interface ICryptoCallbacks {
- getCrossSigningKey?: (keyType: string, pubKey: string) => Promise<Uint8Array | null>;
- saveCrossSigningKeys?: (keys: Record<string, Uint8Array>) => void;
- shouldUpgradeDeviceVerifications?: (users: Record<string, any>) => Promise<string[]>;
- getSecretStorageKey?: (keys: {
- keys: Record<string, SecretStorageKeyDescription>;
- }, name: string) => Promise<[string, Uint8Array] | null>;
- cacheSecretStorageKey?: (keyId: string, keyInfo: SecretStorageKeyDescription, key: Uint8Array) => void;
- onSecretRequested?: (userId: string, deviceId: string, requestId: string, secretName: string, deviceTrust: DeviceTrustLevel) => Promise<string | undefined>;
- getDehydrationKey?: (keyInfo: SecretStorageKeyDescription, checkFunc: (key: Uint8Array) => void) => Promise<Uint8Array>;
- getBackupKey?: () => Promise<Uint8Array>;
-}
-interface IRoomKey {
- room_id: string;
- algorithm: string;
-}
-/**
- * The parameters of a room key request. The details of the request may
- * vary with the crypto algorithm, but the management and storage layers for
- * outgoing requests expect it to have 'room_id' and 'session_id' properties.
- */
-export interface IRoomKeyRequestBody extends IRoomKey {
- session_id: string;
- sender_key: string;
-}
-export interface ICheckOwnCrossSigningTrustOpts {
- allowPrivateKeyRequests?: boolean;
-}
-interface IUserOlmSession {
- deviceIdKey: string;
- sessions: {
- sessionId: string;
- hasReceivedMessage: boolean;
- }[];
-}
-export interface IRoomKeyRequestRecipient {
- userId: string;
- deviceId: string;
-}
-interface ISignableObject {
- signatures?: ISignatures;
- unsigned?: object;
-}
-export interface IRequestsMap {
- getRequest(event: MatrixEvent): VerificationRequest | undefined;
- getRequestByChannel(channel: IVerificationChannel): VerificationRequest | undefined;
- setRequest(event: MatrixEvent, request: VerificationRequest): void;
- setRequestByChannel(channel: IVerificationChannel, request: VerificationRequest): void;
-}
-export interface IOlmEncryptedContent {
- algorithm: typeof olmlib.OLM_ALGORITHM;
- sender_key: string;
- ciphertext: Record<string, IMessage>;
- [ToDeviceMessageId]?: string;
-}
-export interface IMegolmEncryptedContent {
- algorithm: typeof olmlib.MEGOLM_ALGORITHM;
- sender_key: string;
- session_id: string;
- device_id: string;
- ciphertext: string;
- [ToDeviceMessageId]?: string;
-}
-export type IEncryptedContent = IOlmEncryptedContent | IMegolmEncryptedContent;
-export declare enum CryptoEvent {
- DeviceVerificationChanged = "deviceVerificationChanged",
- UserTrustStatusChanged = "userTrustStatusChanged",
- UserCrossSigningUpdated = "userCrossSigningUpdated",
- RoomKeyRequest = "crypto.roomKeyRequest",
- RoomKeyRequestCancellation = "crypto.roomKeyRequestCancellation",
- KeyBackupStatus = "crypto.keyBackupStatus",
- KeyBackupFailed = "crypto.keyBackupFailed",
- KeyBackupSessionsRemaining = "crypto.keyBackupSessionsRemaining",
- KeySignatureUploadFailure = "crypto.keySignatureUploadFailure",
- VerificationRequest = "crypto.verification.request",
- Warning = "crypto.warning",
- WillUpdateDevices = "crypto.willUpdateDevices",
- DevicesUpdated = "crypto.devicesUpdated",
- KeysChanged = "crossSigning.keysChanged"
-}
-export type CryptoEventHandlerMap = {
- /**
- * Fires when a device is marked as verified/unverified/blocked/unblocked by
- * {@link MatrixClient#setDeviceVerified|MatrixClient.setDeviceVerified} or
- * {@link MatrixClient#setDeviceBlocked|MatrixClient.setDeviceBlocked}.
- *
- * @param userId - the owner of the verified device
- * @param deviceId - the id of the verified device
- * @param deviceInfo - updated device information
- */
- [CryptoEvent.DeviceVerificationChanged]: (userId: string, deviceId: string, device: DeviceInfo) => void;
- /**
- * Fires when the trust status of a user changes
- * If userId is the userId of the logged-in user, this indicated a change
- * in the trust status of the cross-signing data on the account.
- *
- * The cross-signing API is currently UNSTABLE and may change without notice.
- * @experimental
- *
- * @param userId - the userId of the user in question
- * @param trustLevel - The new trust level of the user
- */
- [CryptoEvent.UserTrustStatusChanged]: (userId: string, trustLevel: UserTrustLevel) => void;
- /**
- * Fires when we receive a room key request
- *
- * @param req - request details
- */
- [CryptoEvent.RoomKeyRequest]: (request: IncomingRoomKeyRequest) => void;
- /**
- * Fires when we receive a room key request cancellation
- */
- [CryptoEvent.RoomKeyRequestCancellation]: (request: IncomingRoomKeyRequestCancellation) => void;
- /**
- * Fires whenever the status of e2e key backup changes, as returned by getKeyBackupEnabled()
- * @param enabled - true if key backup has been enabled, otherwise false
- * @example
- * ```
- * matrixClient.on("crypto.keyBackupStatus", function(enabled){
- * if (enabled) {
- * [...]
- * }
- * });
- * ```
- */
- [CryptoEvent.KeyBackupStatus]: (enabled: boolean) => void;
- [CryptoEvent.KeyBackupFailed]: (errcode: string) => void;
- [CryptoEvent.KeyBackupSessionsRemaining]: (remaining: number) => void;
- [CryptoEvent.KeySignatureUploadFailure]: (failures: IUploadKeySignaturesResponse["failures"], source: "checkOwnCrossSigningTrust" | "afterCrossSigningLocalKeyChange" | "setDeviceVerification", upload: (opts: {
- shouldEmit: boolean;
- }) => Promise<void>) => void;
- /**
- * Fires when a key verification is requested.
- */
- [CryptoEvent.VerificationRequest]: (request: VerificationRequest<any>) => void;
- /**
- * Fires when the app may wish to warn the user about something related
- * the end-to-end crypto.
- *
- * @param type - One of the strings listed above
- */
- [CryptoEvent.Warning]: (type: string) => void;
- /**
- * Fires when the user's cross-signing keys have changed or cross-signing
- * has been enabled/disabled. The client can use getStoredCrossSigningForUser
- * with the user ID of the logged in user to check if cross-signing is
- * enabled on the account. If enabled, it can test whether the current key
- * is trusted using with checkUserTrust with the user ID of the logged
- * in user. The checkOwnCrossSigningTrust function may be used to reconcile
- * the trust in the account key.
- *
- * The cross-signing API is currently UNSTABLE and may change without notice.
- * @experimental
- */
- [CryptoEvent.KeysChanged]: (data: {}) => void;
- /**
- * Fires whenever the stored devices for a user will be updated
- * @param users - A list of user IDs that will be updated
- * @param initialFetch - If true, the store is empty (apart
- * from our own device) and is being seeded.
- */
- [CryptoEvent.WillUpdateDevices]: (users: string[], initialFetch: boolean) => void;
- /**
- * Fires whenever the stored devices for a user have changed
- * @param users - A list of user IDs that were updated
- * @param initialFetch - If true, the store was empty (apart
- * from our own device) and has been seeded.
- */
- [CryptoEvent.DevicesUpdated]: (users: string[], initialFetch: boolean) => void;
- [CryptoEvent.UserCrossSigningUpdated]: (userId: string) => void;
-};
-export declare class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap> implements CryptoBackend {
- readonly baseApis: MatrixClient;
- readonly userId: string;
- private readonly deviceId;
- private readonly clientStore;
- readonly cryptoStore: CryptoStore;
- private readonly roomList;
- /**
- * @returns The version of Olm.
- */
- static getOlmVersion(): [number, number, number];
- readonly backupManager: BackupManager;
- readonly crossSigningInfo: CrossSigningInfo;
- readonly olmDevice: OlmDevice;
- readonly deviceList: DeviceList;
- readonly dehydrationManager: DehydrationManager;
- readonly secretStorage: SecretStorage;
- private readonly reEmitter;
- private readonly verificationMethods;
- readonly supportedAlgorithms: string[];
- private readonly outgoingRoomKeyRequestManager;
- private readonly toDeviceVerificationRequests;
- readonly inRoomVerificationRequests: InRoomRequests;
- private trustCrossSignedDevices;
- private lastOneTimeKeyCheck;
- private oneTimeKeyCheckInProgress;
- private roomEncryptors;
- private roomDecryptors;
- private deviceKeys;
- globalBlacklistUnverifiedDevices: boolean;
- globalErrorOnUnknownDevices: boolean;
- private receivedRoomKeyRequests;
- private receivedRoomKeyRequestCancellations;
- private processingRoomKeyRequests;
- private lazyLoadMembers;
- private roomDeviceTrackingState;
- private lastNewSessionForced;
- private sendKeyRequestsImmediately;
- private oneTimeKeyCount?;
- private needsNewFallback?;
- private fallbackCleanup?;
- /**
- * Cryptography bits
- *
- * This module is internal to the js-sdk; the public API is via MatrixClient.
- *
- * @internal
- *
- * @param baseApis - base matrix api interface
- *
- * @param userId - The user ID for the local user
- *
- * @param deviceId - The identifier for this device.
- *
- * @param clientStore - the MatrixClient data store.
- *
- * @param cryptoStore - storage for the crypto layer.
- *
- * @param roomList - An initialised RoomList object
- *
- * @param verificationMethods - Array of verification methods to use.
- * Each element can either be a string from MatrixClient.verificationMethods
- * or a class that implements a verification method.
- */
- constructor(baseApis: MatrixClient, userId: string, deviceId: string, clientStore: IStore, cryptoStore: CryptoStore, roomList: RoomList, verificationMethods: Array<VerificationMethod | (typeof VerificationBase & {
- NAME: string;
- })>);
- /**
- * Initialise the crypto module so that it is ready for use
- *
- * Returns a promise which resolves once the crypto module is ready for use.
- *
- * @param exportedOlmDevice - (Optional) data from exported device
- * that must be re-created.
- */
- init({ exportedOlmDevice, pickleKey }?: IInitOpts): Promise<void>;
- /**
- * Whether to trust a others users signatures of their devices.
- * If false, devices will only be considered 'verified' if we have
- * verified that device individually (effectively disabling cross-signing).
- *
- * Default: true
- *
- * @returns True if trusting cross-signed devices
- */
- getCryptoTrustCrossSignedDevices(): boolean;
- /**
- * See getCryptoTrustCrossSignedDevices
-
- * This may be set before initCrypto() is called to ensure no races occur.
- *
- * @param val - True to trust cross-signed devices
- */
- setCryptoTrustCrossSignedDevices(val: boolean): void;
- /**
- * Create a recovery key from a user-supplied passphrase.
- *
- * @param password - Passphrase string that can be entered by the user
- * when restoring the backup as an alternative to entering the recovery key.
- * Optional.
- * @returns Object with public key metadata, encoded private
- * recovery key which should be disposed of after displaying to the user,
- * and raw private key to avoid round tripping if needed.
- */
- createRecoveryKeyFromPassphrase(password?: string): Promise<IRecoveryKey>;
- /**
- * Checks if the user has previously published cross-signing keys
- *
- * This means downloading the devicelist for the user and checking if the list includes
- * the cross-signing pseudo-device.
- *
- * @internal
- */
- userHasCrossSigningKeys(): Promise<boolean>;
- /**
- * Checks whether cross signing:
- * - is enabled on this account and trusted by this device
- * - has private keys either cached locally or stored in secret storage
- *
- * If this function returns false, bootstrapCrossSigning() can be used
- * to fix things such that it returns true. That is to say, after
- * bootstrapCrossSigning() completes successfully, this function should
- * return true.
- *
- * The cross-signing API is currently UNSTABLE and may change without notice.
- *
- * @returns True if cross-signing is ready to be used on this device
- */
- isCrossSigningReady(): Promise<boolean>;
- /**
- * Checks whether secret storage:
- * - is enabled on this account
- * - is storing cross-signing private keys
- * - is storing session backup key (if enabled)
- *
- * If this function returns false, bootstrapSecretStorage() can be used
- * to fix things such that it returns true. That is to say, after
- * bootstrapSecretStorage() completes successfully, this function should
- * return true.
- *
- * The Secure Secret Storage API is currently UNSTABLE and may change without notice.
- *
- * @returns True if secret storage is ready to be used on this device
- */
- isSecretStorageReady(): Promise<boolean>;
- /**
- * Bootstrap cross-signing by creating keys if needed. If everything is already
- * set up, then no changes are made, so this is safe to run to ensure
- * cross-signing is ready for use.
- *
- * This function:
- * - creates new cross-signing keys if they are not found locally cached nor in
- * secret storage (if it has been setup)
- *
- * The cross-signing API is currently UNSTABLE and may change without notice.
- *
- * @param authUploadDeviceSigningKeys - Function
- * called to await an interactive auth flow when uploading device signing keys.
- * @param setupNewCrossSigning - Optional. Reset even if keys
- * already exist.
- * Args:
- * A function that makes the request requiring auth. Receives the
- * auth data as an object. Can be called multiple times, first with an empty
- * authDict, to obtain the flows.
- */
- bootstrapCrossSigning({ authUploadDeviceSigningKeys, setupNewCrossSigning, }?: IBootstrapCrossSigningOpts): Promise<void>;
- /**
- * Bootstrap Secure Secret Storage if needed by creating a default key. If everything is
- * already set up, then no changes are made, so this is safe to run to ensure secret
- * storage is ready for use.
- *
- * This function
- * - creates a new Secure Secret Storage key if no default key exists
- * - if a key backup exists, it is migrated to store the key in the Secret
- * Storage
- * - creates a backup if none exists, and one is requested
- * - migrates Secure Secret Storage to use the latest algorithm, if an outdated
- * algorithm is found
- *
- * The Secure Secret Storage API is currently UNSTABLE and may change without notice.
- *
- * @param createSecretStorageKey - Optional. Function
- * called to await a secret storage key creation flow.
- * Returns a Promise which resolves to an object with public key metadata, encoded private
- * recovery key which should be disposed of after displaying to the user,
- * and raw private key to avoid round tripping if needed.
- * @param keyBackupInfo - The current key backup object. If passed,
- * the passphrase and recovery key from this backup will be used.
- * @param setupNewKeyBackup - If true, a new key backup version will be
- * created and the private key stored in the new SSSS store. Ignored if keyBackupInfo
- * is supplied.
- * @param setupNewSecretStorage - Optional. Reset even if keys already exist.
- * @param getKeyBackupPassphrase - Optional. Function called to get the user's
- * current key backup passphrase. Should return a promise that resolves with a Buffer
- * containing the key, or rejects if the key cannot be obtained.
- * Returns:
- * A promise which resolves to key creation data for
- * SecretStorage#addKey: an object with `passphrase` etc fields.
- */
- bootstrapSecretStorage({ createSecretStorageKey, keyBackupInfo, setupNewKeyBackup, setupNewSecretStorage, getKeyBackupPassphrase, }?: ICreateSecretStorageOpts): Promise<void>;
- addSecretStorageKey(algorithm: string, opts: IAddSecretStorageKeyOpts, keyID?: string): Promise<SecretStorageKeyObject>;
- hasSecretStorageKey(keyID?: string): Promise<boolean>;
- getSecretStorageKey(keyID?: string): Promise<SecretStorageKeyTuple | null>;
- storeSecret(name: string, secret: string, keys?: string[]): Promise<void>;
- getSecret(name: string): Promise<string | undefined>;
- isSecretStored(name: string): Promise<Record<string, SecretStorageKeyDescription> | null>;
- requestSecret(name: string, devices: string[]): ISecretRequest;
- getDefaultSecretStorageKeyId(): Promise<string | null>;
- setDefaultSecretStorageKeyId(k: string): Promise<void>;
- checkSecretStorageKey(key: Uint8Array, info: SecretStorageKeyDescription): Promise<boolean>;
- /**
- * Checks that a given secret storage private key matches a given public key.
- * This can be used by the getSecretStorageKey callback to verify that the
- * private key it is about to supply is the one that was requested.
- *
- * @param privateKey - The private key
- * @param expectedPublicKey - The public key
- * @returns true if the key matches, otherwise false
- */
- checkSecretStoragePrivateKey(privateKey: Uint8Array, expectedPublicKey: string): boolean;
- /**
- * Fetches the backup private key, if cached
- * @returns the key, if any, or null
- */
- getSessionBackupPrivateKey(): Promise<Uint8Array | null>;
- /**
- * Stores the session backup key to the cache
- * @param key - the private key
- * @returns a promise so you can catch failures
- */
- storeSessionBackupPrivateKey(key: ArrayLike<number>): Promise<void>;
- /**
- * Checks that a given cross-signing private key matches a given public key.
- * This can be used by the getCrossSigningKey callback to verify that the
- * private key it is about to supply is the one that was requested.
- *
- * @param privateKey - The private key
- * @param expectedPublicKey - The public key
- * @returns true if the key matches, otherwise false
- */
- checkCrossSigningPrivateKey(privateKey: Uint8Array, expectedPublicKey: string): boolean;
- /**
- * Run various follow-up actions after cross-signing keys have changed locally
- * (either by resetting the keys for the account or by getting them from secret
- * storage), such as signing the current device, upgrading device
- * verifications, etc.
- */
- private afterCrossSigningLocalKeyChange;
- /**
- * Check if a user's cross-signing key is a candidate for upgrading from device
- * verification.
- *
- * @param userId - the user whose cross-signing information is to be checked
- * @param crossSigningInfo - the cross-signing information to check
- */
- private checkForDeviceVerificationUpgrade;
- /**
- * Check if the cross-signing key is signed by a verified device.
- *
- * @param userId - the user ID whose key is being checked
- * @param key - the key that is being checked
- * @param devices - the user's devices. Should be a map from device ID
- * to device info
- */
- private checkForValidDeviceSignature;
- /**
- * Get the user's cross-signing key ID.
- *
- * @param type - The type of key to get the ID of. One of
- * "master", "self_signing", or "user_signing". Defaults to "master".
- *
- * @returns the key ID
- */
- getCrossSigningId(type: string): string | null;
- /**
- * Get the cross signing information for a given user.
- *
- * @param userId - the user ID to get the cross-signing info for.
- *
- * @returns the cross signing information for the user.
- */
- getStoredCrossSigningForUser(userId: string): CrossSigningInfo | null;
- /**
- * Check whether a given user is trusted.
- *
- * @param userId - The ID of the user to check.
- *
- * @returns
- */
- checkUserTrust(userId: string): UserTrustLevel;
- /**
- * Check whether a given device is trusted.
- *
- * @param userId - The ID of the user whose devices is to be checked.
- * @param deviceId - The ID of the device to check
- *
- * @returns
- */
- checkDeviceTrust(userId: string, deviceId: string): DeviceTrustLevel;
- /**
- * Check whether a given deviceinfo is trusted.
- *
- * @param userId - The ID of the user whose devices is to be checked.
- * @param device - The device info object to check
- *
- * @returns
- */
- checkDeviceInfoTrust(userId: string, device?: DeviceInfo): DeviceTrustLevel;
- /**
- * Check whether one of our own devices is cross-signed by our
- * user's stored keys, regardless of whether we trust those keys yet.
- *
- * @param deviceId - The ID of the device to check
- *
- * @returns true if the device is cross-signed
- */
- checkIfOwnDeviceCrossSigned(deviceId: string): boolean;
- private onDeviceListUserCrossSigningUpdated;
- /**
- * Check the copy of our cross-signing key that we have in the device list and
- * see if we can get the private key. If so, mark it as trusted.
- */
- checkOwnCrossSigningTrust({ allowPrivateKeyRequests, }?: ICheckOwnCrossSigningTrustOpts): Promise<void>;
- /**
- * Store a set of keys as our own, trusted, cross-signing keys.
- *
- * @param keys - The new trusted set of keys
- */
- private storeTrustedSelfKeys;
- /**
- * Check if the master key is signed by a verified device, and if so, prompt
- * the application to mark it as verified.
- *
- * @param userId - the user ID whose key should be checked
- */
- private checkDeviceVerifications;
- /**
- */
- enableLazyLoading(): void;
- /**
- * Tell the crypto module to register for MatrixClient events which it needs to
- * listen for
- *
- * @param eventEmitter - event source where we can register
- * for event notifications
- */
- registerEventHandlers(eventEmitter: TypedEventEmitter<RoomMemberEvent.Membership | ClientEvent.ToDeviceEvent | RoomEvent.Timeline | MatrixEventEvent.Decrypted, any>): void;
- /**
- * @deprecated this does nothing and will be removed in a future version
- */
- start(): void;
- /** Stop background processes related to crypto */
- stop(): void;
- /**
- * Get the Ed25519 key for this device
- *
- * @returns base64-encoded ed25519 key.
- */
- getDeviceEd25519Key(): string | null;
- /**
- * Get the Curve25519 key for this device
- *
- * @returns base64-encoded curve25519 key.
- */
- getDeviceCurve25519Key(): string | null;
- /**
- * Set the global override for whether the client should ever send encrypted
- * messages to unverified devices. This provides the default for rooms which
- * do not specify a value.
- *
- * @param value - whether to blacklist all unverified devices by default
- *
- * @deprecated For external code, use {@link MatrixClient#setGlobalBlacklistUnverifiedDevices}. For
- * internal code, set {@link MatrixClient#globalBlacklistUnverifiedDevices} directly.
- */
- setGlobalBlacklistUnverifiedDevices(value: boolean): void;
- /**
- * @returns whether to blacklist all unverified devices by default
- *
- * @deprecated For external code, use {@link MatrixClient#getGlobalBlacklistUnverifiedDevices}. For
- * internal code, reference {@link MatrixClient#globalBlacklistUnverifiedDevices} directly.
- */
- getGlobalBlacklistUnverifiedDevices(): boolean;
- /**
- * Upload the device keys to the homeserver.
- * @returns A promise that will resolve when the keys are uploaded.
- */
- uploadDeviceKeys(): Promise<IKeysUploadResponse>;
- /**
- * Stores the current one_time_key count which will be handled later (in a call of
- * onSyncCompleted). The count is e.g. coming from a /sync response.
- *
- * @param currentCount - The current count of one_time_keys to be stored
- */
- updateOneTimeKeyCount(currentCount: number): void;
- setNeedsNewFallback(needsNewFallback: boolean): void;
- getNeedsNewFallback(): boolean;
- private maybeUploadOneTimeKeys;
- private uploadOneTimeKeys;
- /**
- * Download the keys for a list of users and stores the keys in the session
- * store.
- * @param userIds - The users to fetch.
- * @param forceDownload - Always download the keys even if cached.
- *
- * @returns A promise which resolves to a map `userId->deviceId->{@link DeviceInfo}`.
- */
- downloadKeys(userIds: string[], forceDownload?: boolean): Promise<DeviceInfoMap>;
- /**
- * Get the stored device keys for a user id
- *
- * @param userId - the user to list keys for.
- *
- * @returns list of devices, or null if we haven't
- * managed to get a list of devices for this user yet.
- */
- getStoredDevicesForUser(userId: string): Array<DeviceInfo> | null;
- /**
- * Get the stored keys for a single device
- *
- *
- * @returns device, or undefined
- * if we don't know about this device
- */
- getStoredDevice(userId: string, deviceId: string): DeviceInfo | undefined;
- /**
- * Save the device list, if necessary
- *
- * @param delay - Time in ms before which the save actually happens.
- * By default, the save is delayed for a short period in order to batch
- * multiple writes, but this behaviour can be disabled by passing 0.
- *
- * @returns true if the data was saved, false if
- * it was not (eg. because no changes were pending). The promise
- * will only resolve once the data is saved, so may take some time
- * to resolve.
- */
- saveDeviceList(delay: number): Promise<boolean>;
- /**
- * Update the blocked/verified state of the given device
- *
- * @param userId - owner of the device
- * @param deviceId - unique identifier for the device or user's
- * cross-signing public key ID.
- *
- * @param verified - whether to mark the device as verified. Null to
- * leave unchanged.
- *
- * @param blocked - whether to mark the device as blocked. Null to
- * leave unchanged.
- *
- * @param known - whether to mark that the user has been made aware of
- * the existence of this device. Null to leave unchanged
- *
- * @param keys - The list of keys that was present
- * during the device verification. This will be double checked with the list
- * of keys the given device has currently.
- *
- * @returns updated DeviceInfo
- */
- setDeviceVerification(userId: string, deviceId: string, verified?: boolean | null, blocked?: boolean | null, known?: boolean | null, keys?: Record<string, string>): Promise<DeviceInfo | CrossSigningInfo>;
- findVerificationRequestDMInProgress(roomId: string): VerificationRequest | undefined;
- getVerificationRequestsToDeviceInProgress(userId: string): VerificationRequest[];
- requestVerificationDM(userId: string, roomId: string): Promise<VerificationRequest>;
- requestVerification(userId: string, devices?: string[]): Promise<VerificationRequest>;
- private requestVerificationWithChannel;
- beginKeyVerification(method: string, userId: string, deviceId: string, transactionId?: string | null): VerificationBase<any, any>;
- legacyDeviceVerification(userId: string, deviceId: string, method: VerificationMethod): Promise<VerificationRequest>;
- /**
- * Get information on the active olm sessions with a user
- * <p>
- * Returns a map from device id to an object with keys 'deviceIdKey' (the
- * device's curve25519 identity key) and 'sessions' (an array of objects in the
- * same format as that returned by
- * {@link OlmDevice#getSessionInfoForDevice}).
- * <p>
- * This method is provided for debugging purposes.
- *
- * @param userId - id of user to inspect
- */
- getOlmSessionsForUser(userId: string): Promise<Record<string, IUserOlmSession>>;
- /**
- * Get the device which sent an event
- *
- * @param event - event to be checked
- */
- getEventSenderDeviceInfo(event: MatrixEvent): DeviceInfo | null;
- /**
- * Get information about the encryption of an event
- *
- * @param event - event to be checked
- *
- * @returns An object with the fields:
- * - encrypted: whether the event is encrypted (if not encrypted, some of the
- * other properties may not be set)
- * - senderKey: the sender's key
- * - algorithm: the algorithm used to encrypt the event
- * - authenticated: whether we can be sure that the owner of the senderKey
- * sent the event
- * - sender: the sender's device information, if available
- * - mismatchedSender: if the event's ed25519 and curve25519 keys don't match
- * (only meaningful if `sender` is set)
- */
- getEventEncryptionInfo(event: MatrixEvent): IEncryptedEventInfo;
- /**
- * Forces the current outbound group session to be discarded such
- * that another one will be created next time an event is sent.
- *
- * @param roomId - The ID of the room to discard the session for
- *
- * This should not normally be necessary.
- */
- forceDiscardSession(roomId: string): Promise<void>;
- /**
- * Configure a room to use encryption (ie, save a flag in the cryptoStore).
- *
- * @param roomId - The room ID to enable encryption in.
- *
- * @param config - The encryption config for the room.
- *
- * @param inhibitDeviceQuery - true to suppress device list query for
- * users in the room (for now). In case lazy loading is enabled,
- * the device query is always inhibited as the members are not tracked.
- *
- * @deprecated It is normally incorrect to call this method directly. Encryption
- * is enabled by receiving an `m.room.encryption` event (which we may have sent
- * previously).
- */
- setRoomEncryption(roomId: string, config: IRoomEncryption, inhibitDeviceQuery?: boolean): Promise<void>;
- /**
- * Set up encryption for a room.
- *
- * This is called when an <tt>m.room.encryption</tt> event is received. It saves a flag
- * for the room in the cryptoStore (if it wasn't already set), sets up an "encryptor" for
- * the room, and enables device-list tracking for the room.
- *
- * It does <em>not</em> initiate a device list query for the room. That is normally
- * done once we finish processing the sync, in onSyncCompleted.
- *
- * @param room - The room to enable encryption in.
- * @param config - The encryption config for the room.
- */
- private setRoomEncryptionImpl;
- /**
- * Make sure we are tracking the device lists for all users in this room.
- *
- * @param roomId - The room ID to start tracking devices in.
- * @returns when all devices for the room have been fetched and marked to track
- * @deprecated there's normally no need to call this function: device list tracking
- * will be enabled as soon as we have the full membership list.
- */
- trackRoomDevices(roomId: string): Promise<void>;
- /**
- * Make sure we are tracking the device lists for all users in this room.
- *
- * This is normally called when we are about to send an encrypted event, to make sure
- * we have all the devices in the room; but it is also called when processing an
- * m.room.encryption state event (if lazy-loading is disabled), or when members are
- * loaded (if lazy-loading is enabled), to prepare the device list.
- *
- * @param room - Room to enable device-list tracking in
- */
- private trackRoomDevicesImpl;
- /**
- * Try to make sure we have established olm sessions for all known devices for
- * the given users.
- *
- * @param users - list of user ids
- * @param force - If true, force a new Olm session to be created. Default false.
- *
- * @returns resolves once the sessions are complete, to
- * an Object mapping from userId to deviceId to
- * {@link OlmSessionResult}
- */
- ensureOlmSessionsForUsers(users: string[], force?: boolean): Promise<Map<string, Map<string, olmlib.IOlmSessionResult>>>;
- /**
- * Get a list containing all of the room keys
- *
- * @returns a list of session export objects
- */
- exportRoomKeys(): Promise<IMegolmSessionData[]>;
- /**
- * Import a list of room keys previously exported by exportRoomKeys
- *
- * @param keys - a list of session export objects
- * @returns a promise which resolves once the keys have been imported
- */
- importRoomKeys(keys: IMegolmSessionData[], opts?: IImportRoomKeysOpts): Promise<void>;
- /**
- * Counts the number of end to end session keys that are waiting to be backed up
- * @returns Promise which resolves to the number of sessions requiring backup
- */
- countSessionsNeedingBackup(): Promise<number>;
- /**
- * Perform any background tasks that can be done before a message is ready to
- * send, in order to speed up sending of the message.
- *
- * @param room - the room the event is in
- */
- prepareToEncrypt(room: Room): void;
- /**
- * Encrypt an event according to the configuration of the room.
- *
- * @param event - event to be sent
- *
- * @param room - destination room.
- *
- * @returns Promise which resolves when the event has been
- * encrypted, or null if nothing was needed
- */
- encryptEvent(event: MatrixEvent, room: Room): Promise<void>;
- /**
- * Decrypt a received event
- *
- *
- * @returns resolves once we have
- * finished decrypting. Rejects with an `algorithms.DecryptionError` if there
- * is a problem decrypting the event.
- */
- decryptEvent(event: MatrixEvent): Promise<IEventDecryptionResult>;
- /**
- * Handle the notification from /sync or /keys/changes that device lists have
- * been changed.
- *
- * @param syncData - Object containing sync tokens associated with this sync
- * @param syncDeviceLists - device_lists field from /sync, or response from
- * /keys/changes
- */
- handleDeviceListChanges(syncData: ISyncStateData, syncDeviceLists: Required<ISyncResponse>["device_lists"]): Promise<void>;
- /**
- * Send a request for some room keys, if we have not already done so
- *
- * @param resend - whether to resend the key request if there is
- * already one
- *
- * @returns a promise that resolves when the key request is queued
- */
- requestRoomKey(requestBody: IRoomKeyRequestBody, recipients: IRoomKeyRequestRecipient[], resend?: boolean): Promise<void>;
- /**
- * Cancel any earlier room key request
- *
- * @param requestBody - parameters to match for cancellation
- */
- cancelRoomKeyRequest(requestBody: IRoomKeyRequestBody): void;
- /**
- * Re-send any outgoing key requests, eg after verification
- * @returns
- */
- cancelAndResendAllOutgoingKeyRequests(): Promise<void>;
- /**
- * handle an m.room.encryption event
- *
- * @param room - in which the event was received
- * @param event - encryption event to be processed
- */
- onCryptoEvent(room: Room, event: MatrixEvent): Promise<void>;
- /**
- * Called before the result of a sync is processed
- *
- * @param syncData - the data from the 'MatrixClient.sync' event
- */
- onSyncWillProcess(syncData: ISyncStateData): Promise<void>;
- /**
- * handle the completion of a /sync
- *
- * This is called after the processing of each successful /sync response.
- * It is an opportunity to do a batch process on the information received.
- *
- * @param syncData - the data from the 'MatrixClient.sync' event
- */
- onSyncCompleted(syncData: OnSyncCompletedData): Promise<void>;
- /**
- * Trigger the appropriate invalidations and removes for a given
- * device list
- *
- * @param deviceLists - device_lists field from /sync, or response from
- * /keys/changes
- */
- private evalDeviceListChanges;
- /**
- * Get a list of all the IDs of users we share an e2e room with
- * for which we are tracking devices already
- *
- * @returns List of user IDs
- */
- private getTrackedE2eUsers;
- /**
- * Get a list of the e2e-enabled rooms we are members of,
- * and for which we are already tracking the devices
- *
- * @returns
- */
- private getTrackedE2eRooms;
- /**
- * Encrypts and sends a given object via Olm to-device messages to a given
- * set of devices.
- * @param userDeviceInfoArr - the devices to send to
- * @param payload - fields to include in the encrypted payload
- * @returns Promise which
- * resolves once the message has been encrypted and sent to the given
- * userDeviceMap, and returns the `{ contentMap, deviceInfoByDeviceId }`
- * of the successfully sent messages.
- */
- encryptAndSendToDevices(userDeviceInfoArr: IOlmDevice<DeviceInfo>[], payload: object): Promise<void>;
- private onMembership;
- preprocessToDeviceMessages(events: IToDeviceEvent[]): Promise<IToDeviceEvent[]>;
- preprocessOneTimeKeyCounts(oneTimeKeysCounts: Map<string, number>): Promise<void>;
- preprocessUnusedFallbackKeys(unusedFallbackKeys: Set<string>): Promise<void>;
- private onToDeviceEvent;
- /**
- * Handle a key event
- *
- * @internal
- * @param event - key event
- */
- private onRoomKeyEvent;
- /**
- * Handle a key withheld event
- *
- * @internal
- * @param event - key withheld event
- */
- private onRoomKeyWithheldEvent;
- /**
- * Handle a general key verification event.
- *
- * @internal
- * @param event - verification start event
- */
- private onKeyVerificationMessage;
- /**
- * Handle key verification requests sent as timeline events
- *
- * @internal
- * @param event - the timeline event
- * @param room - not used
- * @param atStart - not used
- * @param removed - not used
- * @param whether - this is a live event
- */
- private onTimelineEvent;
- private handleVerificationEvent;
- /**
- * Handle a toDevice event that couldn't be decrypted
- *
- * @internal
- * @param event - undecryptable event
- */
- private onToDeviceBadEncrypted;
- /**
- * Handle a change in the membership state of a member of a room
- *
- * @internal
- * @param event - event causing the change
- * @param member - user whose membership changed
- * @param oldMembership - previous membership
- */
- private onRoomMembership;
- /**
- * Called when we get an m.room_key_request event.
- *
- * @internal
- * @param event - key request event
- */
- private onRoomKeyRequestEvent;
- /**
- * Process any m.room_key_request events which were queued up during the
- * current sync.
- *
- * @internal
- */
- private processReceivedRoomKeyRequests;
- /**
- * Helper for processReceivedRoomKeyRequests
- *
- */
- private processReceivedRoomKeyRequest;
- /**
- * Helper for processReceivedRoomKeyRequests
- *
- */
- private processReceivedRoomKeyRequestCancellation;
- /**
- * Get a decryptor for a given room and algorithm.
- *
- * If we already have a decryptor for the given room and algorithm, return
- * it. Otherwise try to instantiate it.
- *
- * @internal
- *
- * @param roomId - room id for decryptor. If undefined, a temporary
- * decryptor is instantiated.
- *
- * @param algorithm - crypto algorithm
- *
- * @throws {@link DecryptionError} if the algorithm is unknown
- */
- getRoomDecryptor(roomId: string | null, algorithm: string): DecryptionAlgorithm;
- /**
- * Get all the room decryptors for a given encryption algorithm.
- *
- * @param algorithm - The encryption algorithm
- *
- * @returns An array of room decryptors
- */
- private getRoomDecryptors;
- /**
- * sign the given object with our ed25519 key
- *
- * @param obj - Object to which we will add a 'signatures' property
- */
- signObject<T extends ISignableObject & object>(obj: T): Promise<void>;
-}
-/**
- * Fix up the backup key, that may be in the wrong format due to a bug in a
- * migration step. Some backup keys were stored as a comma-separated list of
- * integers, rather than a base64-encoded byte array. If this function is
- * passed a string that looks like a list of integers rather than a base64
- * string, it will attempt to convert it to the right format.
- *
- * @param key - the key to check
- * @returns If the key is in the wrong format, then the fixed
- * key will be returned. Otherwise null will be returned.
- *
- */
-export declare function fixBackupKey(key?: string): string | null;
-/**
- * Represents a received m.room_key_request event
- */
-export declare class IncomingRoomKeyRequest {
- /** user requesting the key */
- readonly userId: string;
- /** device requesting the key */
- readonly deviceId: string;
- /** unique id for the request */
- readonly requestId: string;
- readonly requestBody: IRoomKeyRequestBody;
- /**
- * callback which, when called, will ask
- * the relevant crypto algorithm implementation to share the keys for
- * this request.
- */
- share: () => void;
- constructor(event: MatrixEvent);
-}
-/**
- * Represents a received m.room_key_request cancellation
- */
-declare class IncomingRoomKeyRequestCancellation {
- /** user requesting the cancellation */
- readonly userId: string;
- /** device requesting the cancellation */
- readonly deviceId: string;
- /** unique id for the request to be cancelled */
- readonly requestId: string;
- constructor(event: MatrixEvent);
-}
-export type { IEventDecryptionResult, IMegolmSessionData } from "../@types/crypto";
-//# sourceMappingURL=index.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/index.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/index.d.ts.map
deleted file mode 100644
index c7021f3..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/index.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/crypto/index.ts"],"names":[],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/index.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/index.js
deleted file mode 100644
index d7d8551..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/index.js
+++ /dev/null
@@ -1,3290 +0,0 @@
-"use strict";
-
-var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.IncomingRoomKeyRequest = exports.CryptoEvent = exports.Crypto = void 0;
-exports.fixBackupKey = fixBackupKey;
-exports.isCryptoAvailable = isCryptoAvailable;
-exports.verificationMethods = void 0;
-var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
-var _anotherJson = _interopRequireDefault(require("another-json"));
-var _uuid = require("uuid");
-var _event = require("../@types/event");
-var _ReEmitter = require("../ReEmitter");
-var _logger = require("../logger");
-var _OlmDevice = require("./OlmDevice");
-var olmlib = _interopRequireWildcard(require("./olmlib"));
-var _DeviceList = require("./DeviceList");
-var _deviceinfo = require("./deviceinfo");
-var algorithms = _interopRequireWildcard(require("./algorithms"));
-var _CrossSigning = require("./CrossSigning");
-var _EncryptionSetup = require("./EncryptionSetup");
-var _SecretStorage = require("./SecretStorage");
-var _OutgoingRoomKeyRequestManager = require("./OutgoingRoomKeyRequestManager");
-var _indexeddbCryptoStore = require("./store/indexeddb-crypto-store");
-var _QRCode = require("./verification/QRCode");
-var _SAS = require("./verification/SAS");
-var _key_passphrase = require("./key_passphrase");
-var _recoverykey = require("./recoverykey");
-var _VerificationRequest = require("./verification/request/VerificationRequest");
-var _InRoomChannel = require("./verification/request/InRoomChannel");
-var _ToDeviceChannel = require("./verification/request/ToDeviceChannel");
-var _IllegalMethod = require("./verification/IllegalMethod");
-var _errors = require("../errors");
-var _aes = require("./aes");
-var _dehydration = require("./dehydration");
-var _backup = require("./backup");
-var _room = require("../models/room");
-var _roomMember = require("../models/room-member");
-var _event2 = require("../models/event");
-var _client = require("../client");
-var _typedEventEmitter = require("../models/typed-event-emitter");
-var _roomState = require("../models/room-state");
-var _utils = require("../utils");
-function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
-function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
-function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
-function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
-const DeviceVerification = _deviceinfo.DeviceInfo.DeviceVerification;
-const defaultVerificationMethods = {
- [_QRCode.ReciprocateQRCode.NAME]: _QRCode.ReciprocateQRCode,
- [_SAS.SAS.NAME]: _SAS.SAS,
- // These two can't be used for actual verification, but we do
- // need to be able to define them here for the verification flows
- // to start.
- [_QRCode.SHOW_QR_CODE_METHOD]: _IllegalMethod.IllegalMethod,
- [_QRCode.SCAN_QR_CODE_METHOD]: _IllegalMethod.IllegalMethod
-};
-
-/**
- * verification method names
- */
-// legacy export identifier
-const verificationMethods = {
- RECIPROCATE_QR_CODE: _QRCode.ReciprocateQRCode.NAME,
- SAS: _SAS.SAS.NAME
-};
-exports.verificationMethods = verificationMethods;
-function isCryptoAvailable() {
- return Boolean(global.Olm);
-}
-const MIN_FORCE_SESSION_INTERVAL_MS = 60 * 60 * 1000;
-let CryptoEvent;
-exports.CryptoEvent = CryptoEvent;
-(function (CryptoEvent) {
- CryptoEvent["DeviceVerificationChanged"] = "deviceVerificationChanged";
- CryptoEvent["UserTrustStatusChanged"] = "userTrustStatusChanged";
- CryptoEvent["UserCrossSigningUpdated"] = "userCrossSigningUpdated";
- CryptoEvent["RoomKeyRequest"] = "crypto.roomKeyRequest";
- CryptoEvent["RoomKeyRequestCancellation"] = "crypto.roomKeyRequestCancellation";
- CryptoEvent["KeyBackupStatus"] = "crypto.keyBackupStatus";
- CryptoEvent["KeyBackupFailed"] = "crypto.keyBackupFailed";
- CryptoEvent["KeyBackupSessionsRemaining"] = "crypto.keyBackupSessionsRemaining";
- CryptoEvent["KeySignatureUploadFailure"] = "crypto.keySignatureUploadFailure";
- CryptoEvent["VerificationRequest"] = "crypto.verification.request";
- CryptoEvent["Warning"] = "crypto.warning";
- CryptoEvent["WillUpdateDevices"] = "crypto.willUpdateDevices";
- CryptoEvent["DevicesUpdated"] = "crypto.devicesUpdated";
- CryptoEvent["KeysChanged"] = "crossSigning.keysChanged";
-})(CryptoEvent || (exports.CryptoEvent = CryptoEvent = {}));
-class Crypto extends _typedEventEmitter.TypedEventEmitter {
- /**
- * @returns The version of Olm.
- */
- static getOlmVersion() {
- return _OlmDevice.OlmDevice.getOlmVersion();
- }
- /**
- * Cryptography bits
- *
- * This module is internal to the js-sdk; the public API is via MatrixClient.
- *
- * @internal
- *
- * @param baseApis - base matrix api interface
- *
- * @param userId - The user ID for the local user
- *
- * @param deviceId - The identifier for this device.
- *
- * @param clientStore - the MatrixClient data store.
- *
- * @param cryptoStore - storage for the crypto layer.
- *
- * @param roomList - An initialised RoomList object
- *
- * @param verificationMethods - Array of verification methods to use.
- * Each element can either be a string from MatrixClient.verificationMethods
- * or a class that implements a verification method.
- */
- constructor(baseApis, userId, deviceId, clientStore, cryptoStore, roomList, verificationMethods) {
- super();
- this.baseApis = baseApis;
- this.userId = userId;
- this.deviceId = deviceId;
- this.clientStore = clientStore;
- this.cryptoStore = cryptoStore;
- this.roomList = roomList;
- (0, _defineProperty2.default)(this, "backupManager", void 0);
- (0, _defineProperty2.default)(this, "crossSigningInfo", void 0);
- (0, _defineProperty2.default)(this, "olmDevice", void 0);
- (0, _defineProperty2.default)(this, "deviceList", void 0);
- (0, _defineProperty2.default)(this, "dehydrationManager", void 0);
- (0, _defineProperty2.default)(this, "secretStorage", void 0);
- (0, _defineProperty2.default)(this, "reEmitter", void 0);
- (0, _defineProperty2.default)(this, "verificationMethods", void 0);
- (0, _defineProperty2.default)(this, "supportedAlgorithms", void 0);
- (0, _defineProperty2.default)(this, "outgoingRoomKeyRequestManager", void 0);
- (0, _defineProperty2.default)(this, "toDeviceVerificationRequests", void 0);
- (0, _defineProperty2.default)(this, "inRoomVerificationRequests", void 0);
- (0, _defineProperty2.default)(this, "trustCrossSignedDevices", true);
- (0, _defineProperty2.default)(this, "lastOneTimeKeyCheck", null);
- (0, _defineProperty2.default)(this, "oneTimeKeyCheckInProgress", false);
- (0, _defineProperty2.default)(this, "roomEncryptors", new Map());
- (0, _defineProperty2.default)(this, "roomDecryptors", new Map());
- (0, _defineProperty2.default)(this, "deviceKeys", {});
- (0, _defineProperty2.default)(this, "globalBlacklistUnverifiedDevices", false);
- (0, _defineProperty2.default)(this, "globalErrorOnUnknownDevices", true);
- (0, _defineProperty2.default)(this, "receivedRoomKeyRequests", []);
- (0, _defineProperty2.default)(this, "receivedRoomKeyRequestCancellations", []);
- (0, _defineProperty2.default)(this, "processingRoomKeyRequests", false);
- (0, _defineProperty2.default)(this, "lazyLoadMembers", false);
- (0, _defineProperty2.default)(this, "roomDeviceTrackingState", {});
- (0, _defineProperty2.default)(this, "lastNewSessionForced", new _utils.MapWithDefault(() => new _utils.MapWithDefault(() => 0)));
- (0, _defineProperty2.default)(this, "sendKeyRequestsImmediately", false);
- (0, _defineProperty2.default)(this, "oneTimeKeyCount", void 0);
- (0, _defineProperty2.default)(this, "needsNewFallback", void 0);
- (0, _defineProperty2.default)(this, "fallbackCleanup", void 0);
- (0, _defineProperty2.default)(this, "onDeviceListUserCrossSigningUpdated", async userId => {
- if (userId === this.userId) {
- // An update to our own cross-signing key.
- // Get the new key first:
- const newCrossSigning = this.deviceList.getStoredCrossSigningForUser(userId);
- const seenPubkey = newCrossSigning ? newCrossSigning.getId() : null;
- const currentPubkey = this.crossSigningInfo.getId();
- const changed = currentPubkey !== seenPubkey;
- if (currentPubkey && seenPubkey && !changed) {
- // If it's not changed, just make sure everything is up to date
- await this.checkOwnCrossSigningTrust();
- } else {
- // We'll now be in a state where cross-signing on the account is not trusted
- // because our locally stored cross-signing keys will not match the ones
- // on the server for our account. So we clear our own stored cross-signing keys,
- // effectively disabling cross-signing until the user gets verified by the device
- // that reset the keys
- this.storeTrustedSelfKeys(null);
- // emit cross-signing has been disabled
- this.emit(CryptoEvent.KeysChanged, {});
- // as the trust for our own user has changed,
- // also emit an event for this
- this.emit(CryptoEvent.UserTrustStatusChanged, this.userId, this.checkUserTrust(userId));
- }
- } else {
- await this.checkDeviceVerifications(userId);
-
- // Update verified before latch using the current state and save the new
- // latch value in the device list store.
- const crossSigning = this.deviceList.getStoredCrossSigningForUser(userId);
- if (crossSigning) {
- crossSigning.updateCrossSigningVerifiedBefore(this.checkUserTrust(userId).isCrossSigningVerified());
- this.deviceList.setRawStoredCrossSigningForUser(userId, crossSigning.toStorage());
- }
- this.emit(CryptoEvent.UserTrustStatusChanged, userId, this.checkUserTrust(userId));
- }
- });
- (0, _defineProperty2.default)(this, "onMembership", (event, member, oldMembership) => {
- try {
- this.onRoomMembership(event, member, oldMembership);
- } catch (e) {
- _logger.logger.error("Error handling membership change:", e);
- }
- });
- (0, _defineProperty2.default)(this, "onToDeviceEvent", event => {
- try {
- _logger.logger.log(`received to-device ${event.getType()} from: ` + `${event.getSender()} id: ${event.getContent()[_event.ToDeviceMessageId]}`);
- if (event.getType() == "m.room_key" || event.getType() == "m.forwarded_room_key") {
- this.onRoomKeyEvent(event);
- } else if (event.getType() == "m.room_key_request") {
- this.onRoomKeyRequestEvent(event);
- } else if (event.getType() === "m.secret.request") {
- this.secretStorage.onRequestReceived(event);
- } else if (event.getType() === "m.secret.send") {
- this.secretStorage.onSecretReceived(event);
- } else if (event.getType() === "m.room_key.withheld") {
- this.onRoomKeyWithheldEvent(event);
- } else if (event.getContent().transaction_id) {
- this.onKeyVerificationMessage(event);
- } else if (event.getContent().msgtype === "m.bad.encrypted") {
- this.onToDeviceBadEncrypted(event);
- } else if (event.isBeingDecrypted() || event.shouldAttemptDecryption()) {
- if (!event.isBeingDecrypted()) {
- event.attemptDecryption(this);
- }
- // once the event has been decrypted, try again
- event.once(_event2.MatrixEventEvent.Decrypted, ev => {
- this.onToDeviceEvent(ev);
- });
- }
- } catch (e) {
- _logger.logger.error("Error handling toDeviceEvent:", e);
- }
- });
- (0, _defineProperty2.default)(this, "onTimelineEvent", (event, room, atStart, removed, {
- liveEvent = true
- } = {}) => {
- if (!_InRoomChannel.InRoomChannel.validateEvent(event, this.baseApis)) {
- return;
- }
- const createRequest = event => {
- const channel = new _InRoomChannel.InRoomChannel(this.baseApis, event.getRoomId());
- return new _VerificationRequest.VerificationRequest(channel, this.verificationMethods, this.baseApis);
- };
- this.handleVerificationEvent(event, this.inRoomVerificationRequests, createRequest, liveEvent);
- });
- this.reEmitter = new _ReEmitter.TypedReEmitter(this);
- if (verificationMethods) {
- this.verificationMethods = new Map();
- for (const method of verificationMethods) {
- if (typeof method === "string") {
- if (defaultVerificationMethods[method]) {
- this.verificationMethods.set(method, defaultVerificationMethods[method]);
- }
- } else if (method["NAME"]) {
- this.verificationMethods.set(method["NAME"], method);
- } else {
- _logger.logger.warn(`Excluding unknown verification method ${method}`);
- }
- }
- } else {
- this.verificationMethods = new Map(Object.entries(defaultVerificationMethods));
- }
- this.backupManager = new _backup.BackupManager(baseApis, async () => {
- // try to get key from cache
- const cachedKey = await this.getSessionBackupPrivateKey();
- if (cachedKey) {
- return cachedKey;
- }
-
- // try to get key from secret storage
- const storedKey = await this.getSecret("m.megolm_backup.v1");
- if (storedKey) {
- // ensure that the key is in the right format. If not, fix the key and
- // store the fixed version
- const fixedKey = fixBackupKey(storedKey);
- if (fixedKey) {
- const keys = await this.getSecretStorageKey();
- await this.storeSecret("m.megolm_backup.v1", fixedKey, [keys[0]]);
- }
- return olmlib.decodeBase64(fixedKey || storedKey);
- }
-
- // try to get key from app
- if (this.baseApis.cryptoCallbacks && this.baseApis.cryptoCallbacks.getBackupKey) {
- return this.baseApis.cryptoCallbacks.getBackupKey();
- }
- throw new Error("Unable to get private key");
- });
- this.olmDevice = new _OlmDevice.OlmDevice(cryptoStore);
- this.deviceList = new _DeviceList.DeviceList(baseApis, cryptoStore, this.olmDevice);
-
- // XXX: This isn't removed at any point, but then none of the event listeners
- // this class sets seem to be removed at any point... :/
- this.deviceList.on(CryptoEvent.UserCrossSigningUpdated, this.onDeviceListUserCrossSigningUpdated);
- this.reEmitter.reEmit(this.deviceList, [CryptoEvent.DevicesUpdated, CryptoEvent.WillUpdateDevices]);
- this.supportedAlgorithms = Array.from(algorithms.DECRYPTION_CLASSES.keys());
- this.outgoingRoomKeyRequestManager = new _OutgoingRoomKeyRequestManager.OutgoingRoomKeyRequestManager(baseApis, this.deviceId, this.cryptoStore);
- this.toDeviceVerificationRequests = new _ToDeviceChannel.ToDeviceRequests();
- this.inRoomVerificationRequests = new _InRoomChannel.InRoomRequests();
- const cryptoCallbacks = this.baseApis.cryptoCallbacks || {};
- const cacheCallbacks = (0, _CrossSigning.createCryptoStoreCacheCallbacks)(cryptoStore, this.olmDevice);
- this.crossSigningInfo = new _CrossSigning.CrossSigningInfo(userId, cryptoCallbacks, cacheCallbacks);
- // Yes, we pass the client twice here: see SecretStorage
- this.secretStorage = new _SecretStorage.SecretStorage(baseApis, cryptoCallbacks, baseApis);
- this.dehydrationManager = new _dehydration.DehydrationManager(this);
-
- // Assuming no app-supplied callback, default to getting from SSSS.
- if (!cryptoCallbacks.getCrossSigningKey && cryptoCallbacks.getSecretStorageKey) {
- cryptoCallbacks.getCrossSigningKey = async type => {
- return _CrossSigning.CrossSigningInfo.getFromSecretStorage(type, this.secretStorage);
- };
- }
- }
-
- /**
- * Initialise the crypto module so that it is ready for use
- *
- * Returns a promise which resolves once the crypto module is ready for use.
- *
- * @param exportedOlmDevice - (Optional) data from exported device
- * that must be re-created.
- */
- async init({
- exportedOlmDevice,
- pickleKey
- } = {}) {
- _logger.logger.log("Crypto: initialising Olm...");
- await global.Olm.init();
- _logger.logger.log(exportedOlmDevice ? "Crypto: initialising Olm device from exported device..." : "Crypto: initialising Olm device...");
- await this.olmDevice.init({
- fromExportedDevice: exportedOlmDevice,
- pickleKey
- });
- _logger.logger.log("Crypto: loading device list...");
- await this.deviceList.load();
-
- // build our device keys: these will later be uploaded
- this.deviceKeys["ed25519:" + this.deviceId] = this.olmDevice.deviceEd25519Key;
- this.deviceKeys["curve25519:" + this.deviceId] = this.olmDevice.deviceCurve25519Key;
- _logger.logger.log("Crypto: fetching own devices...");
- let myDevices = this.deviceList.getRawStoredDevicesForUser(this.userId);
- if (!myDevices) {
- myDevices = {};
- }
- if (!myDevices[this.deviceId]) {
- // add our own deviceinfo to the cryptoStore
- _logger.logger.log("Crypto: adding this device to the store...");
- const deviceInfo = {
- keys: this.deviceKeys,
- algorithms: this.supportedAlgorithms,
- verified: DeviceVerification.VERIFIED,
- known: true
- };
- myDevices[this.deviceId] = deviceInfo;
- this.deviceList.storeDevicesForUser(this.userId, myDevices);
- this.deviceList.saveIfDirty();
- }
- await this.cryptoStore.doTxn("readonly", [_indexeddbCryptoStore.IndexedDBCryptoStore.STORE_ACCOUNT], txn => {
- this.cryptoStore.getCrossSigningKeys(txn, keys => {
- // can be an empty object after resetting cross-signing keys, see storeTrustedSelfKeys
- if (keys && Object.keys(keys).length !== 0) {
- _logger.logger.log("Loaded cross-signing public keys from crypto store");
- this.crossSigningInfo.setKeys(keys);
- }
- });
- });
- // make sure we are keeping track of our own devices
- // (this is important for key backups & things)
- this.deviceList.startTrackingDeviceList(this.userId);
- _logger.logger.log("Crypto: checking for key backup...");
- this.backupManager.checkAndStart();
- }
-
- /**
- * Whether to trust a others users signatures of their devices.
- * If false, devices will only be considered 'verified' if we have
- * verified that device individually (effectively disabling cross-signing).
- *
- * Default: true
- *
- * @returns True if trusting cross-signed devices
- */
- getCryptoTrustCrossSignedDevices() {
- return this.trustCrossSignedDevices;
- }
-
- /**
- * See getCryptoTrustCrossSignedDevices
- * This may be set before initCrypto() is called to ensure no races occur.
- *
- * @param val - True to trust cross-signed devices
- */
- setCryptoTrustCrossSignedDevices(val) {
- this.trustCrossSignedDevices = val;
- for (const userId of this.deviceList.getKnownUserIds()) {
- const devices = this.deviceList.getRawStoredDevicesForUser(userId);
- for (const deviceId of Object.keys(devices)) {
- const deviceTrust = this.checkDeviceTrust(userId, deviceId);
- // If the device is locally verified then isVerified() is always true,
- // so this will only have caused the value to change if the device is
- // cross-signing verified but not locally verified
- if (!deviceTrust.isLocallyVerified() && deviceTrust.isCrossSigningVerified()) {
- const deviceObj = this.deviceList.getStoredDevice(userId, deviceId);
- this.emit(CryptoEvent.DeviceVerificationChanged, userId, deviceId, deviceObj);
- }
- }
- }
- }
-
- /**
- * Create a recovery key from a user-supplied passphrase.
- *
- * @param password - Passphrase string that can be entered by the user
- * when restoring the backup as an alternative to entering the recovery key.
- * Optional.
- * @returns Object with public key metadata, encoded private
- * recovery key which should be disposed of after displaying to the user,
- * and raw private key to avoid round tripping if needed.
- */
- async createRecoveryKeyFromPassphrase(password) {
- const decryption = new global.Olm.PkDecryption();
- try {
- const keyInfo = {};
- if (password) {
- const derivation = await (0, _key_passphrase.keyFromPassphrase)(password);
- keyInfo.passphrase = {
- algorithm: "m.pbkdf2",
- iterations: derivation.iterations,
- salt: derivation.salt
- };
- keyInfo.pubkey = decryption.init_with_private_key(derivation.key);
- } else {
- keyInfo.pubkey = decryption.generate_key();
- }
- const privateKey = decryption.get_private_key();
- const encodedPrivateKey = (0, _recoverykey.encodeRecoveryKey)(privateKey);
- return {
- keyInfo: keyInfo,
- encodedPrivateKey,
- privateKey
- };
- } finally {
- decryption === null || decryption === void 0 ? void 0 : decryption.free();
- }
- }
-
- /**
- * Checks if the user has previously published cross-signing keys
- *
- * This means downloading the devicelist for the user and checking if the list includes
- * the cross-signing pseudo-device.
- *
- * @internal
- */
- async userHasCrossSigningKeys() {
- await this.downloadKeys([this.userId]);
- return this.deviceList.getStoredCrossSigningForUser(this.userId) !== null;
- }
-
- /**
- * Checks whether cross signing:
- * - is enabled on this account and trusted by this device
- * - has private keys either cached locally or stored in secret storage
- *
- * If this function returns false, bootstrapCrossSigning() can be used
- * to fix things such that it returns true. That is to say, after
- * bootstrapCrossSigning() completes successfully, this function should
- * return true.
- *
- * The cross-signing API is currently UNSTABLE and may change without notice.
- *
- * @returns True if cross-signing is ready to be used on this device
- */
- async isCrossSigningReady() {
- const publicKeysOnDevice = this.crossSigningInfo.getId();
- const privateKeysExistSomewhere = (await this.crossSigningInfo.isStoredInKeyCache()) || (await this.crossSigningInfo.isStoredInSecretStorage(this.secretStorage));
- return !!(publicKeysOnDevice && privateKeysExistSomewhere);
- }
-
- /**
- * Checks whether secret storage:
- * - is enabled on this account
- * - is storing cross-signing private keys
- * - is storing session backup key (if enabled)
- *
- * If this function returns false, bootstrapSecretStorage() can be used
- * to fix things such that it returns true. That is to say, after
- * bootstrapSecretStorage() completes successfully, this function should
- * return true.
- *
- * The Secure Secret Storage API is currently UNSTABLE and may change without notice.
- *
- * @returns True if secret storage is ready to be used on this device
- */
- async isSecretStorageReady() {
- const secretStorageKeyInAccount = await this.secretStorage.hasKey();
- const privateKeysInStorage = await this.crossSigningInfo.isStoredInSecretStorage(this.secretStorage);
- const sessionBackupInStorage = !this.backupManager.getKeyBackupEnabled() || (await this.baseApis.isKeyBackupKeyStored());
- return !!(secretStorageKeyInAccount && privateKeysInStorage && sessionBackupInStorage);
- }
-
- /**
- * Bootstrap cross-signing by creating keys if needed. If everything is already
- * set up, then no changes are made, so this is safe to run to ensure
- * cross-signing is ready for use.
- *
- * This function:
- * - creates new cross-signing keys if they are not found locally cached nor in
- * secret storage (if it has been setup)
- *
- * The cross-signing API is currently UNSTABLE and may change without notice.
- *
- * @param authUploadDeviceSigningKeys - Function
- * called to await an interactive auth flow when uploading device signing keys.
- * @param setupNewCrossSigning - Optional. Reset even if keys
- * already exist.
- * Args:
- * A function that makes the request requiring auth. Receives the
- * auth data as an object. Can be called multiple times, first with an empty
- * authDict, to obtain the flows.
- */
- async bootstrapCrossSigning({
- authUploadDeviceSigningKeys,
- setupNewCrossSigning
- } = {}) {
- _logger.logger.log("Bootstrapping cross-signing");
- const delegateCryptoCallbacks = this.baseApis.cryptoCallbacks;
- const builder = new _EncryptionSetup.EncryptionSetupBuilder(this.baseApis.store.accountData, delegateCryptoCallbacks);
- const crossSigningInfo = new _CrossSigning.CrossSigningInfo(this.userId, builder.crossSigningCallbacks, builder.crossSigningCallbacks);
-
- // Reset the cross-signing keys
- const resetCrossSigning = async () => {
- crossSigningInfo.resetKeys();
- // Sign master key with device key
- await this.signObject(crossSigningInfo.keys.master);
-
- // Store auth flow helper function, as we need to call it when uploading
- // to ensure we handle auth errors properly.
- builder.addCrossSigningKeys(authUploadDeviceSigningKeys, crossSigningInfo.keys);
-
- // Cross-sign own device
- const device = this.deviceList.getStoredDevice(this.userId, this.deviceId);
- const deviceSignature = await crossSigningInfo.signDevice(this.userId, device);
- builder.addKeySignature(this.userId, this.deviceId, deviceSignature);
-
- // Sign message key backup with cross-signing master key
- if (this.backupManager.backupInfo) {
- await crossSigningInfo.signObject(this.backupManager.backupInfo.auth_data, "master");
- builder.addSessionBackup(this.backupManager.backupInfo);
- }
- };
- const publicKeysOnDevice = this.crossSigningInfo.getId();
- const privateKeysInCache = await this.crossSigningInfo.isStoredInKeyCache();
- const privateKeysInStorage = await this.crossSigningInfo.isStoredInSecretStorage(this.secretStorage);
- const privateKeysExistSomewhere = privateKeysInCache || privateKeysInStorage;
-
- // Log all relevant state for easier parsing of debug logs.
- _logger.logger.log({
- setupNewCrossSigning,
- publicKeysOnDevice,
- privateKeysInCache,
- privateKeysInStorage,
- privateKeysExistSomewhere
- });
- if (!privateKeysExistSomewhere || setupNewCrossSigning) {
- _logger.logger.log("Cross-signing private keys not found locally or in secret storage, " + "creating new keys");
- // If a user has multiple devices, it important to only call bootstrap
- // as part of some UI flow (and not silently during startup), as they
- // may have setup cross-signing on a platform which has not saved keys
- // to secret storage, and this would reset them. In such a case, you
- // should prompt the user to verify any existing devices first (and
- // request private keys from those devices) before calling bootstrap.
- await resetCrossSigning();
- } else if (publicKeysOnDevice && privateKeysInCache) {
- _logger.logger.log("Cross-signing public keys trusted and private keys found locally");
- } else if (privateKeysInStorage) {
- _logger.logger.log("Cross-signing private keys not found locally, but they are available " + "in secret storage, reading storage and caching locally");
- await this.checkOwnCrossSigningTrust({
- allowPrivateKeyRequests: true
- });
- }
-
- // Assuming no app-supplied callback, default to storing new private keys in
- // secret storage if it exists. If it does not, it is assumed this will be
- // done as part of setting up secret storage later.
- const crossSigningPrivateKeys = builder.crossSigningCallbacks.privateKeys;
- if (crossSigningPrivateKeys.size && !this.baseApis.cryptoCallbacks.saveCrossSigningKeys) {
- const secretStorage = new _SecretStorage.SecretStorage(builder.accountDataClientAdapter, builder.ssssCryptoCallbacks, undefined);
- if (await secretStorage.hasKey()) {
- _logger.logger.log("Storing new cross-signing private keys in secret storage");
- // This is writing to in-memory account data in
- // builder.accountDataClientAdapter so won't fail
- await _CrossSigning.CrossSigningInfo.storeInSecretStorage(crossSigningPrivateKeys, secretStorage);
- }
- }
- const operation = builder.buildOperation();
- await operation.apply(this);
- // This persists private keys and public keys as trusted,
- // only do this if apply succeeded for now as retry isn't in place yet
- await builder.persist(this);
- _logger.logger.log("Cross-signing ready");
- }
-
- /**
- * Bootstrap Secure Secret Storage if needed by creating a default key. If everything is
- * already set up, then no changes are made, so this is safe to run to ensure secret
- * storage is ready for use.
- *
- * This function
- * - creates a new Secure Secret Storage key if no default key exists
- * - if a key backup exists, it is migrated to store the key in the Secret
- * Storage
- * - creates a backup if none exists, and one is requested
- * - migrates Secure Secret Storage to use the latest algorithm, if an outdated
- * algorithm is found
- *
- * The Secure Secret Storage API is currently UNSTABLE and may change without notice.
- *
- * @param createSecretStorageKey - Optional. Function
- * called to await a secret storage key creation flow.
- * Returns a Promise which resolves to an object with public key metadata, encoded private
- * recovery key which should be disposed of after displaying to the user,
- * and raw private key to avoid round tripping if needed.
- * @param keyBackupInfo - The current key backup object. If passed,
- * the passphrase and recovery key from this backup will be used.
- * @param setupNewKeyBackup - If true, a new key backup version will be
- * created and the private key stored in the new SSSS store. Ignored if keyBackupInfo
- * is supplied.
- * @param setupNewSecretStorage - Optional. Reset even if keys already exist.
- * @param getKeyBackupPassphrase - Optional. Function called to get the user's
- * current key backup passphrase. Should return a promise that resolves with a Buffer
- * containing the key, or rejects if the key cannot be obtained.
- * Returns:
- * A promise which resolves to key creation data for
- * SecretStorage#addKey: an object with `passphrase` etc fields.
- */
- // TODO this does not resolve with what it says it does
- async bootstrapSecretStorage({
- createSecretStorageKey = async () => ({}),
- keyBackupInfo,
- setupNewKeyBackup,
- setupNewSecretStorage,
- getKeyBackupPassphrase
- } = {}) {
- _logger.logger.log("Bootstrapping Secure Secret Storage");
- const delegateCryptoCallbacks = this.baseApis.cryptoCallbacks;
- const builder = new _EncryptionSetup.EncryptionSetupBuilder(this.baseApis.store.accountData, delegateCryptoCallbacks);
- const secretStorage = new _SecretStorage.SecretStorage(builder.accountDataClientAdapter, builder.ssssCryptoCallbacks, undefined);
-
- // the ID of the new SSSS key, if we create one
- let newKeyId = null;
-
- // create a new SSSS key and set it as default
- const createSSSS = async (opts, privateKey) => {
- if (privateKey) {
- opts.key = privateKey;
- }
- const {
- keyId,
- keyInfo
- } = await secretStorage.addKey(_SecretStorage.SECRET_STORAGE_ALGORITHM_V1_AES, opts);
- if (privateKey) {
- // make the private key available to encrypt 4S secrets
- builder.ssssCryptoCallbacks.addPrivateKey(keyId, keyInfo, privateKey);
- }
- await secretStorage.setDefaultKeyId(keyId);
- return keyId;
- };
- const ensureCanCheckPassphrase = async (keyId, keyInfo) => {
- if (!keyInfo.mac) {
- var _this$baseApis$crypto, _this$baseApis$crypto2;
- const key = await ((_this$baseApis$crypto = (_this$baseApis$crypto2 = this.baseApis.cryptoCallbacks).getSecretStorageKey) === null || _this$baseApis$crypto === void 0 ? void 0 : _this$baseApis$crypto.call(_this$baseApis$crypto2, {
- keys: {
- [keyId]: keyInfo
- }
- }, ""));
- if (key) {
- const privateKey = key[1];
- builder.ssssCryptoCallbacks.addPrivateKey(keyId, keyInfo, privateKey);
- const {
- iv,
- mac
- } = await (0, _aes.calculateKeyCheck)(privateKey);
- keyInfo.iv = iv;
- keyInfo.mac = mac;
- await builder.setAccountData(`m.secret_storage.key.${keyId}`, keyInfo);
- }
- }
- };
- const signKeyBackupWithCrossSigning = async keyBackupAuthData => {
- if (this.crossSigningInfo.getId() && (await this.crossSigningInfo.isStoredInKeyCache("master"))) {
- try {
- _logger.logger.log("Adding cross-signing signature to key backup");
- await this.crossSigningInfo.signObject(keyBackupAuthData, "master");
- } catch (e) {
- // This step is not critical (just helpful), so we catch here
- // and continue if it fails.
- _logger.logger.error("Signing key backup with cross-signing keys failed", e);
- }
- } else {
- _logger.logger.warn("Cross-signing keys not available, skipping signature on key backup");
- }
- };
- const oldSSSSKey = await this.getSecretStorageKey();
- const [oldKeyId, oldKeyInfo] = oldSSSSKey || [null, null];
- const storageExists = !setupNewSecretStorage && oldKeyInfo && oldKeyInfo.algorithm === _SecretStorage.SECRET_STORAGE_ALGORITHM_V1_AES;
-
- // Log all relevant state for easier parsing of debug logs.
- _logger.logger.log({
- keyBackupInfo,
- setupNewKeyBackup,
- setupNewSecretStorage,
- storageExists,
- oldKeyInfo
- });
- if (!storageExists && !keyBackupInfo) {
- // either we don't have anything, or we've been asked to restart
- // from scratch
- _logger.logger.log("Secret storage does not exist, creating new storage key");
-
- // if we already have a usable default SSSS key and aren't resetting
- // SSSS just use it. otherwise, create a new one
- // Note: we leave the old SSSS key in place: there could be other
- // secrets using it, in theory. We could move them to the new key but a)
- // that would mean we'd need to prompt for the old passphrase, and b)
- // it's not clear that would be the right thing to do anyway.
- const {
- keyInfo = {},
- privateKey
- } = await createSecretStorageKey();
- newKeyId = await createSSSS(keyInfo, privateKey);
- } else if (!storageExists && keyBackupInfo) {
- // we have an existing backup, but no SSSS
- _logger.logger.log("Secret storage does not exist, using key backup key");
-
- // if we have the backup key already cached, use it; otherwise use the
- // callback to prompt for the key
- const backupKey = (await this.getSessionBackupPrivateKey()) || (await (getKeyBackupPassphrase === null || getKeyBackupPassphrase === void 0 ? void 0 : getKeyBackupPassphrase()));
-
- // create a new SSSS key and use the backup key as the new SSSS key
- const opts = {};
- if (keyBackupInfo.auth_data.private_key_salt && keyBackupInfo.auth_data.private_key_iterations) {
- // FIXME: ???
- opts.passphrase = {
- algorithm: "m.pbkdf2",
- iterations: keyBackupInfo.auth_data.private_key_iterations,
- salt: keyBackupInfo.auth_data.private_key_salt,
- bits: 256
- };
- }
- newKeyId = await createSSSS(opts, backupKey);
-
- // store the backup key in secret storage
- await secretStorage.store("m.megolm_backup.v1", olmlib.encodeBase64(backupKey), [newKeyId]);
-
- // The backup is trusted because the user provided the private key.
- // Sign the backup with the cross-signing key so the key backup can
- // be trusted via cross-signing.
- await signKeyBackupWithCrossSigning(keyBackupInfo.auth_data);
- builder.addSessionBackup(keyBackupInfo);
- } else {
- // 4S is already set up
- _logger.logger.log("Secret storage exists");
- if (oldKeyInfo && oldKeyInfo.algorithm === _SecretStorage.SECRET_STORAGE_ALGORITHM_V1_AES) {
- // make sure that the default key has the information needed to
- // check the passphrase
- await ensureCanCheckPassphrase(oldKeyId, oldKeyInfo);
- }
- }
-
- // If we have cross-signing private keys cached, store them in secret
- // storage if they are not there already.
- if (!this.baseApis.cryptoCallbacks.saveCrossSigningKeys && (await this.isCrossSigningReady()) && (newKeyId || !(await this.crossSigningInfo.isStoredInSecretStorage(secretStorage)))) {
- _logger.logger.log("Copying cross-signing private keys from cache to secret storage");
- const crossSigningPrivateKeys = await this.crossSigningInfo.getCrossSigningKeysFromCache();
- // This is writing to in-memory account data in
- // builder.accountDataClientAdapter so won't fail
- await _CrossSigning.CrossSigningInfo.storeInSecretStorage(crossSigningPrivateKeys, secretStorage);
- }
- if (setupNewKeyBackup && !keyBackupInfo) {
- _logger.logger.log("Creating new message key backup version");
- const info = await this.baseApis.prepareKeyBackupVersion(null /* random key */,
- // don't write to secret storage, as it will write to this.secretStorage.
- // Here, we want to capture all the side-effects of bootstrapping,
- // and want to write to the local secretStorage object
- {
- secureSecretStorage: false
- });
- // write the key ourselves to 4S
- const privateKey = (0, _recoverykey.decodeRecoveryKey)(info.recovery_key);
- await secretStorage.store("m.megolm_backup.v1", olmlib.encodeBase64(privateKey));
-
- // create keyBackupInfo object to add to builder
- const data = {
- algorithm: info.algorithm,
- auth_data: info.auth_data
- };
-
- // Sign with cross-signing master key
- await signKeyBackupWithCrossSigning(data.auth_data);
-
- // sign with the device fingerprint
- await this.signObject(data.auth_data);
- builder.addSessionBackup(data);
- }
-
- // Cache the session backup key
- const sessionBackupKey = await secretStorage.get("m.megolm_backup.v1");
- if (sessionBackupKey) {
- _logger.logger.info("Got session backup key from secret storage: caching");
- // fix up the backup key if it's in the wrong format, and replace
- // in secret storage
- const fixedBackupKey = fixBackupKey(sessionBackupKey);
- if (fixedBackupKey) {
- const keyId = newKeyId || oldKeyId;
- await secretStorage.store("m.megolm_backup.v1", fixedBackupKey, keyId ? [keyId] : null);
- }
- const decodedBackupKey = new Uint8Array(olmlib.decodeBase64(fixedBackupKey || sessionBackupKey));
- builder.addSessionBackupPrivateKeyToCache(decodedBackupKey);
- } else if (this.backupManager.getKeyBackupEnabled()) {
- // key backup is enabled but we don't have a session backup key in SSSS: see if we have one in
- // the cache or the user can provide one, and if so, write it to SSSS
- const backupKey = (await this.getSessionBackupPrivateKey()) || (await (getKeyBackupPassphrase === null || getKeyBackupPassphrase === void 0 ? void 0 : getKeyBackupPassphrase()));
- if (!backupKey) {
- // This will require user intervention to recover from since we don't have the key
- // backup key anywhere. The user should probably just set up a new key backup and
- // the key for the new backup will be stored. If we hit this scenario in the wild
- // with any frequency, we should do more than just log an error.
- _logger.logger.error("Key backup is enabled but couldn't get key backup key!");
- return;
- }
- _logger.logger.info("Got session backup key from cache/user that wasn't in SSSS: saving to SSSS");
- await secretStorage.store("m.megolm_backup.v1", olmlib.encodeBase64(backupKey));
- }
- const operation = builder.buildOperation();
- await operation.apply(this);
- // this persists private keys and public keys as trusted,
- // only do this if apply succeeded for now as retry isn't in place yet
- await builder.persist(this);
- _logger.logger.log("Secure Secret Storage ready");
- }
- addSecretStorageKey(algorithm, opts, keyID) {
- return this.secretStorage.addKey(algorithm, opts, keyID);
- }
- hasSecretStorageKey(keyID) {
- return this.secretStorage.hasKey(keyID);
- }
- getSecretStorageKey(keyID) {
- return this.secretStorage.getKey(keyID);
- }
- storeSecret(name, secret, keys) {
- return this.secretStorage.store(name, secret, keys);
- }
- getSecret(name) {
- return this.secretStorage.get(name);
- }
- isSecretStored(name) {
- return this.secretStorage.isStored(name);
- }
- requestSecret(name, devices) {
- if (!devices) {
- devices = Object.keys(this.deviceList.getRawStoredDevicesForUser(this.userId));
- }
- return this.secretStorage.request(name, devices);
- }
- getDefaultSecretStorageKeyId() {
- return this.secretStorage.getDefaultKeyId();
- }
- setDefaultSecretStorageKeyId(k) {
- return this.secretStorage.setDefaultKeyId(k);
- }
- checkSecretStorageKey(key, info) {
- return this.secretStorage.checkKey(key, info);
- }
-
- /**
- * Checks that a given secret storage private key matches a given public key.
- * This can be used by the getSecretStorageKey callback to verify that the
- * private key it is about to supply is the one that was requested.
- *
- * @param privateKey - The private key
- * @param expectedPublicKey - The public key
- * @returns true if the key matches, otherwise false
- */
- checkSecretStoragePrivateKey(privateKey, expectedPublicKey) {
- let decryption = null;
- try {
- decryption = new global.Olm.PkDecryption();
- const gotPubkey = decryption.init_with_private_key(privateKey);
- // make sure it agrees with the given pubkey
- return gotPubkey === expectedPublicKey;
- } finally {
- var _decryption;
- (_decryption = decryption) === null || _decryption === void 0 ? void 0 : _decryption.free();
- }
- }
-
- /**
- * Fetches the backup private key, if cached
- * @returns the key, if any, or null
- */
- async getSessionBackupPrivateKey() {
- let key = await new Promise(resolve => {
- // TODO types
- this.cryptoStore.doTxn("readonly", [_indexeddbCryptoStore.IndexedDBCryptoStore.STORE_ACCOUNT], txn => {
- this.cryptoStore.getSecretStorePrivateKey(txn, resolve, "m.megolm_backup.v1");
- });
- });
-
- // make sure we have a Uint8Array, rather than a string
- if (key && typeof key === "string") {
- key = new Uint8Array(olmlib.decodeBase64(fixBackupKey(key) || key));
- await this.storeSessionBackupPrivateKey(key);
- }
- if (key && key.ciphertext) {
- const pickleKey = Buffer.from(this.olmDevice.pickleKey);
- const decrypted = await (0, _aes.decryptAES)(key, pickleKey, "m.megolm_backup.v1");
- key = olmlib.decodeBase64(decrypted);
- }
- return key;
- }
-
- /**
- * Stores the session backup key to the cache
- * @param key - the private key
- * @returns a promise so you can catch failures
- */
- async storeSessionBackupPrivateKey(key) {
- if (!(key instanceof Uint8Array)) {
- // eslint-disable-next-line @typescript-eslint/no-base-to-string
- throw new Error(`storeSessionBackupPrivateKey expects Uint8Array, got ${key}`);
- }
- const pickleKey = Buffer.from(this.olmDevice.pickleKey);
- const encryptedKey = await (0, _aes.encryptAES)(olmlib.encodeBase64(key), pickleKey, "m.megolm_backup.v1");
- return this.cryptoStore.doTxn("readwrite", [_indexeddbCryptoStore.IndexedDBCryptoStore.STORE_ACCOUNT], txn => {
- this.cryptoStore.storeSecretStorePrivateKey(txn, "m.megolm_backup.v1", encryptedKey);
- });
- }
-
- /**
- * Checks that a given cross-signing private key matches a given public key.
- * This can be used by the getCrossSigningKey callback to verify that the
- * private key it is about to supply is the one that was requested.
- *
- * @param privateKey - The private key
- * @param expectedPublicKey - The public key
- * @returns true if the key matches, otherwise false
- */
- checkCrossSigningPrivateKey(privateKey, expectedPublicKey) {
- let signing = null;
- try {
- signing = new global.Olm.PkSigning();
- const gotPubkey = signing.init_with_seed(privateKey);
- // make sure it agrees with the given pubkey
- return gotPubkey === expectedPublicKey;
- } finally {
- var _signing;
- (_signing = signing) === null || _signing === void 0 ? void 0 : _signing.free();
- }
- }
-
- /**
- * Run various follow-up actions after cross-signing keys have changed locally
- * (either by resetting the keys for the account or by getting them from secret
- * storage), such as signing the current device, upgrading device
- * verifications, etc.
- */
- async afterCrossSigningLocalKeyChange() {
- _logger.logger.info("Starting cross-signing key change post-processing");
-
- // sign the current device with the new key, and upload to the server
- const device = this.deviceList.getStoredDevice(this.userId, this.deviceId);
- const signedDevice = await this.crossSigningInfo.signDevice(this.userId, device);
- _logger.logger.info(`Starting background key sig upload for ${this.deviceId}`);
- const upload = ({
- shouldEmit = false
- }) => {
- return this.baseApis.uploadKeySignatures({
- [this.userId]: {
- [this.deviceId]: signedDevice
- }
- }).then(response => {
- const {
- failures
- } = response || {};
- if (Object.keys(failures || []).length > 0) {
- if (shouldEmit) {
- this.baseApis.emit(CryptoEvent.KeySignatureUploadFailure, failures, "afterCrossSigningLocalKeyChange", upload // continuation
- );
- }
-
- throw new _errors.KeySignatureUploadError("Key upload failed", {
- failures
- });
- }
- _logger.logger.info(`Finished background key sig upload for ${this.deviceId}`);
- }).catch(e => {
- _logger.logger.error(`Error during background key sig upload for ${this.deviceId}`, e);
- });
- };
- upload({
- shouldEmit: true
- });
- const shouldUpgradeCb = this.baseApis.cryptoCallbacks.shouldUpgradeDeviceVerifications;
- if (shouldUpgradeCb) {
- _logger.logger.info("Starting device verification upgrade");
-
- // Check all users for signatures if upgrade callback present
- // FIXME: do this in batches
- const users = {};
- for (const [userId, crossSigningInfo] of Object.entries(this.deviceList.crossSigningInfo)) {
- const upgradeInfo = await this.checkForDeviceVerificationUpgrade(userId, _CrossSigning.CrossSigningInfo.fromStorage(crossSigningInfo, userId));
- if (upgradeInfo) {
- users[userId] = upgradeInfo;
- }
- }
- if (Object.keys(users).length > 0) {
- _logger.logger.info(`Found ${Object.keys(users).length} verif users to upgrade`);
- try {
- const usersToUpgrade = await shouldUpgradeCb({
- users: users
- });
- if (usersToUpgrade) {
- for (const userId of usersToUpgrade) {
- if (userId in users) {
- await this.baseApis.setDeviceVerified(userId, users[userId].crossSigningInfo.getId());
- }
- }
- }
- } catch (e) {
- _logger.logger.log("shouldUpgradeDeviceVerifications threw an error: not upgrading", e);
- }
- }
- _logger.logger.info("Finished device verification upgrade");
- }
- _logger.logger.info("Finished cross-signing key change post-processing");
- }
-
- /**
- * Check if a user's cross-signing key is a candidate for upgrading from device
- * verification.
- *
- * @param userId - the user whose cross-signing information is to be checked
- * @param crossSigningInfo - the cross-signing information to check
- */
- async checkForDeviceVerificationUpgrade(userId, crossSigningInfo) {
- // only upgrade if this is the first cross-signing key that we've seen for
- // them, and if their cross-signing key isn't already verified
- const trustLevel = this.crossSigningInfo.checkUserTrust(crossSigningInfo);
- if (crossSigningInfo.firstUse && !trustLevel.isVerified()) {
- const devices = this.deviceList.getRawStoredDevicesForUser(userId);
- const deviceIds = await this.checkForValidDeviceSignature(userId, crossSigningInfo.keys.master, devices);
- if (deviceIds.length) {
- return {
- devices: deviceIds.map(deviceId => _deviceinfo.DeviceInfo.fromStorage(devices[deviceId], deviceId)),
- crossSigningInfo
- };
- }
- }
- }
-
- /**
- * Check if the cross-signing key is signed by a verified device.
- *
- * @param userId - the user ID whose key is being checked
- * @param key - the key that is being checked
- * @param devices - the user's devices. Should be a map from device ID
- * to device info
- */
- async checkForValidDeviceSignature(userId, key, devices) {
- const deviceIds = [];
- if (devices && key.signatures && key.signatures[userId]) {
- for (const signame of Object.keys(key.signatures[userId])) {
- const [, deviceId] = signame.split(":", 2);
- if (deviceId in devices && devices[deviceId].verified === DeviceVerification.VERIFIED) {
- try {
- await olmlib.verifySignature(this.olmDevice, key, userId, deviceId, devices[deviceId].keys[signame]);
- deviceIds.push(deviceId);
- } catch (e) {}
- }
- }
- }
- return deviceIds;
- }
-
- /**
- * Get the user's cross-signing key ID.
- *
- * @param type - The type of key to get the ID of. One of
- * "master", "self_signing", or "user_signing". Defaults to "master".
- *
- * @returns the key ID
- */
- getCrossSigningId(type) {
- return this.crossSigningInfo.getId(type);
- }
-
- /**
- * Get the cross signing information for a given user.
- *
- * @param userId - the user ID to get the cross-signing info for.
- *
- * @returns the cross signing information for the user.
- */
- getStoredCrossSigningForUser(userId) {
- return this.deviceList.getStoredCrossSigningForUser(userId);
- }
-
- /**
- * Check whether a given user is trusted.
- *
- * @param userId - The ID of the user to check.
- *
- * @returns
- */
- checkUserTrust(userId) {
- const userCrossSigning = this.deviceList.getStoredCrossSigningForUser(userId);
- if (!userCrossSigning) {
- return new _CrossSigning.UserTrustLevel(false, false, false);
- }
- return this.crossSigningInfo.checkUserTrust(userCrossSigning);
- }
-
- /**
- * Check whether a given device is trusted.
- *
- * @param userId - The ID of the user whose devices is to be checked.
- * @param deviceId - The ID of the device to check
- *
- * @returns
- */
- checkDeviceTrust(userId, deviceId) {
- const device = this.deviceList.getStoredDevice(userId, deviceId);
- return this.checkDeviceInfoTrust(userId, device);
- }
-
- /**
- * Check whether a given deviceinfo is trusted.
- *
- * @param userId - The ID of the user whose devices is to be checked.
- * @param device - The device info object to check
- *
- * @returns
- */
- checkDeviceInfoTrust(userId, device) {
- const trustedLocally = !!(device !== null && device !== void 0 && device.isVerified());
- const userCrossSigning = this.deviceList.getStoredCrossSigningForUser(userId);
- if (device && userCrossSigning) {
- // The trustCrossSignedDevices only affects trust of other people's cross-signing
- // signatures
- const trustCrossSig = this.trustCrossSignedDevices || userId === this.userId;
- return this.crossSigningInfo.checkDeviceTrust(userCrossSigning, device, trustedLocally, trustCrossSig);
- } else {
- return new _CrossSigning.DeviceTrustLevel(false, false, trustedLocally, false);
- }
- }
-
- /**
- * Check whether one of our own devices is cross-signed by our
- * user's stored keys, regardless of whether we trust those keys yet.
- *
- * @param deviceId - The ID of the device to check
- *
- * @returns true if the device is cross-signed
- */
- checkIfOwnDeviceCrossSigned(deviceId) {
- var _userCrossSigning$che;
- const device = this.deviceList.getStoredDevice(this.userId, deviceId);
- if (!device) return false;
- const userCrossSigning = this.deviceList.getStoredCrossSigningForUser(this.userId);
- return (_userCrossSigning$che = userCrossSigning === null || userCrossSigning === void 0 ? void 0 : userCrossSigning.checkDeviceTrust(userCrossSigning, device, false, true).isCrossSigningVerified()) !== null && _userCrossSigning$che !== void 0 ? _userCrossSigning$che : false;
- }
-
- /*
- * Event handler for DeviceList's userNewDevices event
- */
-
- /**
- * Check the copy of our cross-signing key that we have in the device list and
- * see if we can get the private key. If so, mark it as trusted.
- */
- async checkOwnCrossSigningTrust({
- allowPrivateKeyRequests = false
- } = {}) {
- const userId = this.userId;
-
- // Before proceeding, ensure our cross-signing public keys have been
- // downloaded via the device list.
- await this.downloadKeys([this.userId]);
-
- // Also check which private keys are locally cached.
- const crossSigningPrivateKeys = await this.crossSigningInfo.getCrossSigningKeysFromCache();
-
- // If we see an update to our own master key, check it against the master
- // key we have and, if it matches, mark it as verified
-
- // First, get the new cross-signing info
- const newCrossSigning = this.deviceList.getStoredCrossSigningForUser(userId);
- if (!newCrossSigning) {
- _logger.logger.error("Got cross-signing update event for user " + userId + " but no new cross-signing information found!");
- return;
- }
- const seenPubkey = newCrossSigning.getId();
- const masterChanged = this.crossSigningInfo.getId() !== seenPubkey;
- const masterExistsNotLocallyCached = newCrossSigning.getId() && !crossSigningPrivateKeys.has("master");
- if (masterChanged) {
- _logger.logger.info("Got new master public key", seenPubkey);
- }
- if (allowPrivateKeyRequests && (masterChanged || masterExistsNotLocallyCached)) {
- _logger.logger.info("Attempting to retrieve cross-signing master private key");
- let signing = null;
- // It's important for control flow that we leave any errors alone for
- // higher levels to handle so that e.g. cancelling access properly
- // aborts any larger operation as well.
- try {
- const ret = await this.crossSigningInfo.getCrossSigningKey("master", seenPubkey);
- signing = ret[1];
- _logger.logger.info("Got cross-signing master private key");
- } finally {
- var _signing2;
- (_signing2 = signing) === null || _signing2 === void 0 ? void 0 : _signing2.free();
- }
- }
- const oldSelfSigningId = this.crossSigningInfo.getId("self_signing");
- const oldUserSigningId = this.crossSigningInfo.getId("user_signing");
-
- // Update the version of our keys in our cross-signing object and the local store
- this.storeTrustedSelfKeys(newCrossSigning.keys);
- const selfSigningChanged = oldSelfSigningId !== newCrossSigning.getId("self_signing");
- const userSigningChanged = oldUserSigningId !== newCrossSigning.getId("user_signing");
- const selfSigningExistsNotLocallyCached = newCrossSigning.getId("self_signing") && !crossSigningPrivateKeys.has("self_signing");
- const userSigningExistsNotLocallyCached = newCrossSigning.getId("user_signing") && !crossSigningPrivateKeys.has("user_signing");
- const keySignatures = {};
- if (selfSigningChanged) {
- _logger.logger.info("Got new self-signing key", newCrossSigning.getId("self_signing"));
- }
- if (allowPrivateKeyRequests && (selfSigningChanged || selfSigningExistsNotLocallyCached)) {
- _logger.logger.info("Attempting to retrieve cross-signing self-signing private key");
- let signing = null;
- try {
- const ret = await this.crossSigningInfo.getCrossSigningKey("self_signing", newCrossSigning.getId("self_signing"));
- signing = ret[1];
- _logger.logger.info("Got cross-signing self-signing private key");
- } finally {
- var _signing3;
- (_signing3 = signing) === null || _signing3 === void 0 ? void 0 : _signing3.free();
- }
- const device = this.deviceList.getStoredDevice(this.userId, this.deviceId);
- const signedDevice = await this.crossSigningInfo.signDevice(this.userId, device);
- keySignatures[this.deviceId] = signedDevice;
- }
- if (userSigningChanged) {
- _logger.logger.info("Got new user-signing key", newCrossSigning.getId("user_signing"));
- }
- if (allowPrivateKeyRequests && (userSigningChanged || userSigningExistsNotLocallyCached)) {
- _logger.logger.info("Attempting to retrieve cross-signing user-signing private key");
- let signing = null;
- try {
- const ret = await this.crossSigningInfo.getCrossSigningKey("user_signing", newCrossSigning.getId("user_signing"));
- signing = ret[1];
- _logger.logger.info("Got cross-signing user-signing private key");
- } finally {
- var _signing4;
- (_signing4 = signing) === null || _signing4 === void 0 ? void 0 : _signing4.free();
- }
- }
- if (masterChanged) {
- const masterKey = this.crossSigningInfo.keys.master;
- await this.signObject(masterKey);
- const deviceSig = masterKey.signatures[this.userId]["ed25519:" + this.deviceId];
- // Include only the _new_ device signature in the upload.
- // We may have existing signatures from deleted devices, which will cause
- // the entire upload to fail.
- keySignatures[this.crossSigningInfo.getId()] = Object.assign({}, masterKey, {
- signatures: {
- [this.userId]: {
- ["ed25519:" + this.deviceId]: deviceSig
- }
- }
- });
- }
- const keysToUpload = Object.keys(keySignatures);
- if (keysToUpload.length) {
- const upload = ({
- shouldEmit = false
- }) => {
- _logger.logger.info(`Starting background key sig upload for ${keysToUpload}`);
- return this.baseApis.uploadKeySignatures({
- [this.userId]: keySignatures
- }).then(response => {
- const {
- failures
- } = response || {};
- _logger.logger.info(`Finished background key sig upload for ${keysToUpload}`);
- if (Object.keys(failures || []).length > 0) {
- if (shouldEmit) {
- this.baseApis.emit(CryptoEvent.KeySignatureUploadFailure, failures, "checkOwnCrossSigningTrust", upload);
- }
- throw new _errors.KeySignatureUploadError("Key upload failed", {
- failures
- });
- }
- }).catch(e => {
- _logger.logger.error(`Error during background key sig upload for ${keysToUpload}`, e);
- });
- };
- upload({
- shouldEmit: true
- });
- }
- this.emit(CryptoEvent.UserTrustStatusChanged, userId, this.checkUserTrust(userId));
- if (masterChanged) {
- this.emit(CryptoEvent.KeysChanged, {});
- await this.afterCrossSigningLocalKeyChange();
- }
-
- // Now we may be able to trust our key backup
- await this.backupManager.checkKeyBackup();
- // FIXME: if we previously trusted the backup, should we automatically sign
- // the backup with the new key (if not already signed)?
- }
-
- /**
- * Store a set of keys as our own, trusted, cross-signing keys.
- *
- * @param keys - The new trusted set of keys
- */
- async storeTrustedSelfKeys(keys) {
- if (keys) {
- this.crossSigningInfo.setKeys(keys);
- } else {
- this.crossSigningInfo.clearKeys();
- }
- await this.cryptoStore.doTxn("readwrite", [_indexeddbCryptoStore.IndexedDBCryptoStore.STORE_ACCOUNT], txn => {
- this.cryptoStore.storeCrossSigningKeys(txn, this.crossSigningInfo.keys);
- });
- }
-
- /**
- * Check if the master key is signed by a verified device, and if so, prompt
- * the application to mark it as verified.
- *
- * @param userId - the user ID whose key should be checked
- */
- async checkDeviceVerifications(userId) {
- const shouldUpgradeCb = this.baseApis.cryptoCallbacks.shouldUpgradeDeviceVerifications;
- if (!shouldUpgradeCb) {
- // Upgrading skipped when callback is not present.
- return;
- }
- _logger.logger.info(`Starting device verification upgrade for ${userId}`);
- if (this.crossSigningInfo.keys.user_signing) {
- const crossSigningInfo = this.deviceList.getStoredCrossSigningForUser(userId);
- if (crossSigningInfo) {
- const upgradeInfo = await this.checkForDeviceVerificationUpgrade(userId, crossSigningInfo);
- if (upgradeInfo) {
- const usersToUpgrade = await shouldUpgradeCb({
- users: {
- [userId]: upgradeInfo
- }
- });
- if (usersToUpgrade.includes(userId)) {
- await this.baseApis.setDeviceVerified(userId, crossSigningInfo.getId());
- }
- }
- }
- }
- _logger.logger.info(`Finished device verification upgrade for ${userId}`);
- }
-
- /**
- */
- enableLazyLoading() {
- this.lazyLoadMembers = true;
- }
-
- /**
- * Tell the crypto module to register for MatrixClient events which it needs to
- * listen for
- *
- * @param eventEmitter - event source where we can register
- * for event notifications
- */
- registerEventHandlers(eventEmitter) {
- eventEmitter.on(_roomMember.RoomMemberEvent.Membership, this.onMembership);
- eventEmitter.on(_client.ClientEvent.ToDeviceEvent, this.onToDeviceEvent);
- eventEmitter.on(_room.RoomEvent.Timeline, this.onTimelineEvent);
- eventEmitter.on(_event2.MatrixEventEvent.Decrypted, this.onTimelineEvent);
- }
-
- /**
- * @deprecated this does nothing and will be removed in a future version
- */
- start() {
- _logger.logger.warn("MatrixClient.crypto.start() is deprecated");
- }
-
- /** Stop background processes related to crypto */
- stop() {
- this.outgoingRoomKeyRequestManager.stop();
- this.deviceList.stop();
- this.dehydrationManager.stop();
- }
-
- /**
- * Get the Ed25519 key for this device
- *
- * @returns base64-encoded ed25519 key.
- */
- getDeviceEd25519Key() {
- return this.olmDevice.deviceEd25519Key;
- }
-
- /**
- * Get the Curve25519 key for this device
- *
- * @returns base64-encoded curve25519 key.
- */
- getDeviceCurve25519Key() {
- return this.olmDevice.deviceCurve25519Key;
- }
-
- /**
- * Set the global override for whether the client should ever send encrypted
- * messages to unverified devices. This provides the default for rooms which
- * do not specify a value.
- *
- * @param value - whether to blacklist all unverified devices by default
- *
- * @deprecated For external code, use {@link MatrixClient#setGlobalBlacklistUnverifiedDevices}. For
- * internal code, set {@link MatrixClient#globalBlacklistUnverifiedDevices} directly.
- */
- setGlobalBlacklistUnverifiedDevices(value) {
- this.globalBlacklistUnverifiedDevices = value;
- }
-
- /**
- * @returns whether to blacklist all unverified devices by default
- *
- * @deprecated For external code, use {@link MatrixClient#getGlobalBlacklistUnverifiedDevices}. For
- * internal code, reference {@link MatrixClient#globalBlacklistUnverifiedDevices} directly.
- */
- getGlobalBlacklistUnverifiedDevices() {
- return this.globalBlacklistUnverifiedDevices;
- }
-
- /**
- * Upload the device keys to the homeserver.
- * @returns A promise that will resolve when the keys are uploaded.
- */
- uploadDeviceKeys() {
- const deviceKeys = {
- algorithms: this.supportedAlgorithms,
- device_id: this.deviceId,
- keys: this.deviceKeys,
- user_id: this.userId
- };
- return this.signObject(deviceKeys).then(() => {
- return this.baseApis.uploadKeysRequest({
- device_keys: deviceKeys
- });
- });
- }
-
- /**
- * Stores the current one_time_key count which will be handled later (in a call of
- * onSyncCompleted). The count is e.g. coming from a /sync response.
- *
- * @param currentCount - The current count of one_time_keys to be stored
- */
- updateOneTimeKeyCount(currentCount) {
- if (isFinite(currentCount)) {
- this.oneTimeKeyCount = currentCount;
- } else {
- throw new TypeError("Parameter for updateOneTimeKeyCount has to be a number");
- }
- }
- setNeedsNewFallback(needsNewFallback) {
- this.needsNewFallback = needsNewFallback;
- }
- getNeedsNewFallback() {
- return !!this.needsNewFallback;
- }
-
- // check if it's time to upload one-time keys, and do so if so.
- maybeUploadOneTimeKeys() {
- // frequency with which to check & upload one-time keys
- const uploadPeriod = 1000 * 60; // one minute
-
- // max number of keys to upload at once
- // Creating keys can be an expensive operation so we limit the
- // number we generate in one go to avoid blocking the application
- // for too long.
- const maxKeysPerCycle = 5;
- if (this.oneTimeKeyCheckInProgress) {
- return;
- }
- const now = Date.now();
- if (this.lastOneTimeKeyCheck !== null && now - this.lastOneTimeKeyCheck < uploadPeriod) {
- // we've done a key upload recently.
- return;
- }
- this.lastOneTimeKeyCheck = now;
-
- // We need to keep a pool of one time public keys on the server so that
- // other devices can start conversations with us. But we can only store
- // a finite number of private keys in the olm Account object.
- // To complicate things further then can be a delay between a device
- // claiming a public one time key from the server and it sending us a
- // message. We need to keep the corresponding private key locally until
- // we receive the message.
- // But that message might never arrive leaving us stuck with duff
- // private keys clogging up our local storage.
- // So we need some kind of engineering compromise to balance all of
- // these factors.
-
- // Check how many keys we can store in the Account object.
- const maxOneTimeKeys = this.olmDevice.maxNumberOfOneTimeKeys();
- // Try to keep at most half that number on the server. This leaves the
- // rest of the slots free to hold keys that have been claimed from the
- // server but we haven't received a message for.
- // If we run out of slots when generating new keys then olm will
- // discard the oldest private keys first. This will eventually clean
- // out stale private keys that won't receive a message.
- const keyLimit = Math.floor(maxOneTimeKeys / 2);
- const uploadLoop = async keyCount => {
- while (keyLimit > keyCount || this.getNeedsNewFallback()) {
- // Ask olm to generate new one time keys, then upload them to synapse.
- if (keyLimit > keyCount) {
- _logger.logger.info("generating oneTimeKeys");
- const keysThisLoop = Math.min(keyLimit - keyCount, maxKeysPerCycle);
- await this.olmDevice.generateOneTimeKeys(keysThisLoop);
- }
- if (this.getNeedsNewFallback()) {
- const fallbackKeys = await this.olmDevice.getFallbackKey();
- // if fallbackKeys is non-empty, we've already generated a
- // fallback key, but it hasn't been published yet, so we
- // can use that instead of generating a new one
- if (!fallbackKeys.curve25519 || Object.keys(fallbackKeys.curve25519).length == 0) {
- _logger.logger.info("generating fallback key");
- if (this.fallbackCleanup) {
- // cancel any pending fallback cleanup because generating
- // a new fallback key will already drop the old fallback
- // that would have been dropped, and we don't want to kill
- // the current key
- clearTimeout(this.fallbackCleanup);
- delete this.fallbackCleanup;
- }
- await this.olmDevice.generateFallbackKey();
- }
- }
- _logger.logger.info("calling uploadOneTimeKeys");
- const res = await this.uploadOneTimeKeys();
- if (res.one_time_key_counts && res.one_time_key_counts.signed_curve25519) {
- // if the response contains a more up to date value use this
- // for the next loop
- keyCount = res.one_time_key_counts.signed_curve25519;
- } else {
- throw new Error("response for uploading keys does not contain " + "one_time_key_counts.signed_curve25519");
- }
- }
- };
- this.oneTimeKeyCheckInProgress = true;
- Promise.resolve().then(() => {
- if (this.oneTimeKeyCount !== undefined) {
- // We already have the current one_time_key count from a /sync response.
- // Use this value instead of asking the server for the current key count.
- return Promise.resolve(this.oneTimeKeyCount);
- }
- // ask the server how many keys we have
- return this.baseApis.uploadKeysRequest({}).then(res => {
- return res.one_time_key_counts.signed_curve25519 || 0;
- });
- }).then(keyCount => {
- // Start the uploadLoop with the current keyCount. The function checks if
- // we need to upload new keys or not.
- // If there are too many keys on the server then we don't need to
- // create any more keys.
- return uploadLoop(keyCount);
- }).catch(e => {
- _logger.logger.error("Error uploading one-time keys", e.stack || e);
- }).finally(() => {
- // reset oneTimeKeyCount to prevent start uploading based on old data.
- // it will be set again on the next /sync-response
- this.oneTimeKeyCount = undefined;
- this.oneTimeKeyCheckInProgress = false;
- });
- }
-
- // returns a promise which resolves to the response
- async uploadOneTimeKeys() {
- const promises = [];
- let fallbackJson;
- if (this.getNeedsNewFallback()) {
- fallbackJson = {};
- const fallbackKeys = await this.olmDevice.getFallbackKey();
- for (const [keyId, key] of Object.entries(fallbackKeys.curve25519)) {
- const k = {
- key,
- fallback: true
- };
- fallbackJson["signed_curve25519:" + keyId] = k;
- promises.push(this.signObject(k));
- }
- this.setNeedsNewFallback(false);
- }
- const oneTimeKeys = await this.olmDevice.getOneTimeKeys();
- const oneTimeJson = {};
- for (const keyId in oneTimeKeys.curve25519) {
- if (oneTimeKeys.curve25519.hasOwnProperty(keyId)) {
- const k = {
- key: oneTimeKeys.curve25519[keyId]
- };
- oneTimeJson["signed_curve25519:" + keyId] = k;
- promises.push(this.signObject(k));
- }
- }
- await Promise.all(promises);
- const requestBody = {
- one_time_keys: oneTimeJson
- };
- if (fallbackJson) {
- requestBody["org.matrix.msc2732.fallback_keys"] = fallbackJson;
- requestBody["fallback_keys"] = fallbackJson;
- }
- const res = await this.baseApis.uploadKeysRequest(requestBody);
- if (fallbackJson) {
- this.fallbackCleanup = setTimeout(() => {
- delete this.fallbackCleanup;
- this.olmDevice.forgetOldFallbackKey();
- }, 60 * 60 * 1000);
- }
- await this.olmDevice.markKeysAsPublished();
- return res;
- }
-
- /**
- * Download the keys for a list of users and stores the keys in the session
- * store.
- * @param userIds - The users to fetch.
- * @param forceDownload - Always download the keys even if cached.
- *
- * @returns A promise which resolves to a map `userId->deviceId->{@link DeviceInfo}`.
- */
- downloadKeys(userIds, forceDownload) {
- return this.deviceList.downloadKeys(userIds, !!forceDownload);
- }
-
- /**
- * Get the stored device keys for a user id
- *
- * @param userId - the user to list keys for.
- *
- * @returns list of devices, or null if we haven't
- * managed to get a list of devices for this user yet.
- */
- getStoredDevicesForUser(userId) {
- return this.deviceList.getStoredDevicesForUser(userId);
- }
-
- /**
- * Get the stored keys for a single device
- *
- *
- * @returns device, or undefined
- * if we don't know about this device
- */
- getStoredDevice(userId, deviceId) {
- return this.deviceList.getStoredDevice(userId, deviceId);
- }
-
- /**
- * Save the device list, if necessary
- *
- * @param delay - Time in ms before which the save actually happens.
- * By default, the save is delayed for a short period in order to batch
- * multiple writes, but this behaviour can be disabled by passing 0.
- *
- * @returns true if the data was saved, false if
- * it was not (eg. because no changes were pending). The promise
- * will only resolve once the data is saved, so may take some time
- * to resolve.
- */
- saveDeviceList(delay) {
- return this.deviceList.saveIfDirty(delay);
- }
-
- /**
- * Update the blocked/verified state of the given device
- *
- * @param userId - owner of the device
- * @param deviceId - unique identifier for the device or user's
- * cross-signing public key ID.
- *
- * @param verified - whether to mark the device as verified. Null to
- * leave unchanged.
- *
- * @param blocked - whether to mark the device as blocked. Null to
- * leave unchanged.
- *
- * @param known - whether to mark that the user has been made aware of
- * the existence of this device. Null to leave unchanged
- *
- * @param keys - The list of keys that was present
- * during the device verification. This will be double checked with the list
- * of keys the given device has currently.
- *
- * @returns updated DeviceInfo
- */
- async setDeviceVerification(userId, deviceId, verified = null, blocked = null, known = null, keys) {
- // Check if the 'device' is actually a cross signing key
- // The js-sdk's verification treats cross-signing keys as devices
- // and so uses this method to mark them verified.
- const xsk = this.deviceList.getStoredCrossSigningForUser(userId);
- if (xsk && xsk.getId() === deviceId) {
- if (blocked !== null || known !== null) {
- throw new Error("Cannot set blocked or known for a cross-signing key");
- }
- if (!verified) {
- throw new Error("Cannot set a cross-signing key as unverified");
- }
- const gotKeyId = keys ? Object.values(keys)[0] : null;
- if (keys && (Object.values(keys).length !== 1 || gotKeyId !== xsk.getId())) {
- throw new Error(`Key did not match expected value: expected ${xsk.getId()}, got ${gotKeyId}`);
- }
- if (!this.crossSigningInfo.getId() && userId === this.crossSigningInfo.userId) {
- this.storeTrustedSelfKeys(xsk.keys);
- // This will cause our own user trust to change, so emit the event
- this.emit(CryptoEvent.UserTrustStatusChanged, this.userId, this.checkUserTrust(userId));
- }
-
- // Now sign the master key with our user signing key (unless it's ourself)
- if (userId !== this.userId) {
- _logger.logger.info("Master key " + xsk.getId() + " for " + userId + " marked verified. Signing...");
- const device = await this.crossSigningInfo.signUser(xsk);
- if (device) {
- const upload = async ({
- shouldEmit = false
- }) => {
- _logger.logger.info("Uploading signature for " + userId + "...");
- const response = await this.baseApis.uploadKeySignatures({
- [userId]: {
- [deviceId]: device
- }
- });
- const {
- failures
- } = response || {};
- if (Object.keys(failures || []).length > 0) {
- if (shouldEmit) {
- this.baseApis.emit(CryptoEvent.KeySignatureUploadFailure, failures, "setDeviceVerification", upload);
- }
- /* Throwing here causes the process to be cancelled and the other
- * user to be notified */
- throw new _errors.KeySignatureUploadError("Key upload failed", {
- failures
- });
- }
- };
- await upload({
- shouldEmit: true
- });
-
- // This will emit events when it comes back down the sync
- // (we could do local echo to speed things up)
- }
-
- return device; // TODO types
- } else {
- return xsk;
- }
- }
- const devices = this.deviceList.getRawStoredDevicesForUser(userId);
- if (!devices || !devices[deviceId]) {
- throw new Error("Unknown device " + userId + ":" + deviceId);
- }
- const dev = devices[deviceId];
- let verificationStatus = dev.verified;
- if (verified) {
- if (keys) {
- for (const [keyId, key] of Object.entries(keys)) {
- if (dev.keys[keyId] !== key) {
- throw new Error(`Key did not match expected value: expected ${key}, got ${dev.keys[keyId]}`);
- }
- }
- }
- verificationStatus = DeviceVerification.VERIFIED;
- } else if (verified !== null && verificationStatus == DeviceVerification.VERIFIED) {
- verificationStatus = DeviceVerification.UNVERIFIED;
- }
- if (blocked) {
- verificationStatus = DeviceVerification.BLOCKED;
- } else if (blocked !== null && verificationStatus == DeviceVerification.BLOCKED) {
- verificationStatus = DeviceVerification.UNVERIFIED;
- }
- let knownStatus = dev.known;
- if (known !== null) {
- knownStatus = known;
- }
- if (dev.verified !== verificationStatus || dev.known !== knownStatus) {
- dev.verified = verificationStatus;
- dev.known = knownStatus;
- this.deviceList.storeDevicesForUser(userId, devices);
- this.deviceList.saveIfDirty();
- }
-
- // do cross-signing
- if (verified && userId === this.userId) {
- _logger.logger.info("Own device " + deviceId + " marked verified: signing");
-
- // Signing only needed if other device not already signed
- let device;
- const deviceTrust = this.checkDeviceTrust(userId, deviceId);
- if (deviceTrust.isCrossSigningVerified()) {
- _logger.logger.log(`Own device ${deviceId} already cross-signing verified`);
- } else {
- device = await this.crossSigningInfo.signDevice(userId, _deviceinfo.DeviceInfo.fromStorage(dev, deviceId));
- }
- if (device) {
- const upload = async ({
- shouldEmit = false
- }) => {
- _logger.logger.info("Uploading signature for " + deviceId);
- const response = await this.baseApis.uploadKeySignatures({
- [userId]: {
- [deviceId]: device
- }
- });
- const {
- failures
- } = response || {};
- if (Object.keys(failures || []).length > 0) {
- if (shouldEmit) {
- this.baseApis.emit(CryptoEvent.KeySignatureUploadFailure, failures, "setDeviceVerification", upload // continuation
- );
- }
-
- throw new _errors.KeySignatureUploadError("Key upload failed", {
- failures
- });
- }
- };
- await upload({
- shouldEmit: true
- });
- // XXX: we'll need to wait for the device list to be updated
- }
- }
-
- const deviceObj = _deviceinfo.DeviceInfo.fromStorage(dev, deviceId);
- this.emit(CryptoEvent.DeviceVerificationChanged, userId, deviceId, deviceObj);
- return deviceObj;
- }
- findVerificationRequestDMInProgress(roomId) {
- return this.inRoomVerificationRequests.findRequestInProgress(roomId);
- }
- getVerificationRequestsToDeviceInProgress(userId) {
- return this.toDeviceVerificationRequests.getRequestsInProgress(userId);
- }
- requestVerificationDM(userId, roomId) {
- const existingRequest = this.inRoomVerificationRequests.findRequestInProgress(roomId);
- if (existingRequest) {
- return Promise.resolve(existingRequest);
- }
- const channel = new _InRoomChannel.InRoomChannel(this.baseApis, roomId, userId);
- return this.requestVerificationWithChannel(userId, channel, this.inRoomVerificationRequests);
- }
- requestVerification(userId, devices) {
- if (!devices) {
- devices = Object.keys(this.deviceList.getRawStoredDevicesForUser(userId));
- }
- const existingRequest = this.toDeviceVerificationRequests.findRequestInProgress(userId, devices);
- if (existingRequest) {
- return Promise.resolve(existingRequest);
- }
- const channel = new _ToDeviceChannel.ToDeviceChannel(this.baseApis, userId, devices, _ToDeviceChannel.ToDeviceChannel.makeTransactionId());
- return this.requestVerificationWithChannel(userId, channel, this.toDeviceVerificationRequests);
- }
- async requestVerificationWithChannel(userId, channel, requestsMap) {
- let request = new _VerificationRequest.VerificationRequest(channel, this.verificationMethods, this.baseApis);
- // if transaction id is already known, add request
- if (channel.transactionId) {
- requestsMap.setRequestByChannel(channel, request);
- }
- await request.sendRequest();
- // don't replace the request created by a racing remote echo
- const racingRequest = requestsMap.getRequestByChannel(channel);
- if (racingRequest) {
- request = racingRequest;
- } else {
- _logger.logger.log(`Crypto: adding new request to ` + `requestsByTxnId with id ${channel.transactionId} ${channel.roomId}`);
- requestsMap.setRequestByChannel(channel, request);
- }
- return request;
- }
- beginKeyVerification(method, userId, deviceId, transactionId = null) {
- let request;
- if (transactionId) {
- request = this.toDeviceVerificationRequests.getRequestBySenderAndTxnId(userId, transactionId);
- if (!request) {
- throw new Error(`No request found for user ${userId} with ` + `transactionId ${transactionId}`);
- }
- } else {
- transactionId = _ToDeviceChannel.ToDeviceChannel.makeTransactionId();
- const channel = new _ToDeviceChannel.ToDeviceChannel(this.baseApis, userId, [deviceId], transactionId, deviceId);
- request = new _VerificationRequest.VerificationRequest(channel, this.verificationMethods, this.baseApis);
- this.toDeviceVerificationRequests.setRequestBySenderAndTxnId(userId, transactionId, request);
- }
- return request.beginKeyVerification(method, {
- userId,
- deviceId
- });
- }
- async legacyDeviceVerification(userId, deviceId, method) {
- const transactionId = _ToDeviceChannel.ToDeviceChannel.makeTransactionId();
- const channel = new _ToDeviceChannel.ToDeviceChannel(this.baseApis, userId, [deviceId], transactionId, deviceId);
- const request = new _VerificationRequest.VerificationRequest(channel, this.verificationMethods, this.baseApis);
- this.toDeviceVerificationRequests.setRequestBySenderAndTxnId(userId, transactionId, request);
- const verifier = request.beginKeyVerification(method, {
- userId,
- deviceId
- });
- // either reject by an error from verify() while sending .start
- // or resolve when the request receives the
- // local (fake remote) echo for sending the .start event
- await Promise.race([verifier.verify(), request.waitFor(r => r.started)]);
- return request;
- }
-
- /**
- * Get information on the active olm sessions with a user
- * <p>
- * Returns a map from device id to an object with keys 'deviceIdKey' (the
- * device's curve25519 identity key) and 'sessions' (an array of objects in the
- * same format as that returned by
- * {@link OlmDevice#getSessionInfoForDevice}).
- * <p>
- * This method is provided for debugging purposes.
- *
- * @param userId - id of user to inspect
- */
- async getOlmSessionsForUser(userId) {
- const devices = this.getStoredDevicesForUser(userId) || [];
- const result = {};
- for (const device of devices) {
- const deviceKey = device.getIdentityKey();
- const sessions = await this.olmDevice.getSessionInfoForDevice(deviceKey);
- result[device.deviceId] = {
- deviceIdKey: deviceKey,
- sessions: sessions
- };
- }
- return result;
- }
-
- /**
- * Get the device which sent an event
- *
- * @param event - event to be checked
- */
- getEventSenderDeviceInfo(event) {
- const senderKey = event.getSenderKey();
- const algorithm = event.getWireContent().algorithm;
- if (!senderKey || !algorithm) {
- return null;
- }
- if (event.isKeySourceUntrusted()) {
- // we got the key for this event from a source that we consider untrusted
- return null;
- }
-
- // senderKey is the Curve25519 identity key of the device which the event
- // was sent from. In the case of Megolm, it's actually the Curve25519
- // identity key of the device which set up the Megolm session.
-
- const device = this.deviceList.getDeviceByIdentityKey(algorithm, senderKey);
- if (device === null) {
- // we haven't downloaded the details of this device yet.
- return null;
- }
-
- // so far so good, but now we need to check that the sender of this event
- // hadn't advertised someone else's Curve25519 key as their own. We do that
- // by checking the Ed25519 claimed by the event (or, in the case of megolm,
- // the event which set up the megolm session), to check that it matches the
- // fingerprint of the purported sending device.
- //
- // (see https://github.com/vector-im/vector-web/issues/2215)
-
- const claimedKey = event.getClaimedEd25519Key();
- if (!claimedKey) {
- _logger.logger.warn("Event " + event.getId() + " claims no ed25519 key: " + "cannot verify sending device");
- return null;
- }
- if (claimedKey !== device.getFingerprint()) {
- _logger.logger.warn("Event " + event.getId() + " claims ed25519 key " + claimedKey + " but sender device has key " + device.getFingerprint());
- return null;
- }
- return device;
- }
-
- /**
- * Get information about the encryption of an event
- *
- * @param event - event to be checked
- *
- * @returns An object with the fields:
- * - encrypted: whether the event is encrypted (if not encrypted, some of the
- * other properties may not be set)
- * - senderKey: the sender's key
- * - algorithm: the algorithm used to encrypt the event
- * - authenticated: whether we can be sure that the owner of the senderKey
- * sent the event
- * - sender: the sender's device information, if available
- * - mismatchedSender: if the event's ed25519 and curve25519 keys don't match
- * (only meaningful if `sender` is set)
- */
- getEventEncryptionInfo(event) {
- var _event$getSenderKey, _this$deviceList$getD;
- const ret = {};
- ret.senderKey = (_event$getSenderKey = event.getSenderKey()) !== null && _event$getSenderKey !== void 0 ? _event$getSenderKey : undefined;
- ret.algorithm = event.getWireContent().algorithm;
- if (!ret.senderKey || !ret.algorithm) {
- ret.encrypted = false;
- return ret;
- }
- ret.encrypted = true;
- if (event.isKeySourceUntrusted()) {
- // we got the key this event from somewhere else
- // TODO: check if we can trust the forwarders.
- ret.authenticated = false;
- } else {
- ret.authenticated = true;
- }
-
- // senderKey is the Curve25519 identity key of the device which the event
- // was sent from. In the case of Megolm, it's actually the Curve25519
- // identity key of the device which set up the Megolm session.
-
- ret.sender = (_this$deviceList$getD = this.deviceList.getDeviceByIdentityKey(ret.algorithm, ret.senderKey)) !== null && _this$deviceList$getD !== void 0 ? _this$deviceList$getD : undefined;
-
- // so far so good, but now we need to check that the sender of this event
- // hadn't advertised someone else's Curve25519 key as their own. We do that
- // by checking the Ed25519 claimed by the event (or, in the case of megolm,
- // the event which set up the megolm session), to check that it matches the
- // fingerprint of the purported sending device.
- //
- // (see https://github.com/vector-im/vector-web/issues/2215)
-
- const claimedKey = event.getClaimedEd25519Key();
- if (!claimedKey) {
- _logger.logger.warn("Event " + event.getId() + " claims no ed25519 key: " + "cannot verify sending device");
- ret.mismatchedSender = true;
- }
- if (ret.sender && claimedKey !== ret.sender.getFingerprint()) {
- _logger.logger.warn("Event " + event.getId() + " claims ed25519 key " + claimedKey + "but sender device has key " + ret.sender.getFingerprint());
- ret.mismatchedSender = true;
- }
- return ret;
- }
-
- /**
- * Forces the current outbound group session to be discarded such
- * that another one will be created next time an event is sent.
- *
- * @param roomId - The ID of the room to discard the session for
- *
- * This should not normally be necessary.
- */
- forceDiscardSession(roomId) {
- const alg = this.roomEncryptors.get(roomId);
- if (alg === undefined) throw new Error("Room not encrypted");
- if (alg.forceDiscardSession === undefined) {
- throw new Error("Room encryption algorithm doesn't support session discarding");
- }
- alg.forceDiscardSession();
- return Promise.resolve();
- }
-
- /**
- * Configure a room to use encryption (ie, save a flag in the cryptoStore).
- *
- * @param roomId - The room ID to enable encryption in.
- *
- * @param config - The encryption config for the room.
- *
- * @param inhibitDeviceQuery - true to suppress device list query for
- * users in the room (for now). In case lazy loading is enabled,
- * the device query is always inhibited as the members are not tracked.
- *
- * @deprecated It is normally incorrect to call this method directly. Encryption
- * is enabled by receiving an `m.room.encryption` event (which we may have sent
- * previously).
- */
- async setRoomEncryption(roomId, config, inhibitDeviceQuery) {
- const room = this.clientStore.getRoom(roomId);
- if (!room) {
- throw new Error(`Unable to enable encryption tracking devices in unknown room ${roomId}`);
- }
- await this.setRoomEncryptionImpl(room, config);
- if (!this.lazyLoadMembers && !inhibitDeviceQuery) {
- this.deviceList.refreshOutdatedDeviceLists();
- }
- }
-
- /**
- * Set up encryption for a room.
- *
- * This is called when an <tt>m.room.encryption</tt> event is received. It saves a flag
- * for the room in the cryptoStore (if it wasn't already set), sets up an "encryptor" for
- * the room, and enables device-list tracking for the room.
- *
- * It does <em>not</em> initiate a device list query for the room. That is normally
- * done once we finish processing the sync, in onSyncCompleted.
- *
- * @param room - The room to enable encryption in.
- * @param config - The encryption config for the room.
- */
- async setRoomEncryptionImpl(room, config) {
- const roomId = room.roomId;
-
- // ignore crypto events with no algorithm defined
- // This will happen if a crypto event is redacted before we fetch the room state
- // It would otherwise just throw later as an unknown algorithm would, but we may
- // as well catch this here
- if (!config.algorithm) {
- _logger.logger.log("Ignoring setRoomEncryption with no algorithm");
- return;
- }
-
- // if state is being replayed from storage, we might already have a configuration
- // for this room as they are persisted as well.
- // We just need to make sure the algorithm is initialized in this case.
- // However, if the new config is different,
- // we should bail out as room encryption can't be changed once set.
- const existingConfig = this.roomList.getRoomEncryption(roomId);
- if (existingConfig) {
- if (JSON.stringify(existingConfig) != JSON.stringify(config)) {
- _logger.logger.error("Ignoring m.room.encryption event which requests " + "a change of config in " + roomId);
- return;
- }
- }
- // if we already have encryption in this room, we should ignore this event,
- // as it would reset the encryption algorithm.
- // This is at least expected to be called twice, as sync calls onCryptoEvent
- // for both the timeline and state sections in the /sync response,
- // the encryption event would appear in both.
- // If it's called more than twice though,
- // it signals a bug on client or server.
- const existingAlg = this.roomEncryptors.get(roomId);
- if (existingAlg) {
- return;
- }
-
- // _roomList.getRoomEncryption will not race with _roomList.setRoomEncryption
- // because it first stores in memory. We should await the promise only
- // after all the in-memory state (roomEncryptors and _roomList) has been updated
- // to avoid races when calling this method multiple times. Hence keep a hold of the promise.
- let storeConfigPromise = null;
- if (!existingConfig) {
- storeConfigPromise = this.roomList.setRoomEncryption(roomId, config);
- }
- const AlgClass = algorithms.ENCRYPTION_CLASSES.get(config.algorithm);
- if (!AlgClass) {
- throw new Error("Unable to encrypt with " + config.algorithm);
- }
- const alg = new AlgClass({
- userId: this.userId,
- deviceId: this.deviceId,
- crypto: this,
- olmDevice: this.olmDevice,
- baseApis: this.baseApis,
- roomId,
- config
- });
- this.roomEncryptors.set(roomId, alg);
- if (storeConfigPromise) {
- await storeConfigPromise;
- }
- _logger.logger.log(`Enabling encryption in ${roomId}`);
-
- // we don't want to force a download of the full membership list of this room, but as soon as we have that
- // list we can start tracking the device list.
- if (room.membersLoaded()) {
- await this.trackRoomDevicesImpl(room);
- } else {
- // wait for the membership list to be loaded
- const onState = _state => {
- room.off(_roomState.RoomStateEvent.Update, onState);
- if (room.membersLoaded()) {
- this.trackRoomDevicesImpl(room).catch(e => {
- _logger.logger.error(`Error enabling device tracking in ${roomId}`, e);
- });
- }
- };
- room.on(_roomState.RoomStateEvent.Update, onState);
- }
- }
-
- /**
- * Make sure we are tracking the device lists for all users in this room.
- *
- * @param roomId - The room ID to start tracking devices in.
- * @returns when all devices for the room have been fetched and marked to track
- * @deprecated there's normally no need to call this function: device list tracking
- * will be enabled as soon as we have the full membership list.
- */
- trackRoomDevices(roomId) {
- const room = this.clientStore.getRoom(roomId);
- if (!room) {
- throw new Error(`Unable to start tracking devices in unknown room ${roomId}`);
- }
- return this.trackRoomDevicesImpl(room);
- }
-
- /**
- * Make sure we are tracking the device lists for all users in this room.
- *
- * This is normally called when we are about to send an encrypted event, to make sure
- * we have all the devices in the room; but it is also called when processing an
- * m.room.encryption state event (if lazy-loading is disabled), or when members are
- * loaded (if lazy-loading is enabled), to prepare the device list.
- *
- * @param room - Room to enable device-list tracking in
- */
- trackRoomDevicesImpl(room) {
- const roomId = room.roomId;
- const trackMembers = async () => {
- // not an encrypted room
- if (!this.roomEncryptors.has(roomId)) {
- return;
- }
- _logger.logger.log(`Starting to track devices for room ${roomId} ...`);
- const members = await room.getEncryptionTargetMembers();
- members.forEach(m => {
- this.deviceList.startTrackingDeviceList(m.userId);
- });
- };
- let promise = this.roomDeviceTrackingState[roomId];
- if (!promise) {
- promise = trackMembers();
- this.roomDeviceTrackingState[roomId] = promise.catch(err => {
- delete this.roomDeviceTrackingState[roomId];
- throw err;
- });
- }
- return promise;
- }
-
- /**
- * Try to make sure we have established olm sessions for all known devices for
- * the given users.
- *
- * @param users - list of user ids
- * @param force - If true, force a new Olm session to be created. Default false.
- *
- * @returns resolves once the sessions are complete, to
- * an Object mapping from userId to deviceId to
- * {@link OlmSessionResult}
- */
- ensureOlmSessionsForUsers(users, force) {
- // map user Id → DeviceInfo[]
- const devicesByUser = new Map();
- for (const userId of users) {
- const userDevices = [];
- devicesByUser.set(userId, userDevices);
- const devices = this.getStoredDevicesForUser(userId) || [];
- for (const deviceInfo of devices) {
- const key = deviceInfo.getIdentityKey();
- if (key == this.olmDevice.deviceCurve25519Key) {
- // don't bother setting up session to ourself
- continue;
- }
- if (deviceInfo.verified == DeviceVerification.BLOCKED) {
- // don't bother setting up sessions with blocked users
- continue;
- }
- userDevices.push(deviceInfo);
- }
- }
- return olmlib.ensureOlmSessionsForDevices(this.olmDevice, this.baseApis, devicesByUser, force);
- }
-
- /**
- * Get a list containing all of the room keys
- *
- * @returns a list of session export objects
- */
- async exportRoomKeys() {
- const exportedSessions = [];
- await this.cryptoStore.doTxn("readonly", [_indexeddbCryptoStore.IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS], txn => {
- this.cryptoStore.getAllEndToEndInboundGroupSessions(txn, s => {
- if (s === null) return;
- const sess = this.olmDevice.exportInboundGroupSession(s.senderKey, s.sessionId, s.sessionData);
- delete sess.first_known_index;
- sess.algorithm = olmlib.MEGOLM_ALGORITHM;
- exportedSessions.push(sess);
- });
- });
- return exportedSessions;
- }
-
- /**
- * Import a list of room keys previously exported by exportRoomKeys
- *
- * @param keys - a list of session export objects
- * @returns a promise which resolves once the keys have been imported
- */
- importRoomKeys(keys, opts = {}) {
- let successes = 0;
- let failures = 0;
- const total = keys.length;
- function updateProgress() {
- var _opts$progressCallbac;
- (_opts$progressCallbac = opts.progressCallback) === null || _opts$progressCallbac === void 0 ? void 0 : _opts$progressCallbac.call(opts, {
- stage: "load_keys",
- successes,
- failures,
- total
- });
- }
- return Promise.all(keys.map(key => {
- if (!key.room_id || !key.algorithm) {
- _logger.logger.warn("ignoring room key entry with missing fields", key);
- failures++;
- if (opts.progressCallback) {
- updateProgress();
- }
- return null;
- }
- const alg = this.getRoomDecryptor(key.room_id, key.algorithm);
- return alg.importRoomKey(key, opts).finally(() => {
- successes++;
- if (opts.progressCallback) {
- updateProgress();
- }
- });
- })).then();
- }
-
- /**
- * Counts the number of end to end session keys that are waiting to be backed up
- * @returns Promise which resolves to the number of sessions requiring backup
- */
- countSessionsNeedingBackup() {
- return this.backupManager.countSessionsNeedingBackup();
- }
-
- /**
- * Perform any background tasks that can be done before a message is ready to
- * send, in order to speed up sending of the message.
- *
- * @param room - the room the event is in
- */
- prepareToEncrypt(room) {
- const alg = this.roomEncryptors.get(room.roomId);
- if (alg) {
- alg.prepareToEncrypt(room);
- }
- }
-
- /**
- * Encrypt an event according to the configuration of the room.
- *
- * @param event - event to be sent
- *
- * @param room - destination room.
- *
- * @returns Promise which resolves when the event has been
- * encrypted, or null if nothing was needed
- */
- async encryptEvent(event, room) {
- const roomId = event.getRoomId();
- const alg = this.roomEncryptors.get(roomId);
- if (!alg) {
- // MatrixClient has already checked that this room should be encrypted,
- // so this is an unexpected situation.
- throw new Error("Room " + roomId + " was previously configured to use encryption, but is " + "no longer. Perhaps the homeserver is hiding the " + "configuration event.");
- }
-
- // wait for all the room devices to be loaded
- await this.trackRoomDevicesImpl(room);
- let content = event.getContent();
- // If event has an m.relates_to then we need
- // to put this on the wrapping event instead
- const mRelatesTo = content["m.relates_to"];
- if (mRelatesTo) {
- // Clone content here so we don't remove `m.relates_to` from the local-echo
- content = Object.assign({}, content);
- delete content["m.relates_to"];
- }
-
- // Treat element's performance metrics the same as `m.relates_to` (when present)
- const elementPerfMetrics = content["io.element.performance_metrics"];
- if (elementPerfMetrics) {
- content = Object.assign({}, content);
- delete content["io.element.performance_metrics"];
- }
- const encryptedContent = await alg.encryptMessage(room, event.getType(), content);
- if (mRelatesTo) {
- encryptedContent["m.relates_to"] = mRelatesTo;
- }
- if (elementPerfMetrics) {
- encryptedContent["io.element.performance_metrics"] = elementPerfMetrics;
- }
- event.makeEncrypted("m.room.encrypted", encryptedContent, this.olmDevice.deviceCurve25519Key, this.olmDevice.deviceEd25519Key);
- }
-
- /**
- * Decrypt a received event
- *
- *
- * @returns resolves once we have
- * finished decrypting. Rejects with an `algorithms.DecryptionError` if there
- * is a problem decrypting the event.
- */
- async decryptEvent(event) {
- if (event.isRedacted()) {
- // Try to decrypt the redaction event, to support encrypted
- // redaction reasons. If we can't decrypt, just fall back to using
- // the original redacted_because.
- const redactionEvent = new _event2.MatrixEvent(_objectSpread({
- room_id: event.getRoomId()
- }, event.getUnsigned().redacted_because));
- let redactedBecause = event.getUnsigned().redacted_because;
- if (redactionEvent.isEncrypted()) {
- try {
- const decryptedEvent = await this.decryptEvent(redactionEvent);
- redactedBecause = decryptedEvent.clearEvent;
- } catch (e) {
- _logger.logger.warn("Decryption of redaction failed. Falling back to unencrypted event.", e);
- }
- }
- return {
- clearEvent: {
- room_id: event.getRoomId(),
- type: "m.room.message",
- content: {},
- unsigned: {
- redacted_because: redactedBecause
- }
- }
- };
- } else {
- const content = event.getWireContent();
- const alg = this.getRoomDecryptor(event.getRoomId(), content.algorithm);
- return alg.decryptEvent(event);
- }
- }
-
- /**
- * Handle the notification from /sync or /keys/changes that device lists have
- * been changed.
- *
- * @param syncData - Object containing sync tokens associated with this sync
- * @param syncDeviceLists - device_lists field from /sync, or response from
- * /keys/changes
- */
- async handleDeviceListChanges(syncData, syncDeviceLists) {
- // Initial syncs don't have device change lists. We'll either get the complete list
- // of changes for the interval or will have invalidated everything in willProcessSync
- if (!syncData.oldSyncToken) return;
-
- // Here, we're relying on the fact that we only ever save the sync data after
- // sucessfully saving the device list data, so we're guaranteed that the device
- // list store is at least as fresh as the sync token from the sync store, ie.
- // any device changes received in sync tokens prior to the 'next' token here
- // have been processed and are reflected in the current device list.
- // If we didn't make this assumption, we'd have to use the /keys/changes API
- // to get key changes between the sync token in the device list and the 'old'
- // sync token used here to make sure we didn't miss any.
- await this.evalDeviceListChanges(syncDeviceLists);
- }
-
- /**
- * Send a request for some room keys, if we have not already done so
- *
- * @param resend - whether to resend the key request if there is
- * already one
- *
- * @returns a promise that resolves when the key request is queued
- */
- requestRoomKey(requestBody, recipients, resend = false) {
- return this.outgoingRoomKeyRequestManager.queueRoomKeyRequest(requestBody, recipients, resend).then(() => {
- if (this.sendKeyRequestsImmediately) {
- this.outgoingRoomKeyRequestManager.sendQueuedRequests();
- }
- }).catch(e => {
- // this normally means we couldn't talk to the store
- _logger.logger.error("Error requesting key for event", e);
- });
- }
-
- /**
- * Cancel any earlier room key request
- *
- * @param requestBody - parameters to match for cancellation
- */
- cancelRoomKeyRequest(requestBody) {
- this.outgoingRoomKeyRequestManager.cancelRoomKeyRequest(requestBody).catch(e => {
- _logger.logger.warn("Error clearing pending room key requests", e);
- });
- }
-
- /**
- * Re-send any outgoing key requests, eg after verification
- * @returns
- */
- async cancelAndResendAllOutgoingKeyRequests() {
- await this.outgoingRoomKeyRequestManager.cancelAndResendAllOutgoingRequests();
- }
-
- /**
- * handle an m.room.encryption event
- *
- * @param room - in which the event was received
- * @param event - encryption event to be processed
- */
- async onCryptoEvent(room, event) {
- const content = event.getContent();
- await this.setRoomEncryptionImpl(room, content);
- }
-
- /**
- * Called before the result of a sync is processed
- *
- * @param syncData - the data from the 'MatrixClient.sync' event
- */
- async onSyncWillProcess(syncData) {
- if (!syncData.oldSyncToken) {
- // If there is no old sync token, we start all our tracking from
- // scratch, so mark everything as untracked. onCryptoEvent will
- // be called for all e2e rooms during the processing of the sync,
- // at which point we'll start tracking all the users of that room.
- _logger.logger.log("Initial sync performed - resetting device tracking state");
- this.deviceList.stopTrackingAllDeviceLists();
- // we always track our own device list (for key backups etc)
- this.deviceList.startTrackingDeviceList(this.userId);
- this.roomDeviceTrackingState = {};
- }
- this.sendKeyRequestsImmediately = false;
- }
-
- /**
- * handle the completion of a /sync
- *
- * This is called after the processing of each successful /sync response.
- * It is an opportunity to do a batch process on the information received.
- *
- * @param syncData - the data from the 'MatrixClient.sync' event
- */
- async onSyncCompleted(syncData) {
- var _syncData$nextSyncTok;
- this.deviceList.setSyncToken((_syncData$nextSyncTok = syncData.nextSyncToken) !== null && _syncData$nextSyncTok !== void 0 ? _syncData$nextSyncTok : null);
- this.deviceList.saveIfDirty();
-
- // we always track our own device list (for key backups etc)
- this.deviceList.startTrackingDeviceList(this.userId);
- this.deviceList.refreshOutdatedDeviceLists();
-
- // we don't start uploading one-time keys until we've caught up with
- // to-device messages, to help us avoid throwing away one-time-keys that we
- // are about to receive messages for
- // (https://github.com/vector-im/element-web/issues/2782).
- if (!syncData.catchingUp) {
- this.maybeUploadOneTimeKeys();
- this.processReceivedRoomKeyRequests();
-
- // likewise don't start requesting keys until we've caught up
- // on to_device messages, otherwise we'll request keys that we're
- // just about to get.
- this.outgoingRoomKeyRequestManager.sendQueuedRequests();
-
- // Sync has finished so send key requests straight away.
- this.sendKeyRequestsImmediately = true;
- }
- }
-
- /**
- * Trigger the appropriate invalidations and removes for a given
- * device list
- *
- * @param deviceLists - device_lists field from /sync, or response from
- * /keys/changes
- */
- async evalDeviceListChanges(deviceLists) {
- if (Array.isArray(deviceLists === null || deviceLists === void 0 ? void 0 : deviceLists.changed)) {
- deviceLists.changed.forEach(u => {
- this.deviceList.invalidateUserDeviceList(u);
- });
- }
- if (Array.isArray(deviceLists === null || deviceLists === void 0 ? void 0 : deviceLists.left) && deviceLists.left.length) {
- // Check we really don't share any rooms with these users
- // any more: the server isn't required to give us the
- // exact correct set.
- const e2eUserIds = new Set(await this.getTrackedE2eUsers());
- deviceLists.left.forEach(u => {
- if (!e2eUserIds.has(u)) {
- this.deviceList.stopTrackingDeviceList(u);
- }
- });
- }
- }
-
- /**
- * Get a list of all the IDs of users we share an e2e room with
- * for which we are tracking devices already
- *
- * @returns List of user IDs
- */
- async getTrackedE2eUsers() {
- const e2eUserIds = [];
- for (const room of this.getTrackedE2eRooms()) {
- const members = await room.getEncryptionTargetMembers();
- for (const member of members) {
- e2eUserIds.push(member.userId);
- }
- }
- return e2eUserIds;
- }
-
- /**
- * Get a list of the e2e-enabled rooms we are members of,
- * and for which we are already tracking the devices
- *
- * @returns
- */
- getTrackedE2eRooms() {
- return this.clientStore.getRooms().filter(room => {
- // check for rooms with encryption enabled
- const alg = this.roomEncryptors.get(room.roomId);
- if (!alg) {
- return false;
- }
- if (!this.roomDeviceTrackingState[room.roomId]) {
- return false;
- }
-
- // ignore any rooms which we have left
- const myMembership = room.getMyMembership();
- return myMembership === "join" || myMembership === "invite";
- });
- }
-
- /**
- * Encrypts and sends a given object via Olm to-device messages to a given
- * set of devices.
- * @param userDeviceInfoArr - the devices to send to
- * @param payload - fields to include in the encrypted payload
- * @returns Promise which
- * resolves once the message has been encrypted and sent to the given
- * userDeviceMap, and returns the `{ contentMap, deviceInfoByDeviceId }`
- * of the successfully sent messages.
- */
- async encryptAndSendToDevices(userDeviceInfoArr, payload) {
- const toDeviceBatch = {
- eventType: _event.EventType.RoomMessageEncrypted,
- batch: []
- };
- try {
- await Promise.all(userDeviceInfoArr.map(async ({
- userId,
- deviceInfo
- }) => {
- const deviceId = deviceInfo.deviceId;
- const encryptedContent = {
- algorithm: olmlib.OLM_ALGORITHM,
- sender_key: this.olmDevice.deviceCurve25519Key,
- ciphertext: {},
- [_event.ToDeviceMessageId]: (0, _uuid.v4)()
- };
- toDeviceBatch.batch.push({
- userId,
- deviceId,
- payload: encryptedContent
- });
- await olmlib.ensureOlmSessionsForDevices(this.olmDevice, this.baseApis, new Map([[userId, [deviceInfo]]]));
- await olmlib.encryptMessageForDevice(encryptedContent.ciphertext, this.userId, this.deviceId, this.olmDevice, userId, deviceInfo, payload);
- }));
-
- // prune out any devices that encryptMessageForDevice could not encrypt for,
- // in which case it will have just not added anything to the ciphertext object.
- // There's no point sending messages to devices if we couldn't encrypt to them,
- // since that's effectively a blank message.
- toDeviceBatch.batch = toDeviceBatch.batch.filter(msg => {
- if (Object.keys(msg.payload.ciphertext).length > 0) {
- return true;
- } else {
- _logger.logger.log(`No ciphertext for device ${msg.userId}:${msg.deviceId}: pruning`);
- return false;
- }
- });
- try {
- await this.baseApis.queueToDevice(toDeviceBatch);
- } catch (e) {
- _logger.logger.error("sendToDevice failed", e);
- throw e;
- }
- } catch (e) {
- _logger.logger.error("encryptAndSendToDevices promises failed", e);
- throw e;
- }
- }
- async preprocessToDeviceMessages(events) {
- // all we do here is filter out encrypted to-device messages with the wrong algorithm. Decryption
- // happens later in decryptEvent, via the EventMapper
- return events.filter(toDevice => {
- var _toDevice$content;
- if (toDevice.type === _event.EventType.RoomMessageEncrypted && !["m.olm.v1.curve25519-aes-sha2"].includes((_toDevice$content = toDevice.content) === null || _toDevice$content === void 0 ? void 0 : _toDevice$content.algorithm)) {
- _logger.logger.log("Ignoring invalid encrypted to-device event from " + toDevice.sender);
- return false;
- }
- return true;
- });
- }
- preprocessOneTimeKeyCounts(oneTimeKeysCounts) {
- const currentCount = oneTimeKeysCounts.get("signed_curve25519") || 0;
- this.updateOneTimeKeyCount(currentCount);
- return Promise.resolve();
- }
- preprocessUnusedFallbackKeys(unusedFallbackKeys) {
- this.setNeedsNewFallback(!unusedFallbackKeys.has("signed_curve25519"));
- return Promise.resolve();
- }
- /**
- * Handle a key event
- *
- * @internal
- * @param event - key event
- */
- onRoomKeyEvent(event) {
- const content = event.getContent();
- if (!content.room_id || !content.algorithm) {
- _logger.logger.error("key event is missing fields");
- return;
- }
- if (!this.backupManager.checkedForBackup) {
- // don't bother awaiting on this - the important thing is that we retry if we
- // haven't managed to check before
- this.backupManager.checkAndStart();
- }
- const alg = this.getRoomDecryptor(content.room_id, content.algorithm);
- alg.onRoomKeyEvent(event);
- }
-
- /**
- * Handle a key withheld event
- *
- * @internal
- * @param event - key withheld event
- */
- onRoomKeyWithheldEvent(event) {
- const content = event.getContent();
- if (content.code !== "m.no_olm" && (!content.room_id || !content.session_id) || !content.algorithm || !content.sender_key) {
- _logger.logger.error("key withheld event is missing fields");
- return;
- }
- _logger.logger.info(`Got room key withheld event from ${event.getSender()} ` + `for ${content.algorithm} session ${content.sender_key}|${content.session_id} ` + `in room ${content.room_id} with code ${content.code} (${content.reason})`);
- const alg = this.getRoomDecryptor(content.room_id, content.algorithm);
- if (alg.onRoomKeyWithheldEvent) {
- alg.onRoomKeyWithheldEvent(event);
- }
- if (!content.room_id) {
- // retry decryption for all events sent by the sender_key. This will
- // update the events to show a message indicating that the olm session was
- // wedged.
- const roomDecryptors = this.getRoomDecryptors(content.algorithm);
- for (const decryptor of roomDecryptors) {
- decryptor.retryDecryptionFromSender(content.sender_key);
- }
- }
- }
-
- /**
- * Handle a general key verification event.
- *
- * @internal
- * @param event - verification start event
- */
- onKeyVerificationMessage(event) {
- if (!_ToDeviceChannel.ToDeviceChannel.validateEvent(event, this.baseApis)) {
- return;
- }
- const createRequest = event => {
- if (!_ToDeviceChannel.ToDeviceChannel.canCreateRequest(_ToDeviceChannel.ToDeviceChannel.getEventType(event))) {
- return;
- }
- const content = event.getContent();
- const deviceId = content && content.from_device;
- if (!deviceId) {
- return;
- }
- const userId = event.getSender();
- const channel = new _ToDeviceChannel.ToDeviceChannel(this.baseApis, userId, [deviceId]);
- return new _VerificationRequest.VerificationRequest(channel, this.verificationMethods, this.baseApis);
- };
- this.handleVerificationEvent(event, this.toDeviceVerificationRequests, createRequest);
- }
-
- /**
- * Handle key verification requests sent as timeline events
- *
- * @internal
- * @param event - the timeline event
- * @param room - not used
- * @param atStart - not used
- * @param removed - not used
- * @param whether - this is a live event
- */
-
- async handleVerificationEvent(event, requestsMap, createRequest, isLiveEvent = true) {
- // Wait for event to get its final ID with pendingEventOrdering: "chronological", since DM channels depend on it.
- if (event.isSending() && event.status != _event2.EventStatus.SENT) {
- let eventIdListener;
- let statusListener;
- try {
- await new Promise((resolve, reject) => {
- eventIdListener = resolve;
- statusListener = () => {
- if (event.status == _event2.EventStatus.CANCELLED) {
- reject(new Error("Event status set to CANCELLED."));
- }
- };
- event.once(_event2.MatrixEventEvent.LocalEventIdReplaced, eventIdListener);
- event.on(_event2.MatrixEventEvent.Status, statusListener);
- });
- } catch (err) {
- _logger.logger.error("error while waiting for the verification event to be sent: ", err);
- return;
- } finally {
- event.removeListener(_event2.MatrixEventEvent.LocalEventIdReplaced, eventIdListener);
- event.removeListener(_event2.MatrixEventEvent.Status, statusListener);
- }
- }
- let request = requestsMap.getRequest(event);
- let isNewRequest = false;
- if (!request) {
- request = createRequest(event);
- // a request could not be made from this event, so ignore event
- if (!request) {
- _logger.logger.log(`Crypto: could not find VerificationRequest for ` + `${event.getType()}, and could not create one, so ignoring.`);
- return;
- }
- isNewRequest = true;
- requestsMap.setRequest(event, request);
- }
- event.setVerificationRequest(request);
- try {
- await request.channel.handleEvent(event, request, isLiveEvent);
- } catch (err) {
- _logger.logger.error("error while handling verification event", err);
- }
- const shouldEmit = isNewRequest && !request.initiatedByMe && !request.invalid &&
- // check it has enough events to pass the UNSENT stage
- !request.observeOnly;
- if (shouldEmit) {
- this.baseApis.emit(CryptoEvent.VerificationRequest, request);
- }
- }
-
- /**
- * Handle a toDevice event that couldn't be decrypted
- *
- * @internal
- * @param event - undecryptable event
- */
- async onToDeviceBadEncrypted(event) {
- const content = event.getWireContent();
- const sender = event.getSender();
- const algorithm = content.algorithm;
- const deviceKey = content.sender_key;
- this.baseApis.emit(_client.ClientEvent.UndecryptableToDeviceEvent, event);
-
- // retry decryption for all events sent by the sender_key. This will
- // update the events to show a message indicating that the olm session was
- // wedged.
- const retryDecryption = () => {
- const roomDecryptors = this.getRoomDecryptors(olmlib.MEGOLM_ALGORITHM);
- for (const decryptor of roomDecryptors) {
- decryptor.retryDecryptionFromSender(deviceKey);
- }
- };
- if (sender === undefined || deviceKey === undefined || deviceKey === undefined) {
- return;
- }
-
- // check when we last forced a new session with this device: if we've already done so
- // recently, don't do it again.
- const lastNewSessionDevices = this.lastNewSessionForced.getOrCreate(sender);
- const lastNewSessionForced = lastNewSessionDevices.getOrCreate(deviceKey);
- if (lastNewSessionForced + MIN_FORCE_SESSION_INTERVAL_MS > Date.now()) {
- _logger.logger.debug("New session already forced with device " + sender + ":" + deviceKey + " at " + lastNewSessionForced + ": not forcing another");
- await this.olmDevice.recordSessionProblem(deviceKey, "wedged", true);
- retryDecryption();
- return;
- }
-
- // establish a new olm session with this device since we're failing to decrypt messages
- // on a current session.
- // Note that an undecryptable message from another device could easily be spoofed -
- // is there anything we can do to mitigate this?
- let device = this.deviceList.getDeviceByIdentityKey(algorithm, deviceKey);
- if (!device) {
- // if we don't know about the device, fetch the user's devices again
- // and retry before giving up
- await this.downloadKeys([sender], false);
- device = this.deviceList.getDeviceByIdentityKey(algorithm, deviceKey);
- if (!device) {
- _logger.logger.info("Couldn't find device for identity key " + deviceKey + ": not re-establishing session");
- await this.olmDevice.recordSessionProblem(deviceKey, "wedged", false);
- retryDecryption();
- return;
- }
- }
- const devicesByUser = new Map([[sender, [device]]]);
- await olmlib.ensureOlmSessionsForDevices(this.olmDevice, this.baseApis, devicesByUser, true);
- lastNewSessionDevices.set(deviceKey, Date.now());
-
- // Now send a blank message on that session so the other side knows about it.
- // (The keyshare request is sent in the clear so that won't do)
- // We send this first such that, as long as the toDevice messages arrive in the
- // same order we sent them, the other end will get this first, set up the new session,
- // then get the keyshare request and send the key over this new session (because it
- // is the session it has most recently received a message on).
- const encryptedContent = {
- algorithm: olmlib.OLM_ALGORITHM,
- sender_key: this.olmDevice.deviceCurve25519Key,
- ciphertext: {},
- [_event.ToDeviceMessageId]: (0, _uuid.v4)()
- };
- await olmlib.encryptMessageForDevice(encryptedContent.ciphertext, this.userId, this.deviceId, this.olmDevice, sender, device, {
- type: "m.dummy"
- });
- await this.olmDevice.recordSessionProblem(deviceKey, "wedged", true);
- retryDecryption();
- await this.baseApis.sendToDevice("m.room.encrypted", new Map([[sender, new Map([[device.deviceId, encryptedContent]])]]));
-
- // Most of the time this probably won't be necessary since we'll have queued up a key request when
- // we failed to decrypt the message and will be waiting a bit for the key to arrive before sending
- // it. This won't always be the case though so we need to re-send any that have already been sent
- // to avoid races.
- const requestsToResend = await this.outgoingRoomKeyRequestManager.getOutgoingSentRoomKeyRequest(sender, device.deviceId);
- for (const keyReq of requestsToResend) {
- this.requestRoomKey(keyReq.requestBody, keyReq.recipients, true);
- }
- }
-
- /**
- * Handle a change in the membership state of a member of a room
- *
- * @internal
- * @param event - event causing the change
- * @param member - user whose membership changed
- * @param oldMembership - previous membership
- */
- onRoomMembership(event, member, oldMembership) {
- // this event handler is registered on the *client* (as opposed to the room
- // member itself), which means it is only called on changes to the *live*
- // membership state (ie, it is not called when we back-paginate, nor when
- // we load the state in the initialsync).
- //
- // Further, it is automatically registered and called when new members
- // arrive in the room.
-
- const roomId = member.roomId;
- const alg = this.roomEncryptors.get(roomId);
- if (!alg) {
- // not encrypting in this room
- return;
- }
- // only mark users in this room as tracked if we already started tracking in this room
- // this way we don't start device queries after sync on behalf of this room which we won't use
- // the result of anyway, as we'll need to do a query again once all the members are fetched
- // by calling _trackRoomDevices
- if (roomId in this.roomDeviceTrackingState) {
- var _this$clientStore$get;
- if (member.membership == "join") {
- _logger.logger.log("Join event for " + member.userId + " in " + roomId);
- // make sure we are tracking the deviceList for this user
- this.deviceList.startTrackingDeviceList(member.userId);
- } else if (member.membership == "invite" && (_this$clientStore$get = this.clientStore.getRoom(roomId)) !== null && _this$clientStore$get !== void 0 && _this$clientStore$get.shouldEncryptForInvitedMembers()) {
- _logger.logger.log("Invite event for " + member.userId + " in " + roomId);
- this.deviceList.startTrackingDeviceList(member.userId);
- }
- }
- alg.onRoomMembership(event, member, oldMembership);
- }
-
- /**
- * Called when we get an m.room_key_request event.
- *
- * @internal
- * @param event - key request event
- */
- onRoomKeyRequestEvent(event) {
- const content = event.getContent();
- if (content.action === "request") {
- // Queue it up for now, because they tend to arrive before the room state
- // events at initial sync, and we want to see if we know anything about the
- // room before passing them on to the app.
- const req = new IncomingRoomKeyRequest(event);
- this.receivedRoomKeyRequests.push(req);
- } else if (content.action === "request_cancellation") {
- const req = new IncomingRoomKeyRequestCancellation(event);
- this.receivedRoomKeyRequestCancellations.push(req);
- }
- }
-
- /**
- * Process any m.room_key_request events which were queued up during the
- * current sync.
- *
- * @internal
- */
- async processReceivedRoomKeyRequests() {
- if (this.processingRoomKeyRequests) {
- // we're still processing last time's requests; keep queuing new ones
- // up for now.
- return;
- }
- this.processingRoomKeyRequests = true;
- try {
- // we need to grab and clear the queues in the synchronous bit of this method,
- // so that we don't end up racing with the next /sync.
- const requests = this.receivedRoomKeyRequests;
- this.receivedRoomKeyRequests = [];
- const cancellations = this.receivedRoomKeyRequestCancellations;
- this.receivedRoomKeyRequestCancellations = [];
-
- // Process all of the requests, *then* all of the cancellations.
- //
- // This makes sure that if we get a request and its cancellation in the
- // same /sync result, then we process the request before the
- // cancellation (and end up with a cancelled request), rather than the
- // cancellation before the request (and end up with an outstanding
- // request which should have been cancelled.)
- await Promise.all(requests.map(req => this.processReceivedRoomKeyRequest(req)));
- await Promise.all(cancellations.map(cancellation => this.processReceivedRoomKeyRequestCancellation(cancellation)));
- } catch (e) {
- _logger.logger.error(`Error processing room key requsts: ${e}`);
- } finally {
- this.processingRoomKeyRequests = false;
- }
- }
-
- /**
- * Helper for processReceivedRoomKeyRequests
- *
- */
- async processReceivedRoomKeyRequest(req) {
- const userId = req.userId;
- const deviceId = req.deviceId;
- const body = req.requestBody;
- const roomId = body.room_id;
- const alg = body.algorithm;
- _logger.logger.log(`m.room_key_request from ${userId}:${deviceId}` + ` for ${roomId} / ${body.session_id} (id ${req.requestId})`);
- if (userId !== this.userId) {
- if (!this.roomEncryptors.get(roomId)) {
- _logger.logger.debug(`room key request for unencrypted room ${roomId}`);
- return;
- }
- const encryptor = this.roomEncryptors.get(roomId);
- const device = this.deviceList.getStoredDevice(userId, deviceId);
- if (!device) {
- _logger.logger.debug(`Ignoring keyshare for unknown device ${userId}:${deviceId}`);
- return;
- }
- try {
- await encryptor.reshareKeyWithDevice(body.sender_key, body.session_id, userId, device);
- } catch (e) {
- _logger.logger.warn("Failed to re-share keys for session " + body.session_id + " with device " + userId + ":" + device.deviceId, e);
- }
- return;
- }
- if (deviceId === this.deviceId) {
- // We'll always get these because we send room key requests to
- // '*' (ie. 'all devices') which includes the sending device,
- // so ignore requests from ourself because apart from it being
- // very silly, it won't work because an Olm session cannot send
- // messages to itself.
- // The log here is probably superfluous since we know this will
- // always happen, but let's log anyway for now just in case it
- // causes issues.
- _logger.logger.log("Ignoring room key request from ourselves");
- return;
- }
-
- // todo: should we queue up requests we don't yet have keys for,
- // in case they turn up later?
-
- // if we don't have a decryptor for this room/alg, we don't have
- // the keys for the requested events, and can drop the requests.
- if (!this.roomDecryptors.has(roomId)) {
- _logger.logger.log(`room key request for unencrypted room ${roomId}`);
- return;
- }
- const decryptor = this.roomDecryptors.get(roomId).get(alg);
- if (!decryptor) {
- _logger.logger.log(`room key request for unknown alg ${alg} in room ${roomId}`);
- return;
- }
- if (!(await decryptor.hasKeysForKeyRequest(req))) {
- _logger.logger.log(`room key request for unknown session ${roomId} / ` + body.session_id);
- return;
- }
- req.share = () => {
- decryptor.shareKeysWithDevice(req);
- };
-
- // if the device is verified already, share the keys
- if (this.checkDeviceTrust(userId, deviceId).isVerified()) {
- _logger.logger.log("device is already verified: sharing keys");
- req.share();
- return;
- }
- this.emit(CryptoEvent.RoomKeyRequest, req);
- }
-
- /**
- * Helper for processReceivedRoomKeyRequests
- *
- */
- async processReceivedRoomKeyRequestCancellation(cancellation) {
- _logger.logger.log(`m.room_key_request cancellation for ${cancellation.userId}:` + `${cancellation.deviceId} (id ${cancellation.requestId})`);
-
- // we should probably only notify the app of cancellations we told it
- // about, but we don't currently have a record of that, so we just pass
- // everything through.
- this.emit(CryptoEvent.RoomKeyRequestCancellation, cancellation);
- }
-
- /**
- * Get a decryptor for a given room and algorithm.
- *
- * If we already have a decryptor for the given room and algorithm, return
- * it. Otherwise try to instantiate it.
- *
- * @internal
- *
- * @param roomId - room id for decryptor. If undefined, a temporary
- * decryptor is instantiated.
- *
- * @param algorithm - crypto algorithm
- *
- * @throws {@link DecryptionError} if the algorithm is unknown
- */
- getRoomDecryptor(roomId, algorithm) {
- let decryptors;
- let alg;
- if (roomId) {
- decryptors = this.roomDecryptors.get(roomId);
- if (!decryptors) {
- decryptors = new Map();
- this.roomDecryptors.set(roomId, decryptors);
- }
- alg = decryptors.get(algorithm);
- if (alg) {
- return alg;
- }
- }
- const AlgClass = algorithms.DECRYPTION_CLASSES.get(algorithm);
- if (!AlgClass) {
- throw new algorithms.DecryptionError("UNKNOWN_ENCRYPTION_ALGORITHM", 'Unknown encryption algorithm "' + algorithm + '".');
- }
- alg = new AlgClass({
- userId: this.userId,
- crypto: this,
- olmDevice: this.olmDevice,
- baseApis: this.baseApis,
- roomId: roomId !== null && roomId !== void 0 ? roomId : undefined
- });
- if (decryptors) {
- decryptors.set(algorithm, alg);
- }
- return alg;
- }
-
- /**
- * Get all the room decryptors for a given encryption algorithm.
- *
- * @param algorithm - The encryption algorithm
- *
- * @returns An array of room decryptors
- */
- getRoomDecryptors(algorithm) {
- const decryptors = [];
- for (const d of this.roomDecryptors.values()) {
- if (d.has(algorithm)) {
- decryptors.push(d.get(algorithm));
- }
- }
- return decryptors;
- }
-
- /**
- * sign the given object with our ed25519 key
- *
- * @param obj - Object to which we will add a 'signatures' property
- */
- async signObject(obj) {
- const sigs = new Map(Object.entries(obj.signatures || {}));
- const unsigned = obj.unsigned;
- delete obj.signatures;
- delete obj.unsigned;
- const userSignatures = sigs.get(this.userId) || {};
- sigs.set(this.userId, userSignatures);
- userSignatures["ed25519:" + this.deviceId] = await this.olmDevice.sign(_anotherJson.default.stringify(obj));
- obj.signatures = (0, _utils.recursiveMapToObject)(sigs);
- if (unsigned !== undefined) obj.unsigned = unsigned;
- }
-}
-
-/**
- * Fix up the backup key, that may be in the wrong format due to a bug in a
- * migration step. Some backup keys were stored as a comma-separated list of
- * integers, rather than a base64-encoded byte array. If this function is
- * passed a string that looks like a list of integers rather than a base64
- * string, it will attempt to convert it to the right format.
- *
- * @param key - the key to check
- * @returns If the key is in the wrong format, then the fixed
- * key will be returned. Otherwise null will be returned.
- *
- */
-exports.Crypto = Crypto;
-function fixBackupKey(key) {
- if (typeof key !== "string" || key.indexOf(",") < 0) {
- return null;
- }
- const fixedKey = Uint8Array.from(key.split(","), x => parseInt(x));
- return olmlib.encodeBase64(fixedKey);
-}
-
-/**
- * Represents a received m.room_key_request event
- */
-class IncomingRoomKeyRequest {
- /** user requesting the key */
-
- /** device requesting the key */
-
- /** unique id for the request */
-
- /**
- * callback which, when called, will ask
- * the relevant crypto algorithm implementation to share the keys for
- * this request.
- */
-
- constructor(event) {
- (0, _defineProperty2.default)(this, "userId", void 0);
- (0, _defineProperty2.default)(this, "deviceId", void 0);
- (0, _defineProperty2.default)(this, "requestId", void 0);
- (0, _defineProperty2.default)(this, "requestBody", void 0);
- (0, _defineProperty2.default)(this, "share", void 0);
- const content = event.getContent();
- this.userId = event.getSender();
- this.deviceId = content.requesting_device_id;
- this.requestId = content.request_id;
- this.requestBody = content.body || {};
- this.share = () => {
- throw new Error("don't know how to share keys for this request yet");
- };
- }
-}
-
-/**
- * Represents a received m.room_key_request cancellation
- */
-exports.IncomingRoomKeyRequest = IncomingRoomKeyRequest;
-class IncomingRoomKeyRequestCancellation {
- /** user requesting the cancellation */
-
- /** device requesting the cancellation */
-
- /** unique id for the request to be cancelled */
-
- constructor(event) {
- (0, _defineProperty2.default)(this, "userId", void 0);
- (0, _defineProperty2.default)(this, "deviceId", void 0);
- (0, _defineProperty2.default)(this, "requestId", void 0);
- const content = event.getContent();
- this.userId = event.getSender();
- this.deviceId = content.requesting_device_id;
- this.requestId = content.request_id;
- }
-}
-
-// a number of types are re-exported for backwards compatibility, in case any applications are referencing it.
-//# sourceMappingURL=index.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/index.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/index.js.map
deleted file mode 100644
index c9b3f6a..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/index.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"index.js","names":["_anotherJson","_interopRequireDefault","require","_uuid","_event","_ReEmitter","_logger","_OlmDevice","olmlib","_interopRequireWildcard","_DeviceList","_deviceinfo","algorithms","_CrossSigning","_EncryptionSetup","_SecretStorage","_OutgoingRoomKeyRequestManager","_indexeddbCryptoStore","_QRCode","_SAS","_key_passphrase","_recoverykey","_VerificationRequest","_InRoomChannel","_ToDeviceChannel","_IllegalMethod","_errors","_aes","_dehydration","_backup","_room","_roomMember","_event2","_client","_typedEventEmitter","_roomState","_utils","_getRequireWildcardCache","nodeInterop","WeakMap","cacheBabelInterop","cacheNodeInterop","obj","__esModule","default","cache","has","get","newObj","hasPropertyDescriptor","Object","defineProperty","getOwnPropertyDescriptor","key","prototype","hasOwnProperty","call","desc","set","ownKeys","object","enumerableOnly","keys","getOwnPropertySymbols","symbols","filter","sym","enumerable","push","apply","_objectSpread","target","i","arguments","length","source","forEach","_defineProperty2","getOwnPropertyDescriptors","defineProperties","DeviceVerification","DeviceInfo","defaultVerificationMethods","ReciprocateQRCode","NAME","SASVerification","SHOW_QR_CODE_METHOD","IllegalMethod","SCAN_QR_CODE_METHOD","verificationMethods","RECIPROCATE_QR_CODE","SAS","exports","isCryptoAvailable","Boolean","global","Olm","MIN_FORCE_SESSION_INTERVAL_MS","CryptoEvent","Crypto","TypedEventEmitter","getOlmVersion","OlmDevice","constructor","baseApis","userId","deviceId","clientStore","cryptoStore","roomList","Map","MapWithDefault","newCrossSigning","deviceList","getStoredCrossSigningForUser","seenPubkey","getId","currentPubkey","crossSigningInfo","changed","checkOwnCrossSigningTrust","storeTrustedSelfKeys","emit","KeysChanged","UserTrustStatusChanged","checkUserTrust","checkDeviceVerifications","crossSigning","updateCrossSigningVerifiedBefore","isCrossSigningVerified","setRawStoredCrossSigningForUser","toStorage","event","member","oldMembership","onRoomMembership","e","logger","error","log","getType","getSender","getContent","ToDeviceMessageId","onRoomKeyEvent","onRoomKeyRequestEvent","secretStorage","onRequestReceived","onSecretReceived","onRoomKeyWithheldEvent","transaction_id","onKeyVerificationMessage","msgtype","onToDeviceBadEncrypted","isBeingDecrypted","shouldAttemptDecryption","attemptDecryption","once","MatrixEventEvent","Decrypted","ev","onToDeviceEvent","room","atStart","removed","liveEvent","InRoomChannel","validateEvent","createRequest","channel","getRoomId","VerificationRequest","handleVerificationEvent","inRoomVerificationRequests","reEmitter","TypedReEmitter","method","warn","entries","backupManager","BackupManager","cachedKey","getSessionBackupPrivateKey","storedKey","getSecret","fixedKey","fixBackupKey","getSecretStorageKey","storeSecret","decodeBase64","cryptoCallbacks","getBackupKey","Error","olmDevice","DeviceList","on","UserCrossSigningUpdated","onDeviceListUserCrossSigningUpdated","reEmit","DevicesUpdated","WillUpdateDevices","supportedAlgorithms","Array","from","DECRYPTION_CLASSES","outgoingRoomKeyRequestManager","OutgoingRoomKeyRequestManager","toDeviceVerificationRequests","ToDeviceRequests","InRoomRequests","cacheCallbacks","createCryptoStoreCacheCallbacks","CrossSigningInfo","SecretStorage","dehydrationManager","DehydrationManager","getCrossSigningKey","type","getFromSecretStorage","init","exportedOlmDevice","pickleKey","fromExportedDevice","load","deviceKeys","deviceEd25519Key","deviceCurve25519Key","myDevices","getRawStoredDevicesForUser","deviceInfo","verified","VERIFIED","known","storeDevicesForUser","saveIfDirty","doTxn","IndexedDBCryptoStore","STORE_ACCOUNT","txn","getCrossSigningKeys","setKeys","startTrackingDeviceList","checkAndStart","getCryptoTrustCrossSignedDevices","trustCrossSignedDevices","setCryptoTrustCrossSignedDevices","val","getKnownUserIds","devices","deviceTrust","checkDeviceTrust","isLocallyVerified","deviceObj","getStoredDevice","DeviceVerificationChanged","createRecoveryKeyFromPassphrase","password","decryption","PkDecryption","keyInfo","derivation","keyFromPassphrase","passphrase","algorithm","iterations","salt","pubkey","init_with_private_key","generate_key","privateKey","get_private_key","encodedPrivateKey","encodeRecoveryKey","free","userHasCrossSigningKeys","downloadKeys","isCrossSigningReady","publicKeysOnDevice","privateKeysExistSomewhere","isStoredInKeyCache","isStoredInSecretStorage","isSecretStorageReady","secretStorageKeyInAccount","hasKey","privateKeysInStorage","sessionBackupInStorage","getKeyBackupEnabled","isKeyBackupKeyStored","bootstrapCrossSigning","authUploadDeviceSigningKeys","setupNewCrossSigning","delegateCryptoCallbacks","builder","EncryptionSetupBuilder","store","accountData","crossSigningCallbacks","resetCrossSigning","resetKeys","signObject","master","addCrossSigningKeys","device","deviceSignature","signDevice","addKeySignature","backupInfo","auth_data","addSessionBackup","privateKeysInCache","allowPrivateKeyRequests","crossSigningPrivateKeys","privateKeys","size","saveCrossSigningKeys","accountDataClientAdapter","ssssCryptoCallbacks","undefined","storeInSecretStorage","operation","buildOperation","persist","bootstrapSecretStorage","createSecretStorageKey","keyBackupInfo","setupNewKeyBackup","setupNewSecretStorage","getKeyBackupPassphrase","newKeyId","createSSSS","opts","keyId","addKey","SECRET_STORAGE_ALGORITHM_V1_AES","addPrivateKey","setDefaultKeyId","ensureCanCheckPassphrase","mac","_this$baseApis$crypto","_this$baseApis$crypto2","iv","calculateKeyCheck","setAccountData","signKeyBackupWithCrossSigning","keyBackupAuthData","oldSSSSKey","oldKeyId","oldKeyInfo","storageExists","backupKey","private_key_salt","private_key_iterations","bits","encodeBase64","getCrossSigningKeysFromCache","info","prepareKeyBackupVersion","secureSecretStorage","decodeRecoveryKey","recovery_key","data","sessionBackupKey","fixedBackupKey","decodedBackupKey","Uint8Array","addSessionBackupPrivateKeyToCache","addSecretStorageKey","keyID","hasSecretStorageKey","getKey","name","secret","isSecretStored","isStored","requestSecret","request","getDefaultSecretStorageKeyId","getDefaultKeyId","setDefaultSecretStorageKeyId","k","checkSecretStorageKey","checkKey","checkSecretStoragePrivateKey","expectedPublicKey","gotPubkey","_decryption","Promise","resolve","getSecretStorePrivateKey","storeSessionBackupPrivateKey","ciphertext","Buffer","decrypted","decryptAES","encryptedKey","encryptAES","storeSecretStorePrivateKey","checkCrossSigningPrivateKey","signing","PkSigning","init_with_seed","_signing","afterCrossSigningLocalKeyChange","signedDevice","upload","shouldEmit","uploadKeySignatures","then","response","failures","KeySignatureUploadFailure","KeySignatureUploadError","catch","shouldUpgradeCb","shouldUpgradeDeviceVerifications","users","upgradeInfo","checkForDeviceVerificationUpgrade","fromStorage","usersToUpgrade","setDeviceVerified","trustLevel","firstUse","isVerified","deviceIds","checkForValidDeviceSignature","map","signatures","signame","split","verifySignature","getCrossSigningId","userCrossSigning","UserTrustLevel","checkDeviceInfoTrust","trustedLocally","trustCrossSig","DeviceTrustLevel","checkIfOwnDeviceCrossSigned","_userCrossSigning$che","masterChanged","masterExistsNotLocallyCached","ret","_signing2","oldSelfSigningId","oldUserSigningId","selfSigningChanged","userSigningChanged","selfSigningExistsNotLocallyCached","userSigningExistsNotLocallyCached","keySignatures","_signing3","_signing4","masterKey","deviceSig","assign","keysToUpload","checkKeyBackup","clearKeys","storeCrossSigningKeys","user_signing","includes","enableLazyLoading","lazyLoadMembers","registerEventHandlers","eventEmitter","RoomMemberEvent","Membership","onMembership","ClientEvent","ToDeviceEvent","RoomEvent","Timeline","onTimelineEvent","start","stop","getDeviceEd25519Key","getDeviceCurve25519Key","setGlobalBlacklistUnverifiedDevices","value","globalBlacklistUnverifiedDevices","getGlobalBlacklistUnverifiedDevices","uploadDeviceKeys","device_id","user_id","uploadKeysRequest","device_keys","updateOneTimeKeyCount","currentCount","isFinite","oneTimeKeyCount","TypeError","setNeedsNewFallback","needsNewFallback","getNeedsNewFallback","maybeUploadOneTimeKeys","uploadPeriod","maxKeysPerCycle","oneTimeKeyCheckInProgress","now","Date","lastOneTimeKeyCheck","maxOneTimeKeys","maxNumberOfOneTimeKeys","keyLimit","Math","floor","uploadLoop","keyCount","keysThisLoop","min","generateOneTimeKeys","fallbackKeys","getFallbackKey","curve25519","fallbackCleanup","clearTimeout","generateFallbackKey","res","uploadOneTimeKeys","one_time_key_counts","signed_curve25519","stack","finally","promises","fallbackJson","fallback","oneTimeKeys","getOneTimeKeys","oneTimeJson","all","requestBody","one_time_keys","setTimeout","forgetOldFallbackKey","markKeysAsPublished","userIds","forceDownload","getStoredDevicesForUser","saveDeviceList","delay","setDeviceVerification","blocked","xsk","gotKeyId","values","signUser","dev","verificationStatus","UNVERIFIED","BLOCKED","knownStatus","findVerificationRequestDMInProgress","roomId","findRequestInProgress","getVerificationRequestsToDeviceInProgress","getRequestsInProgress","requestVerificationDM","existingRequest","requestVerificationWithChannel","requestVerification","ToDeviceChannel","makeTransactionId","requestsMap","transactionId","setRequestByChannel","sendRequest","racingRequest","getRequestByChannel","beginKeyVerification","getRequestBySenderAndTxnId","setRequestBySenderAndTxnId","legacyDeviceVerification","verifier","race","verify","waitFor","r","started","getOlmSessionsForUser","result","deviceKey","getIdentityKey","sessions","getSessionInfoForDevice","deviceIdKey","getEventSenderDeviceInfo","senderKey","getSenderKey","getWireContent","isKeySourceUntrusted","getDeviceByIdentityKey","claimedKey","getClaimedEd25519Key","getFingerprint","getEventEncryptionInfo","_event$getSenderKey","_this$deviceList$getD","encrypted","authenticated","sender","mismatchedSender","forceDiscardSession","alg","roomEncryptors","setRoomEncryption","config","inhibitDeviceQuery","getRoom","setRoomEncryptionImpl","refreshOutdatedDeviceLists","existingConfig","getRoomEncryption","JSON","stringify","existingAlg","storeConfigPromise","AlgClass","ENCRYPTION_CLASSES","crypto","membersLoaded","trackRoomDevicesImpl","onState","_state","off","RoomStateEvent","Update","trackRoomDevices","trackMembers","members","getEncryptionTargetMembers","m","promise","roomDeviceTrackingState","err","ensureOlmSessionsForUsers","force","devicesByUser","userDevices","ensureOlmSessionsForDevices","exportRoomKeys","exportedSessions","STORE_INBOUND_GROUP_SESSIONS","getAllEndToEndInboundGroupSessions","s","sess","exportInboundGroupSession","sessionId","sessionData","first_known_index","MEGOLM_ALGORITHM","importRoomKeys","successes","total","updateProgress","_opts$progressCallbac","progressCallback","stage","room_id","getRoomDecryptor","importRoomKey","countSessionsNeedingBackup","prepareToEncrypt","encryptEvent","content","mRelatesTo","elementPerfMetrics","encryptedContent","encryptMessage","makeEncrypted","decryptEvent","isRedacted","redactionEvent","MatrixEvent","getUnsigned","redacted_because","redactedBecause","isEncrypted","decryptedEvent","clearEvent","unsigned","handleDeviceListChanges","syncData","syncDeviceLists","oldSyncToken","evalDeviceListChanges","requestRoomKey","recipients","resend","queueRoomKeyRequest","sendKeyRequestsImmediately","sendQueuedRequests","cancelRoomKeyRequest","cancelAndResendAllOutgoingKeyRequests","cancelAndResendAllOutgoingRequests","onCryptoEvent","onSyncWillProcess","stopTrackingAllDeviceLists","onSyncCompleted","_syncData$nextSyncTok","setSyncToken","nextSyncToken","catchingUp","processReceivedRoomKeyRequests","deviceLists","isArray","u","invalidateUserDeviceList","left","e2eUserIds","Set","getTrackedE2eUsers","stopTrackingDeviceList","getTrackedE2eRooms","getRooms","myMembership","getMyMembership","encryptAndSendToDevices","userDeviceInfoArr","payload","toDeviceBatch","eventType","EventType","RoomMessageEncrypted","batch","OLM_ALGORITHM","sender_key","uuidv4","encryptMessageForDevice","msg","queueToDevice","preprocessToDeviceMessages","events","toDevice","_toDevice$content","preprocessOneTimeKeyCounts","oneTimeKeysCounts","preprocessUnusedFallbackKeys","unusedFallbackKeys","checkedForBackup","code","session_id","reason","roomDecryptors","getRoomDecryptors","decryptor","retryDecryptionFromSender","canCreateRequest","getEventType","from_device","isLiveEvent","isSending","status","EventStatus","SENT","eventIdListener","statusListener","reject","CANCELLED","LocalEventIdReplaced","Status","removeListener","getRequest","isNewRequest","setRequest","setVerificationRequest","handleEvent","initiatedByMe","invalid","observeOnly","UndecryptableToDeviceEvent","retryDecryption","lastNewSessionDevices","lastNewSessionForced","getOrCreate","debug","recordSessionProblem","sendToDevice","requestsToResend","getOutgoingSentRoomKeyRequest","keyReq","_this$clientStore$get","membership","shouldEncryptForInvitedMembers","action","req","IncomingRoomKeyRequest","receivedRoomKeyRequests","IncomingRoomKeyRequestCancellation","receivedRoomKeyRequestCancellations","processingRoomKeyRequests","requests","cancellations","processReceivedRoomKeyRequest","cancellation","processReceivedRoomKeyRequestCancellation","body","requestId","encryptor","reshareKeyWithDevice","hasKeysForKeyRequest","share","shareKeysWithDevice","RoomKeyRequest","RoomKeyRequestCancellation","decryptors","DecryptionError","d","sigs","userSignatures","sign","anotherjson","recursiveMapToObject","indexOf","x","parseInt","requesting_device_id","request_id"],"sources":["../../src/crypto/index.ts"],"sourcesContent":["/*\nCopyright 2016 OpenMarket Ltd\nCopyright 2017 Vector Creations Ltd\nCopyright 2018-2019 New Vector Ltd\nCopyright 2019-2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport anotherjson from \"another-json\";\nimport { v4 as uuidv4 } from \"uuid\";\n\nimport type { IDeviceKeys, IEventDecryptionResult, IMegolmSessionData, IOneTimeKey } from \"../@types/crypto\";\nimport type { PkDecryption, PkSigning } from \"@matrix-org/olm\";\nimport { EventType, ToDeviceMessageId } from \"../@types/event\";\nimport { TypedReEmitter } from \"../ReEmitter\";\nimport { logger } from \"../logger\";\nimport { IExportedDevice, OlmDevice } from \"./OlmDevice\";\nimport { IOlmDevice } from \"./algorithms/megolm\";\nimport * as olmlib from \"./olmlib\";\nimport { DeviceInfoMap, DeviceList } from \"./DeviceList\";\nimport { DeviceInfo, IDevice } from \"./deviceinfo\";\nimport type { DecryptionAlgorithm, EncryptionAlgorithm } from \"./algorithms\";\nimport * as algorithms from \"./algorithms\";\nimport { createCryptoStoreCacheCallbacks, CrossSigningInfo, DeviceTrustLevel, UserTrustLevel } from \"./CrossSigning\";\nimport { EncryptionSetupBuilder } from \"./EncryptionSetup\";\nimport {\n IAccountDataClient,\n ISecretRequest,\n SECRET_STORAGE_ALGORITHM_V1_AES,\n SecretStorage,\n SecretStorageKeyObject,\n SecretStorageKeyTuple,\n} from \"./SecretStorage\";\nimport {\n IAddSecretStorageKeyOpts,\n ICreateSecretStorageOpts,\n IEncryptedEventInfo,\n IImportRoomKeysOpts,\n IRecoveryKey,\n} from \"./api\";\nimport { OutgoingRoomKeyRequestManager } from \"./OutgoingRoomKeyRequestManager\";\nimport { IndexedDBCryptoStore } from \"./store/indexeddb-crypto-store\";\nimport { VerificationBase } from \"./verification/Base\";\nimport { ReciprocateQRCode, SCAN_QR_CODE_METHOD, SHOW_QR_CODE_METHOD } from \"./verification/QRCode\";\nimport { SAS as SASVerification } from \"./verification/SAS\";\nimport { keyFromPassphrase } from \"./key_passphrase\";\nimport { decodeRecoveryKey, encodeRecoveryKey } from \"./recoverykey\";\nimport { VerificationRequest } from \"./verification/request/VerificationRequest\";\nimport { InRoomChannel, InRoomRequests } from \"./verification/request/InRoomChannel\";\nimport { ToDeviceChannel, ToDeviceRequests, Request } from \"./verification/request/ToDeviceChannel\";\nimport { IllegalMethod } from \"./verification/IllegalMethod\";\nimport { KeySignatureUploadError } from \"../errors\";\nimport { calculateKeyCheck, decryptAES, encryptAES } from \"./aes\";\nimport { DehydrationManager } from \"./dehydration\";\nimport { BackupManager } from \"./backup\";\nimport { IStore } from \"../store\";\nimport { Room, RoomEvent } from \"../models/room\";\nimport { RoomMember, RoomMemberEvent } from \"../models/room-member\";\nimport { EventStatus, IEvent, MatrixEvent, MatrixEventEvent } from \"../models/event\";\nimport { ToDeviceBatch } from \"../models/ToDeviceMessage\";\nimport {\n ClientEvent,\n ICrossSigningKey,\n IKeysUploadResponse,\n ISignedKey,\n IUploadKeySignaturesResponse,\n MatrixClient,\n} from \"../client\";\nimport type { IRoomEncryption, RoomList } from \"./RoomList\";\nimport { IKeyBackupInfo } from \"./keybackup\";\nimport { ISyncStateData } from \"../sync\";\nimport { CryptoStore } from \"./store/base\";\nimport { IVerificationChannel } from \"./verification/request/Channel\";\nimport { TypedEventEmitter } from \"../models/typed-event-emitter\";\nimport { IContent } from \"../models/event\";\nimport { ISyncResponse, IToDeviceEvent } from \"../sync-accumulator\";\nimport { ISignatures } from \"../@types/signed\";\nimport { IMessage } from \"./algorithms/olm\";\nimport { CryptoBackend, OnSyncCompletedData } from \"../common-crypto/CryptoBackend\";\nimport { RoomState, RoomStateEvent } from \"../models/room-state\";\nimport { MapWithDefault, recursiveMapToObject } from \"../utils\";\nimport { SecretStorageKeyDescription } from \"../secret-storage\";\n\nconst DeviceVerification = DeviceInfo.DeviceVerification;\n\nconst defaultVerificationMethods = {\n [ReciprocateQRCode.NAME]: ReciprocateQRCode,\n [SASVerification.NAME]: SASVerification,\n\n // These two can't be used for actual verification, but we do\n // need to be able to define them here for the verification flows\n // to start.\n [SHOW_QR_CODE_METHOD]: IllegalMethod,\n [SCAN_QR_CODE_METHOD]: IllegalMethod,\n} as const;\n\n/**\n * verification method names\n */\n// legacy export identifier\nexport const verificationMethods = {\n RECIPROCATE_QR_CODE: ReciprocateQRCode.NAME,\n SAS: SASVerification.NAME,\n} as const;\n\nexport type VerificationMethod = keyof typeof verificationMethods | string;\n\nexport function isCryptoAvailable(): boolean {\n return Boolean(global.Olm);\n}\n\nconst MIN_FORCE_SESSION_INTERVAL_MS = 60 * 60 * 1000;\n\ninterface IInitOpts {\n exportedOlmDevice?: IExportedDevice;\n pickleKey?: string;\n}\n\nexport interface IBootstrapCrossSigningOpts {\n /** Optional. Reset even if keys already exist. */\n setupNewCrossSigning?: boolean;\n /**\n * A function that makes the request requiring auth. Receives the auth data as an object.\n * Can be called multiple times, first with an empty authDict, to obtain the flows.\n */\n authUploadDeviceSigningKeys?(makeRequest: (authData: any) => Promise<{}>): Promise<void>;\n}\n\nexport interface ICryptoCallbacks {\n getCrossSigningKey?: (keyType: string, pubKey: string) => Promise<Uint8Array | null>;\n saveCrossSigningKeys?: (keys: Record<string, Uint8Array>) => void;\n shouldUpgradeDeviceVerifications?: (users: Record<string, any>) => Promise<string[]>;\n getSecretStorageKey?: (\n keys: { keys: Record<string, SecretStorageKeyDescription> },\n name: string,\n ) => Promise<[string, Uint8Array] | null>;\n cacheSecretStorageKey?: (keyId: string, keyInfo: SecretStorageKeyDescription, key: Uint8Array) => void;\n onSecretRequested?: (\n userId: string,\n deviceId: string,\n requestId: string,\n secretName: string,\n deviceTrust: DeviceTrustLevel,\n ) => Promise<string | undefined>;\n getDehydrationKey?: (\n keyInfo: SecretStorageKeyDescription,\n checkFunc: (key: Uint8Array) => void,\n ) => Promise<Uint8Array>;\n getBackupKey?: () => Promise<Uint8Array>;\n}\n\n/* eslint-disable camelcase */\ninterface IRoomKey {\n room_id: string;\n algorithm: string;\n}\n\n/**\n * The parameters of a room key request. The details of the request may\n * vary with the crypto algorithm, but the management and storage layers for\n * outgoing requests expect it to have 'room_id' and 'session_id' properties.\n */\nexport interface IRoomKeyRequestBody extends IRoomKey {\n session_id: string;\n sender_key: string;\n}\n\n/* eslint-enable camelcase */\n\ninterface IDeviceVerificationUpgrade {\n devices: DeviceInfo[];\n crossSigningInfo: CrossSigningInfo;\n}\n\nexport interface ICheckOwnCrossSigningTrustOpts {\n allowPrivateKeyRequests?: boolean;\n}\n\ninterface IUserOlmSession {\n deviceIdKey: string;\n sessions: {\n sessionId: string;\n hasReceivedMessage: boolean;\n }[];\n}\n\nexport interface IRoomKeyRequestRecipient {\n userId: string;\n deviceId: string;\n}\n\ninterface ISignableObject {\n signatures?: ISignatures;\n unsigned?: object;\n}\n\nexport interface IRequestsMap {\n getRequest(event: MatrixEvent): VerificationRequest | undefined;\n getRequestByChannel(channel: IVerificationChannel): VerificationRequest | undefined;\n setRequest(event: MatrixEvent, request: VerificationRequest): void;\n setRequestByChannel(channel: IVerificationChannel, request: VerificationRequest): void;\n}\n\n/* eslint-disable camelcase */\nexport interface IOlmEncryptedContent {\n algorithm: typeof olmlib.OLM_ALGORITHM;\n sender_key: string;\n ciphertext: Record<string, IMessage>;\n [ToDeviceMessageId]?: string;\n}\n\nexport interface IMegolmEncryptedContent {\n algorithm: typeof olmlib.MEGOLM_ALGORITHM;\n sender_key: string;\n session_id: string;\n device_id: string;\n ciphertext: string;\n [ToDeviceMessageId]?: string;\n}\n/* eslint-enable camelcase */\n\nexport type IEncryptedContent = IOlmEncryptedContent | IMegolmEncryptedContent;\n\nexport enum CryptoEvent {\n DeviceVerificationChanged = \"deviceVerificationChanged\",\n UserTrustStatusChanged = \"userTrustStatusChanged\",\n UserCrossSigningUpdated = \"userCrossSigningUpdated\",\n RoomKeyRequest = \"crypto.roomKeyRequest\",\n RoomKeyRequestCancellation = \"crypto.roomKeyRequestCancellation\",\n KeyBackupStatus = \"crypto.keyBackupStatus\",\n KeyBackupFailed = \"crypto.keyBackupFailed\",\n KeyBackupSessionsRemaining = \"crypto.keyBackupSessionsRemaining\",\n KeySignatureUploadFailure = \"crypto.keySignatureUploadFailure\",\n VerificationRequest = \"crypto.verification.request\",\n Warning = \"crypto.warning\",\n WillUpdateDevices = \"crypto.willUpdateDevices\",\n DevicesUpdated = \"crypto.devicesUpdated\",\n KeysChanged = \"crossSigning.keysChanged\",\n}\n\nexport type CryptoEventHandlerMap = {\n /**\n * Fires when a device is marked as verified/unverified/blocked/unblocked by\n * {@link MatrixClient#setDeviceVerified|MatrixClient.setDeviceVerified} or\n * {@link MatrixClient#setDeviceBlocked|MatrixClient.setDeviceBlocked}.\n *\n * @param userId - the owner of the verified device\n * @param deviceId - the id of the verified device\n * @param deviceInfo - updated device information\n */\n [CryptoEvent.DeviceVerificationChanged]: (userId: string, deviceId: string, device: DeviceInfo) => void;\n /**\n * Fires when the trust status of a user changes\n * If userId is the userId of the logged-in user, this indicated a change\n * in the trust status of the cross-signing data on the account.\n *\n * The cross-signing API is currently UNSTABLE and may change without notice.\n * @experimental\n *\n * @param userId - the userId of the user in question\n * @param trustLevel - The new trust level of the user\n */\n [CryptoEvent.UserTrustStatusChanged]: (userId: string, trustLevel: UserTrustLevel) => void;\n /**\n * Fires when we receive a room key request\n *\n * @param req - request details\n */\n [CryptoEvent.RoomKeyRequest]: (request: IncomingRoomKeyRequest) => void;\n /**\n * Fires when we receive a room key request cancellation\n */\n [CryptoEvent.RoomKeyRequestCancellation]: (request: IncomingRoomKeyRequestCancellation) => void;\n /**\n * Fires whenever the status of e2e key backup changes, as returned by getKeyBackupEnabled()\n * @param enabled - true if key backup has been enabled, otherwise false\n * @example\n * ```\n * matrixClient.on(\"crypto.keyBackupStatus\", function(enabled){\n * if (enabled) {\n * [...]\n * }\n * });\n * ```\n */\n [CryptoEvent.KeyBackupStatus]: (enabled: boolean) => void;\n [CryptoEvent.KeyBackupFailed]: (errcode: string) => void;\n [CryptoEvent.KeyBackupSessionsRemaining]: (remaining: number) => void;\n [CryptoEvent.KeySignatureUploadFailure]: (\n failures: IUploadKeySignaturesResponse[\"failures\"],\n source: \"checkOwnCrossSigningTrust\" | \"afterCrossSigningLocalKeyChange\" | \"setDeviceVerification\",\n upload: (opts: { shouldEmit: boolean }) => Promise<void>,\n ) => void;\n /**\n * Fires when a key verification is requested.\n */\n [CryptoEvent.VerificationRequest]: (request: VerificationRequest<any>) => void;\n /**\n * Fires when the app may wish to warn the user about something related\n * the end-to-end crypto.\n *\n * @param type - One of the strings listed above\n */\n [CryptoEvent.Warning]: (type: string) => void;\n /**\n * Fires when the user's cross-signing keys have changed or cross-signing\n * has been enabled/disabled. The client can use getStoredCrossSigningForUser\n * with the user ID of the logged in user to check if cross-signing is\n * enabled on the account. If enabled, it can test whether the current key\n * is trusted using with checkUserTrust with the user ID of the logged\n * in user. The checkOwnCrossSigningTrust function may be used to reconcile\n * the trust in the account key.\n *\n * The cross-signing API is currently UNSTABLE and may change without notice.\n * @experimental\n */\n [CryptoEvent.KeysChanged]: (data: {}) => void;\n /**\n * Fires whenever the stored devices for a user will be updated\n * @param users - A list of user IDs that will be updated\n * @param initialFetch - If true, the store is empty (apart\n * from our own device) and is being seeded.\n */\n [CryptoEvent.WillUpdateDevices]: (users: string[], initialFetch: boolean) => void;\n /**\n * Fires whenever the stored devices for a user have changed\n * @param users - A list of user IDs that were updated\n * @param initialFetch - If true, the store was empty (apart\n * from our own device) and has been seeded.\n */\n [CryptoEvent.DevicesUpdated]: (users: string[], initialFetch: boolean) => void;\n [CryptoEvent.UserCrossSigningUpdated]: (userId: string) => void;\n};\n\nexport class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap> implements CryptoBackend {\n /**\n * @returns The version of Olm.\n */\n public static getOlmVersion(): [number, number, number] {\n return OlmDevice.getOlmVersion();\n }\n\n public readonly backupManager: BackupManager;\n public readonly crossSigningInfo: CrossSigningInfo;\n public readonly olmDevice: OlmDevice;\n public readonly deviceList: DeviceList;\n public readonly dehydrationManager: DehydrationManager;\n public readonly secretStorage: SecretStorage;\n\n private readonly reEmitter: TypedReEmitter<CryptoEvent, CryptoEventHandlerMap>;\n private readonly verificationMethods: Map<VerificationMethod, typeof VerificationBase>;\n public readonly supportedAlgorithms: string[];\n private readonly outgoingRoomKeyRequestManager: OutgoingRoomKeyRequestManager;\n private readonly toDeviceVerificationRequests: ToDeviceRequests;\n public readonly inRoomVerificationRequests: InRoomRequests;\n\n private trustCrossSignedDevices = true;\n // the last time we did a check for the number of one-time-keys on the server.\n private lastOneTimeKeyCheck: number | null = null;\n private oneTimeKeyCheckInProgress = false;\n\n // EncryptionAlgorithm instance for each room\n private roomEncryptors = new Map<string, EncryptionAlgorithm>();\n // map from algorithm to DecryptionAlgorithm instance, for each room\n private roomDecryptors = new Map<string, Map<string, DecryptionAlgorithm>>();\n\n private deviceKeys: Record<string, string> = {}; // type: key\n\n public globalBlacklistUnverifiedDevices = false;\n public globalErrorOnUnknownDevices = true;\n\n // list of IncomingRoomKeyRequests/IncomingRoomKeyRequestCancellations\n // we received in the current sync.\n private receivedRoomKeyRequests: IncomingRoomKeyRequest[] = [];\n private receivedRoomKeyRequestCancellations: IncomingRoomKeyRequestCancellation[] = [];\n // true if we are currently processing received room key requests\n private processingRoomKeyRequests = false;\n // controls whether device tracking is delayed\n // until calling encryptEvent or trackRoomDevices,\n // or done immediately upon enabling room encryption.\n private lazyLoadMembers = false;\n // in case lazyLoadMembers is true,\n // track if an initial tracking of all the room members\n // has happened for a given room. This is delayed\n // to avoid loading room members as long as possible.\n private roomDeviceTrackingState: { [roomId: string]: Promise<void> } = {};\n\n // The timestamp of the last time we forced establishment\n // of a new session for each device, in milliseconds.\n // {\n // userId: {\n // deviceId: 1234567890000,\n // },\n // }\n // Map: user Id → device Id → timestamp\n private lastNewSessionForced: MapWithDefault<string, MapWithDefault<string, number>> = new MapWithDefault(\n () => new MapWithDefault(() => 0),\n );\n\n // This flag will be unset whilst the client processes a sync response\n // so that we don't start requesting keys until we've actually finished\n // processing the response.\n private sendKeyRequestsImmediately = false;\n\n private oneTimeKeyCount?: number;\n private needsNewFallback?: boolean;\n private fallbackCleanup?: ReturnType<typeof setTimeout>;\n\n /**\n * Cryptography bits\n *\n * This module is internal to the js-sdk; the public API is via MatrixClient.\n *\n * @internal\n *\n * @param baseApis - base matrix api interface\n *\n * @param userId - The user ID for the local user\n *\n * @param deviceId - The identifier for this device.\n *\n * @param clientStore - the MatrixClient data store.\n *\n * @param cryptoStore - storage for the crypto layer.\n *\n * @param roomList - An initialised RoomList object\n *\n * @param verificationMethods - Array of verification methods to use.\n * Each element can either be a string from MatrixClient.verificationMethods\n * or a class that implements a verification method.\n */\n public constructor(\n public readonly baseApis: MatrixClient,\n public readonly userId: string,\n private readonly deviceId: string,\n private readonly clientStore: IStore,\n public readonly cryptoStore: CryptoStore,\n private readonly roomList: RoomList,\n verificationMethods: Array<VerificationMethod | (typeof VerificationBase & { NAME: string })>,\n ) {\n super();\n this.reEmitter = new TypedReEmitter(this);\n\n if (verificationMethods) {\n this.verificationMethods = new Map();\n for (const method of verificationMethods) {\n if (typeof method === \"string\") {\n if (defaultVerificationMethods[method]) {\n this.verificationMethods.set(\n method,\n <typeof VerificationBase>defaultVerificationMethods[method],\n );\n }\n } else if (method[\"NAME\"]) {\n this.verificationMethods.set(method[\"NAME\"], method as typeof VerificationBase);\n } else {\n logger.warn(`Excluding unknown verification method ${method}`);\n }\n }\n } else {\n this.verificationMethods = new Map(Object.entries(defaultVerificationMethods)) as Map<\n VerificationMethod,\n typeof VerificationBase\n >;\n }\n\n this.backupManager = new BackupManager(baseApis, async () => {\n // try to get key from cache\n const cachedKey = await this.getSessionBackupPrivateKey();\n if (cachedKey) {\n return cachedKey;\n }\n\n // try to get key from secret storage\n const storedKey = await this.getSecret(\"m.megolm_backup.v1\");\n\n if (storedKey) {\n // ensure that the key is in the right format. If not, fix the key and\n // store the fixed version\n const fixedKey = fixBackupKey(storedKey);\n if (fixedKey) {\n const keys = await this.getSecretStorageKey();\n await this.storeSecret(\"m.megolm_backup.v1\", fixedKey, [keys![0]]);\n }\n\n return olmlib.decodeBase64(fixedKey || storedKey);\n }\n\n // try to get key from app\n if (this.baseApis.cryptoCallbacks && this.baseApis.cryptoCallbacks.getBackupKey) {\n return this.baseApis.cryptoCallbacks.getBackupKey();\n }\n\n throw new Error(\"Unable to get private key\");\n });\n\n this.olmDevice = new OlmDevice(cryptoStore);\n this.deviceList = new DeviceList(baseApis, cryptoStore, this.olmDevice);\n\n // XXX: This isn't removed at any point, but then none of the event listeners\n // this class sets seem to be removed at any point... :/\n this.deviceList.on(CryptoEvent.UserCrossSigningUpdated, this.onDeviceListUserCrossSigningUpdated);\n this.reEmitter.reEmit(this.deviceList, [CryptoEvent.DevicesUpdated, CryptoEvent.WillUpdateDevices]);\n\n this.supportedAlgorithms = Array.from(algorithms.DECRYPTION_CLASSES.keys());\n\n this.outgoingRoomKeyRequestManager = new OutgoingRoomKeyRequestManager(\n baseApis,\n this.deviceId,\n this.cryptoStore,\n );\n\n this.toDeviceVerificationRequests = new ToDeviceRequests();\n this.inRoomVerificationRequests = new InRoomRequests();\n\n const cryptoCallbacks = this.baseApis.cryptoCallbacks || {};\n const cacheCallbacks = createCryptoStoreCacheCallbacks(cryptoStore, this.olmDevice);\n\n this.crossSigningInfo = new CrossSigningInfo(userId, cryptoCallbacks, cacheCallbacks);\n // Yes, we pass the client twice here: see SecretStorage\n this.secretStorage = new SecretStorage(baseApis as IAccountDataClient, cryptoCallbacks, baseApis);\n this.dehydrationManager = new DehydrationManager(this);\n\n // Assuming no app-supplied callback, default to getting from SSSS.\n if (!cryptoCallbacks.getCrossSigningKey && cryptoCallbacks.getSecretStorageKey) {\n cryptoCallbacks.getCrossSigningKey = async (type): Promise<Uint8Array | null> => {\n return CrossSigningInfo.getFromSecretStorage(type, this.secretStorage);\n };\n }\n }\n\n /**\n * Initialise the crypto module so that it is ready for use\n *\n * Returns a promise which resolves once the crypto module is ready for use.\n *\n * @param exportedOlmDevice - (Optional) data from exported device\n * that must be re-created.\n */\n public async init({ exportedOlmDevice, pickleKey }: IInitOpts = {}): Promise<void> {\n logger.log(\"Crypto: initialising Olm...\");\n await global.Olm.init();\n logger.log(\n exportedOlmDevice\n ? \"Crypto: initialising Olm device from exported device...\"\n : \"Crypto: initialising Olm device...\",\n );\n await this.olmDevice.init({ fromExportedDevice: exportedOlmDevice, pickleKey });\n logger.log(\"Crypto: loading device list...\");\n await this.deviceList.load();\n\n // build our device keys: these will later be uploaded\n this.deviceKeys[\"ed25519:\" + this.deviceId] = this.olmDevice.deviceEd25519Key!;\n this.deviceKeys[\"curve25519:\" + this.deviceId] = this.olmDevice.deviceCurve25519Key!;\n\n logger.log(\"Crypto: fetching own devices...\");\n let myDevices = this.deviceList.getRawStoredDevicesForUser(this.userId);\n\n if (!myDevices) {\n myDevices = {};\n }\n\n if (!myDevices[this.deviceId]) {\n // add our own deviceinfo to the cryptoStore\n logger.log(\"Crypto: adding this device to the store...\");\n const deviceInfo = {\n keys: this.deviceKeys,\n algorithms: this.supportedAlgorithms,\n verified: DeviceVerification.VERIFIED,\n known: true,\n };\n\n myDevices[this.deviceId] = deviceInfo;\n this.deviceList.storeDevicesForUser(this.userId, myDevices);\n this.deviceList.saveIfDirty();\n }\n\n await this.cryptoStore.doTxn(\"readonly\", [IndexedDBCryptoStore.STORE_ACCOUNT], (txn) => {\n this.cryptoStore.getCrossSigningKeys(txn, (keys) => {\n // can be an empty object after resetting cross-signing keys, see storeTrustedSelfKeys\n if (keys && Object.keys(keys).length !== 0) {\n logger.log(\"Loaded cross-signing public keys from crypto store\");\n this.crossSigningInfo.setKeys(keys);\n }\n });\n });\n // make sure we are keeping track of our own devices\n // (this is important for key backups & things)\n this.deviceList.startTrackingDeviceList(this.userId);\n\n logger.log(\"Crypto: checking for key backup...\");\n this.backupManager.checkAndStart();\n }\n\n /**\n * Whether to trust a others users signatures of their devices.\n * If false, devices will only be considered 'verified' if we have\n * verified that device individually (effectively disabling cross-signing).\n *\n * Default: true\n *\n * @returns True if trusting cross-signed devices\n */\n public getCryptoTrustCrossSignedDevices(): boolean {\n return this.trustCrossSignedDevices;\n }\n\n /**\n * See getCryptoTrustCrossSignedDevices\n\n * This may be set before initCrypto() is called to ensure no races occur.\n *\n * @param val - True to trust cross-signed devices\n */\n public setCryptoTrustCrossSignedDevices(val: boolean): void {\n this.trustCrossSignedDevices = val;\n\n for (const userId of this.deviceList.getKnownUserIds()) {\n const devices = this.deviceList.getRawStoredDevicesForUser(userId);\n for (const deviceId of Object.keys(devices)) {\n const deviceTrust = this.checkDeviceTrust(userId, deviceId);\n // If the device is locally verified then isVerified() is always true,\n // so this will only have caused the value to change if the device is\n // cross-signing verified but not locally verified\n if (!deviceTrust.isLocallyVerified() && deviceTrust.isCrossSigningVerified()) {\n const deviceObj = this.deviceList.getStoredDevice(userId, deviceId)!;\n this.emit(CryptoEvent.DeviceVerificationChanged, userId, deviceId, deviceObj);\n }\n }\n }\n }\n\n /**\n * Create a recovery key from a user-supplied passphrase.\n *\n * @param password - Passphrase string that can be entered by the user\n * when restoring the backup as an alternative to entering the recovery key.\n * Optional.\n * @returns Object with public key metadata, encoded private\n * recovery key which should be disposed of after displaying to the user,\n * and raw private key to avoid round tripping if needed.\n */\n public async createRecoveryKeyFromPassphrase(password?: string): Promise<IRecoveryKey> {\n const decryption = new global.Olm.PkDecryption();\n try {\n const keyInfo: Partial<IRecoveryKey[\"keyInfo\"]> = {};\n if (password) {\n const derivation = await keyFromPassphrase(password);\n keyInfo.passphrase = {\n algorithm: \"m.pbkdf2\",\n iterations: derivation.iterations,\n salt: derivation.salt,\n };\n keyInfo.pubkey = decryption.init_with_private_key(derivation.key);\n } else {\n keyInfo.pubkey = decryption.generate_key();\n }\n const privateKey = decryption.get_private_key();\n const encodedPrivateKey = encodeRecoveryKey(privateKey);\n return {\n keyInfo: keyInfo as IRecoveryKey[\"keyInfo\"],\n encodedPrivateKey,\n privateKey,\n };\n } finally {\n decryption?.free();\n }\n }\n\n /**\n * Checks if the user has previously published cross-signing keys\n *\n * This means downloading the devicelist for the user and checking if the list includes\n * the cross-signing pseudo-device.\n *\n * @internal\n */\n public async userHasCrossSigningKeys(): Promise<boolean> {\n await this.downloadKeys([this.userId]);\n return this.deviceList.getStoredCrossSigningForUser(this.userId) !== null;\n }\n\n /**\n * Checks whether cross signing:\n * - is enabled on this account and trusted by this device\n * - has private keys either cached locally or stored in secret storage\n *\n * If this function returns false, bootstrapCrossSigning() can be used\n * to fix things such that it returns true. That is to say, after\n * bootstrapCrossSigning() completes successfully, this function should\n * return true.\n *\n * The cross-signing API is currently UNSTABLE and may change without notice.\n *\n * @returns True if cross-signing is ready to be used on this device\n */\n public async isCrossSigningReady(): Promise<boolean> {\n const publicKeysOnDevice = this.crossSigningInfo.getId();\n const privateKeysExistSomewhere =\n (await this.crossSigningInfo.isStoredInKeyCache()) ||\n (await this.crossSigningInfo.isStoredInSecretStorage(this.secretStorage));\n\n return !!(publicKeysOnDevice && privateKeysExistSomewhere);\n }\n\n /**\n * Checks whether secret storage:\n * - is enabled on this account\n * - is storing cross-signing private keys\n * - is storing session backup key (if enabled)\n *\n * If this function returns false, bootstrapSecretStorage() can be used\n * to fix things such that it returns true. That is to say, after\n * bootstrapSecretStorage() completes successfully, this function should\n * return true.\n *\n * The Secure Secret Storage API is currently UNSTABLE and may change without notice.\n *\n * @returns True if secret storage is ready to be used on this device\n */\n public async isSecretStorageReady(): Promise<boolean> {\n const secretStorageKeyInAccount = await this.secretStorage.hasKey();\n const privateKeysInStorage = await this.crossSigningInfo.isStoredInSecretStorage(this.secretStorage);\n const sessionBackupInStorage =\n !this.backupManager.getKeyBackupEnabled() || (await this.baseApis.isKeyBackupKeyStored());\n\n return !!(secretStorageKeyInAccount && privateKeysInStorage && sessionBackupInStorage);\n }\n\n /**\n * Bootstrap cross-signing by creating keys if needed. If everything is already\n * set up, then no changes are made, so this is safe to run to ensure\n * cross-signing is ready for use.\n *\n * This function:\n * - creates new cross-signing keys if they are not found locally cached nor in\n * secret storage (if it has been setup)\n *\n * The cross-signing API is currently UNSTABLE and may change without notice.\n *\n * @param authUploadDeviceSigningKeys - Function\n * called to await an interactive auth flow when uploading device signing keys.\n * @param setupNewCrossSigning - Optional. Reset even if keys\n * already exist.\n * Args:\n * A function that makes the request requiring auth. Receives the\n * auth data as an object. Can be called multiple times, first with an empty\n * authDict, to obtain the flows.\n */\n public async bootstrapCrossSigning({\n authUploadDeviceSigningKeys,\n setupNewCrossSigning,\n }: IBootstrapCrossSigningOpts = {}): Promise<void> {\n logger.log(\"Bootstrapping cross-signing\");\n\n const delegateCryptoCallbacks = this.baseApis.cryptoCallbacks;\n const builder = new EncryptionSetupBuilder(this.baseApis.store.accountData, delegateCryptoCallbacks);\n const crossSigningInfo = new CrossSigningInfo(\n this.userId,\n builder.crossSigningCallbacks,\n builder.crossSigningCallbacks,\n );\n\n // Reset the cross-signing keys\n const resetCrossSigning = async (): Promise<void> => {\n crossSigningInfo.resetKeys();\n // Sign master key with device key\n await this.signObject(crossSigningInfo.keys.master);\n\n // Store auth flow helper function, as we need to call it when uploading\n // to ensure we handle auth errors properly.\n builder.addCrossSigningKeys(authUploadDeviceSigningKeys, crossSigningInfo.keys);\n\n // Cross-sign own device\n const device = this.deviceList.getStoredDevice(this.userId, this.deviceId)!;\n const deviceSignature = await crossSigningInfo.signDevice(this.userId, device);\n builder.addKeySignature(this.userId, this.deviceId, deviceSignature!);\n\n // Sign message key backup with cross-signing master key\n if (this.backupManager.backupInfo) {\n await crossSigningInfo.signObject(this.backupManager.backupInfo.auth_data, \"master\");\n builder.addSessionBackup(this.backupManager.backupInfo);\n }\n };\n\n const publicKeysOnDevice = this.crossSigningInfo.getId();\n const privateKeysInCache = await this.crossSigningInfo.isStoredInKeyCache();\n const privateKeysInStorage = await this.crossSigningInfo.isStoredInSecretStorage(this.secretStorage);\n const privateKeysExistSomewhere = privateKeysInCache || privateKeysInStorage;\n\n // Log all relevant state for easier parsing of debug logs.\n logger.log({\n setupNewCrossSigning,\n publicKeysOnDevice,\n privateKeysInCache,\n privateKeysInStorage,\n privateKeysExistSomewhere,\n });\n\n if (!privateKeysExistSomewhere || setupNewCrossSigning) {\n logger.log(\"Cross-signing private keys not found locally or in secret storage, \" + \"creating new keys\");\n // If a user has multiple devices, it important to only call bootstrap\n // as part of some UI flow (and not silently during startup), as they\n // may have setup cross-signing on a platform which has not saved keys\n // to secret storage, and this would reset them. In such a case, you\n // should prompt the user to verify any existing devices first (and\n // request private keys from those devices) before calling bootstrap.\n await resetCrossSigning();\n } else if (publicKeysOnDevice && privateKeysInCache) {\n logger.log(\"Cross-signing public keys trusted and private keys found locally\");\n } else if (privateKeysInStorage) {\n logger.log(\n \"Cross-signing private keys not found locally, but they are available \" +\n \"in secret storage, reading storage and caching locally\",\n );\n await this.checkOwnCrossSigningTrust({\n allowPrivateKeyRequests: true,\n });\n }\n\n // Assuming no app-supplied callback, default to storing new private keys in\n // secret storage if it exists. If it does not, it is assumed this will be\n // done as part of setting up secret storage later.\n const crossSigningPrivateKeys = builder.crossSigningCallbacks.privateKeys;\n if (crossSigningPrivateKeys.size && !this.baseApis.cryptoCallbacks.saveCrossSigningKeys) {\n const secretStorage = new SecretStorage(\n builder.accountDataClientAdapter,\n builder.ssssCryptoCallbacks,\n undefined,\n );\n if (await secretStorage.hasKey()) {\n logger.log(\"Storing new cross-signing private keys in secret storage\");\n // This is writing to in-memory account data in\n // builder.accountDataClientAdapter so won't fail\n await CrossSigningInfo.storeInSecretStorage(crossSigningPrivateKeys, secretStorage);\n }\n }\n\n const operation = builder.buildOperation();\n await operation.apply(this);\n // This persists private keys and public keys as trusted,\n // only do this if apply succeeded for now as retry isn't in place yet\n await builder.persist(this);\n\n logger.log(\"Cross-signing ready\");\n }\n\n /**\n * Bootstrap Secure Secret Storage if needed by creating a default key. If everything is\n * already set up, then no changes are made, so this is safe to run to ensure secret\n * storage is ready for use.\n *\n * This function\n * - creates a new Secure Secret Storage key if no default key exists\n * - if a key backup exists, it is migrated to store the key in the Secret\n * Storage\n * - creates a backup if none exists, and one is requested\n * - migrates Secure Secret Storage to use the latest algorithm, if an outdated\n * algorithm is found\n *\n * The Secure Secret Storage API is currently UNSTABLE and may change without notice.\n *\n * @param createSecretStorageKey - Optional. Function\n * called to await a secret storage key creation flow.\n * Returns a Promise which resolves to an object with public key metadata, encoded private\n * recovery key which should be disposed of after displaying to the user,\n * and raw private key to avoid round tripping if needed.\n * @param keyBackupInfo - The current key backup object. If passed,\n * the passphrase and recovery key from this backup will be used.\n * @param setupNewKeyBackup - If true, a new key backup version will be\n * created and the private key stored in the new SSSS store. Ignored if keyBackupInfo\n * is supplied.\n * @param setupNewSecretStorage - Optional. Reset even if keys already exist.\n * @param getKeyBackupPassphrase - Optional. Function called to get the user's\n * current key backup passphrase. Should return a promise that resolves with a Buffer\n * containing the key, or rejects if the key cannot be obtained.\n * Returns:\n * A promise which resolves to key creation data for\n * SecretStorage#addKey: an object with `passphrase` etc fields.\n */\n // TODO this does not resolve with what it says it does\n public async bootstrapSecretStorage({\n createSecretStorageKey = async (): Promise<IRecoveryKey> => ({} as IRecoveryKey),\n keyBackupInfo,\n setupNewKeyBackup,\n setupNewSecretStorage,\n getKeyBackupPassphrase,\n }: ICreateSecretStorageOpts = {}): Promise<void> {\n logger.log(\"Bootstrapping Secure Secret Storage\");\n const delegateCryptoCallbacks = this.baseApis.cryptoCallbacks;\n const builder = new EncryptionSetupBuilder(this.baseApis.store.accountData, delegateCryptoCallbacks);\n const secretStorage = new SecretStorage(\n builder.accountDataClientAdapter,\n builder.ssssCryptoCallbacks,\n undefined,\n );\n\n // the ID of the new SSSS key, if we create one\n let newKeyId: string | null = null;\n\n // create a new SSSS key and set it as default\n const createSSSS = async (opts: IAddSecretStorageKeyOpts, privateKey?: Uint8Array): Promise<string> => {\n if (privateKey) {\n opts.key = privateKey;\n }\n\n const { keyId, keyInfo } = await secretStorage.addKey(SECRET_STORAGE_ALGORITHM_V1_AES, opts);\n\n if (privateKey) {\n // make the private key available to encrypt 4S secrets\n builder.ssssCryptoCallbacks.addPrivateKey(keyId, keyInfo, privateKey);\n }\n\n await secretStorage.setDefaultKeyId(keyId);\n return keyId;\n };\n\n const ensureCanCheckPassphrase = async (keyId: string, keyInfo: SecretStorageKeyDescription): Promise<void> => {\n if (!keyInfo.mac) {\n const key = await this.baseApis.cryptoCallbacks.getSecretStorageKey?.(\n { keys: { [keyId]: keyInfo } },\n \"\",\n );\n if (key) {\n const privateKey = key[1];\n builder.ssssCryptoCallbacks.addPrivateKey(keyId, keyInfo, privateKey);\n const { iv, mac } = await calculateKeyCheck(privateKey);\n keyInfo.iv = iv;\n keyInfo.mac = mac;\n\n await builder.setAccountData(`m.secret_storage.key.${keyId}`, keyInfo);\n }\n }\n };\n\n const signKeyBackupWithCrossSigning = async (keyBackupAuthData: IKeyBackupInfo[\"auth_data\"]): Promise<void> => {\n if (this.crossSigningInfo.getId() && (await this.crossSigningInfo.isStoredInKeyCache(\"master\"))) {\n try {\n logger.log(\"Adding cross-signing signature to key backup\");\n await this.crossSigningInfo.signObject(keyBackupAuthData, \"master\");\n } catch (e) {\n // This step is not critical (just helpful), so we catch here\n // and continue if it fails.\n logger.error(\"Signing key backup with cross-signing keys failed\", e);\n }\n } else {\n logger.warn(\"Cross-signing keys not available, skipping signature on key backup\");\n }\n };\n\n const oldSSSSKey = await this.getSecretStorageKey();\n const [oldKeyId, oldKeyInfo] = oldSSSSKey || [null, null];\n const storageExists =\n !setupNewSecretStorage && oldKeyInfo && oldKeyInfo.algorithm === SECRET_STORAGE_ALGORITHM_V1_AES;\n\n // Log all relevant state for easier parsing of debug logs.\n logger.log({\n keyBackupInfo,\n setupNewKeyBackup,\n setupNewSecretStorage,\n storageExists,\n oldKeyInfo,\n });\n\n if (!storageExists && !keyBackupInfo) {\n // either we don't have anything, or we've been asked to restart\n // from scratch\n logger.log(\"Secret storage does not exist, creating new storage key\");\n\n // if we already have a usable default SSSS key and aren't resetting\n // SSSS just use it. otherwise, create a new one\n // Note: we leave the old SSSS key in place: there could be other\n // secrets using it, in theory. We could move them to the new key but a)\n // that would mean we'd need to prompt for the old passphrase, and b)\n // it's not clear that would be the right thing to do anyway.\n const { keyInfo = {} as IAddSecretStorageKeyOpts, privateKey } = await createSecretStorageKey();\n newKeyId = await createSSSS(keyInfo, privateKey);\n } else if (!storageExists && keyBackupInfo) {\n // we have an existing backup, but no SSSS\n logger.log(\"Secret storage does not exist, using key backup key\");\n\n // if we have the backup key already cached, use it; otherwise use the\n // callback to prompt for the key\n const backupKey = (await this.getSessionBackupPrivateKey()) || (await getKeyBackupPassphrase?.());\n\n // create a new SSSS key and use the backup key as the new SSSS key\n const opts = {} as IAddSecretStorageKeyOpts;\n\n if (keyBackupInfo.auth_data.private_key_salt && keyBackupInfo.auth_data.private_key_iterations) {\n // FIXME: ???\n opts.passphrase = {\n algorithm: \"m.pbkdf2\",\n iterations: keyBackupInfo.auth_data.private_key_iterations,\n salt: keyBackupInfo.auth_data.private_key_salt,\n bits: 256,\n };\n }\n\n newKeyId = await createSSSS(opts, backupKey);\n\n // store the backup key in secret storage\n await secretStorage.store(\"m.megolm_backup.v1\", olmlib.encodeBase64(backupKey!), [newKeyId]);\n\n // The backup is trusted because the user provided the private key.\n // Sign the backup with the cross-signing key so the key backup can\n // be trusted via cross-signing.\n await signKeyBackupWithCrossSigning(keyBackupInfo.auth_data);\n\n builder.addSessionBackup(keyBackupInfo);\n } else {\n // 4S is already set up\n logger.log(\"Secret storage exists\");\n\n if (oldKeyInfo && oldKeyInfo.algorithm === SECRET_STORAGE_ALGORITHM_V1_AES) {\n // make sure that the default key has the information needed to\n // check the passphrase\n await ensureCanCheckPassphrase(oldKeyId, oldKeyInfo);\n }\n }\n\n // If we have cross-signing private keys cached, store them in secret\n // storage if they are not there already.\n if (\n !this.baseApis.cryptoCallbacks.saveCrossSigningKeys &&\n (await this.isCrossSigningReady()) &&\n (newKeyId || !(await this.crossSigningInfo.isStoredInSecretStorage(secretStorage)))\n ) {\n logger.log(\"Copying cross-signing private keys from cache to secret storage\");\n const crossSigningPrivateKeys = await this.crossSigningInfo.getCrossSigningKeysFromCache();\n // This is writing to in-memory account data in\n // builder.accountDataClientAdapter so won't fail\n await CrossSigningInfo.storeInSecretStorage(crossSigningPrivateKeys, secretStorage);\n }\n\n if (setupNewKeyBackup && !keyBackupInfo) {\n logger.log(\"Creating new message key backup version\");\n const info = await this.baseApis.prepareKeyBackupVersion(\n null /* random key */,\n // don't write to secret storage, as it will write to this.secretStorage.\n // Here, we want to capture all the side-effects of bootstrapping,\n // and want to write to the local secretStorage object\n { secureSecretStorage: false },\n );\n // write the key ourselves to 4S\n const privateKey = decodeRecoveryKey(info.recovery_key);\n await secretStorage.store(\"m.megolm_backup.v1\", olmlib.encodeBase64(privateKey));\n\n // create keyBackupInfo object to add to builder\n const data: IKeyBackupInfo = {\n algorithm: info.algorithm,\n auth_data: info.auth_data,\n };\n\n // Sign with cross-signing master key\n await signKeyBackupWithCrossSigning(data.auth_data);\n\n // sign with the device fingerprint\n await this.signObject(data.auth_data);\n\n builder.addSessionBackup(data);\n }\n\n // Cache the session backup key\n const sessionBackupKey = await secretStorage.get(\"m.megolm_backup.v1\");\n if (sessionBackupKey) {\n logger.info(\"Got session backup key from secret storage: caching\");\n // fix up the backup key if it's in the wrong format, and replace\n // in secret storage\n const fixedBackupKey = fixBackupKey(sessionBackupKey);\n if (fixedBackupKey) {\n const keyId = newKeyId || oldKeyId;\n await secretStorage.store(\"m.megolm_backup.v1\", fixedBackupKey, keyId ? [keyId] : null);\n }\n const decodedBackupKey = new Uint8Array(olmlib.decodeBase64(fixedBackupKey || sessionBackupKey));\n builder.addSessionBackupPrivateKeyToCache(decodedBackupKey);\n } else if (this.backupManager.getKeyBackupEnabled()) {\n // key backup is enabled but we don't have a session backup key in SSSS: see if we have one in\n // the cache or the user can provide one, and if so, write it to SSSS\n const backupKey = (await this.getSessionBackupPrivateKey()) || (await getKeyBackupPassphrase?.());\n if (!backupKey) {\n // This will require user intervention to recover from since we don't have the key\n // backup key anywhere. The user should probably just set up a new key backup and\n // the key for the new backup will be stored. If we hit this scenario in the wild\n // with any frequency, we should do more than just log an error.\n logger.error(\"Key backup is enabled but couldn't get key backup key!\");\n return;\n }\n logger.info(\"Got session backup key from cache/user that wasn't in SSSS: saving to SSSS\");\n await secretStorage.store(\"m.megolm_backup.v1\", olmlib.encodeBase64(backupKey));\n }\n\n const operation = builder.buildOperation();\n await operation.apply(this);\n // this persists private keys and public keys as trusted,\n // only do this if apply succeeded for now as retry isn't in place yet\n await builder.persist(this);\n\n logger.log(\"Secure Secret Storage ready\");\n }\n\n public addSecretStorageKey(\n algorithm: string,\n opts: IAddSecretStorageKeyOpts,\n keyID?: string,\n ): Promise<SecretStorageKeyObject> {\n return this.secretStorage.addKey(algorithm, opts, keyID);\n }\n\n public hasSecretStorageKey(keyID?: string): Promise<boolean> {\n return this.secretStorage.hasKey(keyID);\n }\n\n public getSecretStorageKey(keyID?: string): Promise<SecretStorageKeyTuple | null> {\n return this.secretStorage.getKey(keyID);\n }\n\n public storeSecret(name: string, secret: string, keys?: string[]): Promise<void> {\n return this.secretStorage.store(name, secret, keys);\n }\n\n public getSecret(name: string): Promise<string | undefined> {\n return this.secretStorage.get(name);\n }\n\n public isSecretStored(name: string): Promise<Record<string, SecretStorageKeyDescription> | null> {\n return this.secretStorage.isStored(name);\n }\n\n public requestSecret(name: string, devices: string[]): ISecretRequest {\n if (!devices) {\n devices = Object.keys(this.deviceList.getRawStoredDevicesForUser(this.userId));\n }\n return this.secretStorage.request(name, devices);\n }\n\n public getDefaultSecretStorageKeyId(): Promise<string | null> {\n return this.secretStorage.getDefaultKeyId();\n }\n\n public setDefaultSecretStorageKeyId(k: string): Promise<void> {\n return this.secretStorage.setDefaultKeyId(k);\n }\n\n public checkSecretStorageKey(key: Uint8Array, info: SecretStorageKeyDescription): Promise<boolean> {\n return this.secretStorage.checkKey(key, info);\n }\n\n /**\n * Checks that a given secret storage private key matches a given public key.\n * This can be used by the getSecretStorageKey callback to verify that the\n * private key it is about to supply is the one that was requested.\n *\n * @param privateKey - The private key\n * @param expectedPublicKey - The public key\n * @returns true if the key matches, otherwise false\n */\n public checkSecretStoragePrivateKey(privateKey: Uint8Array, expectedPublicKey: string): boolean {\n let decryption: PkDecryption | null = null;\n try {\n decryption = new global.Olm.PkDecryption();\n const gotPubkey = decryption.init_with_private_key(privateKey);\n // make sure it agrees with the given pubkey\n return gotPubkey === expectedPublicKey;\n } finally {\n decryption?.free();\n }\n }\n\n /**\n * Fetches the backup private key, if cached\n * @returns the key, if any, or null\n */\n public async getSessionBackupPrivateKey(): Promise<Uint8Array | null> {\n let key = await new Promise<any>((resolve) => {\n // TODO types\n this.cryptoStore.doTxn(\"readonly\", [IndexedDBCryptoStore.STORE_ACCOUNT], (txn) => {\n this.cryptoStore.getSecretStorePrivateKey(txn, resolve, \"m.megolm_backup.v1\");\n });\n });\n\n // make sure we have a Uint8Array, rather than a string\n if (key && typeof key === \"string\") {\n key = new Uint8Array(olmlib.decodeBase64(fixBackupKey(key) || key));\n await this.storeSessionBackupPrivateKey(key);\n }\n if (key && key.ciphertext) {\n const pickleKey = Buffer.from(this.olmDevice.pickleKey);\n const decrypted = await decryptAES(key, pickleKey, \"m.megolm_backup.v1\");\n key = olmlib.decodeBase64(decrypted);\n }\n return key;\n }\n\n /**\n * Stores the session backup key to the cache\n * @param key - the private key\n * @returns a promise so you can catch failures\n */\n public async storeSessionBackupPrivateKey(key: ArrayLike<number>): Promise<void> {\n if (!(key instanceof Uint8Array)) {\n // eslint-disable-next-line @typescript-eslint/no-base-to-string\n throw new Error(`storeSessionBackupPrivateKey expects Uint8Array, got ${key}`);\n }\n const pickleKey = Buffer.from(this.olmDevice.pickleKey);\n const encryptedKey = await encryptAES(olmlib.encodeBase64(key), pickleKey, \"m.megolm_backup.v1\");\n return this.cryptoStore.doTxn(\"readwrite\", [IndexedDBCryptoStore.STORE_ACCOUNT], (txn) => {\n this.cryptoStore.storeSecretStorePrivateKey(txn, \"m.megolm_backup.v1\", encryptedKey);\n });\n }\n\n /**\n * Checks that a given cross-signing private key matches a given public key.\n * This can be used by the getCrossSigningKey callback to verify that the\n * private key it is about to supply is the one that was requested.\n *\n * @param privateKey - The private key\n * @param expectedPublicKey - The public key\n * @returns true if the key matches, otherwise false\n */\n public checkCrossSigningPrivateKey(privateKey: Uint8Array, expectedPublicKey: string): boolean {\n let signing: PkSigning | null = null;\n try {\n signing = new global.Olm.PkSigning();\n const gotPubkey = signing.init_with_seed(privateKey);\n // make sure it agrees with the given pubkey\n return gotPubkey === expectedPublicKey;\n } finally {\n signing?.free();\n }\n }\n\n /**\n * Run various follow-up actions after cross-signing keys have changed locally\n * (either by resetting the keys for the account or by getting them from secret\n * storage), such as signing the current device, upgrading device\n * verifications, etc.\n */\n private async afterCrossSigningLocalKeyChange(): Promise<void> {\n logger.info(\"Starting cross-signing key change post-processing\");\n\n // sign the current device with the new key, and upload to the server\n const device = this.deviceList.getStoredDevice(this.userId, this.deviceId)!;\n const signedDevice = await this.crossSigningInfo.signDevice(this.userId, device);\n logger.info(`Starting background key sig upload for ${this.deviceId}`);\n\n const upload = ({ shouldEmit = false }): Promise<void> => {\n return this.baseApis\n .uploadKeySignatures({\n [this.userId]: {\n [this.deviceId]: signedDevice!,\n },\n })\n .then((response) => {\n const { failures } = response || {};\n if (Object.keys(failures || []).length > 0) {\n if (shouldEmit) {\n this.baseApis.emit(\n CryptoEvent.KeySignatureUploadFailure,\n failures,\n \"afterCrossSigningLocalKeyChange\",\n upload, // continuation\n );\n }\n throw new KeySignatureUploadError(\"Key upload failed\", { failures });\n }\n logger.info(`Finished background key sig upload for ${this.deviceId}`);\n })\n .catch((e) => {\n logger.error(`Error during background key sig upload for ${this.deviceId}`, e);\n });\n };\n upload({ shouldEmit: true });\n\n const shouldUpgradeCb = this.baseApis.cryptoCallbacks.shouldUpgradeDeviceVerifications;\n if (shouldUpgradeCb) {\n logger.info(\"Starting device verification upgrade\");\n\n // Check all users for signatures if upgrade callback present\n // FIXME: do this in batches\n const users: Record<string, IDeviceVerificationUpgrade> = {};\n for (const [userId, crossSigningInfo] of Object.entries(this.deviceList.crossSigningInfo)) {\n const upgradeInfo = await this.checkForDeviceVerificationUpgrade(\n userId,\n CrossSigningInfo.fromStorage(crossSigningInfo, userId),\n );\n if (upgradeInfo) {\n users[userId] = upgradeInfo;\n }\n }\n\n if (Object.keys(users).length > 0) {\n logger.info(`Found ${Object.keys(users).length} verif users to upgrade`);\n try {\n const usersToUpgrade = await shouldUpgradeCb({ users: users });\n if (usersToUpgrade) {\n for (const userId of usersToUpgrade) {\n if (userId in users) {\n await this.baseApis.setDeviceVerified(userId, users[userId].crossSigningInfo.getId()!);\n }\n }\n }\n } catch (e) {\n logger.log(\"shouldUpgradeDeviceVerifications threw an error: not upgrading\", e);\n }\n }\n\n logger.info(\"Finished device verification upgrade\");\n }\n\n logger.info(\"Finished cross-signing key change post-processing\");\n }\n\n /**\n * Check if a user's cross-signing key is a candidate for upgrading from device\n * verification.\n *\n * @param userId - the user whose cross-signing information is to be checked\n * @param crossSigningInfo - the cross-signing information to check\n */\n private async checkForDeviceVerificationUpgrade(\n userId: string,\n crossSigningInfo: CrossSigningInfo,\n ): Promise<IDeviceVerificationUpgrade | undefined> {\n // only upgrade if this is the first cross-signing key that we've seen for\n // them, and if their cross-signing key isn't already verified\n const trustLevel = this.crossSigningInfo.checkUserTrust(crossSigningInfo);\n if (crossSigningInfo.firstUse && !trustLevel.isVerified()) {\n const devices = this.deviceList.getRawStoredDevicesForUser(userId);\n const deviceIds = await this.checkForValidDeviceSignature(userId, crossSigningInfo.keys.master, devices);\n if (deviceIds.length) {\n return {\n devices: deviceIds.map((deviceId) => DeviceInfo.fromStorage(devices[deviceId], deviceId)),\n crossSigningInfo,\n };\n }\n }\n }\n\n /**\n * Check if the cross-signing key is signed by a verified device.\n *\n * @param userId - the user ID whose key is being checked\n * @param key - the key that is being checked\n * @param devices - the user's devices. Should be a map from device ID\n * to device info\n */\n private async checkForValidDeviceSignature(\n userId: string,\n key: ICrossSigningKey,\n devices: Record<string, IDevice>,\n ): Promise<string[]> {\n const deviceIds: string[] = [];\n if (devices && key.signatures && key.signatures[userId]) {\n for (const signame of Object.keys(key.signatures[userId])) {\n const [, deviceId] = signame.split(\":\", 2);\n if (deviceId in devices && devices[deviceId].verified === DeviceVerification.VERIFIED) {\n try {\n await olmlib.verifySignature(\n this.olmDevice,\n key,\n userId,\n deviceId,\n devices[deviceId].keys[signame],\n );\n deviceIds.push(deviceId);\n } catch (e) {}\n }\n }\n }\n return deviceIds;\n }\n\n /**\n * Get the user's cross-signing key ID.\n *\n * @param type - The type of key to get the ID of. One of\n * \"master\", \"self_signing\", or \"user_signing\". Defaults to \"master\".\n *\n * @returns the key ID\n */\n public getCrossSigningId(type: string): string | null {\n return this.crossSigningInfo.getId(type);\n }\n\n /**\n * Get the cross signing information for a given user.\n *\n * @param userId - the user ID to get the cross-signing info for.\n *\n * @returns the cross signing information for the user.\n */\n public getStoredCrossSigningForUser(userId: string): CrossSigningInfo | null {\n return this.deviceList.getStoredCrossSigningForUser(userId);\n }\n\n /**\n * Check whether a given user is trusted.\n *\n * @param userId - The ID of the user to check.\n *\n * @returns\n */\n public checkUserTrust(userId: string): UserTrustLevel {\n const userCrossSigning = this.deviceList.getStoredCrossSigningForUser(userId);\n if (!userCrossSigning) {\n return new UserTrustLevel(false, false, false);\n }\n return this.crossSigningInfo.checkUserTrust(userCrossSigning);\n }\n\n /**\n * Check whether a given device is trusted.\n *\n * @param userId - The ID of the user whose devices is to be checked.\n * @param deviceId - The ID of the device to check\n *\n * @returns\n */\n public checkDeviceTrust(userId: string, deviceId: string): DeviceTrustLevel {\n const device = this.deviceList.getStoredDevice(userId, deviceId);\n return this.checkDeviceInfoTrust(userId, device);\n }\n\n /**\n * Check whether a given deviceinfo is trusted.\n *\n * @param userId - The ID of the user whose devices is to be checked.\n * @param device - The device info object to check\n *\n * @returns\n */\n public checkDeviceInfoTrust(userId: string, device?: DeviceInfo): DeviceTrustLevel {\n const trustedLocally = !!device?.isVerified();\n\n const userCrossSigning = this.deviceList.getStoredCrossSigningForUser(userId);\n if (device && userCrossSigning) {\n // The trustCrossSignedDevices only affects trust of other people's cross-signing\n // signatures\n const trustCrossSig = this.trustCrossSignedDevices || userId === this.userId;\n return this.crossSigningInfo.checkDeviceTrust(userCrossSigning, device, trustedLocally, trustCrossSig);\n } else {\n return new DeviceTrustLevel(false, false, trustedLocally, false);\n }\n }\n\n /**\n * Check whether one of our own devices is cross-signed by our\n * user's stored keys, regardless of whether we trust those keys yet.\n *\n * @param deviceId - The ID of the device to check\n *\n * @returns true if the device is cross-signed\n */\n public checkIfOwnDeviceCrossSigned(deviceId: string): boolean {\n const device = this.deviceList.getStoredDevice(this.userId, deviceId);\n if (!device) return false;\n const userCrossSigning = this.deviceList.getStoredCrossSigningForUser(this.userId);\n return (\n userCrossSigning?.checkDeviceTrust(userCrossSigning, device, false, true).isCrossSigningVerified() ?? false\n );\n }\n\n /*\n * Event handler for DeviceList's userNewDevices event\n */\n private onDeviceListUserCrossSigningUpdated = async (userId: string): Promise<void> => {\n if (userId === this.userId) {\n // An update to our own cross-signing key.\n // Get the new key first:\n const newCrossSigning = this.deviceList.getStoredCrossSigningForUser(userId);\n const seenPubkey = newCrossSigning ? newCrossSigning.getId() : null;\n const currentPubkey = this.crossSigningInfo.getId();\n const changed = currentPubkey !== seenPubkey;\n\n if (currentPubkey && seenPubkey && !changed) {\n // If it's not changed, just make sure everything is up to date\n await this.checkOwnCrossSigningTrust();\n } else {\n // We'll now be in a state where cross-signing on the account is not trusted\n // because our locally stored cross-signing keys will not match the ones\n // on the server for our account. So we clear our own stored cross-signing keys,\n // effectively disabling cross-signing until the user gets verified by the device\n // that reset the keys\n this.storeTrustedSelfKeys(null);\n // emit cross-signing has been disabled\n this.emit(CryptoEvent.KeysChanged, {});\n // as the trust for our own user has changed,\n // also emit an event for this\n this.emit(CryptoEvent.UserTrustStatusChanged, this.userId, this.checkUserTrust(userId));\n }\n } else {\n await this.checkDeviceVerifications(userId);\n\n // Update verified before latch using the current state and save the new\n // latch value in the device list store.\n const crossSigning = this.deviceList.getStoredCrossSigningForUser(userId);\n if (crossSigning) {\n crossSigning.updateCrossSigningVerifiedBefore(this.checkUserTrust(userId).isCrossSigningVerified());\n this.deviceList.setRawStoredCrossSigningForUser(userId, crossSigning.toStorage());\n }\n\n this.emit(CryptoEvent.UserTrustStatusChanged, userId, this.checkUserTrust(userId));\n }\n };\n\n /**\n * Check the copy of our cross-signing key that we have in the device list and\n * see if we can get the private key. If so, mark it as trusted.\n */\n public async checkOwnCrossSigningTrust({\n allowPrivateKeyRequests = false,\n }: ICheckOwnCrossSigningTrustOpts = {}): Promise<void> {\n const userId = this.userId;\n\n // Before proceeding, ensure our cross-signing public keys have been\n // downloaded via the device list.\n await this.downloadKeys([this.userId]);\n\n // Also check which private keys are locally cached.\n const crossSigningPrivateKeys = await this.crossSigningInfo.getCrossSigningKeysFromCache();\n\n // If we see an update to our own master key, check it against the master\n // key we have and, if it matches, mark it as verified\n\n // First, get the new cross-signing info\n const newCrossSigning = this.deviceList.getStoredCrossSigningForUser(userId);\n if (!newCrossSigning) {\n logger.error(\n \"Got cross-signing update event for user \" + userId + \" but no new cross-signing information found!\",\n );\n return;\n }\n\n const seenPubkey = newCrossSigning.getId()!;\n const masterChanged = this.crossSigningInfo.getId() !== seenPubkey;\n const masterExistsNotLocallyCached = newCrossSigning.getId() && !crossSigningPrivateKeys.has(\"master\");\n if (masterChanged) {\n logger.info(\"Got new master public key\", seenPubkey);\n }\n if (allowPrivateKeyRequests && (masterChanged || masterExistsNotLocallyCached)) {\n logger.info(\"Attempting to retrieve cross-signing master private key\");\n let signing: PkSigning | null = null;\n // It's important for control flow that we leave any errors alone for\n // higher levels to handle so that e.g. cancelling access properly\n // aborts any larger operation as well.\n try {\n const ret = await this.crossSigningInfo.getCrossSigningKey(\"master\", seenPubkey);\n signing = ret[1];\n logger.info(\"Got cross-signing master private key\");\n } finally {\n signing?.free();\n }\n }\n\n const oldSelfSigningId = this.crossSigningInfo.getId(\"self_signing\");\n const oldUserSigningId = this.crossSigningInfo.getId(\"user_signing\");\n\n // Update the version of our keys in our cross-signing object and the local store\n this.storeTrustedSelfKeys(newCrossSigning.keys);\n\n const selfSigningChanged = oldSelfSigningId !== newCrossSigning.getId(\"self_signing\");\n const userSigningChanged = oldUserSigningId !== newCrossSigning.getId(\"user_signing\");\n\n const selfSigningExistsNotLocallyCached =\n newCrossSigning.getId(\"self_signing\") && !crossSigningPrivateKeys.has(\"self_signing\");\n const userSigningExistsNotLocallyCached =\n newCrossSigning.getId(\"user_signing\") && !crossSigningPrivateKeys.has(\"user_signing\");\n\n const keySignatures: Record<string, ISignedKey> = {};\n\n if (selfSigningChanged) {\n logger.info(\"Got new self-signing key\", newCrossSigning.getId(\"self_signing\"));\n }\n if (allowPrivateKeyRequests && (selfSigningChanged || selfSigningExistsNotLocallyCached)) {\n logger.info(\"Attempting to retrieve cross-signing self-signing private key\");\n let signing: PkSigning | null = null;\n try {\n const ret = await this.crossSigningInfo.getCrossSigningKey(\n \"self_signing\",\n newCrossSigning.getId(\"self_signing\")!,\n );\n signing = ret[1];\n logger.info(\"Got cross-signing self-signing private key\");\n } finally {\n signing?.free();\n }\n\n const device = this.deviceList.getStoredDevice(this.userId, this.deviceId)!;\n const signedDevice = await this.crossSigningInfo.signDevice(this.userId, device);\n keySignatures[this.deviceId] = signedDevice!;\n }\n if (userSigningChanged) {\n logger.info(\"Got new user-signing key\", newCrossSigning.getId(\"user_signing\"));\n }\n if (allowPrivateKeyRequests && (userSigningChanged || userSigningExistsNotLocallyCached)) {\n logger.info(\"Attempting to retrieve cross-signing user-signing private key\");\n let signing: PkSigning | null = null;\n try {\n const ret = await this.crossSigningInfo.getCrossSigningKey(\n \"user_signing\",\n newCrossSigning.getId(\"user_signing\")!,\n );\n signing = ret[1];\n logger.info(\"Got cross-signing user-signing private key\");\n } finally {\n signing?.free();\n }\n }\n\n if (masterChanged) {\n const masterKey = this.crossSigningInfo.keys.master;\n await this.signObject(masterKey);\n const deviceSig = masterKey.signatures![this.userId][\"ed25519:\" + this.deviceId];\n // Include only the _new_ device signature in the upload.\n // We may have existing signatures from deleted devices, which will cause\n // the entire upload to fail.\n keySignatures[this.crossSigningInfo.getId()!] = Object.assign({} as ISignedKey, masterKey, {\n signatures: {\n [this.userId]: {\n [\"ed25519:\" + this.deviceId]: deviceSig,\n },\n },\n });\n }\n\n const keysToUpload = Object.keys(keySignatures);\n if (keysToUpload.length) {\n const upload = ({ shouldEmit = false }): Promise<void> => {\n logger.info(`Starting background key sig upload for ${keysToUpload}`);\n return this.baseApis\n .uploadKeySignatures({ [this.userId]: keySignatures })\n .then((response) => {\n const { failures } = response || {};\n logger.info(`Finished background key sig upload for ${keysToUpload}`);\n if (Object.keys(failures || []).length > 0) {\n if (shouldEmit) {\n this.baseApis.emit(\n CryptoEvent.KeySignatureUploadFailure,\n failures,\n \"checkOwnCrossSigningTrust\",\n upload,\n );\n }\n throw new KeySignatureUploadError(\"Key upload failed\", { failures });\n }\n })\n .catch((e) => {\n logger.error(`Error during background key sig upload for ${keysToUpload}`, e);\n });\n };\n upload({ shouldEmit: true });\n }\n\n this.emit(CryptoEvent.UserTrustStatusChanged, userId, this.checkUserTrust(userId));\n\n if (masterChanged) {\n this.emit(CryptoEvent.KeysChanged, {});\n await this.afterCrossSigningLocalKeyChange();\n }\n\n // Now we may be able to trust our key backup\n await this.backupManager.checkKeyBackup();\n // FIXME: if we previously trusted the backup, should we automatically sign\n // the backup with the new key (if not already signed)?\n }\n\n /**\n * Store a set of keys as our own, trusted, cross-signing keys.\n *\n * @param keys - The new trusted set of keys\n */\n private async storeTrustedSelfKeys(keys: Record<string, ICrossSigningKey> | null): Promise<void> {\n if (keys) {\n this.crossSigningInfo.setKeys(keys);\n } else {\n this.crossSigningInfo.clearKeys();\n }\n await this.cryptoStore.doTxn(\"readwrite\", [IndexedDBCryptoStore.STORE_ACCOUNT], (txn) => {\n this.cryptoStore.storeCrossSigningKeys(txn, this.crossSigningInfo.keys);\n });\n }\n\n /**\n * Check if the master key is signed by a verified device, and if so, prompt\n * the application to mark it as verified.\n *\n * @param userId - the user ID whose key should be checked\n */\n private async checkDeviceVerifications(userId: string): Promise<void> {\n const shouldUpgradeCb = this.baseApis.cryptoCallbacks.shouldUpgradeDeviceVerifications;\n if (!shouldUpgradeCb) {\n // Upgrading skipped when callback is not present.\n return;\n }\n logger.info(`Starting device verification upgrade for ${userId}`);\n if (this.crossSigningInfo.keys.user_signing) {\n const crossSigningInfo = this.deviceList.getStoredCrossSigningForUser(userId);\n if (crossSigningInfo) {\n const upgradeInfo = await this.checkForDeviceVerificationUpgrade(userId, crossSigningInfo);\n if (upgradeInfo) {\n const usersToUpgrade = await shouldUpgradeCb({\n users: {\n [userId]: upgradeInfo,\n },\n });\n if (usersToUpgrade.includes(userId)) {\n await this.baseApis.setDeviceVerified(userId, crossSigningInfo.getId()!);\n }\n }\n }\n }\n logger.info(`Finished device verification upgrade for ${userId}`);\n }\n\n /**\n */\n public enableLazyLoading(): void {\n this.lazyLoadMembers = true;\n }\n\n /**\n * Tell the crypto module to register for MatrixClient events which it needs to\n * listen for\n *\n * @param eventEmitter - event source where we can register\n * for event notifications\n */\n public registerEventHandlers(\n eventEmitter: TypedEventEmitter<\n RoomMemberEvent.Membership | ClientEvent.ToDeviceEvent | RoomEvent.Timeline | MatrixEventEvent.Decrypted,\n any\n >,\n ): void {\n eventEmitter.on(RoomMemberEvent.Membership, this.onMembership);\n eventEmitter.on(ClientEvent.ToDeviceEvent, this.onToDeviceEvent);\n eventEmitter.on(RoomEvent.Timeline, this.onTimelineEvent);\n eventEmitter.on(MatrixEventEvent.Decrypted, this.onTimelineEvent);\n }\n\n /**\n * @deprecated this does nothing and will be removed in a future version\n */\n public start(): void {\n logger.warn(\"MatrixClient.crypto.start() is deprecated\");\n }\n\n /** Stop background processes related to crypto */\n public stop(): void {\n this.outgoingRoomKeyRequestManager.stop();\n this.deviceList.stop();\n this.dehydrationManager.stop();\n }\n\n /**\n * Get the Ed25519 key for this device\n *\n * @returns base64-encoded ed25519 key.\n */\n public getDeviceEd25519Key(): string | null {\n return this.olmDevice.deviceEd25519Key;\n }\n\n /**\n * Get the Curve25519 key for this device\n *\n * @returns base64-encoded curve25519 key.\n */\n public getDeviceCurve25519Key(): string | null {\n return this.olmDevice.deviceCurve25519Key;\n }\n\n /**\n * Set the global override for whether the client should ever send encrypted\n * messages to unverified devices. This provides the default for rooms which\n * do not specify a value.\n *\n * @param value - whether to blacklist all unverified devices by default\n *\n * @deprecated For external code, use {@link MatrixClient#setGlobalBlacklistUnverifiedDevices}. For\n * internal code, set {@link MatrixClient#globalBlacklistUnverifiedDevices} directly.\n */\n public setGlobalBlacklistUnverifiedDevices(value: boolean): void {\n this.globalBlacklistUnverifiedDevices = value;\n }\n\n /**\n * @returns whether to blacklist all unverified devices by default\n *\n * @deprecated For external code, use {@link MatrixClient#getGlobalBlacklistUnverifiedDevices}. For\n * internal code, reference {@link MatrixClient#globalBlacklistUnverifiedDevices} directly.\n */\n public getGlobalBlacklistUnverifiedDevices(): boolean {\n return this.globalBlacklistUnverifiedDevices;\n }\n\n /**\n * Upload the device keys to the homeserver.\n * @returns A promise that will resolve when the keys are uploaded.\n */\n public uploadDeviceKeys(): Promise<IKeysUploadResponse> {\n const deviceKeys = {\n algorithms: this.supportedAlgorithms,\n device_id: this.deviceId,\n keys: this.deviceKeys,\n user_id: this.userId,\n };\n\n return this.signObject(deviceKeys).then(() => {\n return this.baseApis.uploadKeysRequest({\n device_keys: deviceKeys as Required<IDeviceKeys>,\n });\n });\n }\n\n /**\n * Stores the current one_time_key count which will be handled later (in a call of\n * onSyncCompleted). The count is e.g. coming from a /sync response.\n *\n * @param currentCount - The current count of one_time_keys to be stored\n */\n public updateOneTimeKeyCount(currentCount: number): void {\n if (isFinite(currentCount)) {\n this.oneTimeKeyCount = currentCount;\n } else {\n throw new TypeError(\"Parameter for updateOneTimeKeyCount has to be a number\");\n }\n }\n\n public setNeedsNewFallback(needsNewFallback: boolean): void {\n this.needsNewFallback = needsNewFallback;\n }\n\n public getNeedsNewFallback(): boolean {\n return !!this.needsNewFallback;\n }\n\n // check if it's time to upload one-time keys, and do so if so.\n private maybeUploadOneTimeKeys(): void {\n // frequency with which to check & upload one-time keys\n const uploadPeriod = 1000 * 60; // one minute\n\n // max number of keys to upload at once\n // Creating keys can be an expensive operation so we limit the\n // number we generate in one go to avoid blocking the application\n // for too long.\n const maxKeysPerCycle = 5;\n\n if (this.oneTimeKeyCheckInProgress) {\n return;\n }\n\n const now = Date.now();\n if (this.lastOneTimeKeyCheck !== null && now - this.lastOneTimeKeyCheck < uploadPeriod) {\n // we've done a key upload recently.\n return;\n }\n\n this.lastOneTimeKeyCheck = now;\n\n // We need to keep a pool of one time public keys on the server so that\n // other devices can start conversations with us. But we can only store\n // a finite number of private keys in the olm Account object.\n // To complicate things further then can be a delay between a device\n // claiming a public one time key from the server and it sending us a\n // message. We need to keep the corresponding private key locally until\n // we receive the message.\n // But that message might never arrive leaving us stuck with duff\n // private keys clogging up our local storage.\n // So we need some kind of engineering compromise to balance all of\n // these factors.\n\n // Check how many keys we can store in the Account object.\n const maxOneTimeKeys = this.olmDevice.maxNumberOfOneTimeKeys();\n // Try to keep at most half that number on the server. This leaves the\n // rest of the slots free to hold keys that have been claimed from the\n // server but we haven't received a message for.\n // If we run out of slots when generating new keys then olm will\n // discard the oldest private keys first. This will eventually clean\n // out stale private keys that won't receive a message.\n const keyLimit = Math.floor(maxOneTimeKeys / 2);\n\n const uploadLoop = async (keyCount: number): Promise<void> => {\n while (keyLimit > keyCount || this.getNeedsNewFallback()) {\n // Ask olm to generate new one time keys, then upload them to synapse.\n if (keyLimit > keyCount) {\n logger.info(\"generating oneTimeKeys\");\n const keysThisLoop = Math.min(keyLimit - keyCount, maxKeysPerCycle);\n await this.olmDevice.generateOneTimeKeys(keysThisLoop);\n }\n\n if (this.getNeedsNewFallback()) {\n const fallbackKeys = await this.olmDevice.getFallbackKey();\n // if fallbackKeys is non-empty, we've already generated a\n // fallback key, but it hasn't been published yet, so we\n // can use that instead of generating a new one\n if (!fallbackKeys.curve25519 || Object.keys(fallbackKeys.curve25519).length == 0) {\n logger.info(\"generating fallback key\");\n if (this.fallbackCleanup) {\n // cancel any pending fallback cleanup because generating\n // a new fallback key will already drop the old fallback\n // that would have been dropped, and we don't want to kill\n // the current key\n clearTimeout(this.fallbackCleanup);\n delete this.fallbackCleanup;\n }\n await this.olmDevice.generateFallbackKey();\n }\n }\n\n logger.info(\"calling uploadOneTimeKeys\");\n const res = await this.uploadOneTimeKeys();\n if (res.one_time_key_counts && res.one_time_key_counts.signed_curve25519) {\n // if the response contains a more up to date value use this\n // for the next loop\n keyCount = res.one_time_key_counts.signed_curve25519;\n } else {\n throw new Error(\n \"response for uploading keys does not contain \" + \"one_time_key_counts.signed_curve25519\",\n );\n }\n }\n };\n\n this.oneTimeKeyCheckInProgress = true;\n Promise.resolve()\n .then(() => {\n if (this.oneTimeKeyCount !== undefined) {\n // We already have the current one_time_key count from a /sync response.\n // Use this value instead of asking the server for the current key count.\n return Promise.resolve(this.oneTimeKeyCount);\n }\n // ask the server how many keys we have\n return this.baseApis.uploadKeysRequest({}).then((res) => {\n return res.one_time_key_counts.signed_curve25519 || 0;\n });\n })\n .then((keyCount) => {\n // Start the uploadLoop with the current keyCount. The function checks if\n // we need to upload new keys or not.\n // If there are too many keys on the server then we don't need to\n // create any more keys.\n return uploadLoop(keyCount);\n })\n .catch((e) => {\n logger.error(\"Error uploading one-time keys\", e.stack || e);\n })\n .finally(() => {\n // reset oneTimeKeyCount to prevent start uploading based on old data.\n // it will be set again on the next /sync-response\n this.oneTimeKeyCount = undefined;\n this.oneTimeKeyCheckInProgress = false;\n });\n }\n\n // returns a promise which resolves to the response\n private async uploadOneTimeKeys(): Promise<IKeysUploadResponse> {\n const promises: Promise<unknown>[] = [];\n\n let fallbackJson: Record<string, IOneTimeKey> | undefined;\n if (this.getNeedsNewFallback()) {\n fallbackJson = {};\n const fallbackKeys = await this.olmDevice.getFallbackKey();\n for (const [keyId, key] of Object.entries(fallbackKeys.curve25519)) {\n const k = { key, fallback: true };\n fallbackJson[\"signed_curve25519:\" + keyId] = k;\n promises.push(this.signObject(k));\n }\n this.setNeedsNewFallback(false);\n }\n\n const oneTimeKeys = await this.olmDevice.getOneTimeKeys();\n const oneTimeJson: Record<string, { key: string }> = {};\n\n for (const keyId in oneTimeKeys.curve25519) {\n if (oneTimeKeys.curve25519.hasOwnProperty(keyId)) {\n const k = {\n key: oneTimeKeys.curve25519[keyId],\n };\n oneTimeJson[\"signed_curve25519:\" + keyId] = k;\n promises.push(this.signObject(k));\n }\n }\n\n await Promise.all(promises);\n\n const requestBody: Record<string, any> = {\n one_time_keys: oneTimeJson,\n };\n\n if (fallbackJson) {\n requestBody[\"org.matrix.msc2732.fallback_keys\"] = fallbackJson;\n requestBody[\"fallback_keys\"] = fallbackJson;\n }\n\n const res = await this.baseApis.uploadKeysRequest(requestBody);\n\n if (fallbackJson) {\n this.fallbackCleanup = setTimeout(() => {\n delete this.fallbackCleanup;\n this.olmDevice.forgetOldFallbackKey();\n }, 60 * 60 * 1000);\n }\n\n await this.olmDevice.markKeysAsPublished();\n return res;\n }\n\n /**\n * Download the keys for a list of users and stores the keys in the session\n * store.\n * @param userIds - The users to fetch.\n * @param forceDownload - Always download the keys even if cached.\n *\n * @returns A promise which resolves to a map `userId->deviceId->{@link DeviceInfo}`.\n */\n public downloadKeys(userIds: string[], forceDownload?: boolean): Promise<DeviceInfoMap> {\n return this.deviceList.downloadKeys(userIds, !!forceDownload);\n }\n\n /**\n * Get the stored device keys for a user id\n *\n * @param userId - the user to list keys for.\n *\n * @returns list of devices, or null if we haven't\n * managed to get a list of devices for this user yet.\n */\n public getStoredDevicesForUser(userId: string): Array<DeviceInfo> | null {\n return this.deviceList.getStoredDevicesForUser(userId);\n }\n\n /**\n * Get the stored keys for a single device\n *\n *\n * @returns device, or undefined\n * if we don't know about this device\n */\n public getStoredDevice(userId: string, deviceId: string): DeviceInfo | undefined {\n return this.deviceList.getStoredDevice(userId, deviceId);\n }\n\n /**\n * Save the device list, if necessary\n *\n * @param delay - Time in ms before which the save actually happens.\n * By default, the save is delayed for a short period in order to batch\n * multiple writes, but this behaviour can be disabled by passing 0.\n *\n * @returns true if the data was saved, false if\n * it was not (eg. because no changes were pending). The promise\n * will only resolve once the data is saved, so may take some time\n * to resolve.\n */\n public saveDeviceList(delay: number): Promise<boolean> {\n return this.deviceList.saveIfDirty(delay);\n }\n\n /**\n * Update the blocked/verified state of the given device\n *\n * @param userId - owner of the device\n * @param deviceId - unique identifier for the device or user's\n * cross-signing public key ID.\n *\n * @param verified - whether to mark the device as verified. Null to\n * leave unchanged.\n *\n * @param blocked - whether to mark the device as blocked. Null to\n * leave unchanged.\n *\n * @param known - whether to mark that the user has been made aware of\n * the existence of this device. Null to leave unchanged\n *\n * @param keys - The list of keys that was present\n * during the device verification. This will be double checked with the list\n * of keys the given device has currently.\n *\n * @returns updated DeviceInfo\n */\n public async setDeviceVerification(\n userId: string,\n deviceId: string,\n verified: boolean | null = null,\n blocked: boolean | null = null,\n known: boolean | null = null,\n keys?: Record<string, string>,\n ): Promise<DeviceInfo | CrossSigningInfo> {\n // Check if the 'device' is actually a cross signing key\n // The js-sdk's verification treats cross-signing keys as devices\n // and so uses this method to mark them verified.\n const xsk = this.deviceList.getStoredCrossSigningForUser(userId);\n if (xsk && xsk.getId() === deviceId) {\n if (blocked !== null || known !== null) {\n throw new Error(\"Cannot set blocked or known for a cross-signing key\");\n }\n if (!verified) {\n throw new Error(\"Cannot set a cross-signing key as unverified\");\n }\n const gotKeyId = keys ? Object.values(keys)[0] : null;\n if (keys && (Object.values(keys).length !== 1 || gotKeyId !== xsk.getId())) {\n throw new Error(`Key did not match expected value: expected ${xsk.getId()}, got ${gotKeyId}`);\n }\n\n if (!this.crossSigningInfo.getId() && userId === this.crossSigningInfo.userId) {\n this.storeTrustedSelfKeys(xsk.keys);\n // This will cause our own user trust to change, so emit the event\n this.emit(CryptoEvent.UserTrustStatusChanged, this.userId, this.checkUserTrust(userId));\n }\n\n // Now sign the master key with our user signing key (unless it's ourself)\n if (userId !== this.userId) {\n logger.info(\"Master key \" + xsk.getId() + \" for \" + userId + \" marked verified. Signing...\");\n const device = await this.crossSigningInfo.signUser(xsk);\n if (device) {\n const upload = async ({ shouldEmit = false }): Promise<void> => {\n logger.info(\"Uploading signature for \" + userId + \"...\");\n const response = await this.baseApis.uploadKeySignatures({\n [userId]: {\n [deviceId]: device,\n },\n });\n const { failures } = response || {};\n if (Object.keys(failures || []).length > 0) {\n if (shouldEmit) {\n this.baseApis.emit(\n CryptoEvent.KeySignatureUploadFailure,\n failures,\n \"setDeviceVerification\",\n upload,\n );\n }\n /* Throwing here causes the process to be cancelled and the other\n * user to be notified */\n throw new KeySignatureUploadError(\"Key upload failed\", { failures });\n }\n };\n await upload({ shouldEmit: true });\n\n // This will emit events when it comes back down the sync\n // (we could do local echo to speed things up)\n }\n return device as any; // TODO types\n } else {\n return xsk;\n }\n }\n\n const devices = this.deviceList.getRawStoredDevicesForUser(userId);\n if (!devices || !devices[deviceId]) {\n throw new Error(\"Unknown device \" + userId + \":\" + deviceId);\n }\n\n const dev = devices[deviceId];\n let verificationStatus = dev.verified;\n\n if (verified) {\n if (keys) {\n for (const [keyId, key] of Object.entries(keys)) {\n if (dev.keys[keyId] !== key) {\n throw new Error(`Key did not match expected value: expected ${key}, got ${dev.keys[keyId]}`);\n }\n }\n }\n verificationStatus = DeviceVerification.VERIFIED;\n } else if (verified !== null && verificationStatus == DeviceVerification.VERIFIED) {\n verificationStatus = DeviceVerification.UNVERIFIED;\n }\n\n if (blocked) {\n verificationStatus = DeviceVerification.BLOCKED;\n } else if (blocked !== null && verificationStatus == DeviceVerification.BLOCKED) {\n verificationStatus = DeviceVerification.UNVERIFIED;\n }\n\n let knownStatus = dev.known;\n if (known !== null) {\n knownStatus = known;\n }\n\n if (dev.verified !== verificationStatus || dev.known !== knownStatus) {\n dev.verified = verificationStatus;\n dev.known = knownStatus;\n this.deviceList.storeDevicesForUser(userId, devices);\n this.deviceList.saveIfDirty();\n }\n\n // do cross-signing\n if (verified && userId === this.userId) {\n logger.info(\"Own device \" + deviceId + \" marked verified: signing\");\n\n // Signing only needed if other device not already signed\n let device: ISignedKey | undefined;\n const deviceTrust = this.checkDeviceTrust(userId, deviceId);\n if (deviceTrust.isCrossSigningVerified()) {\n logger.log(`Own device ${deviceId} already cross-signing verified`);\n } else {\n device = (await this.crossSigningInfo.signDevice(userId, DeviceInfo.fromStorage(dev, deviceId)))!;\n }\n\n if (device) {\n const upload = async ({ shouldEmit = false }): Promise<void> => {\n logger.info(\"Uploading signature for \" + deviceId);\n const response = await this.baseApis.uploadKeySignatures({\n [userId]: {\n [deviceId]: device!,\n },\n });\n const { failures } = response || {};\n if (Object.keys(failures || []).length > 0) {\n if (shouldEmit) {\n this.baseApis.emit(\n CryptoEvent.KeySignatureUploadFailure,\n failures,\n \"setDeviceVerification\",\n upload, // continuation\n );\n }\n throw new KeySignatureUploadError(\"Key upload failed\", { failures });\n }\n };\n await upload({ shouldEmit: true });\n // XXX: we'll need to wait for the device list to be updated\n }\n }\n\n const deviceObj = DeviceInfo.fromStorage(dev, deviceId);\n this.emit(CryptoEvent.DeviceVerificationChanged, userId, deviceId, deviceObj);\n return deviceObj;\n }\n\n public findVerificationRequestDMInProgress(roomId: string): VerificationRequest | undefined {\n return this.inRoomVerificationRequests.findRequestInProgress(roomId);\n }\n\n public getVerificationRequestsToDeviceInProgress(userId: string): VerificationRequest[] {\n return this.toDeviceVerificationRequests.getRequestsInProgress(userId);\n }\n\n public requestVerificationDM(userId: string, roomId: string): Promise<VerificationRequest> {\n const existingRequest = this.inRoomVerificationRequests.findRequestInProgress(roomId);\n if (existingRequest) {\n return Promise.resolve(existingRequest);\n }\n const channel = new InRoomChannel(this.baseApis, roomId, userId);\n return this.requestVerificationWithChannel(userId, channel, this.inRoomVerificationRequests);\n }\n\n public requestVerification(userId: string, devices?: string[]): Promise<VerificationRequest> {\n if (!devices) {\n devices = Object.keys(this.deviceList.getRawStoredDevicesForUser(userId));\n }\n const existingRequest = this.toDeviceVerificationRequests.findRequestInProgress(userId, devices);\n if (existingRequest) {\n return Promise.resolve(existingRequest);\n }\n const channel = new ToDeviceChannel(this.baseApis, userId, devices, ToDeviceChannel.makeTransactionId());\n return this.requestVerificationWithChannel(userId, channel, this.toDeviceVerificationRequests);\n }\n\n private async requestVerificationWithChannel(\n userId: string,\n channel: IVerificationChannel,\n requestsMap: IRequestsMap,\n ): Promise<VerificationRequest> {\n let request = new VerificationRequest(channel, this.verificationMethods, this.baseApis);\n // if transaction id is already known, add request\n if (channel.transactionId) {\n requestsMap.setRequestByChannel(channel, request);\n }\n await request.sendRequest();\n // don't replace the request created by a racing remote echo\n const racingRequest = requestsMap.getRequestByChannel(channel);\n if (racingRequest) {\n request = racingRequest;\n } else {\n logger.log(\n `Crypto: adding new request to ` + `requestsByTxnId with id ${channel.transactionId} ${channel.roomId}`,\n );\n requestsMap.setRequestByChannel(channel, request);\n }\n return request;\n }\n\n public beginKeyVerification(\n method: string,\n userId: string,\n deviceId: string,\n transactionId: string | null = null,\n ): VerificationBase<any, any> {\n let request: Request | undefined;\n if (transactionId) {\n request = this.toDeviceVerificationRequests.getRequestBySenderAndTxnId(userId, transactionId);\n if (!request) {\n throw new Error(`No request found for user ${userId} with ` + `transactionId ${transactionId}`);\n }\n } else {\n transactionId = ToDeviceChannel.makeTransactionId();\n const channel = new ToDeviceChannel(this.baseApis, userId, [deviceId], transactionId, deviceId);\n request = new VerificationRequest(channel, this.verificationMethods, this.baseApis);\n this.toDeviceVerificationRequests.setRequestBySenderAndTxnId(userId, transactionId, request);\n }\n return request.beginKeyVerification(method, { userId, deviceId });\n }\n\n public async legacyDeviceVerification(\n userId: string,\n deviceId: string,\n method: VerificationMethod,\n ): Promise<VerificationRequest> {\n const transactionId = ToDeviceChannel.makeTransactionId();\n const channel = new ToDeviceChannel(this.baseApis, userId, [deviceId], transactionId, deviceId);\n const request = new VerificationRequest(channel, this.verificationMethods, this.baseApis);\n this.toDeviceVerificationRequests.setRequestBySenderAndTxnId(userId, transactionId, request);\n const verifier = request.beginKeyVerification(method, { userId, deviceId });\n // either reject by an error from verify() while sending .start\n // or resolve when the request receives the\n // local (fake remote) echo for sending the .start event\n await Promise.race([verifier.verify(), request.waitFor((r) => r.started)]);\n return request;\n }\n\n /**\n * Get information on the active olm sessions with a user\n * <p>\n * Returns a map from device id to an object with keys 'deviceIdKey' (the\n * device's curve25519 identity key) and 'sessions' (an array of objects in the\n * same format as that returned by\n * {@link OlmDevice#getSessionInfoForDevice}).\n * <p>\n * This method is provided for debugging purposes.\n *\n * @param userId - id of user to inspect\n */\n public async getOlmSessionsForUser(userId: string): Promise<Record<string, IUserOlmSession>> {\n const devices = this.getStoredDevicesForUser(userId) || [];\n const result: { [deviceId: string]: IUserOlmSession } = {};\n for (const device of devices) {\n const deviceKey = device.getIdentityKey();\n const sessions = await this.olmDevice.getSessionInfoForDevice(deviceKey);\n\n result[device.deviceId] = {\n deviceIdKey: deviceKey,\n sessions: sessions,\n };\n }\n return result;\n }\n\n /**\n * Get the device which sent an event\n *\n * @param event - event to be checked\n */\n public getEventSenderDeviceInfo(event: MatrixEvent): DeviceInfo | null {\n const senderKey = event.getSenderKey();\n const algorithm = event.getWireContent().algorithm;\n\n if (!senderKey || !algorithm) {\n return null;\n }\n\n if (event.isKeySourceUntrusted()) {\n // we got the key for this event from a source that we consider untrusted\n return null;\n }\n\n // senderKey is the Curve25519 identity key of the device which the event\n // was sent from. In the case of Megolm, it's actually the Curve25519\n // identity key of the device which set up the Megolm session.\n\n const device = this.deviceList.getDeviceByIdentityKey(algorithm, senderKey);\n\n if (device === null) {\n // we haven't downloaded the details of this device yet.\n return null;\n }\n\n // so far so good, but now we need to check that the sender of this event\n // hadn't advertised someone else's Curve25519 key as their own. We do that\n // by checking the Ed25519 claimed by the event (or, in the case of megolm,\n // the event which set up the megolm session), to check that it matches the\n // fingerprint of the purported sending device.\n //\n // (see https://github.com/vector-im/vector-web/issues/2215)\n\n const claimedKey = event.getClaimedEd25519Key();\n if (!claimedKey) {\n logger.warn(\"Event \" + event.getId() + \" claims no ed25519 key: \" + \"cannot verify sending device\");\n return null;\n }\n\n if (claimedKey !== device.getFingerprint()) {\n logger.warn(\n \"Event \" +\n event.getId() +\n \" claims ed25519 key \" +\n claimedKey +\n \" but sender device has key \" +\n device.getFingerprint(),\n );\n return null;\n }\n\n return device;\n }\n\n /**\n * Get information about the encryption of an event\n *\n * @param event - event to be checked\n *\n * @returns An object with the fields:\n * - encrypted: whether the event is encrypted (if not encrypted, some of the\n * other properties may not be set)\n * - senderKey: the sender's key\n * - algorithm: the algorithm used to encrypt the event\n * - authenticated: whether we can be sure that the owner of the senderKey\n * sent the event\n * - sender: the sender's device information, if available\n * - mismatchedSender: if the event's ed25519 and curve25519 keys don't match\n * (only meaningful if `sender` is set)\n */\n public getEventEncryptionInfo(event: MatrixEvent): IEncryptedEventInfo {\n const ret: Partial<IEncryptedEventInfo> = {};\n\n ret.senderKey = event.getSenderKey() ?? undefined;\n ret.algorithm = event.getWireContent().algorithm;\n\n if (!ret.senderKey || !ret.algorithm) {\n ret.encrypted = false;\n return ret as IEncryptedEventInfo;\n }\n ret.encrypted = true;\n\n if (event.isKeySourceUntrusted()) {\n // we got the key this event from somewhere else\n // TODO: check if we can trust the forwarders.\n ret.authenticated = false;\n } else {\n ret.authenticated = true;\n }\n\n // senderKey is the Curve25519 identity key of the device which the event\n // was sent from. In the case of Megolm, it's actually the Curve25519\n // identity key of the device which set up the Megolm session.\n\n ret.sender = this.deviceList.getDeviceByIdentityKey(ret.algorithm, ret.senderKey) ?? undefined;\n\n // so far so good, but now we need to check that the sender of this event\n // hadn't advertised someone else's Curve25519 key as their own. We do that\n // by checking the Ed25519 claimed by the event (or, in the case of megolm,\n // the event which set up the megolm session), to check that it matches the\n // fingerprint of the purported sending device.\n //\n // (see https://github.com/vector-im/vector-web/issues/2215)\n\n const claimedKey = event.getClaimedEd25519Key();\n if (!claimedKey) {\n logger.warn(\"Event \" + event.getId() + \" claims no ed25519 key: \" + \"cannot verify sending device\");\n ret.mismatchedSender = true;\n }\n\n if (ret.sender && claimedKey !== ret.sender.getFingerprint()) {\n logger.warn(\n \"Event \" +\n event.getId() +\n \" claims ed25519 key \" +\n claimedKey +\n \"but sender device has key \" +\n ret.sender.getFingerprint(),\n );\n ret.mismatchedSender = true;\n }\n\n return ret as IEncryptedEventInfo;\n }\n\n /**\n * Forces the current outbound group session to be discarded such\n * that another one will be created next time an event is sent.\n *\n * @param roomId - The ID of the room to discard the session for\n *\n * This should not normally be necessary.\n */\n public forceDiscardSession(roomId: string): Promise<void> {\n const alg = this.roomEncryptors.get(roomId);\n if (alg === undefined) throw new Error(\"Room not encrypted\");\n if (alg.forceDiscardSession === undefined) {\n throw new Error(\"Room encryption algorithm doesn't support session discarding\");\n }\n alg.forceDiscardSession();\n return Promise.resolve();\n }\n\n /**\n * Configure a room to use encryption (ie, save a flag in the cryptoStore).\n *\n * @param roomId - The room ID to enable encryption in.\n *\n * @param config - The encryption config for the room.\n *\n * @param inhibitDeviceQuery - true to suppress device list query for\n * users in the room (for now). In case lazy loading is enabled,\n * the device query is always inhibited as the members are not tracked.\n *\n * @deprecated It is normally incorrect to call this method directly. Encryption\n * is enabled by receiving an `m.room.encryption` event (which we may have sent\n * previously).\n */\n public async setRoomEncryption(\n roomId: string,\n config: IRoomEncryption,\n inhibitDeviceQuery?: boolean,\n ): Promise<void> {\n const room = this.clientStore.getRoom(roomId);\n if (!room) {\n throw new Error(`Unable to enable encryption tracking devices in unknown room ${roomId}`);\n }\n await this.setRoomEncryptionImpl(room, config);\n if (!this.lazyLoadMembers && !inhibitDeviceQuery) {\n this.deviceList.refreshOutdatedDeviceLists();\n }\n }\n\n /**\n * Set up encryption for a room.\n *\n * This is called when an <tt>m.room.encryption</tt> event is received. It saves a flag\n * for the room in the cryptoStore (if it wasn't already set), sets up an \"encryptor\" for\n * the room, and enables device-list tracking for the room.\n *\n * It does <em>not</em> initiate a device list query for the room. That is normally\n * done once we finish processing the sync, in onSyncCompleted.\n *\n * @param room - The room to enable encryption in.\n * @param config - The encryption config for the room.\n */\n private async setRoomEncryptionImpl(room: Room, config: IRoomEncryption): Promise<void> {\n const roomId = room.roomId;\n\n // ignore crypto events with no algorithm defined\n // This will happen if a crypto event is redacted before we fetch the room state\n // It would otherwise just throw later as an unknown algorithm would, but we may\n // as well catch this here\n if (!config.algorithm) {\n logger.log(\"Ignoring setRoomEncryption with no algorithm\");\n return;\n }\n\n // if state is being replayed from storage, we might already have a configuration\n // for this room as they are persisted as well.\n // We just need to make sure the algorithm is initialized in this case.\n // However, if the new config is different,\n // we should bail out as room encryption can't be changed once set.\n const existingConfig = this.roomList.getRoomEncryption(roomId);\n if (existingConfig) {\n if (JSON.stringify(existingConfig) != JSON.stringify(config)) {\n logger.error(\"Ignoring m.room.encryption event which requests \" + \"a change of config in \" + roomId);\n return;\n }\n }\n // if we already have encryption in this room, we should ignore this event,\n // as it would reset the encryption algorithm.\n // This is at least expected to be called twice, as sync calls onCryptoEvent\n // for both the timeline and state sections in the /sync response,\n // the encryption event would appear in both.\n // If it's called more than twice though,\n // it signals a bug on client or server.\n const existingAlg = this.roomEncryptors.get(roomId);\n if (existingAlg) {\n return;\n }\n\n // _roomList.getRoomEncryption will not race with _roomList.setRoomEncryption\n // because it first stores in memory. We should await the promise only\n // after all the in-memory state (roomEncryptors and _roomList) has been updated\n // to avoid races when calling this method multiple times. Hence keep a hold of the promise.\n let storeConfigPromise: Promise<void> | null = null;\n if (!existingConfig) {\n storeConfigPromise = this.roomList.setRoomEncryption(roomId, config);\n }\n\n const AlgClass = algorithms.ENCRYPTION_CLASSES.get(config.algorithm);\n if (!AlgClass) {\n throw new Error(\"Unable to encrypt with \" + config.algorithm);\n }\n\n const alg = new AlgClass({\n userId: this.userId,\n deviceId: this.deviceId,\n crypto: this,\n olmDevice: this.olmDevice,\n baseApis: this.baseApis,\n roomId,\n config,\n });\n this.roomEncryptors.set(roomId, alg);\n\n if (storeConfigPromise) {\n await storeConfigPromise;\n }\n\n logger.log(`Enabling encryption in ${roomId}`);\n\n // we don't want to force a download of the full membership list of this room, but as soon as we have that\n // list we can start tracking the device list.\n if (room.membersLoaded()) {\n await this.trackRoomDevicesImpl(room);\n } else {\n // wait for the membership list to be loaded\n const onState = (_state: RoomState): void => {\n room.off(RoomStateEvent.Update, onState);\n if (room.membersLoaded()) {\n this.trackRoomDevicesImpl(room).catch((e) => {\n logger.error(`Error enabling device tracking in ${roomId}`, e);\n });\n }\n };\n room.on(RoomStateEvent.Update, onState);\n }\n }\n\n /**\n * Make sure we are tracking the device lists for all users in this room.\n *\n * @param roomId - The room ID to start tracking devices in.\n * @returns when all devices for the room have been fetched and marked to track\n * @deprecated there's normally no need to call this function: device list tracking\n * will be enabled as soon as we have the full membership list.\n */\n public trackRoomDevices(roomId: string): Promise<void> {\n const room = this.clientStore.getRoom(roomId);\n if (!room) {\n throw new Error(`Unable to start tracking devices in unknown room ${roomId}`);\n }\n return this.trackRoomDevicesImpl(room);\n }\n\n /**\n * Make sure we are tracking the device lists for all users in this room.\n *\n * This is normally called when we are about to send an encrypted event, to make sure\n * we have all the devices in the room; but it is also called when processing an\n * m.room.encryption state event (if lazy-loading is disabled), or when members are\n * loaded (if lazy-loading is enabled), to prepare the device list.\n *\n * @param room - Room to enable device-list tracking in\n */\n private trackRoomDevicesImpl(room: Room): Promise<void> {\n const roomId = room.roomId;\n const trackMembers = async (): Promise<void> => {\n // not an encrypted room\n if (!this.roomEncryptors.has(roomId)) {\n return;\n }\n logger.log(`Starting to track devices for room ${roomId} ...`);\n const members = await room.getEncryptionTargetMembers();\n members.forEach((m) => {\n this.deviceList.startTrackingDeviceList(m.userId);\n });\n };\n\n let promise = this.roomDeviceTrackingState[roomId];\n if (!promise) {\n promise = trackMembers();\n this.roomDeviceTrackingState[roomId] = promise.catch((err) => {\n delete this.roomDeviceTrackingState[roomId];\n throw err;\n });\n }\n return promise;\n }\n\n /**\n * Try to make sure we have established olm sessions for all known devices for\n * the given users.\n *\n * @param users - list of user ids\n * @param force - If true, force a new Olm session to be created. Default false.\n *\n * @returns resolves once the sessions are complete, to\n * an Object mapping from userId to deviceId to\n * {@link OlmSessionResult}\n */\n public ensureOlmSessionsForUsers(\n users: string[],\n force?: boolean,\n ): Promise<Map<string, Map<string, olmlib.IOlmSessionResult>>> {\n // map user Id → DeviceInfo[]\n const devicesByUser: Map<string, DeviceInfo[]> = new Map();\n\n for (const userId of users) {\n const userDevices: DeviceInfo[] = [];\n devicesByUser.set(userId, userDevices);\n\n const devices = this.getStoredDevicesForUser(userId) || [];\n for (const deviceInfo of devices) {\n const key = deviceInfo.getIdentityKey();\n if (key == this.olmDevice.deviceCurve25519Key) {\n // don't bother setting up session to ourself\n continue;\n }\n if (deviceInfo.verified == DeviceVerification.BLOCKED) {\n // don't bother setting up sessions with blocked users\n continue;\n }\n\n userDevices.push(deviceInfo);\n }\n }\n\n return olmlib.ensureOlmSessionsForDevices(this.olmDevice, this.baseApis, devicesByUser, force);\n }\n\n /**\n * Get a list containing all of the room keys\n *\n * @returns a list of session export objects\n */\n public async exportRoomKeys(): Promise<IMegolmSessionData[]> {\n const exportedSessions: IMegolmSessionData[] = [];\n await this.cryptoStore.doTxn(\"readonly\", [IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS], (txn) => {\n this.cryptoStore.getAllEndToEndInboundGroupSessions(txn, (s) => {\n if (s === null) return;\n\n const sess = this.olmDevice.exportInboundGroupSession(s.senderKey, s.sessionId, s.sessionData!);\n delete sess.first_known_index;\n sess.algorithm = olmlib.MEGOLM_ALGORITHM;\n exportedSessions.push(sess);\n });\n });\n\n return exportedSessions;\n }\n\n /**\n * Import a list of room keys previously exported by exportRoomKeys\n *\n * @param keys - a list of session export objects\n * @returns a promise which resolves once the keys have been imported\n */\n public importRoomKeys(keys: IMegolmSessionData[], opts: IImportRoomKeysOpts = {}): Promise<void> {\n let successes = 0;\n let failures = 0;\n const total = keys.length;\n\n function updateProgress(): void {\n opts.progressCallback?.({\n stage: \"load_keys\",\n successes,\n failures,\n total,\n });\n }\n\n return Promise.all(\n keys.map((key) => {\n if (!key.room_id || !key.algorithm) {\n logger.warn(\"ignoring room key entry with missing fields\", key);\n failures++;\n if (opts.progressCallback) {\n updateProgress();\n }\n return null;\n }\n\n const alg = this.getRoomDecryptor(key.room_id, key.algorithm);\n return alg.importRoomKey(key, opts).finally(() => {\n successes++;\n if (opts.progressCallback) {\n updateProgress();\n }\n });\n }),\n ).then();\n }\n\n /**\n * Counts the number of end to end session keys that are waiting to be backed up\n * @returns Promise which resolves to the number of sessions requiring backup\n */\n public countSessionsNeedingBackup(): Promise<number> {\n return this.backupManager.countSessionsNeedingBackup();\n }\n\n /**\n * Perform any background tasks that can be done before a message is ready to\n * send, in order to speed up sending of the message.\n *\n * @param room - the room the event is in\n */\n public prepareToEncrypt(room: Room): void {\n const alg = this.roomEncryptors.get(room.roomId);\n if (alg) {\n alg.prepareToEncrypt(room);\n }\n }\n\n /**\n * Encrypt an event according to the configuration of the room.\n *\n * @param event - event to be sent\n *\n * @param room - destination room.\n *\n * @returns Promise which resolves when the event has been\n * encrypted, or null if nothing was needed\n */\n public async encryptEvent(event: MatrixEvent, room: Room): Promise<void> {\n const roomId = event.getRoomId()!;\n\n const alg = this.roomEncryptors.get(roomId);\n if (!alg) {\n // MatrixClient has already checked that this room should be encrypted,\n // so this is an unexpected situation.\n throw new Error(\n \"Room \" +\n roomId +\n \" was previously configured to use encryption, but is \" +\n \"no longer. Perhaps the homeserver is hiding the \" +\n \"configuration event.\",\n );\n }\n\n // wait for all the room devices to be loaded\n await this.trackRoomDevicesImpl(room);\n\n let content = event.getContent();\n // If event has an m.relates_to then we need\n // to put this on the wrapping event instead\n const mRelatesTo = content[\"m.relates_to\"];\n if (mRelatesTo) {\n // Clone content here so we don't remove `m.relates_to` from the local-echo\n content = Object.assign({}, content);\n delete content[\"m.relates_to\"];\n }\n\n // Treat element's performance metrics the same as `m.relates_to` (when present)\n const elementPerfMetrics = content[\"io.element.performance_metrics\"];\n if (elementPerfMetrics) {\n content = Object.assign({}, content);\n delete content[\"io.element.performance_metrics\"];\n }\n\n const encryptedContent = (await alg.encryptMessage(room, event.getType(), content)) as IContent;\n\n if (mRelatesTo) {\n encryptedContent[\"m.relates_to\"] = mRelatesTo;\n }\n if (elementPerfMetrics) {\n encryptedContent[\"io.element.performance_metrics\"] = elementPerfMetrics;\n }\n\n event.makeEncrypted(\n \"m.room.encrypted\",\n encryptedContent,\n this.olmDevice.deviceCurve25519Key!,\n this.olmDevice.deviceEd25519Key!,\n );\n }\n\n /**\n * Decrypt a received event\n *\n *\n * @returns resolves once we have\n * finished decrypting. Rejects with an `algorithms.DecryptionError` if there\n * is a problem decrypting the event.\n */\n public async decryptEvent(event: MatrixEvent): Promise<IEventDecryptionResult> {\n if (event.isRedacted()) {\n // Try to decrypt the redaction event, to support encrypted\n // redaction reasons. If we can't decrypt, just fall back to using\n // the original redacted_because.\n const redactionEvent = new MatrixEvent({\n room_id: event.getRoomId(),\n ...event.getUnsigned().redacted_because,\n });\n let redactedBecause: IEvent = event.getUnsigned().redacted_because!;\n if (redactionEvent.isEncrypted()) {\n try {\n const decryptedEvent = await this.decryptEvent(redactionEvent);\n redactedBecause = decryptedEvent.clearEvent as IEvent;\n } catch (e) {\n logger.warn(\"Decryption of redaction failed. Falling back to unencrypted event.\", e);\n }\n }\n\n return {\n clearEvent: {\n room_id: event.getRoomId(),\n type: \"m.room.message\",\n content: {},\n unsigned: {\n redacted_because: redactedBecause,\n },\n },\n };\n } else {\n const content = event.getWireContent();\n const alg = this.getRoomDecryptor(event.getRoomId()!, content.algorithm);\n return alg.decryptEvent(event);\n }\n }\n\n /**\n * Handle the notification from /sync or /keys/changes that device lists have\n * been changed.\n *\n * @param syncData - Object containing sync tokens associated with this sync\n * @param syncDeviceLists - device_lists field from /sync, or response from\n * /keys/changes\n */\n public async handleDeviceListChanges(\n syncData: ISyncStateData,\n syncDeviceLists: Required<ISyncResponse>[\"device_lists\"],\n ): Promise<void> {\n // Initial syncs don't have device change lists. We'll either get the complete list\n // of changes for the interval or will have invalidated everything in willProcessSync\n if (!syncData.oldSyncToken) return;\n\n // Here, we're relying on the fact that we only ever save the sync data after\n // sucessfully saving the device list data, so we're guaranteed that the device\n // list store is at least as fresh as the sync token from the sync store, ie.\n // any device changes received in sync tokens prior to the 'next' token here\n // have been processed and are reflected in the current device list.\n // If we didn't make this assumption, we'd have to use the /keys/changes API\n // to get key changes between the sync token in the device list and the 'old'\n // sync token used here to make sure we didn't miss any.\n await this.evalDeviceListChanges(syncDeviceLists);\n }\n\n /**\n * Send a request for some room keys, if we have not already done so\n *\n * @param resend - whether to resend the key request if there is\n * already one\n *\n * @returns a promise that resolves when the key request is queued\n */\n public requestRoomKey(\n requestBody: IRoomKeyRequestBody,\n recipients: IRoomKeyRequestRecipient[],\n resend = false,\n ): Promise<void> {\n return this.outgoingRoomKeyRequestManager\n .queueRoomKeyRequest(requestBody, recipients, resend)\n .then(() => {\n if (this.sendKeyRequestsImmediately) {\n this.outgoingRoomKeyRequestManager.sendQueuedRequests();\n }\n })\n .catch((e) => {\n // this normally means we couldn't talk to the store\n logger.error(\"Error requesting key for event\", e);\n });\n }\n\n /**\n * Cancel any earlier room key request\n *\n * @param requestBody - parameters to match for cancellation\n */\n public cancelRoomKeyRequest(requestBody: IRoomKeyRequestBody): void {\n this.outgoingRoomKeyRequestManager.cancelRoomKeyRequest(requestBody).catch((e) => {\n logger.warn(\"Error clearing pending room key requests\", e);\n });\n }\n\n /**\n * Re-send any outgoing key requests, eg after verification\n * @returns\n */\n public async cancelAndResendAllOutgoingKeyRequests(): Promise<void> {\n await this.outgoingRoomKeyRequestManager.cancelAndResendAllOutgoingRequests();\n }\n\n /**\n * handle an m.room.encryption event\n *\n * @param room - in which the event was received\n * @param event - encryption event to be processed\n */\n public async onCryptoEvent(room: Room, event: MatrixEvent): Promise<void> {\n const content = event.getContent<IRoomEncryption>();\n await this.setRoomEncryptionImpl(room, content);\n }\n\n /**\n * Called before the result of a sync is processed\n *\n * @param syncData - the data from the 'MatrixClient.sync' event\n */\n public async onSyncWillProcess(syncData: ISyncStateData): Promise<void> {\n if (!syncData.oldSyncToken) {\n // If there is no old sync token, we start all our tracking from\n // scratch, so mark everything as untracked. onCryptoEvent will\n // be called for all e2e rooms during the processing of the sync,\n // at which point we'll start tracking all the users of that room.\n logger.log(\"Initial sync performed - resetting device tracking state\");\n this.deviceList.stopTrackingAllDeviceLists();\n // we always track our own device list (for key backups etc)\n this.deviceList.startTrackingDeviceList(this.userId);\n this.roomDeviceTrackingState = {};\n }\n\n this.sendKeyRequestsImmediately = false;\n }\n\n /**\n * handle the completion of a /sync\n *\n * This is called after the processing of each successful /sync response.\n * It is an opportunity to do a batch process on the information received.\n *\n * @param syncData - the data from the 'MatrixClient.sync' event\n */\n public async onSyncCompleted(syncData: OnSyncCompletedData): Promise<void> {\n this.deviceList.setSyncToken(syncData.nextSyncToken ?? null);\n this.deviceList.saveIfDirty();\n\n // we always track our own device list (for key backups etc)\n this.deviceList.startTrackingDeviceList(this.userId);\n\n this.deviceList.refreshOutdatedDeviceLists();\n\n // we don't start uploading one-time keys until we've caught up with\n // to-device messages, to help us avoid throwing away one-time-keys that we\n // are about to receive messages for\n // (https://github.com/vector-im/element-web/issues/2782).\n if (!syncData.catchingUp) {\n this.maybeUploadOneTimeKeys();\n this.processReceivedRoomKeyRequests();\n\n // likewise don't start requesting keys until we've caught up\n // on to_device messages, otherwise we'll request keys that we're\n // just about to get.\n this.outgoingRoomKeyRequestManager.sendQueuedRequests();\n\n // Sync has finished so send key requests straight away.\n this.sendKeyRequestsImmediately = true;\n }\n }\n\n /**\n * Trigger the appropriate invalidations and removes for a given\n * device list\n *\n * @param deviceLists - device_lists field from /sync, or response from\n * /keys/changes\n */\n private async evalDeviceListChanges(deviceLists: Required<ISyncResponse>[\"device_lists\"]): Promise<void> {\n if (Array.isArray(deviceLists?.changed)) {\n deviceLists.changed.forEach((u) => {\n this.deviceList.invalidateUserDeviceList(u);\n });\n }\n\n if (Array.isArray(deviceLists?.left) && deviceLists.left.length) {\n // Check we really don't share any rooms with these users\n // any more: the server isn't required to give us the\n // exact correct set.\n const e2eUserIds = new Set(await this.getTrackedE2eUsers());\n\n deviceLists.left.forEach((u) => {\n if (!e2eUserIds.has(u)) {\n this.deviceList.stopTrackingDeviceList(u);\n }\n });\n }\n }\n\n /**\n * Get a list of all the IDs of users we share an e2e room with\n * for which we are tracking devices already\n *\n * @returns List of user IDs\n */\n private async getTrackedE2eUsers(): Promise<string[]> {\n const e2eUserIds: string[] = [];\n for (const room of this.getTrackedE2eRooms()) {\n const members = await room.getEncryptionTargetMembers();\n for (const member of members) {\n e2eUserIds.push(member.userId);\n }\n }\n return e2eUserIds;\n }\n\n /**\n * Get a list of the e2e-enabled rooms we are members of,\n * and for which we are already tracking the devices\n *\n * @returns\n */\n private getTrackedE2eRooms(): Room[] {\n return this.clientStore.getRooms().filter((room) => {\n // check for rooms with encryption enabled\n const alg = this.roomEncryptors.get(room.roomId);\n if (!alg) {\n return false;\n }\n if (!this.roomDeviceTrackingState[room.roomId]) {\n return false;\n }\n\n // ignore any rooms which we have left\n const myMembership = room.getMyMembership();\n return myMembership === \"join\" || myMembership === \"invite\";\n });\n }\n\n /**\n * Encrypts and sends a given object via Olm to-device messages to a given\n * set of devices.\n * @param userDeviceInfoArr - the devices to send to\n * @param payload - fields to include in the encrypted payload\n * @returns Promise which\n * resolves once the message has been encrypted and sent to the given\n * userDeviceMap, and returns the `{ contentMap, deviceInfoByDeviceId }`\n * of the successfully sent messages.\n */\n public async encryptAndSendToDevices(userDeviceInfoArr: IOlmDevice<DeviceInfo>[], payload: object): Promise<void> {\n const toDeviceBatch: ToDeviceBatch = {\n eventType: EventType.RoomMessageEncrypted,\n batch: [],\n };\n\n try {\n await Promise.all(\n userDeviceInfoArr.map(async ({ userId, deviceInfo }) => {\n const deviceId = deviceInfo.deviceId;\n const encryptedContent: IEncryptedContent = {\n algorithm: olmlib.OLM_ALGORITHM,\n sender_key: this.olmDevice.deviceCurve25519Key!,\n ciphertext: {},\n [ToDeviceMessageId]: uuidv4(),\n };\n\n toDeviceBatch.batch.push({\n userId,\n deviceId,\n payload: encryptedContent,\n });\n\n await olmlib.ensureOlmSessionsForDevices(\n this.olmDevice,\n this.baseApis,\n new Map([[userId, [deviceInfo]]]),\n );\n await olmlib.encryptMessageForDevice(\n encryptedContent.ciphertext,\n this.userId,\n this.deviceId,\n this.olmDevice,\n userId,\n deviceInfo,\n payload,\n );\n }),\n );\n\n // prune out any devices that encryptMessageForDevice could not encrypt for,\n // in which case it will have just not added anything to the ciphertext object.\n // There's no point sending messages to devices if we couldn't encrypt to them,\n // since that's effectively a blank message.\n toDeviceBatch.batch = toDeviceBatch.batch.filter((msg) => {\n if (Object.keys(msg.payload.ciphertext).length > 0) {\n return true;\n } else {\n logger.log(`No ciphertext for device ${msg.userId}:${msg.deviceId}: pruning`);\n return false;\n }\n });\n\n try {\n await this.baseApis.queueToDevice(toDeviceBatch);\n } catch (e) {\n logger.error(\"sendToDevice failed\", e);\n throw e;\n }\n } catch (e) {\n logger.error(\"encryptAndSendToDevices promises failed\", e);\n throw e;\n }\n }\n\n private onMembership = (event: MatrixEvent, member: RoomMember, oldMembership?: string): void => {\n try {\n this.onRoomMembership(event, member, oldMembership);\n } catch (e) {\n logger.error(\"Error handling membership change:\", e);\n }\n };\n\n public async preprocessToDeviceMessages(events: IToDeviceEvent[]): Promise<IToDeviceEvent[]> {\n // all we do here is filter out encrypted to-device messages with the wrong algorithm. Decryption\n // happens later in decryptEvent, via the EventMapper\n return events.filter((toDevice) => {\n if (\n toDevice.type === EventType.RoomMessageEncrypted &&\n ![\"m.olm.v1.curve25519-aes-sha2\"].includes(toDevice.content?.algorithm)\n ) {\n logger.log(\"Ignoring invalid encrypted to-device event from \" + toDevice.sender);\n return false;\n }\n return true;\n });\n }\n\n public preprocessOneTimeKeyCounts(oneTimeKeysCounts: Map<string, number>): Promise<void> {\n const currentCount = oneTimeKeysCounts.get(\"signed_curve25519\") || 0;\n this.updateOneTimeKeyCount(currentCount);\n return Promise.resolve();\n }\n\n public preprocessUnusedFallbackKeys(unusedFallbackKeys: Set<string>): Promise<void> {\n this.setNeedsNewFallback(!unusedFallbackKeys.has(\"signed_curve25519\"));\n return Promise.resolve();\n }\n\n private onToDeviceEvent = (event: MatrixEvent): void => {\n try {\n logger.log(\n `received to-device ${event.getType()} from: ` +\n `${event.getSender()} id: ${event.getContent()[ToDeviceMessageId]}`,\n );\n\n if (event.getType() == \"m.room_key\" || event.getType() == \"m.forwarded_room_key\") {\n this.onRoomKeyEvent(event);\n } else if (event.getType() == \"m.room_key_request\") {\n this.onRoomKeyRequestEvent(event);\n } else if (event.getType() === \"m.secret.request\") {\n this.secretStorage.onRequestReceived(event);\n } else if (event.getType() === \"m.secret.send\") {\n this.secretStorage.onSecretReceived(event);\n } else if (event.getType() === \"m.room_key.withheld\") {\n this.onRoomKeyWithheldEvent(event);\n } else if (event.getContent().transaction_id) {\n this.onKeyVerificationMessage(event);\n } else if (event.getContent().msgtype === \"m.bad.encrypted\") {\n this.onToDeviceBadEncrypted(event);\n } else if (event.isBeingDecrypted() || event.shouldAttemptDecryption()) {\n if (!event.isBeingDecrypted()) {\n event.attemptDecryption(this);\n }\n // once the event has been decrypted, try again\n event.once(MatrixEventEvent.Decrypted, (ev) => {\n this.onToDeviceEvent(ev);\n });\n }\n } catch (e) {\n logger.error(\"Error handling toDeviceEvent:\", e);\n }\n };\n\n /**\n * Handle a key event\n *\n * @internal\n * @param event - key event\n */\n private onRoomKeyEvent(event: MatrixEvent): void {\n const content = event.getContent();\n\n if (!content.room_id || !content.algorithm) {\n logger.error(\"key event is missing fields\");\n return;\n }\n\n if (!this.backupManager.checkedForBackup) {\n // don't bother awaiting on this - the important thing is that we retry if we\n // haven't managed to check before\n this.backupManager.checkAndStart();\n }\n\n const alg = this.getRoomDecryptor(content.room_id, content.algorithm);\n alg.onRoomKeyEvent(event);\n }\n\n /**\n * Handle a key withheld event\n *\n * @internal\n * @param event - key withheld event\n */\n private onRoomKeyWithheldEvent(event: MatrixEvent): void {\n const content = event.getContent();\n\n if (\n (content.code !== \"m.no_olm\" && (!content.room_id || !content.session_id)) ||\n !content.algorithm ||\n !content.sender_key\n ) {\n logger.error(\"key withheld event is missing fields\");\n return;\n }\n\n logger.info(\n `Got room key withheld event from ${event.getSender()} ` +\n `for ${content.algorithm} session ${content.sender_key}|${content.session_id} ` +\n `in room ${content.room_id} with code ${content.code} (${content.reason})`,\n );\n\n const alg = this.getRoomDecryptor(content.room_id, content.algorithm);\n if (alg.onRoomKeyWithheldEvent) {\n alg.onRoomKeyWithheldEvent(event);\n }\n if (!content.room_id) {\n // retry decryption for all events sent by the sender_key. This will\n // update the events to show a message indicating that the olm session was\n // wedged.\n const roomDecryptors = this.getRoomDecryptors(content.algorithm);\n for (const decryptor of roomDecryptors) {\n decryptor.retryDecryptionFromSender(content.sender_key);\n }\n }\n }\n\n /**\n * Handle a general key verification event.\n *\n * @internal\n * @param event - verification start event\n */\n private onKeyVerificationMessage(event: MatrixEvent): void {\n if (!ToDeviceChannel.validateEvent(event, this.baseApis)) {\n return;\n }\n const createRequest = (event: MatrixEvent): VerificationRequest | undefined => {\n if (!ToDeviceChannel.canCreateRequest(ToDeviceChannel.getEventType(event))) {\n return;\n }\n const content = event.getContent();\n const deviceId = content && content.from_device;\n if (!deviceId) {\n return;\n }\n const userId = event.getSender()!;\n const channel = new ToDeviceChannel(this.baseApis, userId, [deviceId]);\n return new VerificationRequest(channel, this.verificationMethods, this.baseApis);\n };\n this.handleVerificationEvent(event, this.toDeviceVerificationRequests, createRequest);\n }\n\n /**\n * Handle key verification requests sent as timeline events\n *\n * @internal\n * @param event - the timeline event\n * @param room - not used\n * @param atStart - not used\n * @param removed - not used\n * @param whether - this is a live event\n */\n private onTimelineEvent = (\n event: MatrixEvent,\n room: Room,\n atStart: boolean,\n removed: boolean,\n { liveEvent = true } = {},\n ): void => {\n if (!InRoomChannel.validateEvent(event, this.baseApis)) {\n return;\n }\n const createRequest = (event: MatrixEvent): VerificationRequest => {\n const channel = new InRoomChannel(this.baseApis, event.getRoomId()!);\n return new VerificationRequest(channel, this.verificationMethods, this.baseApis);\n };\n this.handleVerificationEvent(event, this.inRoomVerificationRequests, createRequest, liveEvent);\n };\n\n private async handleVerificationEvent(\n event: MatrixEvent,\n requestsMap: IRequestsMap,\n createRequest: (event: MatrixEvent) => VerificationRequest | undefined,\n isLiveEvent = true,\n ): Promise<void> {\n // Wait for event to get its final ID with pendingEventOrdering: \"chronological\", since DM channels depend on it.\n if (event.isSending() && event.status != EventStatus.SENT) {\n let eventIdListener: () => void;\n let statusListener: () => void;\n try {\n await new Promise<void>((resolve, reject) => {\n eventIdListener = resolve;\n statusListener = (): void => {\n if (event.status == EventStatus.CANCELLED) {\n reject(new Error(\"Event status set to CANCELLED.\"));\n }\n };\n event.once(MatrixEventEvent.LocalEventIdReplaced, eventIdListener);\n event.on(MatrixEventEvent.Status, statusListener);\n });\n } catch (err) {\n logger.error(\"error while waiting for the verification event to be sent: \", err);\n return;\n } finally {\n event.removeListener(MatrixEventEvent.LocalEventIdReplaced, eventIdListener!);\n event.removeListener(MatrixEventEvent.Status, statusListener!);\n }\n }\n let request: VerificationRequest | undefined = requestsMap.getRequest(event);\n let isNewRequest = false;\n if (!request) {\n request = createRequest(event);\n // a request could not be made from this event, so ignore event\n if (!request) {\n logger.log(\n `Crypto: could not find VerificationRequest for ` +\n `${event.getType()}, and could not create one, so ignoring.`,\n );\n return;\n }\n isNewRequest = true;\n requestsMap.setRequest(event, request);\n }\n event.setVerificationRequest(request);\n try {\n await request.channel.handleEvent(event, request, isLiveEvent);\n } catch (err) {\n logger.error(\"error while handling verification event\", err);\n }\n const shouldEmit =\n isNewRequest &&\n !request.initiatedByMe &&\n !request.invalid && // check it has enough events to pass the UNSENT stage\n !request.observeOnly;\n if (shouldEmit) {\n this.baseApis.emit(CryptoEvent.VerificationRequest, request);\n }\n }\n\n /**\n * Handle a toDevice event that couldn't be decrypted\n *\n * @internal\n * @param event - undecryptable event\n */\n private async onToDeviceBadEncrypted(event: MatrixEvent): Promise<void> {\n const content = event.getWireContent();\n const sender = event.getSender();\n const algorithm = content.algorithm;\n const deviceKey = content.sender_key;\n\n this.baseApis.emit(ClientEvent.UndecryptableToDeviceEvent, event);\n\n // retry decryption for all events sent by the sender_key. This will\n // update the events to show a message indicating that the olm session was\n // wedged.\n const retryDecryption = (): void => {\n const roomDecryptors = this.getRoomDecryptors(olmlib.MEGOLM_ALGORITHM);\n for (const decryptor of roomDecryptors) {\n decryptor.retryDecryptionFromSender(deviceKey);\n }\n };\n\n if (sender === undefined || deviceKey === undefined || deviceKey === undefined) {\n return;\n }\n\n // check when we last forced a new session with this device: if we've already done so\n // recently, don't do it again.\n const lastNewSessionDevices = this.lastNewSessionForced.getOrCreate(sender);\n const lastNewSessionForced = lastNewSessionDevices.getOrCreate(deviceKey);\n if (lastNewSessionForced + MIN_FORCE_SESSION_INTERVAL_MS > Date.now()) {\n logger.debug(\n \"New session already forced with device \" +\n sender +\n \":\" +\n deviceKey +\n \" at \" +\n lastNewSessionForced +\n \": not forcing another\",\n );\n await this.olmDevice.recordSessionProblem(deviceKey, \"wedged\", true);\n retryDecryption();\n return;\n }\n\n // establish a new olm session with this device since we're failing to decrypt messages\n // on a current session.\n // Note that an undecryptable message from another device could easily be spoofed -\n // is there anything we can do to mitigate this?\n let device = this.deviceList.getDeviceByIdentityKey(algorithm, deviceKey);\n if (!device) {\n // if we don't know about the device, fetch the user's devices again\n // and retry before giving up\n await this.downloadKeys([sender], false);\n device = this.deviceList.getDeviceByIdentityKey(algorithm, deviceKey);\n if (!device) {\n logger.info(\"Couldn't find device for identity key \" + deviceKey + \": not re-establishing session\");\n await this.olmDevice.recordSessionProblem(deviceKey, \"wedged\", false);\n retryDecryption();\n return;\n }\n }\n const devicesByUser = new Map([[sender, [device]]]);\n await olmlib.ensureOlmSessionsForDevices(this.olmDevice, this.baseApis, devicesByUser, true);\n\n lastNewSessionDevices.set(deviceKey, Date.now());\n\n // Now send a blank message on that session so the other side knows about it.\n // (The keyshare request is sent in the clear so that won't do)\n // We send this first such that, as long as the toDevice messages arrive in the\n // same order we sent them, the other end will get this first, set up the new session,\n // then get the keyshare request and send the key over this new session (because it\n // is the session it has most recently received a message on).\n const encryptedContent: IEncryptedContent = {\n algorithm: olmlib.OLM_ALGORITHM,\n sender_key: this.olmDevice.deviceCurve25519Key!,\n ciphertext: {},\n [ToDeviceMessageId]: uuidv4(),\n };\n await olmlib.encryptMessageForDevice(\n encryptedContent.ciphertext,\n this.userId,\n this.deviceId,\n this.olmDevice,\n sender,\n device,\n { type: \"m.dummy\" },\n );\n\n await this.olmDevice.recordSessionProblem(deviceKey, \"wedged\", true);\n retryDecryption();\n\n await this.baseApis.sendToDevice(\n \"m.room.encrypted\",\n new Map([[sender, new Map([[device.deviceId, encryptedContent]])]]),\n );\n\n // Most of the time this probably won't be necessary since we'll have queued up a key request when\n // we failed to decrypt the message and will be waiting a bit for the key to arrive before sending\n // it. This won't always be the case though so we need to re-send any that have already been sent\n // to avoid races.\n const requestsToResend = await this.outgoingRoomKeyRequestManager.getOutgoingSentRoomKeyRequest(\n sender,\n device.deviceId,\n );\n for (const keyReq of requestsToResend) {\n this.requestRoomKey(keyReq.requestBody, keyReq.recipients, true);\n }\n }\n\n /**\n * Handle a change in the membership state of a member of a room\n *\n * @internal\n * @param event - event causing the change\n * @param member - user whose membership changed\n * @param oldMembership - previous membership\n */\n private onRoomMembership(event: MatrixEvent, member: RoomMember, oldMembership?: string): void {\n // this event handler is registered on the *client* (as opposed to the room\n // member itself), which means it is only called on changes to the *live*\n // membership state (ie, it is not called when we back-paginate, nor when\n // we load the state in the initialsync).\n //\n // Further, it is automatically registered and called when new members\n // arrive in the room.\n\n const roomId = member.roomId;\n\n const alg = this.roomEncryptors.get(roomId);\n if (!alg) {\n // not encrypting in this room\n return;\n }\n // only mark users in this room as tracked if we already started tracking in this room\n // this way we don't start device queries after sync on behalf of this room which we won't use\n // the result of anyway, as we'll need to do a query again once all the members are fetched\n // by calling _trackRoomDevices\n if (roomId in this.roomDeviceTrackingState) {\n if (member.membership == \"join\") {\n logger.log(\"Join event for \" + member.userId + \" in \" + roomId);\n // make sure we are tracking the deviceList for this user\n this.deviceList.startTrackingDeviceList(member.userId);\n } else if (\n member.membership == \"invite\" &&\n this.clientStore.getRoom(roomId)?.shouldEncryptForInvitedMembers()\n ) {\n logger.log(\"Invite event for \" + member.userId + \" in \" + roomId);\n this.deviceList.startTrackingDeviceList(member.userId);\n }\n }\n\n alg.onRoomMembership(event, member, oldMembership);\n }\n\n /**\n * Called when we get an m.room_key_request event.\n *\n * @internal\n * @param event - key request event\n */\n private onRoomKeyRequestEvent(event: MatrixEvent): void {\n const content = event.getContent();\n if (content.action === \"request\") {\n // Queue it up for now, because they tend to arrive before the room state\n // events at initial sync, and we want to see if we know anything about the\n // room before passing them on to the app.\n const req = new IncomingRoomKeyRequest(event);\n this.receivedRoomKeyRequests.push(req);\n } else if (content.action === \"request_cancellation\") {\n const req = new IncomingRoomKeyRequestCancellation(event);\n this.receivedRoomKeyRequestCancellations.push(req);\n }\n }\n\n /**\n * Process any m.room_key_request events which were queued up during the\n * current sync.\n *\n * @internal\n */\n private async processReceivedRoomKeyRequests(): Promise<void> {\n if (this.processingRoomKeyRequests) {\n // we're still processing last time's requests; keep queuing new ones\n // up for now.\n return;\n }\n this.processingRoomKeyRequests = true;\n\n try {\n // we need to grab and clear the queues in the synchronous bit of this method,\n // so that we don't end up racing with the next /sync.\n const requests = this.receivedRoomKeyRequests;\n this.receivedRoomKeyRequests = [];\n const cancellations = this.receivedRoomKeyRequestCancellations;\n this.receivedRoomKeyRequestCancellations = [];\n\n // Process all of the requests, *then* all of the cancellations.\n //\n // This makes sure that if we get a request and its cancellation in the\n // same /sync result, then we process the request before the\n // cancellation (and end up with a cancelled request), rather than the\n // cancellation before the request (and end up with an outstanding\n // request which should have been cancelled.)\n await Promise.all(requests.map((req) => this.processReceivedRoomKeyRequest(req)));\n await Promise.all(\n cancellations.map((cancellation) => this.processReceivedRoomKeyRequestCancellation(cancellation)),\n );\n } catch (e) {\n logger.error(`Error processing room key requsts: ${e}`);\n } finally {\n this.processingRoomKeyRequests = false;\n }\n }\n\n /**\n * Helper for processReceivedRoomKeyRequests\n *\n */\n private async processReceivedRoomKeyRequest(req: IncomingRoomKeyRequest): Promise<void> {\n const userId = req.userId;\n const deviceId = req.deviceId;\n\n const body = req.requestBody;\n const roomId = body.room_id;\n const alg = body.algorithm;\n\n logger.log(\n `m.room_key_request from ${userId}:${deviceId}` +\n ` for ${roomId} / ${body.session_id} (id ${req.requestId})`,\n );\n\n if (userId !== this.userId) {\n if (!this.roomEncryptors.get(roomId)) {\n logger.debug(`room key request for unencrypted room ${roomId}`);\n return;\n }\n const encryptor = this.roomEncryptors.get(roomId)!;\n const device = this.deviceList.getStoredDevice(userId, deviceId);\n if (!device) {\n logger.debug(`Ignoring keyshare for unknown device ${userId}:${deviceId}`);\n return;\n }\n\n try {\n await encryptor.reshareKeyWithDevice!(body.sender_key, body.session_id, userId, device);\n } catch (e) {\n logger.warn(\n \"Failed to re-share keys for session \" +\n body.session_id +\n \" with device \" +\n userId +\n \":\" +\n device.deviceId,\n e,\n );\n }\n return;\n }\n\n if (deviceId === this.deviceId) {\n // We'll always get these because we send room key requests to\n // '*' (ie. 'all devices') which includes the sending device,\n // so ignore requests from ourself because apart from it being\n // very silly, it won't work because an Olm session cannot send\n // messages to itself.\n // The log here is probably superfluous since we know this will\n // always happen, but let's log anyway for now just in case it\n // causes issues.\n logger.log(\"Ignoring room key request from ourselves\");\n return;\n }\n\n // todo: should we queue up requests we don't yet have keys for,\n // in case they turn up later?\n\n // if we don't have a decryptor for this room/alg, we don't have\n // the keys for the requested events, and can drop the requests.\n if (!this.roomDecryptors.has(roomId)) {\n logger.log(`room key request for unencrypted room ${roomId}`);\n return;\n }\n\n const decryptor = this.roomDecryptors.get(roomId)!.get(alg);\n if (!decryptor) {\n logger.log(`room key request for unknown alg ${alg} in room ${roomId}`);\n return;\n }\n\n if (!(await decryptor.hasKeysForKeyRequest(req))) {\n logger.log(`room key request for unknown session ${roomId} / ` + body.session_id);\n return;\n }\n\n req.share = (): void => {\n decryptor.shareKeysWithDevice(req);\n };\n\n // if the device is verified already, share the keys\n if (this.checkDeviceTrust(userId, deviceId).isVerified()) {\n logger.log(\"device is already verified: sharing keys\");\n req.share();\n return;\n }\n\n this.emit(CryptoEvent.RoomKeyRequest, req);\n }\n\n /**\n * Helper for processReceivedRoomKeyRequests\n *\n */\n private async processReceivedRoomKeyRequestCancellation(\n cancellation: IncomingRoomKeyRequestCancellation,\n ): Promise<void> {\n logger.log(\n `m.room_key_request cancellation for ${cancellation.userId}:` +\n `${cancellation.deviceId} (id ${cancellation.requestId})`,\n );\n\n // we should probably only notify the app of cancellations we told it\n // about, but we don't currently have a record of that, so we just pass\n // everything through.\n this.emit(CryptoEvent.RoomKeyRequestCancellation, cancellation);\n }\n\n /**\n * Get a decryptor for a given room and algorithm.\n *\n * If we already have a decryptor for the given room and algorithm, return\n * it. Otherwise try to instantiate it.\n *\n * @internal\n *\n * @param roomId - room id for decryptor. If undefined, a temporary\n * decryptor is instantiated.\n *\n * @param algorithm - crypto algorithm\n *\n * @throws {@link DecryptionError} if the algorithm is unknown\n */\n public getRoomDecryptor(roomId: string | null, algorithm: string): DecryptionAlgorithm {\n let decryptors: Map<string, DecryptionAlgorithm> | undefined;\n let alg: DecryptionAlgorithm | undefined;\n\n if (roomId) {\n decryptors = this.roomDecryptors.get(roomId);\n if (!decryptors) {\n decryptors = new Map<string, DecryptionAlgorithm>();\n this.roomDecryptors.set(roomId, decryptors);\n }\n\n alg = decryptors.get(algorithm);\n if (alg) {\n return alg;\n }\n }\n\n const AlgClass = algorithms.DECRYPTION_CLASSES.get(algorithm);\n if (!AlgClass) {\n throw new algorithms.DecryptionError(\n \"UNKNOWN_ENCRYPTION_ALGORITHM\",\n 'Unknown encryption algorithm \"' + algorithm + '\".',\n );\n }\n alg = new AlgClass({\n userId: this.userId,\n crypto: this,\n olmDevice: this.olmDevice,\n baseApis: this.baseApis,\n roomId: roomId ?? undefined,\n });\n\n if (decryptors) {\n decryptors.set(algorithm, alg);\n }\n return alg;\n }\n\n /**\n * Get all the room decryptors for a given encryption algorithm.\n *\n * @param algorithm - The encryption algorithm\n *\n * @returns An array of room decryptors\n */\n private getRoomDecryptors(algorithm: string): DecryptionAlgorithm[] {\n const decryptors: DecryptionAlgorithm[] = [];\n for (const d of this.roomDecryptors.values()) {\n if (d.has(algorithm)) {\n decryptors.push(d.get(algorithm)!);\n }\n }\n return decryptors;\n }\n\n /**\n * sign the given object with our ed25519 key\n *\n * @param obj - Object to which we will add a 'signatures' property\n */\n public async signObject<T extends ISignableObject & object>(obj: T): Promise<void> {\n const sigs = new Map(Object.entries(obj.signatures || {}));\n const unsigned = obj.unsigned;\n\n delete obj.signatures;\n delete obj.unsigned;\n\n const userSignatures = sigs.get(this.userId) || {};\n sigs.set(this.userId, userSignatures);\n userSignatures[\"ed25519:\" + this.deviceId] = await this.olmDevice.sign(anotherjson.stringify(obj));\n obj.signatures = recursiveMapToObject(sigs);\n if (unsigned !== undefined) obj.unsigned = unsigned;\n }\n}\n\n/**\n * Fix up the backup key, that may be in the wrong format due to a bug in a\n * migration step. Some backup keys were stored as a comma-separated list of\n * integers, rather than a base64-encoded byte array. If this function is\n * passed a string that looks like a list of integers rather than a base64\n * string, it will attempt to convert it to the right format.\n *\n * @param key - the key to check\n * @returns If the key is in the wrong format, then the fixed\n * key will be returned. Otherwise null will be returned.\n *\n */\nexport function fixBackupKey(key?: string): string | null {\n if (typeof key !== \"string\" || key.indexOf(\",\") < 0) {\n return null;\n }\n const fixedKey = Uint8Array.from(key.split(\",\"), (x) => parseInt(x));\n return olmlib.encodeBase64(fixedKey);\n}\n\n/**\n * Represents a received m.room_key_request event\n */\nexport class IncomingRoomKeyRequest {\n /** user requesting the key */\n public readonly userId: string;\n /** device requesting the key */\n public readonly deviceId: string;\n /** unique id for the request */\n public readonly requestId: string;\n public readonly requestBody: IRoomKeyRequestBody;\n /**\n * callback which, when called, will ask\n * the relevant crypto algorithm implementation to share the keys for\n * this request.\n */\n public share: () => void;\n\n public constructor(event: MatrixEvent) {\n const content = event.getContent();\n\n this.userId = event.getSender()!;\n this.deviceId = content.requesting_device_id;\n this.requestId = content.request_id;\n this.requestBody = content.body || {};\n this.share = (): void => {\n throw new Error(\"don't know how to share keys for this request yet\");\n };\n }\n}\n\n/**\n * Represents a received m.room_key_request cancellation\n */\nclass IncomingRoomKeyRequestCancellation {\n /** user requesting the cancellation */\n public readonly userId: string;\n /** device requesting the cancellation */\n public readonly deviceId: string;\n /** unique id for the request to be cancelled */\n public readonly requestId: string;\n\n public constructor(event: MatrixEvent) {\n const content = event.getContent();\n\n this.userId = event.getSender()!;\n this.deviceId = content.requesting_device_id;\n this.requestId = content.request_id;\n }\n}\n\n// a number of types are re-exported for backwards compatibility, in case any applications are referencing it.\nexport type { IEventDecryptionResult, IMegolmSessionData } from \"../@types/crypto\";\n"],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/key_passphrase.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/key_passphrase.d.ts
deleted file mode 100644
index 0ca19fd..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/key_passphrase.d.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-interface IAuthData {
- private_key_salt?: string;
- private_key_iterations?: number;
- private_key_bits?: number;
-}
-interface IKey {
- key: Uint8Array;
- salt: string;
- iterations: number;
-}
-export declare function keyFromAuthData(authData: IAuthData, password: string): Promise<Uint8Array>;
-export declare function keyFromPassphrase(password: string): Promise<IKey>;
-export declare function deriveKey(password: string, salt: string, iterations: number, numBits?: number): Promise<Uint8Array>;
-export {};
-//# sourceMappingURL=key_passphrase.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/key_passphrase.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/key_passphrase.d.ts.map
deleted file mode 100644
index dd8646a..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/key_passphrase.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"key_passphrase.d.ts","sourceRoot":"","sources":["../../src/crypto/key_passphrase.ts"],"names":[],"mappings":"AAwBA,UAAU,SAAS;IACf,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAGD,UAAU,IAAI;IACV,GAAG,EAAE,UAAU,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAe1F;AAED,wBAAsB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAUvE;AAED,wBAAsB,SAAS,CAC3B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,OAAO,SAAkB,GAC1B,OAAO,CAAC,UAAU,CAAC,CAqBrB"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/key_passphrase.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/key_passphrase.js
deleted file mode 100644
index 4ebe4ec..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/key_passphrase.js
+++ /dev/null
@@ -1,68 +0,0 @@
-"use strict";
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.deriveKey = deriveKey;
-exports.keyFromAuthData = keyFromAuthData;
-exports.keyFromPassphrase = keyFromPassphrase;
-var _randomstring = require("../randomstring");
-var _crypto = require("./crypto");
-/*
-Copyright 2018 - 2021 The Matrix.org Foundation C.I.C.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-const DEFAULT_ITERATIONS = 500000;
-const DEFAULT_BITSIZE = 256;
-
-/* eslint-disable camelcase */
-
-function keyFromAuthData(authData, password) {
- if (!global.Olm) {
- throw new Error("Olm is not available");
- }
- if (!authData.private_key_salt || !authData.private_key_iterations) {
- throw new Error("Salt and/or iterations not found: " + "this backup cannot be restored with a passphrase");
- }
- return deriveKey(password, authData.private_key_salt, authData.private_key_iterations, authData.private_key_bits || DEFAULT_BITSIZE);
-}
-async function keyFromPassphrase(password) {
- if (!global.Olm) {
- throw new Error("Olm is not available");
- }
- const salt = (0, _randomstring.randomString)(32);
- const key = await deriveKey(password, salt, DEFAULT_ITERATIONS, DEFAULT_BITSIZE);
- return {
- key,
- salt,
- iterations: DEFAULT_ITERATIONS
- };
-}
-async function deriveKey(password, salt, iterations, numBits = DEFAULT_BITSIZE) {
- if (!_crypto.subtleCrypto || !_crypto.TextEncoder) {
- throw new Error("Password-based backup is not available on this platform");
- }
- const key = await _crypto.subtleCrypto.importKey("raw", new _crypto.TextEncoder().encode(password), {
- name: "PBKDF2"
- }, false, ["deriveBits"]);
- const keybits = await _crypto.subtleCrypto.deriveBits({
- name: "PBKDF2",
- salt: new _crypto.TextEncoder().encode(salt),
- iterations: iterations,
- hash: "SHA-512"
- }, key, numBits);
- return new Uint8Array(keybits);
-}
-//# sourceMappingURL=key_passphrase.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/key_passphrase.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/key_passphrase.js.map
deleted file mode 100644
index 9429e8b..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/key_passphrase.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"key_passphrase.js","names":["_randomstring","require","_crypto","DEFAULT_ITERATIONS","DEFAULT_BITSIZE","keyFromAuthData","authData","password","global","Olm","Error","private_key_salt","private_key_iterations","deriveKey","private_key_bits","keyFromPassphrase","salt","randomString","key","iterations","numBits","subtleCrypto","TextEncoder","importKey","encode","name","keybits","deriveBits","hash","Uint8Array"],"sources":["../../src/crypto/key_passphrase.ts"],"sourcesContent":["/*\nCopyright 2018 - 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { randomString } from \"../randomstring\";\nimport { subtleCrypto, TextEncoder } from \"./crypto\";\n\nconst DEFAULT_ITERATIONS = 500000;\n\nconst DEFAULT_BITSIZE = 256;\n\n/* eslint-disable camelcase */\ninterface IAuthData {\n private_key_salt?: string;\n private_key_iterations?: number;\n private_key_bits?: number;\n}\n/* eslint-enable camelcase */\n\ninterface IKey {\n key: Uint8Array;\n salt: string;\n iterations: number;\n}\n\nexport function keyFromAuthData(authData: IAuthData, password: string): Promise<Uint8Array> {\n if (!global.Olm) {\n throw new Error(\"Olm is not available\");\n }\n\n if (!authData.private_key_salt || !authData.private_key_iterations) {\n throw new Error(\"Salt and/or iterations not found: \" + \"this backup cannot be restored with a passphrase\");\n }\n\n return deriveKey(\n password,\n authData.private_key_salt,\n authData.private_key_iterations,\n authData.private_key_bits || DEFAULT_BITSIZE,\n );\n}\n\nexport async function keyFromPassphrase(password: string): Promise<IKey> {\n if (!global.Olm) {\n throw new Error(\"Olm is not available\");\n }\n\n const salt = randomString(32);\n\n const key = await deriveKey(password, salt, DEFAULT_ITERATIONS, DEFAULT_BITSIZE);\n\n return { key, salt, iterations: DEFAULT_ITERATIONS };\n}\n\nexport async function deriveKey(\n password: string,\n salt: string,\n iterations: number,\n numBits = DEFAULT_BITSIZE,\n): Promise<Uint8Array> {\n if (!subtleCrypto || !TextEncoder) {\n throw new Error(\"Password-based backup is not available on this platform\");\n }\n\n const key = await subtleCrypto.importKey(\"raw\", new TextEncoder().encode(password), { name: \"PBKDF2\" }, false, [\n \"deriveBits\",\n ]);\n\n const keybits = await subtleCrypto.deriveBits(\n {\n name: \"PBKDF2\",\n salt: new TextEncoder().encode(salt),\n iterations: iterations,\n hash: \"SHA-512\",\n },\n key,\n numBits,\n );\n\n return new Uint8Array(keybits);\n}\n"],"mappings":";;;;;;;;AAgBA,IAAAA,aAAA,GAAAC,OAAA;AACA,IAAAC,OAAA,GAAAD,OAAA;AAjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAKA,MAAME,kBAAkB,GAAG,MAAM;AAEjC,MAAMC,eAAe,GAAG,GAAG;;AAE3B;;AAcO,SAASC,eAAeA,CAACC,QAAmB,EAAEC,QAAgB,EAAuB;EACxF,IAAI,CAACC,MAAM,CAACC,GAAG,EAAE;IACb,MAAM,IAAIC,KAAK,CAAC,sBAAsB,CAAC;EAC3C;EAEA,IAAI,CAACJ,QAAQ,CAACK,gBAAgB,IAAI,CAACL,QAAQ,CAACM,sBAAsB,EAAE;IAChE,MAAM,IAAIF,KAAK,CAAC,oCAAoC,GAAG,kDAAkD,CAAC;EAC9G;EAEA,OAAOG,SAAS,CACZN,QAAQ,EACRD,QAAQ,CAACK,gBAAgB,EACzBL,QAAQ,CAACM,sBAAsB,EAC/BN,QAAQ,CAACQ,gBAAgB,IAAIV,eAAe,CAC/C;AACL;AAEO,eAAeW,iBAAiBA,CAACR,QAAgB,EAAiB;EACrE,IAAI,CAACC,MAAM,CAACC,GAAG,EAAE;IACb,MAAM,IAAIC,KAAK,CAAC,sBAAsB,CAAC;EAC3C;EAEA,MAAMM,IAAI,GAAG,IAAAC,0BAAY,EAAC,EAAE,CAAC;EAE7B,MAAMC,GAAG,GAAG,MAAML,SAAS,CAACN,QAAQ,EAAES,IAAI,EAAEb,kBAAkB,EAAEC,eAAe,CAAC;EAEhF,OAAO;IAAEc,GAAG;IAAEF,IAAI;IAAEG,UAAU,EAAEhB;EAAmB,CAAC;AACxD;AAEO,eAAeU,SAASA,CAC3BN,QAAgB,EAChBS,IAAY,EACZG,UAAkB,EAClBC,OAAO,GAAGhB,eAAe,EACN;EACnB,IAAI,CAACiB,oBAAY,IAAI,CAACC,mBAAW,EAAE;IAC/B,MAAM,IAAIZ,KAAK,CAAC,yDAAyD,CAAC;EAC9E;EAEA,MAAMQ,GAAG,GAAG,MAAMG,oBAAY,CAACE,SAAS,CAAC,KAAK,EAAE,IAAID,mBAAW,EAAE,CAACE,MAAM,CAACjB,QAAQ,CAAC,EAAE;IAAEkB,IAAI,EAAE;EAAS,CAAC,EAAE,KAAK,EAAE,CAC3G,YAAY,CACf,CAAC;EAEF,MAAMC,OAAO,GAAG,MAAML,oBAAY,CAACM,UAAU,CACzC;IACIF,IAAI,EAAE,QAAQ;IACdT,IAAI,EAAE,IAAIM,mBAAW,EAAE,CAACE,MAAM,CAACR,IAAI,CAAC;IACpCG,UAAU,EAAEA,UAAU;IACtBS,IAAI,EAAE;EACV,CAAC,EACDV,GAAG,EACHE,OAAO,CACV;EAED,OAAO,IAAIS,UAAU,CAACH,OAAO,CAAC;AAClC"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/keybackup.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/keybackup.d.ts
deleted file mode 100644
index 3e46e9e..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/keybackup.d.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-import { ISigned } from "../@types/signed";
-import { IEncryptedPayload } from "./aes";
-export interface Curve25519SessionData {
- ciphertext: string;
- ephemeral: string;
- mac: string;
-}
-export interface IKeyBackupSession<T = Curve25519SessionData | IEncryptedPayload> {
- first_message_index: number;
- forwarded_count: number;
- is_verified: boolean;
- session_data: T;
-}
-export interface IKeyBackupRoomSessions {
- [sessionId: string]: IKeyBackupSession;
-}
-export interface ICurve25519AuthData {
- public_key: string;
- private_key_salt?: string;
- private_key_iterations?: number;
- private_key_bits?: number;
-}
-export interface IAes256AuthData {
- iv: string;
- mac: string;
- private_key_salt?: string;
- private_key_iterations?: number;
-}
-export interface IKeyBackupInfo {
- algorithm: string;
- auth_data: ISigned & (ICurve25519AuthData | IAes256AuthData);
- count?: number;
- etag?: string;
- version?: string;
-}
-export interface IKeyBackupPrepareOpts {
- /**
- * Whether to use Secure Secret Storage to store the key encrypting key backups.
- * Optional, defaults to false.
- */
- secureSecretStorage: boolean;
-}
-export interface IKeyBackupRestoreResult {
- total: number;
- imported: number;
-}
-export interface IKeyBackupRestoreOpts {
- cacheCompleteCallback?: () => void;
- progressCallback?: (progress: {
- stage: string;
- }) => void;
-}
-//# sourceMappingURL=keybackup.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/keybackup.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/keybackup.d.ts.map
deleted file mode 100644
index 0d54fcc..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/keybackup.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"keybackup.d.ts","sourceRoot":"","sources":["../../src/crypto/keybackup.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAE1C,MAAM,WAAW,qBAAqB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;CACf;AAGD,MAAM,WAAW,iBAAiB,CAAC,CAAC,GAAG,qBAAqB,GAAG,iBAAiB;IAC5E,mBAAmB,EAAE,MAAM,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,OAAO,CAAC;IACrB,YAAY,EAAE,CAAC,CAAC;CACnB;AAED,MAAM,WAAW,sBAAsB;IACnC,CAAC,SAAS,EAAE,MAAM,GAAG,iBAAiB,CAAC;CAC1C;AAED,MAAM,WAAW,mBAAmB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,eAAe;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACnC;AAED,MAAM,WAAW,cAAc;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,OAAO,GAAG,CAAC,mBAAmB,GAAG,eAAe,CAAC,CAAC;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAGD,MAAM,WAAW,qBAAqB;IAClC;;;OAGG;IACH,mBAAmB,EAAE,OAAO,CAAC;CAChC;AAED,MAAM,WAAW,uBAAuB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IAClC,qBAAqB,CAAC,EAAE,MAAM,IAAI,CAAC;IACnC,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CAC5D"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/keybackup.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/keybackup.js
deleted file mode 100644
index ad0a8ab..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/keybackup.js
+++ /dev/null
@@ -1,6 +0,0 @@
-"use strict";
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-//# sourceMappingURL=keybackup.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/keybackup.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/keybackup.js.map
deleted file mode 100644
index e54a145..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/keybackup.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"keybackup.js","names":[],"sources":["../../src/crypto/keybackup.ts"],"sourcesContent":["/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { ISigned } from \"../@types/signed\";\nimport { IEncryptedPayload } from \"./aes\";\n\nexport interface Curve25519SessionData {\n ciphertext: string;\n ephemeral: string;\n mac: string;\n}\n\n/* eslint-disable camelcase */\nexport interface IKeyBackupSession<T = Curve25519SessionData | IEncryptedPayload> {\n first_message_index: number;\n forwarded_count: number;\n is_verified: boolean;\n session_data: T;\n}\n\nexport interface IKeyBackupRoomSessions {\n [sessionId: string]: IKeyBackupSession;\n}\n\nexport interface ICurve25519AuthData {\n public_key: string;\n private_key_salt?: string;\n private_key_iterations?: number;\n private_key_bits?: number;\n}\n\nexport interface IAes256AuthData {\n iv: string;\n mac: string;\n private_key_salt?: string;\n private_key_iterations?: number;\n}\n\nexport interface IKeyBackupInfo {\n algorithm: string;\n auth_data: ISigned & (ICurve25519AuthData | IAes256AuthData);\n count?: number;\n etag?: string;\n version?: string; // number contained within\n}\n/* eslint-enable camelcase */\n\nexport interface IKeyBackupPrepareOpts {\n /**\n * Whether to use Secure Secret Storage to store the key encrypting key backups.\n * Optional, defaults to false.\n */\n secureSecretStorage: boolean;\n}\n\nexport interface IKeyBackupRestoreResult {\n total: number;\n imported: number;\n}\n\nexport interface IKeyBackupRestoreOpts {\n cacheCompleteCallback?: () => void;\n progressCallback?: (progress: { stage: string }) => void;\n}\n"],"mappings":""} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/olmlib.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/olmlib.d.ts
deleted file mode 100644
index 18ee3c9..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/olmlib.d.ts
+++ /dev/null
@@ -1,146 +0,0 @@
-import type { PkSigning } from "@matrix-org/olm";
-import type { IOneTimeKey } from "../@types/crypto";
-import { OlmDevice } from "./OlmDevice";
-import { DeviceInfo } from "./deviceinfo";
-import { MatrixClient } from "../client";
-import { ISignatures } from "../@types/signed";
-import { MatrixEvent } from "../models/event";
-import { IMessage } from "./algorithms/olm";
-declare enum Algorithm {
- Olm = "m.olm.v1.curve25519-aes-sha2",
- Megolm = "m.megolm.v1.aes-sha2",
- MegolmBackup = "m.megolm_backup.v1.curve25519-aes-sha2"
-}
-/**
- * matrix algorithm tag for olm
- */
-export declare const OLM_ALGORITHM = Algorithm.Olm;
-/**
- * matrix algorithm tag for megolm
- */
-export declare const MEGOLM_ALGORITHM = Algorithm.Megolm;
-/**
- * matrix algorithm tag for megolm backups
- */
-export declare const MEGOLM_BACKUP_ALGORITHM = Algorithm.MegolmBackup;
-export interface IOlmSessionResult {
- /** device info */
- device: DeviceInfo;
- /** base64 olm session id; null if no session could be established */
- sessionId: string | null;
-}
-/**
- * Encrypt an event payload for an Olm device
- *
- * @param resultsObject - The `ciphertext` property
- * of the m.room.encrypted event to which to add our result
- *
- * @param olmDevice - olm.js wrapper
- * @param payloadFields - fields to include in the encrypted payload
- *
- * Returns a promise which resolves (to undefined) when the payload
- * has been encrypted into `resultsObject`
- */
-export declare function encryptMessageForDevice(resultsObject: Record<string, IMessage>, ourUserId: string, ourDeviceId: string | undefined, olmDevice: OlmDevice, recipientUserId: string, recipientDevice: DeviceInfo, payloadFields: Record<string, any>): Promise<void>;
-interface IExistingOlmSession {
- device: DeviceInfo;
- sessionId: string | null;
-}
-/**
- * Get the existing olm sessions for the given devices, and the devices that
- * don't have olm sessions.
- *
- *
- *
- * @param devicesByUser - map from userid to list of devices to ensure sessions for
- *
- * @returns resolves to an array. The first element of the array is a
- * a map of user IDs to arrays of deviceInfo, representing the devices that
- * don't have established olm sessions. The second element of the array is
- * a map from userId to deviceId to {@link OlmSessionResult}
- */
-export declare function getExistingOlmSessions(olmDevice: OlmDevice, baseApis: MatrixClient, devicesByUser: Record<string, DeviceInfo[]>): Promise<[Map<string, DeviceInfo[]>, Map<string, Map<string, IExistingOlmSession>>]>;
-/**
- * Try to make sure we have established olm sessions for the given devices.
- *
- * @param devicesByUser - map from userid to list of devices to ensure sessions for
- *
- * @param force - If true, establish a new session even if one
- * already exists.
- *
- * @param otkTimeout - The timeout in milliseconds when requesting
- * one-time keys for establishing new olm sessions.
- *
- * @param failedServers - An array to fill with remote servers that
- * failed to respond to one-time-key requests.
- *
- * @param log - A possibly customised log
- *
- * @returns resolves once the sessions are complete, to
- * an Object mapping from userId to deviceId to
- * {@link OlmSessionResult}
- */
-export declare function ensureOlmSessionsForDevices(olmDevice: OlmDevice, baseApis: MatrixClient, devicesByUser: Map<string, DeviceInfo[]>, force?: boolean, otkTimeout?: number, failedServers?: string[], log?: import("../logger").PrefixedLogger): Promise<Map<string, Map<string, IOlmSessionResult>>>;
-export interface IObject {
- unsigned?: object;
- signatures?: ISignatures;
-}
-/**
- * Verify the signature on an object
- *
- * @param olmDevice - olm wrapper to use for verify op
- *
- * @param obj - object to check signature on.
- *
- * @param signingUserId - ID of the user whose signature should be checked
- *
- * @param signingDeviceId - ID of the device whose signature should be checked
- *
- * @param signingKey - base64-ed ed25519 public key
- *
- * Returns a promise which resolves (to undefined) if the the signature is good,
- * or rejects with an Error if it is bad.
- */
-export declare function verifySignature(olmDevice: OlmDevice, obj: IOneTimeKey | IObject, signingUserId: string, signingDeviceId: string, signingKey: string): Promise<void>;
-/**
- * Sign a JSON object using public key cryptography
- * @param obj - Object to sign. The object will be modified to include
- * the new signature
- * @param key - the signing object or the private key
- * seed
- * @param userId - The user ID who owns the signing key
- * @param pubKey - The public key (ignored if key is a seed)
- * @returns the signature for the object
- */
-export declare function pkSign(obj: object & IObject, key: Uint8Array | PkSigning, userId: string, pubKey: string): string;
-/**
- * Verify a signed JSON object
- * @param obj - Object to verify
- * @param pubKey - The public key to use to verify
- * @param userId - The user ID who signed the object
- */
-export declare function pkVerify(obj: IObject, pubKey: string, userId: string): void;
-/**
- * Check that an event was encrypted using olm.
- */
-export declare function isOlmEncrypted(event: MatrixEvent): boolean;
-/**
- * Encode a typed array of uint8 as base64.
- * @param uint8Array - The data to encode.
- * @returns The base64.
- */
-export declare function encodeBase64(uint8Array: ArrayBuffer | Uint8Array): string;
-/**
- * Encode a typed array of uint8 as unpadded base64.
- * @param uint8Array - The data to encode.
- * @returns The unpadded base64.
- */
-export declare function encodeUnpaddedBase64(uint8Array: ArrayBuffer | Uint8Array): string;
-/**
- * Decode a base64 string to a typed array of uint8.
- * @param base64 - The base64 to decode.
- * @returns The decoded data.
- */
-export declare function decodeBase64(base64: string): Uint8Array;
-export {};
-//# sourceMappingURL=olmlib.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/olmlib.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/olmlib.d.ts.map
deleted file mode 100644
index 684b819..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/olmlib.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"olmlib.d.ts","sourceRoot":"","sources":["../../src/crypto/olmlib.ts"],"names":[],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/olmlib.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/olmlib.js
deleted file mode 100644
index 0b5b14c..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/olmlib.js
+++ /dev/null
@@ -1,467 +0,0 @@
-"use strict";
-
-var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.OLM_ALGORITHM = exports.MEGOLM_BACKUP_ALGORITHM = exports.MEGOLM_ALGORITHM = void 0;
-exports.decodeBase64 = decodeBase64;
-exports.encodeBase64 = encodeBase64;
-exports.encodeUnpaddedBase64 = encodeUnpaddedBase64;
-exports.encryptMessageForDevice = encryptMessageForDevice;
-exports.ensureOlmSessionsForDevices = ensureOlmSessionsForDevices;
-exports.getExistingOlmSessions = getExistingOlmSessions;
-exports.isOlmEncrypted = isOlmEncrypted;
-exports.pkSign = pkSign;
-exports.pkVerify = pkVerify;
-exports.verifySignature = verifySignature;
-var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
-var _anotherJson = _interopRequireDefault(require("another-json"));
-var _logger = require("../logger");
-var _event = require("../@types/event");
-var _utils = require("../utils");
-function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
-function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
-var Algorithm;
-/**
- * matrix algorithm tag for olm
- */
-(function (Algorithm) {
- Algorithm["Olm"] = "m.olm.v1.curve25519-aes-sha2";
- Algorithm["Megolm"] = "m.megolm.v1.aes-sha2";
- Algorithm["MegolmBackup"] = "m.megolm_backup.v1.curve25519-aes-sha2";
-})(Algorithm || (Algorithm = {}));
-const OLM_ALGORITHM = Algorithm.Olm;
-
-/**
- * matrix algorithm tag for megolm
- */
-exports.OLM_ALGORITHM = OLM_ALGORITHM;
-const MEGOLM_ALGORITHM = Algorithm.Megolm;
-
-/**
- * matrix algorithm tag for megolm backups
- */
-exports.MEGOLM_ALGORITHM = MEGOLM_ALGORITHM;
-const MEGOLM_BACKUP_ALGORITHM = Algorithm.MegolmBackup;
-exports.MEGOLM_BACKUP_ALGORITHM = MEGOLM_BACKUP_ALGORITHM;
-/**
- * Encrypt an event payload for an Olm device
- *
- * @param resultsObject - The `ciphertext` property
- * of the m.room.encrypted event to which to add our result
- *
- * @param olmDevice - olm.js wrapper
- * @param payloadFields - fields to include in the encrypted payload
- *
- * Returns a promise which resolves (to undefined) when the payload
- * has been encrypted into `resultsObject`
- */
-async function encryptMessageForDevice(resultsObject, ourUserId, ourDeviceId, olmDevice, recipientUserId, recipientDevice, payloadFields) {
- const deviceKey = recipientDevice.getIdentityKey();
- const sessionId = await olmDevice.getSessionIdForDevice(deviceKey);
- if (sessionId === null) {
- // If we don't have a session for a device then
- // we can't encrypt a message for it.
- _logger.logger.log(`[olmlib.encryptMessageForDevice] Unable to find Olm session for device ` + `${recipientUserId}:${recipientDevice.deviceId}`);
- return;
- }
- _logger.logger.log(`[olmlib.encryptMessageForDevice] Using Olm session ${sessionId} for device ` + `${recipientUserId}:${recipientDevice.deviceId}`);
- const payload = _objectSpread({
- sender: ourUserId,
- // TODO this appears to no longer be used whatsoever
- sender_device: ourDeviceId,
- // Include the Ed25519 key so that the recipient knows what
- // device this message came from.
- // We don't need to include the curve25519 key since the
- // recipient will already know this from the olm headers.
- // When combined with the device keys retrieved from the
- // homeserver signed by the ed25519 key this proves that
- // the curve25519 key and the ed25519 key are owned by
- // the same device.
- keys: {
- ed25519: olmDevice.deviceEd25519Key
- },
- // include the recipient device details in the payload,
- // to avoid unknown key attacks, per
- // https://github.com/vector-im/vector-web/issues/2483
- recipient: recipientUserId,
- recipient_keys: {
- ed25519: recipientDevice.getFingerprint()
- }
- }, payloadFields);
-
- // TODO: technically, a bunch of that stuff only needs to be included for
- // pre-key messages: after that, both sides know exactly which devices are
- // involved in the session. If we're looking to reduce data transfer in the
- // future, we could elide them for subsequent messages.
-
- resultsObject[deviceKey] = await olmDevice.encryptMessage(deviceKey, sessionId, JSON.stringify(payload));
-}
-/**
- * Get the existing olm sessions for the given devices, and the devices that
- * don't have olm sessions.
- *
- *
- *
- * @param devicesByUser - map from userid to list of devices to ensure sessions for
- *
- * @returns resolves to an array. The first element of the array is a
- * a map of user IDs to arrays of deviceInfo, representing the devices that
- * don't have established olm sessions. The second element of the array is
- * a map from userId to deviceId to {@link OlmSessionResult}
- */
-async function getExistingOlmSessions(olmDevice, baseApis, devicesByUser) {
- // map user Id → DeviceInfo[]
- const devicesWithoutSession = new _utils.MapWithDefault(() => []);
- // map user Id → device Id → IExistingOlmSession
- const sessions = new _utils.MapWithDefault(() => new Map());
- const promises = [];
- for (const [userId, devices] of Object.entries(devicesByUser)) {
- for (const deviceInfo of devices) {
- const deviceId = deviceInfo.deviceId;
- const key = deviceInfo.getIdentityKey();
- promises.push((async () => {
- const sessionId = await olmDevice.getSessionIdForDevice(key, true);
- if (sessionId === null) {
- devicesWithoutSession.getOrCreate(userId).push(deviceInfo);
- } else {
- sessions.getOrCreate(userId).set(deviceId, {
- device: deviceInfo,
- sessionId: sessionId
- });
- }
- })());
- }
- }
- await Promise.all(promises);
- return [devicesWithoutSession, sessions];
-}
-
-/**
- * Try to make sure we have established olm sessions for the given devices.
- *
- * @param devicesByUser - map from userid to list of devices to ensure sessions for
- *
- * @param force - If true, establish a new session even if one
- * already exists.
- *
- * @param otkTimeout - The timeout in milliseconds when requesting
- * one-time keys for establishing new olm sessions.
- *
- * @param failedServers - An array to fill with remote servers that
- * failed to respond to one-time-key requests.
- *
- * @param log - A possibly customised log
- *
- * @returns resolves once the sessions are complete, to
- * an Object mapping from userId to deviceId to
- * {@link OlmSessionResult}
- */
-async function ensureOlmSessionsForDevices(olmDevice, baseApis, devicesByUser, force = false, otkTimeout, failedServers, log = _logger.logger) {
- const devicesWithoutSession = [
- // [userId, deviceId], ...
- ];
- // map user Id → device Id → IExistingOlmSession
- const result = new Map();
- // map device key → resolve session fn
- const resolveSession = new Map();
-
- // Mark all sessions this task intends to update as in progress. It is
- // important to do this for all devices this task cares about in a single
- // synchronous operation, as otherwise it is possible to have deadlocks
- // where multiple tasks wait indefinitely on another task to update some set
- // of common devices.
- for (const devices of devicesByUser.values()) {
- for (const deviceInfo of devices) {
- const key = deviceInfo.getIdentityKey();
- if (key === olmDevice.deviceCurve25519Key) {
- // We don't start sessions with ourself, so there's no need to
- // mark it in progress.
- continue;
- }
- if (!olmDevice.sessionsInProgress[key]) {
- // pre-emptively mark the session as in-progress to avoid race
- // conditions. If we find that we already have a session, then
- // we'll resolve
- olmDevice.sessionsInProgress[key] = new Promise(resolve => {
- resolveSession.set(key, v => {
- delete olmDevice.sessionsInProgress[key];
- resolve(v);
- });
- });
- }
- }
- }
- for (const [userId, devices] of devicesByUser) {
- const resultDevices = new Map();
- result.set(userId, resultDevices);
- for (const deviceInfo of devices) {
- const deviceId = deviceInfo.deviceId;
- const key = deviceInfo.getIdentityKey();
- if (key === olmDevice.deviceCurve25519Key) {
- // We should never be trying to start a session with ourself.
- // Apart from talking to yourself being the first sign of madness,
- // olm sessions can't do this because they get confused when
- // they get a message and see that the 'other side' has started a
- // new chain when this side has an active sender chain.
- // If you see this message being logged in the wild, we should find
- // the thing that is trying to send Olm messages to itself and fix it.
- log.info("Attempted to start session with ourself! Ignoring");
- // We must fill in the section in the return value though, as callers
- // expect it to be there.
- resultDevices.set(deviceId, {
- device: deviceInfo,
- sessionId: null
- });
- continue;
- }
- const forWhom = `for ${key} (${userId}:${deviceId})`;
- const sessionId = await olmDevice.getSessionIdForDevice(key, !!resolveSession.get(key), log);
- const resolveSessionFn = resolveSession.get(key);
- if (sessionId !== null && resolveSessionFn) {
- // we found a session, but we had marked the session as
- // in-progress, so resolve it now, which will unmark it and
- // unblock anything that was waiting
- resolveSessionFn();
- }
- if (sessionId === null || force) {
- if (force) {
- log.info(`Forcing new Olm session ${forWhom}`);
- } else {
- log.info(`Making new Olm session ${forWhom}`);
- }
- devicesWithoutSession.push([userId, deviceId]);
- }
- resultDevices.set(deviceId, {
- device: deviceInfo,
- sessionId: sessionId
- });
- }
- }
- if (devicesWithoutSession.length === 0) {
- return result;
- }
- const oneTimeKeyAlgorithm = "signed_curve25519";
- let res;
- let taskDetail = `one-time keys for ${devicesWithoutSession.length} devices`;
- try {
- log.debug(`Claiming ${taskDetail}`);
- res = await baseApis.claimOneTimeKeys(devicesWithoutSession, oneTimeKeyAlgorithm, otkTimeout);
- log.debug(`Claimed ${taskDetail}`);
- } catch (e) {
- for (const resolver of resolveSession.values()) {
- resolver();
- }
- log.log(`Failed to claim ${taskDetail}`, e, devicesWithoutSession);
- throw e;
- }
- if (failedServers && "failures" in res) {
- failedServers.push(...Object.keys(res.failures));
- }
- const otkResult = res.one_time_keys || {};
- const promises = [];
- for (const [userId, devices] of devicesByUser) {
- const userRes = otkResult[userId] || {};
- for (const deviceInfo of devices) {
- var _result$get, _result$get$get;
- const deviceId = deviceInfo.deviceId;
- const key = deviceInfo.getIdentityKey();
- if (key === olmDevice.deviceCurve25519Key) {
- // We've already logged about this above. Skip here too
- // otherwise we'll log saying there are no one-time keys
- // which will be confusing.
- continue;
- }
- if ((_result$get = result.get(userId)) !== null && _result$get !== void 0 && (_result$get$get = _result$get.get(deviceId)) !== null && _result$get$get !== void 0 && _result$get$get.sessionId && !force) {
- // we already have a result for this device
- continue;
- }
- const deviceRes = userRes[deviceId] || {};
- let oneTimeKey = null;
- for (const keyId in deviceRes) {
- if (keyId.indexOf(oneTimeKeyAlgorithm + ":") === 0) {
- oneTimeKey = deviceRes[keyId];
- }
- }
- if (!oneTimeKey) {
- var _resolveSession$get;
- log.warn(`No one-time keys (alg=${oneTimeKeyAlgorithm}) ` + `for device ${userId}:${deviceId}`);
- (_resolveSession$get = resolveSession.get(key)) === null || _resolveSession$get === void 0 ? void 0 : _resolveSession$get();
- continue;
- }
- promises.push(_verifyKeyAndStartSession(olmDevice, oneTimeKey, userId, deviceInfo).then(sid => {
- var _resolveSession$get2, _result$get2;
- (_resolveSession$get2 = resolveSession.get(key)) === null || _resolveSession$get2 === void 0 ? void 0 : _resolveSession$get2(sid !== null && sid !== void 0 ? sid : undefined);
- const deviceInfo = (_result$get2 = result.get(userId)) === null || _result$get2 === void 0 ? void 0 : _result$get2.get(deviceId);
- if (deviceInfo) deviceInfo.sessionId = sid;
- }, e => {
- var _resolveSession$get3;
- (_resolveSession$get3 = resolveSession.get(key)) === null || _resolveSession$get3 === void 0 ? void 0 : _resolveSession$get3();
- throw e;
- }));
- }
- }
- taskDetail = `Olm sessions for ${promises.length} devices`;
- log.debug(`Starting ${taskDetail}`);
- await Promise.all(promises);
- log.debug(`Started ${taskDetail}`);
- return result;
-}
-async function _verifyKeyAndStartSession(olmDevice, oneTimeKey, userId, deviceInfo) {
- const deviceId = deviceInfo.deviceId;
- try {
- await verifySignature(olmDevice, oneTimeKey, userId, deviceId, deviceInfo.getFingerprint());
- } catch (e) {
- _logger.logger.error("Unable to verify signature on one-time key for device " + userId + ":" + deviceId + ":", e);
- return null;
- }
- let sid;
- try {
- sid = await olmDevice.createOutboundSession(deviceInfo.getIdentityKey(), oneTimeKey.key);
- } catch (e) {
- // possibly a bad key
- _logger.logger.error("Error starting olm session with device " + userId + ":" + deviceId + ": " + e);
- return null;
- }
- _logger.logger.log("Started new olm sessionid " + sid + " for device " + userId + ":" + deviceId);
- return sid;
-}
-/**
- * Verify the signature on an object
- *
- * @param olmDevice - olm wrapper to use for verify op
- *
- * @param obj - object to check signature on.
- *
- * @param signingUserId - ID of the user whose signature should be checked
- *
- * @param signingDeviceId - ID of the device whose signature should be checked
- *
- * @param signingKey - base64-ed ed25519 public key
- *
- * Returns a promise which resolves (to undefined) if the the signature is good,
- * or rejects with an Error if it is bad.
- */
-async function verifySignature(olmDevice, obj, signingUserId, signingDeviceId, signingKey) {
- const signKeyId = "ed25519:" + signingDeviceId;
- const signatures = obj.signatures || {};
- const userSigs = signatures[signingUserId] || {};
- const signature = userSigs[signKeyId];
- if (!signature) {
- throw Error("No signature");
- }
-
- // prepare the canonical json: remove unsigned and signatures, and stringify with anotherjson
- const mangledObj = Object.assign({}, obj);
- if ("unsigned" in mangledObj) {
- delete mangledObj.unsigned;
- }
- delete mangledObj.signatures;
- const json = _anotherJson.default.stringify(mangledObj);
- olmDevice.verifySignature(signingKey, json, signature);
-}
-
-/**
- * Sign a JSON object using public key cryptography
- * @param obj - Object to sign. The object will be modified to include
- * the new signature
- * @param key - the signing object or the private key
- * seed
- * @param userId - The user ID who owns the signing key
- * @param pubKey - The public key (ignored if key is a seed)
- * @returns the signature for the object
- */
-function pkSign(obj, key, userId, pubKey) {
- let createdKey = false;
- if (key instanceof Uint8Array) {
- const keyObj = new global.Olm.PkSigning();
- pubKey = keyObj.init_with_seed(key);
- key = keyObj;
- createdKey = true;
- }
- const sigs = obj.signatures || {};
- delete obj.signatures;
- const unsigned = obj.unsigned;
- if (obj.unsigned) delete obj.unsigned;
- try {
- const mysigs = sigs[userId] || {};
- sigs[userId] = mysigs;
- return mysigs["ed25519:" + pubKey] = key.sign(_anotherJson.default.stringify(obj));
- } finally {
- obj.signatures = sigs;
- if (unsigned) obj.unsigned = unsigned;
- if (createdKey) {
- key.free();
- }
- }
-}
-
-/**
- * Verify a signed JSON object
- * @param obj - Object to verify
- * @param pubKey - The public key to use to verify
- * @param userId - The user ID who signed the object
- */
-function pkVerify(obj, pubKey, userId) {
- const keyId = "ed25519:" + pubKey;
- if (!(obj.signatures && obj.signatures[userId] && obj.signatures[userId][keyId])) {
- throw new Error("No signature");
- }
- const signature = obj.signatures[userId][keyId];
- const util = new global.Olm.Utility();
- const sigs = obj.signatures;
- delete obj.signatures;
- const unsigned = obj.unsigned;
- if (obj.unsigned) delete obj.unsigned;
- try {
- util.ed25519_verify(pubKey, _anotherJson.default.stringify(obj), signature);
- } finally {
- obj.signatures = sigs;
- if (unsigned) obj.unsigned = unsigned;
- util.free();
- }
-}
-
-/**
- * Check that an event was encrypted using olm.
- */
-function isOlmEncrypted(event) {
- if (!event.getSenderKey()) {
- _logger.logger.error("Event has no sender key (not encrypted?)");
- return false;
- }
- if (event.getWireType() !== _event.EventType.RoomMessageEncrypted || !["m.olm.v1.curve25519-aes-sha2"].includes(event.getWireContent().algorithm)) {
- _logger.logger.error("Event was not encrypted using an appropriate algorithm");
- return false;
- }
- return true;
-}
-
-/**
- * Encode a typed array of uint8 as base64.
- * @param uint8Array - The data to encode.
- * @returns The base64.
- */
-function encodeBase64(uint8Array) {
- return Buffer.from(uint8Array).toString("base64");
-}
-
-/**
- * Encode a typed array of uint8 as unpadded base64.
- * @param uint8Array - The data to encode.
- * @returns The unpadded base64.
- */
-function encodeUnpaddedBase64(uint8Array) {
- return encodeBase64(uint8Array).replace(/=+$/g, "");
-}
-
-/**
- * Decode a base64 string to a typed array of uint8.
- * @param base64 - The base64 to decode.
- * @returns The decoded data.
- */
-function decodeBase64(base64) {
- return Buffer.from(base64, "base64");
-}
-//# sourceMappingURL=olmlib.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/olmlib.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/olmlib.js.map
deleted file mode 100644
index ebd886f..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/olmlib.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"olmlib.js","names":["_anotherJson","_interopRequireDefault","require","_logger","_event","_utils","ownKeys","object","enumerableOnly","keys","Object","getOwnPropertySymbols","symbols","filter","sym","getOwnPropertyDescriptor","enumerable","push","apply","_objectSpread","target","i","arguments","length","source","forEach","key","_defineProperty2","default","getOwnPropertyDescriptors","defineProperties","defineProperty","Algorithm","OLM_ALGORITHM","Olm","exports","MEGOLM_ALGORITHM","Megolm","MEGOLM_BACKUP_ALGORITHM","MegolmBackup","encryptMessageForDevice","resultsObject","ourUserId","ourDeviceId","olmDevice","recipientUserId","recipientDevice","payloadFields","deviceKey","getIdentityKey","sessionId","getSessionIdForDevice","logger","log","deviceId","payload","sender","sender_device","ed25519","deviceEd25519Key","recipient","recipient_keys","getFingerprint","encryptMessage","JSON","stringify","getExistingOlmSessions","baseApis","devicesByUser","devicesWithoutSession","MapWithDefault","sessions","Map","promises","userId","devices","entries","deviceInfo","getOrCreate","set","device","Promise","all","ensureOlmSessionsForDevices","force","otkTimeout","failedServers","result","resolveSession","values","deviceCurve25519Key","sessionsInProgress","resolve","v","resultDevices","info","forWhom","get","resolveSessionFn","oneTimeKeyAlgorithm","res","taskDetail","debug","claimOneTimeKeys","e","resolver","failures","otkResult","one_time_keys","userRes","_result$get","_result$get$get","deviceRes","oneTimeKey","keyId","indexOf","_resolveSession$get","warn","_verifyKeyAndStartSession","then","sid","_resolveSession$get2","_result$get2","undefined","_resolveSession$get3","verifySignature","error","createOutboundSession","obj","signingUserId","signingDeviceId","signingKey","signKeyId","signatures","userSigs","signature","Error","mangledObj","assign","unsigned","json","anotherjson","pkSign","pubKey","createdKey","Uint8Array","keyObj","global","PkSigning","init_with_seed","sigs","mysigs","sign","free","pkVerify","util","Utility","ed25519_verify","isOlmEncrypted","event","getSenderKey","getWireType","EventType","RoomMessageEncrypted","includes","getWireContent","algorithm","encodeBase64","uint8Array","Buffer","from","toString","encodeUnpaddedBase64","replace","decodeBase64","base64"],"sources":["../../src/crypto/olmlib.ts"],"sourcesContent":["/*\nCopyright 2016 - 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n/**\n * Utilities common to olm encryption algorithms\n */\n\nimport anotherjson from \"another-json\";\n\nimport type { PkSigning } from \"@matrix-org/olm\";\nimport type { IOneTimeKey } from \"../@types/crypto\";\nimport { OlmDevice } from \"./OlmDevice\";\nimport { DeviceInfo } from \"./deviceinfo\";\nimport { logger } from \"../logger\";\nimport { IClaimOTKsResult, MatrixClient } from \"../client\";\nimport { ISignatures } from \"../@types/signed\";\nimport { MatrixEvent } from \"../models/event\";\nimport { EventType } from \"../@types/event\";\nimport { IMessage } from \"./algorithms/olm\";\nimport { MapWithDefault } from \"../utils\";\n\nenum Algorithm {\n Olm = \"m.olm.v1.curve25519-aes-sha2\",\n Megolm = \"m.megolm.v1.aes-sha2\",\n MegolmBackup = \"m.megolm_backup.v1.curve25519-aes-sha2\",\n}\n\n/**\n * matrix algorithm tag for olm\n */\nexport const OLM_ALGORITHM = Algorithm.Olm;\n\n/**\n * matrix algorithm tag for megolm\n */\nexport const MEGOLM_ALGORITHM = Algorithm.Megolm;\n\n/**\n * matrix algorithm tag for megolm backups\n */\nexport const MEGOLM_BACKUP_ALGORITHM = Algorithm.MegolmBackup;\n\nexport interface IOlmSessionResult {\n /** device info */\n device: DeviceInfo;\n /** base64 olm session id; null if no session could be established */\n sessionId: string | null;\n}\n\n/**\n * Encrypt an event payload for an Olm device\n *\n * @param resultsObject - The `ciphertext` property\n * of the m.room.encrypted event to which to add our result\n *\n * @param olmDevice - olm.js wrapper\n * @param payloadFields - fields to include in the encrypted payload\n *\n * Returns a promise which resolves (to undefined) when the payload\n * has been encrypted into `resultsObject`\n */\nexport async function encryptMessageForDevice(\n resultsObject: Record<string, IMessage>,\n ourUserId: string,\n ourDeviceId: string | undefined,\n olmDevice: OlmDevice,\n recipientUserId: string,\n recipientDevice: DeviceInfo,\n payloadFields: Record<string, any>,\n): Promise<void> {\n const deviceKey = recipientDevice.getIdentityKey();\n const sessionId = await olmDevice.getSessionIdForDevice(deviceKey);\n if (sessionId === null) {\n // If we don't have a session for a device then\n // we can't encrypt a message for it.\n logger.log(\n `[olmlib.encryptMessageForDevice] Unable to find Olm session for device ` +\n `${recipientUserId}:${recipientDevice.deviceId}`,\n );\n return;\n }\n\n logger.log(\n `[olmlib.encryptMessageForDevice] Using Olm session ${sessionId} for device ` +\n `${recipientUserId}:${recipientDevice.deviceId}`,\n );\n\n const payload = {\n sender: ourUserId,\n // TODO this appears to no longer be used whatsoever\n sender_device: ourDeviceId,\n\n // Include the Ed25519 key so that the recipient knows what\n // device this message came from.\n // We don't need to include the curve25519 key since the\n // recipient will already know this from the olm headers.\n // When combined with the device keys retrieved from the\n // homeserver signed by the ed25519 key this proves that\n // the curve25519 key and the ed25519 key are owned by\n // the same device.\n keys: {\n ed25519: olmDevice.deviceEd25519Key,\n },\n\n // include the recipient device details in the payload,\n // to avoid unknown key attacks, per\n // https://github.com/vector-im/vector-web/issues/2483\n recipient: recipientUserId,\n recipient_keys: {\n ed25519: recipientDevice.getFingerprint(),\n },\n ...payloadFields,\n };\n\n // TODO: technically, a bunch of that stuff only needs to be included for\n // pre-key messages: after that, both sides know exactly which devices are\n // involved in the session. If we're looking to reduce data transfer in the\n // future, we could elide them for subsequent messages.\n\n resultsObject[deviceKey] = await olmDevice.encryptMessage(deviceKey, sessionId, JSON.stringify(payload));\n}\n\ninterface IExistingOlmSession {\n device: DeviceInfo;\n sessionId: string | null;\n}\n\n/**\n * Get the existing olm sessions for the given devices, and the devices that\n * don't have olm sessions.\n *\n *\n *\n * @param devicesByUser - map from userid to list of devices to ensure sessions for\n *\n * @returns resolves to an array. The first element of the array is a\n * a map of user IDs to arrays of deviceInfo, representing the devices that\n * don't have established olm sessions. The second element of the array is\n * a map from userId to deviceId to {@link OlmSessionResult}\n */\nexport async function getExistingOlmSessions(\n olmDevice: OlmDevice,\n baseApis: MatrixClient,\n devicesByUser: Record<string, DeviceInfo[]>,\n): Promise<[Map<string, DeviceInfo[]>, Map<string, Map<string, IExistingOlmSession>>]> {\n // map user Id → DeviceInfo[]\n const devicesWithoutSession: MapWithDefault<string, DeviceInfo[]> = new MapWithDefault(() => []);\n // map user Id → device Id → IExistingOlmSession\n const sessions: MapWithDefault<string, Map<string, IExistingOlmSession>> = new MapWithDefault(() => new Map());\n\n const promises: Promise<void>[] = [];\n\n for (const [userId, devices] of Object.entries(devicesByUser)) {\n for (const deviceInfo of devices) {\n const deviceId = deviceInfo.deviceId;\n const key = deviceInfo.getIdentityKey();\n promises.push(\n (async (): Promise<void> => {\n const sessionId = await olmDevice.getSessionIdForDevice(key, true);\n if (sessionId === null) {\n devicesWithoutSession.getOrCreate(userId).push(deviceInfo);\n } else {\n sessions.getOrCreate(userId).set(deviceId, {\n device: deviceInfo,\n sessionId: sessionId,\n });\n }\n })(),\n );\n }\n }\n\n await Promise.all(promises);\n\n return [devicesWithoutSession, sessions];\n}\n\n/**\n * Try to make sure we have established olm sessions for the given devices.\n *\n * @param devicesByUser - map from userid to list of devices to ensure sessions for\n *\n * @param force - If true, establish a new session even if one\n * already exists.\n *\n * @param otkTimeout - The timeout in milliseconds when requesting\n * one-time keys for establishing new olm sessions.\n *\n * @param failedServers - An array to fill with remote servers that\n * failed to respond to one-time-key requests.\n *\n * @param log - A possibly customised log\n *\n * @returns resolves once the sessions are complete, to\n * an Object mapping from userId to deviceId to\n * {@link OlmSessionResult}\n */\nexport async function ensureOlmSessionsForDevices(\n olmDevice: OlmDevice,\n baseApis: MatrixClient,\n devicesByUser: Map<string, DeviceInfo[]>,\n force = false,\n otkTimeout?: number,\n failedServers?: string[],\n log = logger,\n): Promise<Map<string, Map<string, IOlmSessionResult>>> {\n const devicesWithoutSession: [string, string][] = [\n // [userId, deviceId], ...\n ];\n // map user Id → device Id → IExistingOlmSession\n const result: Map<string, Map<string, IExistingOlmSession>> = new Map();\n // map device key → resolve session fn\n const resolveSession: Map<string, (sessionId?: string) => void> = new Map();\n\n // Mark all sessions this task intends to update as in progress. It is\n // important to do this for all devices this task cares about in a single\n // synchronous operation, as otherwise it is possible to have deadlocks\n // where multiple tasks wait indefinitely on another task to update some set\n // of common devices.\n for (const devices of devicesByUser.values()) {\n for (const deviceInfo of devices) {\n const key = deviceInfo.getIdentityKey();\n\n if (key === olmDevice.deviceCurve25519Key) {\n // We don't start sessions with ourself, so there's no need to\n // mark it in progress.\n continue;\n }\n\n if (!olmDevice.sessionsInProgress[key]) {\n // pre-emptively mark the session as in-progress to avoid race\n // conditions. If we find that we already have a session, then\n // we'll resolve\n olmDevice.sessionsInProgress[key] = new Promise((resolve) => {\n resolveSession.set(key, (v: any): void => {\n delete olmDevice.sessionsInProgress[key];\n resolve(v);\n });\n });\n }\n }\n }\n\n for (const [userId, devices] of devicesByUser) {\n const resultDevices = new Map();\n result.set(userId, resultDevices);\n\n for (const deviceInfo of devices) {\n const deviceId = deviceInfo.deviceId;\n const key = deviceInfo.getIdentityKey();\n\n if (key === olmDevice.deviceCurve25519Key) {\n // We should never be trying to start a session with ourself.\n // Apart from talking to yourself being the first sign of madness,\n // olm sessions can't do this because they get confused when\n // they get a message and see that the 'other side' has started a\n // new chain when this side has an active sender chain.\n // If you see this message being logged in the wild, we should find\n // the thing that is trying to send Olm messages to itself and fix it.\n log.info(\"Attempted to start session with ourself! Ignoring\");\n // We must fill in the section in the return value though, as callers\n // expect it to be there.\n resultDevices.set(deviceId, {\n device: deviceInfo,\n sessionId: null,\n });\n continue;\n }\n\n const forWhom = `for ${key} (${userId}:${deviceId})`;\n const sessionId = await olmDevice.getSessionIdForDevice(key, !!resolveSession.get(key), log);\n const resolveSessionFn = resolveSession.get(key);\n if (sessionId !== null && resolveSessionFn) {\n // we found a session, but we had marked the session as\n // in-progress, so resolve it now, which will unmark it and\n // unblock anything that was waiting\n resolveSessionFn();\n }\n if (sessionId === null || force) {\n if (force) {\n log.info(`Forcing new Olm session ${forWhom}`);\n } else {\n log.info(`Making new Olm session ${forWhom}`);\n }\n devicesWithoutSession.push([userId, deviceId]);\n }\n resultDevices.set(deviceId, {\n device: deviceInfo,\n sessionId: sessionId,\n });\n }\n }\n\n if (devicesWithoutSession.length === 0) {\n return result;\n }\n\n const oneTimeKeyAlgorithm = \"signed_curve25519\";\n let res: IClaimOTKsResult;\n let taskDetail = `one-time keys for ${devicesWithoutSession.length} devices`;\n try {\n log.debug(`Claiming ${taskDetail}`);\n res = await baseApis.claimOneTimeKeys(devicesWithoutSession, oneTimeKeyAlgorithm, otkTimeout);\n log.debug(`Claimed ${taskDetail}`);\n } catch (e) {\n for (const resolver of resolveSession.values()) {\n resolver();\n }\n log.log(`Failed to claim ${taskDetail}`, e, devicesWithoutSession);\n throw e;\n }\n\n if (failedServers && \"failures\" in res) {\n failedServers.push(...Object.keys(res.failures));\n }\n\n const otkResult = res.one_time_keys || ({} as IClaimOTKsResult[\"one_time_keys\"]);\n const promises: Promise<void>[] = [];\n for (const [userId, devices] of devicesByUser) {\n const userRes = otkResult[userId] || {};\n for (const deviceInfo of devices) {\n const deviceId = deviceInfo.deviceId;\n const key = deviceInfo.getIdentityKey();\n\n if (key === olmDevice.deviceCurve25519Key) {\n // We've already logged about this above. Skip here too\n // otherwise we'll log saying there are no one-time keys\n // which will be confusing.\n continue;\n }\n\n if (result.get(userId)?.get(deviceId)?.sessionId && !force) {\n // we already have a result for this device\n continue;\n }\n\n const deviceRes = userRes[deviceId] || {};\n let oneTimeKey: IOneTimeKey | null = null;\n for (const keyId in deviceRes) {\n if (keyId.indexOf(oneTimeKeyAlgorithm + \":\") === 0) {\n oneTimeKey = deviceRes[keyId];\n }\n }\n\n if (!oneTimeKey) {\n log.warn(`No one-time keys (alg=${oneTimeKeyAlgorithm}) ` + `for device ${userId}:${deviceId}`);\n resolveSession.get(key)?.();\n continue;\n }\n\n promises.push(\n _verifyKeyAndStartSession(olmDevice, oneTimeKey, userId, deviceInfo).then(\n (sid) => {\n resolveSession.get(key)?.(sid ?? undefined);\n const deviceInfo = result.get(userId)?.get(deviceId);\n if (deviceInfo) deviceInfo.sessionId = sid;\n },\n (e) => {\n resolveSession.get(key)?.();\n throw e;\n },\n ),\n );\n }\n }\n\n taskDetail = `Olm sessions for ${promises.length} devices`;\n log.debug(`Starting ${taskDetail}`);\n await Promise.all(promises);\n log.debug(`Started ${taskDetail}`);\n return result;\n}\n\nasync function _verifyKeyAndStartSession(\n olmDevice: OlmDevice,\n oneTimeKey: IOneTimeKey,\n userId: string,\n deviceInfo: DeviceInfo,\n): Promise<string | null> {\n const deviceId = deviceInfo.deviceId;\n try {\n await verifySignature(olmDevice, oneTimeKey, userId, deviceId, deviceInfo.getFingerprint());\n } catch (e) {\n logger.error(\"Unable to verify signature on one-time key for device \" + userId + \":\" + deviceId + \":\", e);\n return null;\n }\n\n let sid;\n try {\n sid = await olmDevice.createOutboundSession(deviceInfo.getIdentityKey(), oneTimeKey.key);\n } catch (e) {\n // possibly a bad key\n logger.error(\"Error starting olm session with device \" + userId + \":\" + deviceId + \": \" + e);\n return null;\n }\n\n logger.log(\"Started new olm sessionid \" + sid + \" for device \" + userId + \":\" + deviceId);\n return sid;\n}\n\nexport interface IObject {\n unsigned?: object;\n signatures?: ISignatures;\n}\n\n/**\n * Verify the signature on an object\n *\n * @param olmDevice - olm wrapper to use for verify op\n *\n * @param obj - object to check signature on.\n *\n * @param signingUserId - ID of the user whose signature should be checked\n *\n * @param signingDeviceId - ID of the device whose signature should be checked\n *\n * @param signingKey - base64-ed ed25519 public key\n *\n * Returns a promise which resolves (to undefined) if the the signature is good,\n * or rejects with an Error if it is bad.\n */\nexport async function verifySignature(\n olmDevice: OlmDevice,\n obj: IOneTimeKey | IObject,\n signingUserId: string,\n signingDeviceId: string,\n signingKey: string,\n): Promise<void> {\n const signKeyId = \"ed25519:\" + signingDeviceId;\n const signatures = obj.signatures || {};\n const userSigs = signatures[signingUserId] || {};\n const signature = userSigs[signKeyId];\n if (!signature) {\n throw Error(\"No signature\");\n }\n\n // prepare the canonical json: remove unsigned and signatures, and stringify with anotherjson\n const mangledObj = Object.assign({}, obj);\n if (\"unsigned\" in mangledObj) {\n delete mangledObj.unsigned;\n }\n delete mangledObj.signatures;\n const json = anotherjson.stringify(mangledObj);\n\n olmDevice.verifySignature(signingKey, json, signature);\n}\n\n/**\n * Sign a JSON object using public key cryptography\n * @param obj - Object to sign. The object will be modified to include\n * the new signature\n * @param key - the signing object or the private key\n * seed\n * @param userId - The user ID who owns the signing key\n * @param pubKey - The public key (ignored if key is a seed)\n * @returns the signature for the object\n */\nexport function pkSign(obj: object & IObject, key: Uint8Array | PkSigning, userId: string, pubKey: string): string {\n let createdKey = false;\n if (key instanceof Uint8Array) {\n const keyObj = new global.Olm.PkSigning();\n pubKey = keyObj.init_with_seed(key);\n key = keyObj;\n createdKey = true;\n }\n const sigs = obj.signatures || {};\n delete obj.signatures;\n const unsigned = obj.unsigned;\n if (obj.unsigned) delete obj.unsigned;\n try {\n const mysigs = sigs[userId] || {};\n sigs[userId] = mysigs;\n\n return (mysigs[\"ed25519:\" + pubKey] = key.sign(anotherjson.stringify(obj)));\n } finally {\n obj.signatures = sigs;\n if (unsigned) obj.unsigned = unsigned;\n if (createdKey) {\n key.free();\n }\n }\n}\n\n/**\n * Verify a signed JSON object\n * @param obj - Object to verify\n * @param pubKey - The public key to use to verify\n * @param userId - The user ID who signed the object\n */\nexport function pkVerify(obj: IObject, pubKey: string, userId: string): void {\n const keyId = \"ed25519:\" + pubKey;\n if (!(obj.signatures && obj.signatures[userId] && obj.signatures[userId][keyId])) {\n throw new Error(\"No signature\");\n }\n const signature = obj.signatures[userId][keyId];\n const util = new global.Olm.Utility();\n const sigs = obj.signatures;\n delete obj.signatures;\n const unsigned = obj.unsigned;\n if (obj.unsigned) delete obj.unsigned;\n try {\n util.ed25519_verify(pubKey, anotherjson.stringify(obj), signature);\n } finally {\n obj.signatures = sigs;\n if (unsigned) obj.unsigned = unsigned;\n util.free();\n }\n}\n\n/**\n * Check that an event was encrypted using olm.\n */\nexport function isOlmEncrypted(event: MatrixEvent): boolean {\n if (!event.getSenderKey()) {\n logger.error(\"Event has no sender key (not encrypted?)\");\n return false;\n }\n if (\n event.getWireType() !== EventType.RoomMessageEncrypted ||\n ![\"m.olm.v1.curve25519-aes-sha2\"].includes(event.getWireContent().algorithm)\n ) {\n logger.error(\"Event was not encrypted using an appropriate algorithm\");\n return false;\n }\n return true;\n}\n\n/**\n * Encode a typed array of uint8 as base64.\n * @param uint8Array - The data to encode.\n * @returns The base64.\n */\nexport function encodeBase64(uint8Array: ArrayBuffer | Uint8Array): string {\n return Buffer.from(uint8Array).toString(\"base64\");\n}\n\n/**\n * Encode a typed array of uint8 as unpadded base64.\n * @param uint8Array - The data to encode.\n * @returns The unpadded base64.\n */\nexport function encodeUnpaddedBase64(uint8Array: ArrayBuffer | Uint8Array): string {\n return encodeBase64(uint8Array).replace(/=+$/g, \"\");\n}\n\n/**\n * Decode a base64 string to a typed array of uint8.\n * @param base64 - The base64 to decode.\n * @returns The decoded data.\n */\nexport function decodeBase64(base64: string): Uint8Array {\n return Buffer.from(base64, \"base64\");\n}\n"],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/recoverykey.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/recoverykey.d.ts
deleted file mode 100644
index c0625cf..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/recoverykey.d.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export declare function encodeRecoveryKey(key: ArrayLike<number>): string | undefined;
-export declare function decodeRecoveryKey(recoveryKey: string): Uint8Array;
-//# sourceMappingURL=recoverykey.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/recoverykey.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/recoverykey.d.ts.map
deleted file mode 100644
index c65ac16..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/recoverykey.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"recoverykey.d.ts","sourceRoot":"","sources":["../../src/crypto/recoverykey.ts"],"names":[],"mappings":"AAsBA,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,SAAS,CAAC,MAAM,CAAC,GAAG,MAAM,GAAG,SAAS,CAa5E;AAED,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,UAAU,CAwBjE"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/recoverykey.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/recoverykey.js
deleted file mode 100644
index fb12171..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/recoverykey.js
+++ /dev/null
@@ -1,62 +0,0 @@
-"use strict";
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.decodeRecoveryKey = decodeRecoveryKey;
-exports.encodeRecoveryKey = encodeRecoveryKey;
-var bs58 = _interopRequireWildcard(require("bs58"));
-function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
-function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
-/*
-Copyright 2018 New Vector Ltd
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-// picked arbitrarily but to try & avoid clashing with any bitcoin ones
-// (which are also base58 encoded, but bitcoin's involve a lot more hashing)
-const OLM_RECOVERY_KEY_PREFIX = [0x8b, 0x01];
-function encodeRecoveryKey(key) {
- var _base58key$match;
- const buf = Buffer.alloc(OLM_RECOVERY_KEY_PREFIX.length + key.length + 1);
- buf.set(OLM_RECOVERY_KEY_PREFIX, 0);
- buf.set(key, OLM_RECOVERY_KEY_PREFIX.length);
- let parity = 0;
- for (let i = 0; i < buf.length - 1; ++i) {
- parity ^= buf[i];
- }
- buf[buf.length - 1] = parity;
- const base58key = bs58.encode(buf);
- return (_base58key$match = base58key.match(/.{1,4}/g)) === null || _base58key$match === void 0 ? void 0 : _base58key$match.join(" ");
-}
-function decodeRecoveryKey(recoveryKey) {
- const result = bs58.decode(recoveryKey.replace(/ /g, ""));
- let parity = 0;
- for (const b of result) {
- parity ^= b;
- }
- if (parity !== 0) {
- throw new Error("Incorrect parity");
- }
- for (let i = 0; i < OLM_RECOVERY_KEY_PREFIX.length; ++i) {
- if (result[i] !== OLM_RECOVERY_KEY_PREFIX[i]) {
- throw new Error("Incorrect prefix");
- }
- }
- if (result.length !== OLM_RECOVERY_KEY_PREFIX.length + global.Olm.PRIVATE_KEY_LENGTH + 1) {
- throw new Error("Incorrect length");
- }
- return Uint8Array.from(result.slice(OLM_RECOVERY_KEY_PREFIX.length, OLM_RECOVERY_KEY_PREFIX.length + global.Olm.PRIVATE_KEY_LENGTH));
-}
-//# sourceMappingURL=recoverykey.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/recoverykey.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/recoverykey.js.map
deleted file mode 100644
index d4a04d3..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/recoverykey.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"recoverykey.js","names":["bs58","_interopRequireWildcard","require","_getRequireWildcardCache","nodeInterop","WeakMap","cacheBabelInterop","cacheNodeInterop","obj","__esModule","default","cache","has","get","newObj","hasPropertyDescriptor","Object","defineProperty","getOwnPropertyDescriptor","key","prototype","hasOwnProperty","call","desc","set","OLM_RECOVERY_KEY_PREFIX","encodeRecoveryKey","_base58key$match","buf","Buffer","alloc","length","parity","i","base58key","encode","match","join","decodeRecoveryKey","recoveryKey","result","decode","replace","b","Error","global","Olm","PRIVATE_KEY_LENGTH","Uint8Array","from","slice"],"sources":["../../src/crypto/recoverykey.ts"],"sourcesContent":["/*\nCopyright 2018 New Vector Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport * as bs58 from \"bs58\";\n\n// picked arbitrarily but to try & avoid clashing with any bitcoin ones\n// (which are also base58 encoded, but bitcoin's involve a lot more hashing)\nconst OLM_RECOVERY_KEY_PREFIX = [0x8b, 0x01];\n\nexport function encodeRecoveryKey(key: ArrayLike<number>): string | undefined {\n const buf = Buffer.alloc(OLM_RECOVERY_KEY_PREFIX.length + key.length + 1);\n buf.set(OLM_RECOVERY_KEY_PREFIX, 0);\n buf.set(key, OLM_RECOVERY_KEY_PREFIX.length);\n\n let parity = 0;\n for (let i = 0; i < buf.length - 1; ++i) {\n parity ^= buf[i];\n }\n buf[buf.length - 1] = parity;\n const base58key = bs58.encode(buf);\n\n return base58key.match(/.{1,4}/g)?.join(\" \");\n}\n\nexport function decodeRecoveryKey(recoveryKey: string): Uint8Array {\n const result = bs58.decode(recoveryKey.replace(/ /g, \"\"));\n\n let parity = 0;\n for (const b of result) {\n parity ^= b;\n }\n if (parity !== 0) {\n throw new Error(\"Incorrect parity\");\n }\n\n for (let i = 0; i < OLM_RECOVERY_KEY_PREFIX.length; ++i) {\n if (result[i] !== OLM_RECOVERY_KEY_PREFIX[i]) {\n throw new Error(\"Incorrect prefix\");\n }\n }\n\n if (result.length !== OLM_RECOVERY_KEY_PREFIX.length + global.Olm.PRIVATE_KEY_LENGTH + 1) {\n throw new Error(\"Incorrect length\");\n }\n\n return Uint8Array.from(\n result.slice(OLM_RECOVERY_KEY_PREFIX.length, OLM_RECOVERY_KEY_PREFIX.length + global.Olm.PRIVATE_KEY_LENGTH),\n );\n}\n"],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/base.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/base.d.ts
deleted file mode 100644
index ccef9c5..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/base.d.ts
+++ /dev/null
@@ -1,143 +0,0 @@
-import { IRoomKeyRequestBody, IRoomKeyRequestRecipient } from "../index";
-import { RoomKeyRequestState } from "../OutgoingRoomKeyRequestManager";
-import { ICrossSigningKey } from "../../client";
-import { IOlmDevice } from "../algorithms/megolm";
-import { TrackingStatus } from "../DeviceList";
-import { IRoomEncryption } from "../RoomList";
-import { IDevice } from "../deviceinfo";
-import { ICrossSigningInfo } from "../CrossSigning";
-import { PrefixedLogger } from "../../logger";
-import { InboundGroupSessionData } from "../OlmDevice";
-import { MatrixEvent } from "../../models/event";
-import { DehydrationManager } from "../dehydration";
-import { IEncryptedPayload } from "../aes";
-/**
- * Internal module. Definitions for storage for the crypto module
- */
-export interface SecretStorePrivateKeys {
- "dehydration": {
- keyInfo: DehydrationManager["keyInfo"];
- key: IEncryptedPayload;
- deviceDisplayName: string;
- time: number;
- } | null;
- "m.megolm_backup.v1": IEncryptedPayload;
-}
-/**
- * Abstraction of things that can store data required for end-to-end encryption
- */
-export interface CryptoStore {
- startup(): Promise<CryptoStore>;
- deleteAllData(): Promise<void>;
- getOrAddOutgoingRoomKeyRequest(request: OutgoingRoomKeyRequest): Promise<OutgoingRoomKeyRequest>;
- getOutgoingRoomKeyRequest(requestBody: IRoomKeyRequestBody): Promise<OutgoingRoomKeyRequest | null>;
- getOutgoingRoomKeyRequestByState(wantedStates: number[]): Promise<OutgoingRoomKeyRequest | null>;
- getAllOutgoingRoomKeyRequestsByState(wantedState: number): Promise<OutgoingRoomKeyRequest[]>;
- getOutgoingRoomKeyRequestsByTarget(userId: string, deviceId: string, wantedStates: number[]): Promise<OutgoingRoomKeyRequest[]>;
- updateOutgoingRoomKeyRequest(requestId: string, expectedState: number, updates: Partial<OutgoingRoomKeyRequest>): Promise<OutgoingRoomKeyRequest | null>;
- deleteOutgoingRoomKeyRequest(requestId: string, expectedState: number): Promise<OutgoingRoomKeyRequest | null>;
- getAccount(txn: unknown, func: (accountPickle: string | null) => void): void;
- storeAccount(txn: unknown, accountPickle: string): void;
- getCrossSigningKeys(txn: unknown, func: (keys: Record<string, ICrossSigningKey> | null) => void): void;
- getSecretStorePrivateKey<K extends keyof SecretStorePrivateKeys>(txn: unknown, func: (key: SecretStorePrivateKeys[K] | null) => void, type: K): void;
- storeCrossSigningKeys(txn: unknown, keys: Record<string, ICrossSigningKey>): void;
- storeSecretStorePrivateKey<K extends keyof SecretStorePrivateKeys>(txn: unknown, type: K, key: SecretStorePrivateKeys[K]): void;
- countEndToEndSessions(txn: unknown, func: (count: number) => void): void;
- getEndToEndSession(deviceKey: string, sessionId: string, txn: unknown, func: (session: ISessionInfo | null) => void): void;
- getEndToEndSessions(deviceKey: string, txn: unknown, func: (sessions: {
- [sessionId: string]: ISessionInfo;
- }) => void): void;
- getAllEndToEndSessions(txn: unknown, func: (session: ISessionInfo | null) => void): void;
- storeEndToEndSession(deviceKey: string, sessionId: string, sessionInfo: ISessionInfo, txn: unknown): void;
- storeEndToEndSessionProblem(deviceKey: string, type: string, fixed: boolean): Promise<void>;
- getEndToEndSessionProblem(deviceKey: string, timestamp: number): Promise<IProblem | null>;
- filterOutNotifiedErrorDevices(devices: IOlmDevice[]): Promise<IOlmDevice[]>;
- getEndToEndInboundGroupSession(senderCurve25519Key: string, sessionId: string, txn: unknown, func: (groupSession: InboundGroupSessionData | null, groupSessionWithheld: IWithheld | null) => void): void;
- getAllEndToEndInboundGroupSessions(txn: unknown, func: (session: ISession | null) => void): void;
- addEndToEndInboundGroupSession(senderCurve25519Key: string, sessionId: string, sessionData: InboundGroupSessionData, txn: unknown): void;
- storeEndToEndInboundGroupSession(senderCurve25519Key: string, sessionId: string, sessionData: InboundGroupSessionData, txn: unknown): void;
- storeEndToEndInboundGroupSessionWithheld(senderCurve25519Key: string, sessionId: string, sessionData: IWithheld, txn: unknown): void;
- getEndToEndDeviceData(txn: unknown, func: (deviceData: IDeviceData | null) => void): void;
- storeEndToEndDeviceData(deviceData: IDeviceData, txn: unknown): void;
- storeEndToEndRoom(roomId: string, roomInfo: IRoomEncryption, txn: unknown): void;
- getEndToEndRooms(txn: unknown, func: (rooms: Record<string, IRoomEncryption>) => void): void;
- getSessionsNeedingBackup(limit: number): Promise<ISession[]>;
- countSessionsNeedingBackup(txn?: unknown): Promise<number>;
- unmarkSessionsNeedingBackup(sessions: ISession[], txn?: unknown): Promise<void>;
- markSessionsNeedingBackup(sessions: ISession[], txn?: unknown): Promise<void>;
- addSharedHistoryInboundGroupSession(roomId: string, senderKey: string, sessionId: string, txn?: unknown): void;
- getSharedHistoryInboundGroupSessions(roomId: string, txn?: unknown): Promise<[senderKey: string, sessionId: string][]>;
- addParkedSharedHistory(roomId: string, data: ParkedSharedHistory, txn?: unknown): void;
- takeParkedSharedHistory(roomId: string, txn?: unknown): Promise<ParkedSharedHistory[]>;
- doTxn<T>(mode: Mode, stores: Iterable<string>, func: (txn: unknown) => T, log?: PrefixedLogger): Promise<T>;
-}
-export type Mode = "readonly" | "readwrite";
-export interface ISession {
- senderKey: string;
- sessionId: string;
- sessionData?: InboundGroupSessionData;
-}
-export interface ISessionInfo {
- deviceKey?: string;
- sessionId?: string;
- session?: string;
- lastReceivedMessageTs?: number;
-}
-export interface IDeviceData {
- devices: {
- [userId: string]: {
- [deviceId: string]: IDevice;
- };
- };
- trackingStatus: {
- [userId: string]: TrackingStatus;
- };
- crossSigningInfo?: Record<string, ICrossSigningInfo>;
- syncToken?: string;
-}
-export interface IProblem {
- type: string;
- fixed: boolean;
- time: number;
-}
-export interface IWithheld {
- room_id: string;
- code: string;
- reason: string;
-}
-/**
- * Represents an outgoing room key request
- */
-export interface OutgoingRoomKeyRequest {
- /**
- * Unique id for this request. Used for both an id within the request for later pairing with a cancellation,
- * and for the transaction id when sending the to_device messages to our local server.
- */
- requestId: string;
- requestTxnId?: string;
- /**
- * Transaction id for the cancellation, if any
- */
- cancellationTxnId?: string;
- /**
- * List of recipients for the request
- */
- recipients: IRoomKeyRequestRecipient[];
- /**
- * Parameters for the request
- */
- requestBody: IRoomKeyRequestBody;
- /**
- * current state of this request (states are defined in {@link OutgoingRoomKeyRequestManager})
- */
- state: RoomKeyRequestState;
-}
-export interface ParkedSharedHistory {
- senderId: string;
- senderKey: string;
- sessionId: string;
- sessionKey: string;
- keysClaimed: ReturnType<MatrixEvent["getKeysClaimed"]>;
- forwardingCurve25519KeyChain: string[];
-}
-//# sourceMappingURL=base.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/base.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/base.d.ts.map
deleted file mode 100644
index 429688e..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/base.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../src/crypto/store/base.ts"],"names":[],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/base.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/base.js
deleted file mode 100644
index f14b94a..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/base.js
+++ /dev/null
@@ -1,6 +0,0 @@
-"use strict";
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-//# sourceMappingURL=base.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/base.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/base.js.map
deleted file mode 100644
index 2235433..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/base.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"base.js","names":[],"sources":["../../../src/crypto/store/base.ts"],"sourcesContent":["/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { IRoomKeyRequestBody, IRoomKeyRequestRecipient } from \"../index\";\nimport { RoomKeyRequestState } from \"../OutgoingRoomKeyRequestManager\";\nimport { ICrossSigningKey } from \"../../client\";\nimport { IOlmDevice } from \"../algorithms/megolm\";\nimport { TrackingStatus } from \"../DeviceList\";\nimport { IRoomEncryption } from \"../RoomList\";\nimport { IDevice } from \"../deviceinfo\";\nimport { ICrossSigningInfo } from \"../CrossSigning\";\nimport { PrefixedLogger } from \"../../logger\";\nimport { InboundGroupSessionData } from \"../OlmDevice\";\nimport { MatrixEvent } from \"../../models/event\";\nimport { DehydrationManager } from \"../dehydration\";\nimport { IEncryptedPayload } from \"../aes\";\n\n/**\n * Internal module. Definitions for storage for the crypto module\n */\n\nexport interface SecretStorePrivateKeys {\n \"dehydration\": {\n keyInfo: DehydrationManager[\"keyInfo\"];\n key: IEncryptedPayload;\n deviceDisplayName: string;\n time: number;\n } | null;\n \"m.megolm_backup.v1\": IEncryptedPayload;\n}\n\n/**\n * Abstraction of things that can store data required for end-to-end encryption\n */\nexport interface CryptoStore {\n startup(): Promise<CryptoStore>;\n deleteAllData(): Promise<void>;\n getOrAddOutgoingRoomKeyRequest(request: OutgoingRoomKeyRequest): Promise<OutgoingRoomKeyRequest>;\n getOutgoingRoomKeyRequest(requestBody: IRoomKeyRequestBody): Promise<OutgoingRoomKeyRequest | null>;\n getOutgoingRoomKeyRequestByState(wantedStates: number[]): Promise<OutgoingRoomKeyRequest | null>;\n getAllOutgoingRoomKeyRequestsByState(wantedState: number): Promise<OutgoingRoomKeyRequest[]>;\n getOutgoingRoomKeyRequestsByTarget(\n userId: string,\n deviceId: string,\n wantedStates: number[],\n ): Promise<OutgoingRoomKeyRequest[]>;\n updateOutgoingRoomKeyRequest(\n requestId: string,\n expectedState: number,\n updates: Partial<OutgoingRoomKeyRequest>,\n ): Promise<OutgoingRoomKeyRequest | null>;\n deleteOutgoingRoomKeyRequest(requestId: string, expectedState: number): Promise<OutgoingRoomKeyRequest | null>;\n\n // Olm Account\n getAccount(txn: unknown, func: (accountPickle: string | null) => void): void;\n storeAccount(txn: unknown, accountPickle: string): void;\n getCrossSigningKeys(txn: unknown, func: (keys: Record<string, ICrossSigningKey> | null) => void): void;\n getSecretStorePrivateKey<K extends keyof SecretStorePrivateKeys>(\n txn: unknown,\n func: (key: SecretStorePrivateKeys[K] | null) => void,\n type: K,\n ): void;\n storeCrossSigningKeys(txn: unknown, keys: Record<string, ICrossSigningKey>): void;\n storeSecretStorePrivateKey<K extends keyof SecretStorePrivateKeys>(\n txn: unknown,\n type: K,\n key: SecretStorePrivateKeys[K],\n ): void;\n\n // Olm Sessions\n countEndToEndSessions(txn: unknown, func: (count: number) => void): void;\n getEndToEndSession(\n deviceKey: string,\n sessionId: string,\n txn: unknown,\n func: (session: ISessionInfo | null) => void,\n ): void;\n getEndToEndSessions(\n deviceKey: string,\n txn: unknown,\n func: (sessions: { [sessionId: string]: ISessionInfo }) => void,\n ): void;\n getAllEndToEndSessions(txn: unknown, func: (session: ISessionInfo | null) => void): void;\n storeEndToEndSession(deviceKey: string, sessionId: string, sessionInfo: ISessionInfo, txn: unknown): void;\n storeEndToEndSessionProblem(deviceKey: string, type: string, fixed: boolean): Promise<void>;\n getEndToEndSessionProblem(deviceKey: string, timestamp: number): Promise<IProblem | null>;\n filterOutNotifiedErrorDevices(devices: IOlmDevice[]): Promise<IOlmDevice[]>;\n\n // Inbound Group Sessions\n getEndToEndInboundGroupSession(\n senderCurve25519Key: string,\n sessionId: string,\n txn: unknown,\n func: (groupSession: InboundGroupSessionData | null, groupSessionWithheld: IWithheld | null) => void,\n ): void;\n getAllEndToEndInboundGroupSessions(txn: unknown, func: (session: ISession | null) => void): void;\n addEndToEndInboundGroupSession(\n senderCurve25519Key: string,\n sessionId: string,\n sessionData: InboundGroupSessionData,\n txn: unknown,\n ): void;\n storeEndToEndInboundGroupSession(\n senderCurve25519Key: string,\n sessionId: string,\n sessionData: InboundGroupSessionData,\n txn: unknown,\n ): void;\n storeEndToEndInboundGroupSessionWithheld(\n senderCurve25519Key: string,\n sessionId: string,\n sessionData: IWithheld,\n txn: unknown,\n ): void;\n\n // Device Data\n getEndToEndDeviceData(txn: unknown, func: (deviceData: IDeviceData | null) => void): void;\n storeEndToEndDeviceData(deviceData: IDeviceData, txn: unknown): void;\n storeEndToEndRoom(roomId: string, roomInfo: IRoomEncryption, txn: unknown): void;\n getEndToEndRooms(txn: unknown, func: (rooms: Record<string, IRoomEncryption>) => void): void;\n getSessionsNeedingBackup(limit: number): Promise<ISession[]>;\n countSessionsNeedingBackup(txn?: unknown): Promise<number>;\n unmarkSessionsNeedingBackup(sessions: ISession[], txn?: unknown): Promise<void>;\n markSessionsNeedingBackup(sessions: ISession[], txn?: unknown): Promise<void>;\n addSharedHistoryInboundGroupSession(roomId: string, senderKey: string, sessionId: string, txn?: unknown): void;\n getSharedHistoryInboundGroupSessions(\n roomId: string,\n txn?: unknown,\n ): Promise<[senderKey: string, sessionId: string][]>;\n addParkedSharedHistory(roomId: string, data: ParkedSharedHistory, txn?: unknown): void;\n takeParkedSharedHistory(roomId: string, txn?: unknown): Promise<ParkedSharedHistory[]>;\n\n // Session key backups\n doTxn<T>(mode: Mode, stores: Iterable<string>, func: (txn: unknown) => T, log?: PrefixedLogger): Promise<T>;\n}\n\nexport type Mode = \"readonly\" | \"readwrite\";\n\nexport interface ISession {\n senderKey: string;\n sessionId: string;\n sessionData?: InboundGroupSessionData;\n}\n\nexport interface ISessionInfo {\n deviceKey?: string;\n sessionId?: string;\n session?: string;\n lastReceivedMessageTs?: number;\n}\n\nexport interface IDeviceData {\n devices: {\n [userId: string]: {\n [deviceId: string]: IDevice;\n };\n };\n trackingStatus: {\n [userId: string]: TrackingStatus;\n };\n crossSigningInfo?: Record<string, ICrossSigningInfo>;\n syncToken?: string;\n}\n\nexport interface IProblem {\n type: string;\n fixed: boolean;\n time: number;\n}\n\nexport interface IWithheld {\n // eslint-disable-next-line camelcase\n room_id: string;\n code: string;\n reason: string;\n}\n\n/**\n * Represents an outgoing room key request\n */\nexport interface OutgoingRoomKeyRequest {\n /**\n * Unique id for this request. Used for both an id within the request for later pairing with a cancellation,\n * and for the transaction id when sending the to_device messages to our local server.\n */\n requestId: string;\n requestTxnId?: string;\n /**\n * Transaction id for the cancellation, if any\n */\n cancellationTxnId?: string;\n /**\n * List of recipients for the request\n */\n recipients: IRoomKeyRequestRecipient[];\n /**\n * Parameters for the request\n */\n requestBody: IRoomKeyRequestBody;\n /**\n * current state of this request (states are defined in {@link OutgoingRoomKeyRequestManager})\n */\n state: RoomKeyRequestState;\n}\n\nexport interface ParkedSharedHistory {\n senderId: string;\n senderKey: string;\n sessionId: string;\n sessionKey: string;\n keysClaimed: ReturnType<MatrixEvent[\"getKeysClaimed\"]>; // XXX: Less type dependence on MatrixEvent\n forwardingCurve25519KeyChain: string[];\n}\n"],"mappings":""} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store-backend.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store-backend.d.ts
deleted file mode 100644
index a111890..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store-backend.d.ts
+++ /dev/null
@@ -1,130 +0,0 @@
-import { PrefixedLogger } from "../../logger";
-import { CryptoStore, IDeviceData, IProblem, ISession, ISessionInfo, IWithheld, Mode, OutgoingRoomKeyRequest, ParkedSharedHistory, SecretStorePrivateKeys } from "./base";
-import { IRoomKeyRequestBody } from "../index";
-import { ICrossSigningKey } from "../../client";
-import { IOlmDevice } from "../algorithms/megolm";
-import { IRoomEncryption } from "../RoomList";
-import { InboundGroupSessionData } from "../OlmDevice";
-/**
- * Implementation of a CryptoStore which is backed by an existing
- * IndexedDB connection. Generally you want IndexedDBCryptoStore
- * which connects to the database and defers to one of these.
- */
-export declare class Backend implements CryptoStore {
- private db;
- private nextTxnId;
- /**
- */
- constructor(db: IDBDatabase);
- startup(): Promise<CryptoStore>;
- deleteAllData(): Promise<void>;
- /**
- * Look for an existing outgoing room key request, and if none is found,
- * add a new one
- *
- *
- * @returns resolves to
- * {@link OutgoingRoomKeyRequest}: either the
- * same instance as passed in, or the existing one.
- */
- getOrAddOutgoingRoomKeyRequest(request: OutgoingRoomKeyRequest): Promise<OutgoingRoomKeyRequest>;
- /**
- * Look for an existing room key request
- *
- * @param requestBody - existing request to look for
- *
- * @returns resolves to the matching
- * {@link OutgoingRoomKeyRequest}, or null if
- * not found
- */
- getOutgoingRoomKeyRequest(requestBody: IRoomKeyRequestBody): Promise<OutgoingRoomKeyRequest | null>;
- /**
- * look for an existing room key request in the db
- *
- * @internal
- * @param txn - database transaction
- * @param requestBody - existing request to look for
- * @param callback - function to call with the results of the
- * search. Either passed a matching
- * {@link OutgoingRoomKeyRequest}, or null if
- * not found.
- */
- private _getOutgoingRoomKeyRequest;
- /**
- * Look for room key requests by state
- *
- * @param wantedStates - list of acceptable states
- *
- * @returns resolves to the a
- * {@link OutgoingRoomKeyRequest}, or null if
- * there are no pending requests in those states. If there are multiple
- * requests in those states, an arbitrary one is chosen.
- */
- getOutgoingRoomKeyRequestByState(wantedStates: number[]): Promise<OutgoingRoomKeyRequest | null>;
- /**
- *
- * @returns All elements in a given state
- */
- getAllOutgoingRoomKeyRequestsByState(wantedState: number): Promise<OutgoingRoomKeyRequest[]>;
- getOutgoingRoomKeyRequestsByTarget(userId: string, deviceId: string, wantedStates: number[]): Promise<OutgoingRoomKeyRequest[]>;
- /**
- * Look for an existing room key request by id and state, and update it if
- * found
- *
- * @param requestId - ID of request to update
- * @param expectedState - state we expect to find the request in
- * @param updates - name/value map of updates to apply
- *
- * @returns resolves to
- * {@link OutgoingRoomKeyRequest}
- * updated request, or null if no matching row was found
- */
- updateOutgoingRoomKeyRequest(requestId: string, expectedState: number, updates: Partial<OutgoingRoomKeyRequest>): Promise<OutgoingRoomKeyRequest | null>;
- /**
- * Look for an existing room key request by id and state, and delete it if
- * found
- *
- * @param requestId - ID of request to update
- * @param expectedState - state we expect to find the request in
- *
- * @returns resolves once the operation is completed
- */
- deleteOutgoingRoomKeyRequest(requestId: string, expectedState: number): Promise<OutgoingRoomKeyRequest | null>;
- getAccount(txn: IDBTransaction, func: (accountPickle: string | null) => void): void;
- storeAccount(txn: IDBTransaction, accountPickle: string): void;
- getCrossSigningKeys(txn: IDBTransaction, func: (keys: Record<string, ICrossSigningKey> | null) => void): void;
- getSecretStorePrivateKey<K extends keyof SecretStorePrivateKeys>(txn: IDBTransaction, func: (key: SecretStorePrivateKeys[K] | null) => void, type: K): void;
- storeCrossSigningKeys(txn: IDBTransaction, keys: Record<string, ICrossSigningKey>): void;
- storeSecretStorePrivateKey<K extends keyof SecretStorePrivateKeys>(txn: IDBTransaction, type: K, key: SecretStorePrivateKeys[K]): void;
- countEndToEndSessions(txn: IDBTransaction, func: (count: number) => void): void;
- getEndToEndSessions(deviceKey: string, txn: IDBTransaction, func: (sessions: {
- [sessionId: string]: ISessionInfo;
- }) => void): void;
- getEndToEndSession(deviceKey: string, sessionId: string, txn: IDBTransaction, func: (session: ISessionInfo | null) => void): void;
- getAllEndToEndSessions(txn: IDBTransaction, func: (session: ISessionInfo | null) => void): void;
- storeEndToEndSession(deviceKey: string, sessionId: string, sessionInfo: ISessionInfo, txn: IDBTransaction): void;
- storeEndToEndSessionProblem(deviceKey: string, type: string, fixed: boolean): Promise<void>;
- getEndToEndSessionProblem(deviceKey: string, timestamp: number): Promise<IProblem | null>;
- filterOutNotifiedErrorDevices(devices: IOlmDevice[]): Promise<IOlmDevice[]>;
- getEndToEndInboundGroupSession(senderCurve25519Key: string, sessionId: string, txn: IDBTransaction, func: (groupSession: InboundGroupSessionData | null, groupSessionWithheld: IWithheld | null) => void): void;
- getAllEndToEndInboundGroupSessions(txn: IDBTransaction, func: (session: ISession | null) => void): void;
- addEndToEndInboundGroupSession(senderCurve25519Key: string, sessionId: string, sessionData: InboundGroupSessionData, txn: IDBTransaction): void;
- storeEndToEndInboundGroupSession(senderCurve25519Key: string, sessionId: string, sessionData: InboundGroupSessionData, txn: IDBTransaction): void;
- storeEndToEndInboundGroupSessionWithheld(senderCurve25519Key: string, sessionId: string, sessionData: IWithheld, txn: IDBTransaction): void;
- getEndToEndDeviceData(txn: IDBTransaction, func: (deviceData: IDeviceData | null) => void): void;
- storeEndToEndDeviceData(deviceData: IDeviceData, txn: IDBTransaction): void;
- storeEndToEndRoom(roomId: string, roomInfo: IRoomEncryption, txn: IDBTransaction): void;
- getEndToEndRooms(txn: IDBTransaction, func: (rooms: Record<string, IRoomEncryption>) => void): void;
- getSessionsNeedingBackup(limit: number): Promise<ISession[]>;
- countSessionsNeedingBackup(txn?: IDBTransaction): Promise<number>;
- unmarkSessionsNeedingBackup(sessions: ISession[], txn?: IDBTransaction): Promise<void>;
- markSessionsNeedingBackup(sessions: ISession[], txn?: IDBTransaction): Promise<void>;
- addSharedHistoryInboundGroupSession(roomId: string, senderKey: string, sessionId: string, txn?: IDBTransaction): void;
- getSharedHistoryInboundGroupSessions(roomId: string, txn?: IDBTransaction): Promise<[senderKey: string, sessionId: string][]>;
- addParkedSharedHistory(roomId: string, parkedData: ParkedSharedHistory, txn?: IDBTransaction): void;
- takeParkedSharedHistory(roomId: string, txn?: IDBTransaction): Promise<ParkedSharedHistory[]>;
- doTxn<T>(mode: Mode, stores: string | string[], func: (txn: IDBTransaction) => T, log?: PrefixedLogger): Promise<T>;
-}
-export declare const VERSION: number;
-export declare function upgradeDatabase(db: IDBDatabase, oldVersion: number): void;
-//# sourceMappingURL=indexeddb-crypto-store-backend.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store-backend.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store-backend.d.ts.map
deleted file mode 100644
index 2c199a3..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store-backend.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"indexeddb-crypto-store-backend.d.ts","sourceRoot":"","sources":["../../../src/crypto/store/indexeddb-crypto-store-backend.ts"],"names":[],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store-backend.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store-backend.js
deleted file mode 100644
index 8e1bb6e..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store-backend.js
+++ /dev/null
@@ -1,918 +0,0 @@
-"use strict";
-
-var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.VERSION = exports.Backend = void 0;
-exports.upgradeDatabase = upgradeDatabase;
-var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
-var _logger = require("../../logger");
-var utils = _interopRequireWildcard(require("../../utils"));
-function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
-function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
-/*
-Copyright 2017 - 2021 The Matrix.org Foundation C.I.C.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-const PROFILE_TRANSACTIONS = false;
-
-/**
- * Implementation of a CryptoStore which is backed by an existing
- * IndexedDB connection. Generally you want IndexedDBCryptoStore
- * which connects to the database and defers to one of these.
- */
-class Backend {
- /**
- */
- constructor(db) {
- this.db = db;
- (0, _defineProperty2.default)(this, "nextTxnId", 0);
- // make sure we close the db on `onversionchange` - otherwise
- // attempts to delete the database will block (and subsequent
- // attempts to re-create it will also block).
- db.onversionchange = () => {
- _logger.logger.log(`versionchange for indexeddb ${this.db.name}: closing`);
- db.close();
- };
- }
- async startup() {
- // No work to do, as the startup is done by the caller (e.g IndexedDBCryptoStore)
- // by passing us a ready IDBDatabase instance
- return this;
- }
- async deleteAllData() {
- throw Error("This is not implemented, call IDBFactory::deleteDatabase(dbName) instead.");
- }
-
- /**
- * Look for an existing outgoing room key request, and if none is found,
- * add a new one
- *
- *
- * @returns resolves to
- * {@link OutgoingRoomKeyRequest}: either the
- * same instance as passed in, or the existing one.
- */
- getOrAddOutgoingRoomKeyRequest(request) {
- const requestBody = request.requestBody;
- return new Promise((resolve, reject) => {
- const txn = this.db.transaction("outgoingRoomKeyRequests", "readwrite");
- txn.onerror = reject;
-
- // first see if we already have an entry for this request.
- this._getOutgoingRoomKeyRequest(txn, requestBody, existing => {
- if (existing) {
- // this entry matches the request - return it.
- _logger.logger.log(`already have key request outstanding for ` + `${requestBody.room_id} / ${requestBody.session_id}: ` + `not sending another`);
- resolve(existing);
- return;
- }
-
- // we got to the end of the list without finding a match
- // - add the new request.
- _logger.logger.log(`enqueueing key request for ${requestBody.room_id} / ` + requestBody.session_id);
- txn.oncomplete = () => {
- resolve(request);
- };
- const store = txn.objectStore("outgoingRoomKeyRequests");
- store.add(request);
- });
- });
- }
-
- /**
- * Look for an existing room key request
- *
- * @param requestBody - existing request to look for
- *
- * @returns resolves to the matching
- * {@link OutgoingRoomKeyRequest}, or null if
- * not found
- */
- getOutgoingRoomKeyRequest(requestBody) {
- return new Promise((resolve, reject) => {
- const txn = this.db.transaction("outgoingRoomKeyRequests", "readonly");
- txn.onerror = reject;
- this._getOutgoingRoomKeyRequest(txn, requestBody, existing => {
- resolve(existing);
- });
- });
- }
-
- /**
- * look for an existing room key request in the db
- *
- * @internal
- * @param txn - database transaction
- * @param requestBody - existing request to look for
- * @param callback - function to call with the results of the
- * search. Either passed a matching
- * {@link OutgoingRoomKeyRequest}, or null if
- * not found.
- */
- // eslint-disable-next-line @typescript-eslint/naming-convention
- _getOutgoingRoomKeyRequest(txn, requestBody, callback) {
- const store = txn.objectStore("outgoingRoomKeyRequests");
- const idx = store.index("session");
- const cursorReq = idx.openCursor([requestBody.room_id, requestBody.session_id]);
- cursorReq.onsuccess = () => {
- const cursor = cursorReq.result;
- if (!cursor) {
- // no match found
- callback(null);
- return;
- }
- const existing = cursor.value;
- if (utils.deepCompare(existing.requestBody, requestBody)) {
- // got a match
- callback(existing);
- return;
- }
-
- // look at the next entry in the index
- cursor.continue();
- };
- }
-
- /**
- * Look for room key requests by state
- *
- * @param wantedStates - list of acceptable states
- *
- * @returns resolves to the a
- * {@link OutgoingRoomKeyRequest}, or null if
- * there are no pending requests in those states. If there are multiple
- * requests in those states, an arbitrary one is chosen.
- */
- getOutgoingRoomKeyRequestByState(wantedStates) {
- if (wantedStates.length === 0) {
- return Promise.resolve(null);
- }
-
- // this is a bit tortuous because we need to make sure we do the lookup
- // in a single transaction, to avoid having a race with the insertion
- // code.
-
- // index into the wantedStates array
- let stateIndex = 0;
- let result;
- function onsuccess() {
- const cursor = this.result;
- if (cursor) {
- // got a match
- result = cursor.value;
- return;
- }
-
- // try the next state in the list
- stateIndex++;
- if (stateIndex >= wantedStates.length) {
- // no matches
- return;
- }
- const wantedState = wantedStates[stateIndex];
- const cursorReq = this.source.openCursor(wantedState);
- cursorReq.onsuccess = onsuccess;
- }
- const txn = this.db.transaction("outgoingRoomKeyRequests", "readonly");
- const store = txn.objectStore("outgoingRoomKeyRequests");
- const wantedState = wantedStates[stateIndex];
- const cursorReq = store.index("state").openCursor(wantedState);
- cursorReq.onsuccess = onsuccess;
- return promiseifyTxn(txn).then(() => result);
- }
-
- /**
- *
- * @returns All elements in a given state
- */
- getAllOutgoingRoomKeyRequestsByState(wantedState) {
- return new Promise((resolve, reject) => {
- const txn = this.db.transaction("outgoingRoomKeyRequests", "readonly");
- const store = txn.objectStore("outgoingRoomKeyRequests");
- const index = store.index("state");
- const request = index.getAll(wantedState);
- request.onsuccess = () => resolve(request.result);
- request.onerror = () => reject(request.error);
- });
- }
- getOutgoingRoomKeyRequestsByTarget(userId, deviceId, wantedStates) {
- let stateIndex = 0;
- const results = [];
- function onsuccess() {
- const cursor = this.result;
- if (cursor) {
- const keyReq = cursor.value;
- if (keyReq.recipients.some(recipient => recipient.userId === userId && recipient.deviceId === deviceId)) {
- results.push(keyReq);
- }
- cursor.continue();
- } else {
- // try the next state in the list
- stateIndex++;
- if (stateIndex >= wantedStates.length) {
- // no matches
- return;
- }
- const wantedState = wantedStates[stateIndex];
- const cursorReq = this.source.openCursor(wantedState);
- cursorReq.onsuccess = onsuccess;
- }
- }
- const txn = this.db.transaction("outgoingRoomKeyRequests", "readonly");
- const store = txn.objectStore("outgoingRoomKeyRequests");
- const wantedState = wantedStates[stateIndex];
- const cursorReq = store.index("state").openCursor(wantedState);
- cursorReq.onsuccess = onsuccess;
- return promiseifyTxn(txn).then(() => results);
- }
-
- /**
- * Look for an existing room key request by id and state, and update it if
- * found
- *
- * @param requestId - ID of request to update
- * @param expectedState - state we expect to find the request in
- * @param updates - name/value map of updates to apply
- *
- * @returns resolves to
- * {@link OutgoingRoomKeyRequest}
- * updated request, or null if no matching row was found
- */
- updateOutgoingRoomKeyRequest(requestId, expectedState, updates) {
- let result = null;
- function onsuccess() {
- const cursor = this.result;
- if (!cursor) {
- return;
- }
- const data = cursor.value;
- if (data.state != expectedState) {
- _logger.logger.warn(`Cannot update room key request from ${expectedState} ` + `as it was already updated to ${data.state}`);
- return;
- }
- Object.assign(data, updates);
- cursor.update(data);
- result = data;
- }
- const txn = this.db.transaction("outgoingRoomKeyRequests", "readwrite");
- const cursorReq = txn.objectStore("outgoingRoomKeyRequests").openCursor(requestId);
- cursorReq.onsuccess = onsuccess;
- return promiseifyTxn(txn).then(() => result);
- }
-
- /**
- * Look for an existing room key request by id and state, and delete it if
- * found
- *
- * @param requestId - ID of request to update
- * @param expectedState - state we expect to find the request in
- *
- * @returns resolves once the operation is completed
- */
- deleteOutgoingRoomKeyRequest(requestId, expectedState) {
- const txn = this.db.transaction("outgoingRoomKeyRequests", "readwrite");
- const cursorReq = txn.objectStore("outgoingRoomKeyRequests").openCursor(requestId);
- cursorReq.onsuccess = () => {
- const cursor = cursorReq.result;
- if (!cursor) {
- return;
- }
- const data = cursor.value;
- if (data.state != expectedState) {
- _logger.logger.warn(`Cannot delete room key request in state ${data.state} ` + `(expected ${expectedState})`);
- return;
- }
- cursor.delete();
- };
- return promiseifyTxn(txn);
- }
-
- // Olm Account
-
- getAccount(txn, func) {
- const objectStore = txn.objectStore("account");
- const getReq = objectStore.get("-");
- getReq.onsuccess = function () {
- try {
- func(getReq.result || null);
- } catch (e) {
- abortWithException(txn, e);
- }
- };
- }
- storeAccount(txn, accountPickle) {
- const objectStore = txn.objectStore("account");
- objectStore.put(accountPickle, "-");
- }
- getCrossSigningKeys(txn, func) {
- const objectStore = txn.objectStore("account");
- const getReq = objectStore.get("crossSigningKeys");
- getReq.onsuccess = function () {
- try {
- func(getReq.result || null);
- } catch (e) {
- abortWithException(txn, e);
- }
- };
- }
- getSecretStorePrivateKey(txn, func, type) {
- const objectStore = txn.objectStore("account");
- const getReq = objectStore.get(`ssss_cache:${type}`);
- getReq.onsuccess = function () {
- try {
- func(getReq.result || null);
- } catch (e) {
- abortWithException(txn, e);
- }
- };
- }
- storeCrossSigningKeys(txn, keys) {
- const objectStore = txn.objectStore("account");
- objectStore.put(keys, "crossSigningKeys");
- }
- storeSecretStorePrivateKey(txn, type, key) {
- const objectStore = txn.objectStore("account");
- objectStore.put(key, `ssss_cache:${type}`);
- }
-
- // Olm Sessions
-
- countEndToEndSessions(txn, func) {
- const objectStore = txn.objectStore("sessions");
- const countReq = objectStore.count();
- countReq.onsuccess = function () {
- try {
- func(countReq.result);
- } catch (e) {
- abortWithException(txn, e);
- }
- };
- }
- getEndToEndSessions(deviceKey, txn, func) {
- const objectStore = txn.objectStore("sessions");
- const idx = objectStore.index("deviceKey");
- const getReq = idx.openCursor(deviceKey);
- const results = {};
- getReq.onsuccess = function () {
- const cursor = getReq.result;
- if (cursor) {
- results[cursor.value.sessionId] = {
- session: cursor.value.session,
- lastReceivedMessageTs: cursor.value.lastReceivedMessageTs
- };
- cursor.continue();
- } else {
- try {
- func(results);
- } catch (e) {
- abortWithException(txn, e);
- }
- }
- };
- }
- getEndToEndSession(deviceKey, sessionId, txn, func) {
- const objectStore = txn.objectStore("sessions");
- const getReq = objectStore.get([deviceKey, sessionId]);
- getReq.onsuccess = function () {
- try {
- if (getReq.result) {
- func({
- session: getReq.result.session,
- lastReceivedMessageTs: getReq.result.lastReceivedMessageTs
- });
- } else {
- func(null);
- }
- } catch (e) {
- abortWithException(txn, e);
- }
- };
- }
- getAllEndToEndSessions(txn, func) {
- const objectStore = txn.objectStore("sessions");
- const getReq = objectStore.openCursor();
- getReq.onsuccess = function () {
- try {
- const cursor = getReq.result;
- if (cursor) {
- func(cursor.value);
- cursor.continue();
- } else {
- func(null);
- }
- } catch (e) {
- abortWithException(txn, e);
- }
- };
- }
- storeEndToEndSession(deviceKey, sessionId, sessionInfo, txn) {
- const objectStore = txn.objectStore("sessions");
- objectStore.put({
- deviceKey,
- sessionId,
- session: sessionInfo.session,
- lastReceivedMessageTs: sessionInfo.lastReceivedMessageTs
- });
- }
- async storeEndToEndSessionProblem(deviceKey, type, fixed) {
- const txn = this.db.transaction("session_problems", "readwrite");
- const objectStore = txn.objectStore("session_problems");
- objectStore.put({
- deviceKey,
- type,
- fixed,
- time: Date.now()
- });
- await promiseifyTxn(txn);
- }
- async getEndToEndSessionProblem(deviceKey, timestamp) {
- let result = null;
- const txn = this.db.transaction("session_problems", "readwrite");
- const objectStore = txn.objectStore("session_problems");
- const index = objectStore.index("deviceKey");
- const req = index.getAll(deviceKey);
- req.onsuccess = () => {
- const problems = req.result;
- if (!problems.length) {
- result = null;
- return;
- }
- problems.sort((a, b) => {
- return a.time - b.time;
- });
- const lastProblem = problems[problems.length - 1];
- for (const problem of problems) {
- if (problem.time > timestamp) {
- result = Object.assign({}, problem, {
- fixed: lastProblem.fixed
- });
- return;
- }
- }
- if (lastProblem.fixed) {
- result = null;
- } else {
- result = lastProblem;
- }
- };
- await promiseifyTxn(txn);
- return result;
- }
-
- // FIXME: we should probably prune this when devices get deleted
- async filterOutNotifiedErrorDevices(devices) {
- const txn = this.db.transaction("notified_error_devices", "readwrite");
- const objectStore = txn.objectStore("notified_error_devices");
- const ret = [];
- await Promise.all(devices.map(device => {
- return new Promise(resolve => {
- const {
- userId,
- deviceInfo
- } = device;
- const getReq = objectStore.get([userId, deviceInfo.deviceId]);
- getReq.onsuccess = function () {
- if (!getReq.result) {
- objectStore.put({
- userId,
- deviceId: deviceInfo.deviceId
- });
- ret.push(device);
- }
- resolve();
- };
- });
- }));
- return ret;
- }
-
- // Inbound group sessions
-
- getEndToEndInboundGroupSession(senderCurve25519Key, sessionId, txn, func) {
- let session = false;
- let withheld = false;
- const objectStore = txn.objectStore("inbound_group_sessions");
- const getReq = objectStore.get([senderCurve25519Key, sessionId]);
- getReq.onsuccess = function () {
- try {
- if (getReq.result) {
- session = getReq.result.session;
- } else {
- session = null;
- }
- if (withheld !== false) {
- func(session, withheld);
- }
- } catch (e) {
- abortWithException(txn, e);
- }
- };
- const withheldObjectStore = txn.objectStore("inbound_group_sessions_withheld");
- const withheldGetReq = withheldObjectStore.get([senderCurve25519Key, sessionId]);
- withheldGetReq.onsuccess = function () {
- try {
- if (withheldGetReq.result) {
- withheld = withheldGetReq.result.session;
- } else {
- withheld = null;
- }
- if (session !== false) {
- func(session, withheld);
- }
- } catch (e) {
- abortWithException(txn, e);
- }
- };
- }
- getAllEndToEndInboundGroupSessions(txn, func) {
- const objectStore = txn.objectStore("inbound_group_sessions");
- const getReq = objectStore.openCursor();
- getReq.onsuccess = function () {
- const cursor = getReq.result;
- if (cursor) {
- try {
- func({
- senderKey: cursor.value.senderCurve25519Key,
- sessionId: cursor.value.sessionId,
- sessionData: cursor.value.session
- });
- } catch (e) {
- abortWithException(txn, e);
- }
- cursor.continue();
- } else {
- try {
- func(null);
- } catch (e) {
- abortWithException(txn, e);
- }
- }
- };
- }
- addEndToEndInboundGroupSession(senderCurve25519Key, sessionId, sessionData, txn) {
- const objectStore = txn.objectStore("inbound_group_sessions");
- const addReq = objectStore.add({
- senderCurve25519Key,
- sessionId,
- session: sessionData
- });
- addReq.onerror = ev => {
- var _addReq$error;
- if (((_addReq$error = addReq.error) === null || _addReq$error === void 0 ? void 0 : _addReq$error.name) === "ConstraintError") {
- // This stops the error from triggering the txn's onerror
- ev.stopPropagation();
- // ...and this stops it from aborting the transaction
- ev.preventDefault();
- _logger.logger.log("Ignoring duplicate inbound group session: " + senderCurve25519Key + " / " + sessionId);
- } else {
- abortWithException(txn, new Error("Failed to add inbound group session: " + addReq.error));
- }
- };
- }
- storeEndToEndInboundGroupSession(senderCurve25519Key, sessionId, sessionData, txn) {
- const objectStore = txn.objectStore("inbound_group_sessions");
- objectStore.put({
- senderCurve25519Key,
- sessionId,
- session: sessionData
- });
- }
- storeEndToEndInboundGroupSessionWithheld(senderCurve25519Key, sessionId, sessionData, txn) {
- const objectStore = txn.objectStore("inbound_group_sessions_withheld");
- objectStore.put({
- senderCurve25519Key,
- sessionId,
- session: sessionData
- });
- }
- getEndToEndDeviceData(txn, func) {
- const objectStore = txn.objectStore("device_data");
- const getReq = objectStore.get("-");
- getReq.onsuccess = function () {
- try {
- func(getReq.result || null);
- } catch (e) {
- abortWithException(txn, e);
- }
- };
- }
- storeEndToEndDeviceData(deviceData, txn) {
- const objectStore = txn.objectStore("device_data");
- objectStore.put(deviceData, "-");
- }
- storeEndToEndRoom(roomId, roomInfo, txn) {
- const objectStore = txn.objectStore("rooms");
- objectStore.put(roomInfo, roomId);
- }
- getEndToEndRooms(txn, func) {
- const rooms = {};
- const objectStore = txn.objectStore("rooms");
- const getReq = objectStore.openCursor();
- getReq.onsuccess = function () {
- const cursor = getReq.result;
- if (cursor) {
- rooms[cursor.key] = cursor.value;
- cursor.continue();
- } else {
- try {
- func(rooms);
- } catch (e) {
- abortWithException(txn, e);
- }
- }
- };
- }
-
- // session backups
-
- getSessionsNeedingBackup(limit) {
- return new Promise((resolve, reject) => {
- const sessions = [];
- const txn = this.db.transaction(["sessions_needing_backup", "inbound_group_sessions"], "readonly");
- txn.onerror = reject;
- txn.oncomplete = function () {
- resolve(sessions);
- };
- const objectStore = txn.objectStore("sessions_needing_backup");
- const sessionStore = txn.objectStore("inbound_group_sessions");
- const getReq = objectStore.openCursor();
- getReq.onsuccess = function () {
- const cursor = getReq.result;
- if (cursor) {
- const sessionGetReq = sessionStore.get(cursor.key);
- sessionGetReq.onsuccess = function () {
- sessions.push({
- senderKey: sessionGetReq.result.senderCurve25519Key,
- sessionId: sessionGetReq.result.sessionId,
- sessionData: sessionGetReq.result.session
- });
- };
- if (!limit || sessions.length < limit) {
- cursor.continue();
- }
- }
- };
- });
- }
- countSessionsNeedingBackup(txn) {
- if (!txn) {
- txn = this.db.transaction("sessions_needing_backup", "readonly");
- }
- const objectStore = txn.objectStore("sessions_needing_backup");
- return new Promise((resolve, reject) => {
- const req = objectStore.count();
- req.onerror = reject;
- req.onsuccess = () => resolve(req.result);
- });
- }
- async unmarkSessionsNeedingBackup(sessions, txn) {
- if (!txn) {
- txn = this.db.transaction("sessions_needing_backup", "readwrite");
- }
- const objectStore = txn.objectStore("sessions_needing_backup");
- await Promise.all(sessions.map(session => {
- return new Promise((resolve, reject) => {
- const req = objectStore.delete([session.senderKey, session.sessionId]);
- req.onsuccess = resolve;
- req.onerror = reject;
- });
- }));
- }
- async markSessionsNeedingBackup(sessions, txn) {
- if (!txn) {
- txn = this.db.transaction("sessions_needing_backup", "readwrite");
- }
- const objectStore = txn.objectStore("sessions_needing_backup");
- await Promise.all(sessions.map(session => {
- return new Promise((resolve, reject) => {
- const req = objectStore.put({
- senderCurve25519Key: session.senderKey,
- sessionId: session.sessionId
- });
- req.onsuccess = resolve;
- req.onerror = reject;
- });
- }));
- }
- addSharedHistoryInboundGroupSession(roomId, senderKey, sessionId, txn) {
- if (!txn) {
- txn = this.db.transaction("shared_history_inbound_group_sessions", "readwrite");
- }
- const objectStore = txn.objectStore("shared_history_inbound_group_sessions");
- const req = objectStore.get([roomId]);
- req.onsuccess = () => {
- const {
- sessions
- } = req.result || {
- sessions: []
- };
- sessions.push([senderKey, sessionId]);
- objectStore.put({
- roomId,
- sessions
- });
- };
- }
- getSharedHistoryInboundGroupSessions(roomId, txn) {
- if (!txn) {
- txn = this.db.transaction("shared_history_inbound_group_sessions", "readonly");
- }
- const objectStore = txn.objectStore("shared_history_inbound_group_sessions");
- const req = objectStore.get([roomId]);
- return new Promise((resolve, reject) => {
- req.onsuccess = () => {
- const {
- sessions
- } = req.result || {
- sessions: []
- };
- resolve(sessions);
- };
- req.onerror = reject;
- });
- }
- addParkedSharedHistory(roomId, parkedData, txn) {
- if (!txn) {
- txn = this.db.transaction("parked_shared_history", "readwrite");
- }
- const objectStore = txn.objectStore("parked_shared_history");
- const req = objectStore.get([roomId]);
- req.onsuccess = () => {
- const {
- parked
- } = req.result || {
- parked: []
- };
- parked.push(parkedData);
- objectStore.put({
- roomId,
- parked
- });
- };
- }
- takeParkedSharedHistory(roomId, txn) {
- if (!txn) {
- txn = this.db.transaction("parked_shared_history", "readwrite");
- }
- const cursorReq = txn.objectStore("parked_shared_history").openCursor(roomId);
- return new Promise((resolve, reject) => {
- cursorReq.onsuccess = () => {
- const cursor = cursorReq.result;
- if (!cursor) {
- resolve([]);
- return;
- }
- const data = cursor.value;
- cursor.delete();
- resolve(data);
- };
- cursorReq.onerror = reject;
- });
- }
- doTxn(mode, stores, func, log = _logger.logger) {
- let startTime;
- let description;
- if (PROFILE_TRANSACTIONS) {
- const txnId = this.nextTxnId++;
- startTime = Date.now();
- description = `${mode} crypto store transaction ${txnId} in ${stores}`;
- log.debug(`Starting ${description}`);
- }
- const txn = this.db.transaction(stores, mode);
- const promise = promiseifyTxn(txn);
- const result = func(txn);
- if (PROFILE_TRANSACTIONS) {
- promise.then(() => {
- const elapsedTime = Date.now() - startTime;
- log.debug(`Finished ${description}, took ${elapsedTime} ms`);
- }, () => {
- const elapsedTime = Date.now() - startTime;
- log.error(`Failed ${description}, took ${elapsedTime} ms`);
- });
- }
- return promise.then(() => {
- return result;
- });
- }
-}
-exports.Backend = Backend;
-const DB_MIGRATIONS = [db => {
- createDatabase(db);
-}, db => {
- db.createObjectStore("account");
-}, db => {
- const sessionsStore = db.createObjectStore("sessions", {
- keyPath: ["deviceKey", "sessionId"]
- });
- sessionsStore.createIndex("deviceKey", "deviceKey");
-}, db => {
- db.createObjectStore("inbound_group_sessions", {
- keyPath: ["senderCurve25519Key", "sessionId"]
- });
-}, db => {
- db.createObjectStore("device_data");
-}, db => {
- db.createObjectStore("rooms");
-}, db => {
- db.createObjectStore("sessions_needing_backup", {
- keyPath: ["senderCurve25519Key", "sessionId"]
- });
-}, db => {
- db.createObjectStore("inbound_group_sessions_withheld", {
- keyPath: ["senderCurve25519Key", "sessionId"]
- });
-}, db => {
- const problemsStore = db.createObjectStore("session_problems", {
- keyPath: ["deviceKey", "time"]
- });
- problemsStore.createIndex("deviceKey", "deviceKey");
- db.createObjectStore("notified_error_devices", {
- keyPath: ["userId", "deviceId"]
- });
-}, db => {
- db.createObjectStore("shared_history_inbound_group_sessions", {
- keyPath: ["roomId"]
- });
-}, db => {
- db.createObjectStore("parked_shared_history", {
- keyPath: ["roomId"]
- });
-}
-// Expand as needed.
-];
-
-const VERSION = DB_MIGRATIONS.length;
-exports.VERSION = VERSION;
-function upgradeDatabase(db, oldVersion) {
- _logger.logger.log(`Upgrading IndexedDBCryptoStore from version ${oldVersion}` + ` to ${VERSION}`);
- DB_MIGRATIONS.forEach((migration, index) => {
- if (oldVersion <= index) migration(db);
- });
-}
-function createDatabase(db) {
- const outgoingRoomKeyRequestsStore = db.createObjectStore("outgoingRoomKeyRequests", {
- keyPath: "requestId"
- });
-
- // we assume that the RoomKeyRequestBody will have room_id and session_id
- // properties, to make the index efficient.
- outgoingRoomKeyRequestsStore.createIndex("session", ["requestBody.room_id", "requestBody.session_id"]);
- outgoingRoomKeyRequestsStore.createIndex("state", "state");
-}
-/*
- * Aborts a transaction with a given exception
- * The transaction promise will be rejected with this exception.
- */
-function abortWithException(txn, e) {
- // We cheekily stick our exception onto the transaction object here
- // We could alternatively make the thing we pass back to the app
- // an object containing the transaction and exception.
- txn._mx_abortexception = e;
- try {
- txn.abort();
- } catch (e) {
- // sometimes we won't be able to abort the transaction
- // (ie. if it's aborted or completed)
- }
-}
-function promiseifyTxn(txn) {
- return new Promise((resolve, reject) => {
- txn.oncomplete = () => {
- if (txn._mx_abortexception !== undefined) {
- reject(txn._mx_abortexception);
- }
- resolve(null);
- };
- txn.onerror = event => {
- if (txn._mx_abortexception !== undefined) {
- reject(txn._mx_abortexception);
- } else {
- _logger.logger.log("Error performing indexeddb txn", event);
- reject(txn.error);
- }
- };
- txn.onabort = event => {
- if (txn._mx_abortexception !== undefined) {
- reject(txn._mx_abortexception);
- } else {
- _logger.logger.log("Error performing indexeddb txn", event);
- reject(txn.error);
- }
- };
- });
-}
-//# sourceMappingURL=indexeddb-crypto-store-backend.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store-backend.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store-backend.js.map
deleted file mode 100644
index 4395ab3..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store-backend.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"indexeddb-crypto-store-backend.js","names":["_logger","require","utils","_interopRequireWildcard","_getRequireWildcardCache","nodeInterop","WeakMap","cacheBabelInterop","cacheNodeInterop","obj","__esModule","default","cache","has","get","newObj","hasPropertyDescriptor","Object","defineProperty","getOwnPropertyDescriptor","key","prototype","hasOwnProperty","call","desc","set","PROFILE_TRANSACTIONS","Backend","constructor","db","_defineProperty2","onversionchange","logger","log","name","close","startup","deleteAllData","Error","getOrAddOutgoingRoomKeyRequest","request","requestBody","Promise","resolve","reject","txn","transaction","onerror","_getOutgoingRoomKeyRequest","existing","room_id","session_id","oncomplete","store","objectStore","add","getOutgoingRoomKeyRequest","callback","idx","index","cursorReq","openCursor","onsuccess","cursor","result","value","deepCompare","continue","getOutgoingRoomKeyRequestByState","wantedStates","length","stateIndex","wantedState","source","promiseifyTxn","then","getAllOutgoingRoomKeyRequestsByState","getAll","error","getOutgoingRoomKeyRequestsByTarget","userId","deviceId","results","keyReq","recipients","some","recipient","push","updateOutgoingRoomKeyRequest","requestId","expectedState","updates","data","state","warn","assign","update","deleteOutgoingRoomKeyRequest","delete","getAccount","func","getReq","e","abortWithException","storeAccount","accountPickle","put","getCrossSigningKeys","getSecretStorePrivateKey","type","storeCrossSigningKeys","keys","storeSecretStorePrivateKey","countEndToEndSessions","countReq","count","getEndToEndSessions","deviceKey","sessionId","session","lastReceivedMessageTs","getEndToEndSession","getAllEndToEndSessions","storeEndToEndSession","sessionInfo","storeEndToEndSessionProblem","fixed","time","Date","now","getEndToEndSessionProblem","timestamp","req","problems","sort","a","b","lastProblem","problem","filterOutNotifiedErrorDevices","devices","ret","all","map","device","deviceInfo","getEndToEndInboundGroupSession","senderCurve25519Key","withheld","withheldObjectStore","withheldGetReq","getAllEndToEndInboundGroupSessions","senderKey","sessionData","addEndToEndInboundGroupSession","addReq","ev","_addReq$error","stopPropagation","preventDefault","storeEndToEndInboundGroupSession","storeEndToEndInboundGroupSessionWithheld","getEndToEndDeviceData","storeEndToEndDeviceData","deviceData","storeEndToEndRoom","roomId","roomInfo","getEndToEndRooms","rooms","getSessionsNeedingBackup","limit","sessions","sessionStore","sessionGetReq","countSessionsNeedingBackup","unmarkSessionsNeedingBackup","markSessionsNeedingBackup","addSharedHistoryInboundGroupSession","getSharedHistoryInboundGroupSessions","addParkedSharedHistory","parkedData","parked","takeParkedSharedHistory","doTxn","mode","stores","startTime","description","txnId","nextTxnId","debug","promise","elapsedTime","exports","DB_MIGRATIONS","createDatabase","createObjectStore","sessionsStore","keyPath","createIndex","problemsStore","VERSION","upgradeDatabase","oldVersion","forEach","migration","outgoingRoomKeyRequestsStore","_mx_abortexception","abort","undefined","event","onabort"],"sources":["../../../src/crypto/store/indexeddb-crypto-store-backend.ts"],"sourcesContent":["/*\nCopyright 2017 - 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { logger, PrefixedLogger } from \"../../logger\";\nimport * as utils from \"../../utils\";\nimport {\n CryptoStore,\n IDeviceData,\n IProblem,\n ISession,\n ISessionInfo,\n IWithheld,\n Mode,\n OutgoingRoomKeyRequest,\n ParkedSharedHistory,\n SecretStorePrivateKeys,\n} from \"./base\";\nimport { IRoomKeyRequestBody, IRoomKeyRequestRecipient } from \"../index\";\nimport { ICrossSigningKey } from \"../../client\";\nimport { IOlmDevice } from \"../algorithms/megolm\";\nimport { IRoomEncryption } from \"../RoomList\";\nimport { InboundGroupSessionData } from \"../OlmDevice\";\n\nconst PROFILE_TRANSACTIONS = false;\n\n/**\n * Implementation of a CryptoStore which is backed by an existing\n * IndexedDB connection. Generally you want IndexedDBCryptoStore\n * which connects to the database and defers to one of these.\n */\nexport class Backend implements CryptoStore {\n private nextTxnId = 0;\n\n /**\n */\n public constructor(private db: IDBDatabase) {\n // make sure we close the db on `onversionchange` - otherwise\n // attempts to delete the database will block (and subsequent\n // attempts to re-create it will also block).\n db.onversionchange = (): void => {\n logger.log(`versionchange for indexeddb ${this.db.name}: closing`);\n db.close();\n };\n }\n\n public async startup(): Promise<CryptoStore> {\n // No work to do, as the startup is done by the caller (e.g IndexedDBCryptoStore)\n // by passing us a ready IDBDatabase instance\n return this;\n }\n public async deleteAllData(): Promise<void> {\n throw Error(\"This is not implemented, call IDBFactory::deleteDatabase(dbName) instead.\");\n }\n\n /**\n * Look for an existing outgoing room key request, and if none is found,\n * add a new one\n *\n *\n * @returns resolves to\n * {@link OutgoingRoomKeyRequest}: either the\n * same instance as passed in, or the existing one.\n */\n public getOrAddOutgoingRoomKeyRequest(request: OutgoingRoomKeyRequest): Promise<OutgoingRoomKeyRequest> {\n const requestBody = request.requestBody;\n\n return new Promise((resolve, reject) => {\n const txn = this.db.transaction(\"outgoingRoomKeyRequests\", \"readwrite\");\n txn.onerror = reject;\n\n // first see if we already have an entry for this request.\n this._getOutgoingRoomKeyRequest(txn, requestBody, (existing) => {\n if (existing) {\n // this entry matches the request - return it.\n logger.log(\n `already have key request outstanding for ` +\n `${requestBody.room_id} / ${requestBody.session_id}: ` +\n `not sending another`,\n );\n resolve(existing);\n return;\n }\n\n // we got to the end of the list without finding a match\n // - add the new request.\n logger.log(`enqueueing key request for ${requestBody.room_id} / ` + requestBody.session_id);\n txn.oncomplete = (): void => {\n resolve(request);\n };\n const store = txn.objectStore(\"outgoingRoomKeyRequests\");\n store.add(request);\n });\n });\n }\n\n /**\n * Look for an existing room key request\n *\n * @param requestBody - existing request to look for\n *\n * @returns resolves to the matching\n * {@link OutgoingRoomKeyRequest}, or null if\n * not found\n */\n public getOutgoingRoomKeyRequest(requestBody: IRoomKeyRequestBody): Promise<OutgoingRoomKeyRequest | null> {\n return new Promise((resolve, reject) => {\n const txn = this.db.transaction(\"outgoingRoomKeyRequests\", \"readonly\");\n txn.onerror = reject;\n\n this._getOutgoingRoomKeyRequest(txn, requestBody, (existing) => {\n resolve(existing);\n });\n });\n }\n\n /**\n * look for an existing room key request in the db\n *\n * @internal\n * @param txn - database transaction\n * @param requestBody - existing request to look for\n * @param callback - function to call with the results of the\n * search. Either passed a matching\n * {@link OutgoingRoomKeyRequest}, or null if\n * not found.\n */\n // eslint-disable-next-line @typescript-eslint/naming-convention\n private _getOutgoingRoomKeyRequest(\n txn: IDBTransaction,\n requestBody: IRoomKeyRequestBody,\n callback: (req: OutgoingRoomKeyRequest | null) => void,\n ): void {\n const store = txn.objectStore(\"outgoingRoomKeyRequests\");\n\n const idx = store.index(\"session\");\n const cursorReq = idx.openCursor([requestBody.room_id, requestBody.session_id]);\n\n cursorReq.onsuccess = (): void => {\n const cursor = cursorReq.result;\n if (!cursor) {\n // no match found\n callback(null);\n return;\n }\n\n const existing = cursor.value;\n\n if (utils.deepCompare(existing.requestBody, requestBody)) {\n // got a match\n callback(existing);\n return;\n }\n\n // look at the next entry in the index\n cursor.continue();\n };\n }\n\n /**\n * Look for room key requests by state\n *\n * @param wantedStates - list of acceptable states\n *\n * @returns resolves to the a\n * {@link OutgoingRoomKeyRequest}, or null if\n * there are no pending requests in those states. If there are multiple\n * requests in those states, an arbitrary one is chosen.\n */\n public getOutgoingRoomKeyRequestByState(wantedStates: number[]): Promise<OutgoingRoomKeyRequest | null> {\n if (wantedStates.length === 0) {\n return Promise.resolve(null);\n }\n\n // this is a bit tortuous because we need to make sure we do the lookup\n // in a single transaction, to avoid having a race with the insertion\n // code.\n\n // index into the wantedStates array\n let stateIndex = 0;\n let result: OutgoingRoomKeyRequest;\n\n function onsuccess(this: IDBRequest<IDBCursorWithValue | null>): void {\n const cursor = this.result;\n if (cursor) {\n // got a match\n result = cursor.value;\n return;\n }\n\n // try the next state in the list\n stateIndex++;\n if (stateIndex >= wantedStates.length) {\n // no matches\n return;\n }\n\n const wantedState = wantedStates[stateIndex];\n const cursorReq = (this.source as IDBIndex).openCursor(wantedState);\n cursorReq.onsuccess = onsuccess;\n }\n\n const txn = this.db.transaction(\"outgoingRoomKeyRequests\", \"readonly\");\n const store = txn.objectStore(\"outgoingRoomKeyRequests\");\n\n const wantedState = wantedStates[stateIndex];\n const cursorReq = store.index(\"state\").openCursor(wantedState);\n cursorReq.onsuccess = onsuccess;\n\n return promiseifyTxn(txn).then(() => result);\n }\n\n /**\n *\n * @returns All elements in a given state\n */\n public getAllOutgoingRoomKeyRequestsByState(wantedState: number): Promise<OutgoingRoomKeyRequest[]> {\n return new Promise((resolve, reject) => {\n const txn = this.db.transaction(\"outgoingRoomKeyRequests\", \"readonly\");\n const store = txn.objectStore(\"outgoingRoomKeyRequests\");\n const index = store.index(\"state\");\n const request = index.getAll(wantedState);\n\n request.onsuccess = (): void => resolve(request.result);\n request.onerror = (): void => reject(request.error);\n });\n }\n\n public getOutgoingRoomKeyRequestsByTarget(\n userId: string,\n deviceId: string,\n wantedStates: number[],\n ): Promise<OutgoingRoomKeyRequest[]> {\n let stateIndex = 0;\n const results: OutgoingRoomKeyRequest[] = [];\n\n function onsuccess(this: IDBRequest<IDBCursorWithValue | null>): void {\n const cursor = this.result;\n if (cursor) {\n const keyReq = cursor.value;\n if (\n keyReq.recipients.some(\n (recipient: IRoomKeyRequestRecipient) =>\n recipient.userId === userId && recipient.deviceId === deviceId,\n )\n ) {\n results.push(keyReq);\n }\n cursor.continue();\n } else {\n // try the next state in the list\n stateIndex++;\n if (stateIndex >= wantedStates.length) {\n // no matches\n return;\n }\n\n const wantedState = wantedStates[stateIndex];\n const cursorReq = (this.source as IDBIndex).openCursor(wantedState);\n cursorReq.onsuccess = onsuccess;\n }\n }\n\n const txn = this.db.transaction(\"outgoingRoomKeyRequests\", \"readonly\");\n const store = txn.objectStore(\"outgoingRoomKeyRequests\");\n\n const wantedState = wantedStates[stateIndex];\n const cursorReq = store.index(\"state\").openCursor(wantedState);\n cursorReq.onsuccess = onsuccess;\n\n return promiseifyTxn(txn).then(() => results);\n }\n\n /**\n * Look for an existing room key request by id and state, and update it if\n * found\n *\n * @param requestId - ID of request to update\n * @param expectedState - state we expect to find the request in\n * @param updates - name/value map of updates to apply\n *\n * @returns resolves to\n * {@link OutgoingRoomKeyRequest}\n * updated request, or null if no matching row was found\n */\n public updateOutgoingRoomKeyRequest(\n requestId: string,\n expectedState: number,\n updates: Partial<OutgoingRoomKeyRequest>,\n ): Promise<OutgoingRoomKeyRequest | null> {\n let result: OutgoingRoomKeyRequest | null = null;\n\n function onsuccess(this: IDBRequest<IDBCursorWithValue | null>): void {\n const cursor = this.result;\n if (!cursor) {\n return;\n }\n const data = cursor.value;\n if (data.state != expectedState) {\n logger.warn(\n `Cannot update room key request from ${expectedState} ` +\n `as it was already updated to ${data.state}`,\n );\n return;\n }\n Object.assign(data, updates);\n cursor.update(data);\n result = data;\n }\n\n const txn = this.db.transaction(\"outgoingRoomKeyRequests\", \"readwrite\");\n const cursorReq = txn.objectStore(\"outgoingRoomKeyRequests\").openCursor(requestId);\n cursorReq.onsuccess = onsuccess;\n return promiseifyTxn(txn).then(() => result);\n }\n\n /**\n * Look for an existing room key request by id and state, and delete it if\n * found\n *\n * @param requestId - ID of request to update\n * @param expectedState - state we expect to find the request in\n *\n * @returns resolves once the operation is completed\n */\n public deleteOutgoingRoomKeyRequest(\n requestId: string,\n expectedState: number,\n ): Promise<OutgoingRoomKeyRequest | null> {\n const txn = this.db.transaction(\"outgoingRoomKeyRequests\", \"readwrite\");\n const cursorReq = txn.objectStore(\"outgoingRoomKeyRequests\").openCursor(requestId);\n cursorReq.onsuccess = (): void => {\n const cursor = cursorReq.result;\n if (!cursor) {\n return;\n }\n const data = cursor.value;\n if (data.state != expectedState) {\n logger.warn(`Cannot delete room key request in state ${data.state} ` + `(expected ${expectedState})`);\n return;\n }\n cursor.delete();\n };\n return promiseifyTxn<OutgoingRoomKeyRequest | null>(txn);\n }\n\n // Olm Account\n\n public getAccount(txn: IDBTransaction, func: (accountPickle: string | null) => void): void {\n const objectStore = txn.objectStore(\"account\");\n const getReq = objectStore.get(\"-\");\n getReq.onsuccess = function (): void {\n try {\n func(getReq.result || null);\n } catch (e) {\n abortWithException(txn, <Error>e);\n }\n };\n }\n\n public storeAccount(txn: IDBTransaction, accountPickle: string): void {\n const objectStore = txn.objectStore(\"account\");\n objectStore.put(accountPickle, \"-\");\n }\n\n public getCrossSigningKeys(\n txn: IDBTransaction,\n func: (keys: Record<string, ICrossSigningKey> | null) => void,\n ): void {\n const objectStore = txn.objectStore(\"account\");\n const getReq = objectStore.get(\"crossSigningKeys\");\n getReq.onsuccess = function (): void {\n try {\n func(getReq.result || null);\n } catch (e) {\n abortWithException(txn, <Error>e);\n }\n };\n }\n\n public getSecretStorePrivateKey<K extends keyof SecretStorePrivateKeys>(\n txn: IDBTransaction,\n func: (key: SecretStorePrivateKeys[K] | null) => void,\n type: K,\n ): void {\n const objectStore = txn.objectStore(\"account\");\n const getReq = objectStore.get(`ssss_cache:${type}`);\n getReq.onsuccess = function (): void {\n try {\n func(getReq.result || null);\n } catch (e) {\n abortWithException(txn, <Error>e);\n }\n };\n }\n\n public storeCrossSigningKeys(txn: IDBTransaction, keys: Record<string, ICrossSigningKey>): void {\n const objectStore = txn.objectStore(\"account\");\n objectStore.put(keys, \"crossSigningKeys\");\n }\n\n public storeSecretStorePrivateKey<K extends keyof SecretStorePrivateKeys>(\n txn: IDBTransaction,\n type: K,\n key: SecretStorePrivateKeys[K],\n ): void {\n const objectStore = txn.objectStore(\"account\");\n objectStore.put(key, `ssss_cache:${type}`);\n }\n\n // Olm Sessions\n\n public countEndToEndSessions(txn: IDBTransaction, func: (count: number) => void): void {\n const objectStore = txn.objectStore(\"sessions\");\n const countReq = objectStore.count();\n countReq.onsuccess = function (): void {\n try {\n func(countReq.result);\n } catch (e) {\n abortWithException(txn, <Error>e);\n }\n };\n }\n\n public getEndToEndSessions(\n deviceKey: string,\n txn: IDBTransaction,\n func: (sessions: { [sessionId: string]: ISessionInfo }) => void,\n ): void {\n const objectStore = txn.objectStore(\"sessions\");\n const idx = objectStore.index(\"deviceKey\");\n const getReq = idx.openCursor(deviceKey);\n const results: Parameters<Parameters<Backend[\"getEndToEndSessions\"]>[2]>[0] = {};\n getReq.onsuccess = function (): void {\n const cursor = getReq.result;\n if (cursor) {\n results[cursor.value.sessionId] = {\n session: cursor.value.session,\n lastReceivedMessageTs: cursor.value.lastReceivedMessageTs,\n };\n cursor.continue();\n } else {\n try {\n func(results);\n } catch (e) {\n abortWithException(txn, <Error>e);\n }\n }\n };\n }\n\n public getEndToEndSession(\n deviceKey: string,\n sessionId: string,\n txn: IDBTransaction,\n func: (session: ISessionInfo | null) => void,\n ): void {\n const objectStore = txn.objectStore(\"sessions\");\n const getReq = objectStore.get([deviceKey, sessionId]);\n getReq.onsuccess = function (): void {\n try {\n if (getReq.result) {\n func({\n session: getReq.result.session,\n lastReceivedMessageTs: getReq.result.lastReceivedMessageTs,\n });\n } else {\n func(null);\n }\n } catch (e) {\n abortWithException(txn, <Error>e);\n }\n };\n }\n\n public getAllEndToEndSessions(txn: IDBTransaction, func: (session: ISessionInfo | null) => void): void {\n const objectStore = txn.objectStore(\"sessions\");\n const getReq = objectStore.openCursor();\n getReq.onsuccess = function (): void {\n try {\n const cursor = getReq.result;\n if (cursor) {\n func(cursor.value);\n cursor.continue();\n } else {\n func(null);\n }\n } catch (e) {\n abortWithException(txn, <Error>e);\n }\n };\n }\n\n public storeEndToEndSession(\n deviceKey: string,\n sessionId: string,\n sessionInfo: ISessionInfo,\n txn: IDBTransaction,\n ): void {\n const objectStore = txn.objectStore(\"sessions\");\n objectStore.put({\n deviceKey,\n sessionId,\n session: sessionInfo.session,\n lastReceivedMessageTs: sessionInfo.lastReceivedMessageTs,\n });\n }\n\n public async storeEndToEndSessionProblem(deviceKey: string, type: string, fixed: boolean): Promise<void> {\n const txn = this.db.transaction(\"session_problems\", \"readwrite\");\n const objectStore = txn.objectStore(\"session_problems\");\n objectStore.put({\n deviceKey,\n type,\n fixed,\n time: Date.now(),\n });\n await promiseifyTxn(txn);\n }\n\n public async getEndToEndSessionProblem(deviceKey: string, timestamp: number): Promise<IProblem | null> {\n let result: IProblem | null = null;\n const txn = this.db.transaction(\"session_problems\", \"readwrite\");\n const objectStore = txn.objectStore(\"session_problems\");\n const index = objectStore.index(\"deviceKey\");\n const req = index.getAll(deviceKey);\n req.onsuccess = (): void => {\n const problems = req.result;\n if (!problems.length) {\n result = null;\n return;\n }\n problems.sort((a, b) => {\n return a.time - b.time;\n });\n const lastProblem = problems[problems.length - 1];\n for (const problem of problems) {\n if (problem.time > timestamp) {\n result = Object.assign({}, problem, { fixed: lastProblem.fixed });\n return;\n }\n }\n if (lastProblem.fixed) {\n result = null;\n } else {\n result = lastProblem;\n }\n };\n await promiseifyTxn(txn);\n return result;\n }\n\n // FIXME: we should probably prune this when devices get deleted\n public async filterOutNotifiedErrorDevices(devices: IOlmDevice[]): Promise<IOlmDevice[]> {\n const txn = this.db.transaction(\"notified_error_devices\", \"readwrite\");\n const objectStore = txn.objectStore(\"notified_error_devices\");\n\n const ret: IOlmDevice[] = [];\n\n await Promise.all(\n devices.map((device) => {\n return new Promise<void>((resolve) => {\n const { userId, deviceInfo } = device;\n const getReq = objectStore.get([userId, deviceInfo.deviceId]);\n getReq.onsuccess = function (): void {\n if (!getReq.result) {\n objectStore.put({ userId, deviceId: deviceInfo.deviceId });\n ret.push(device);\n }\n resolve();\n };\n });\n }),\n );\n\n return ret;\n }\n\n // Inbound group sessions\n\n public getEndToEndInboundGroupSession(\n senderCurve25519Key: string,\n sessionId: string,\n txn: IDBTransaction,\n func: (groupSession: InboundGroupSessionData | null, groupSessionWithheld: IWithheld | null) => void,\n ): void {\n let session: InboundGroupSessionData | null | boolean = false;\n let withheld: IWithheld | null | boolean = false;\n const objectStore = txn.objectStore(\"inbound_group_sessions\");\n const getReq = objectStore.get([senderCurve25519Key, sessionId]);\n getReq.onsuccess = function (): void {\n try {\n if (getReq.result) {\n session = getReq.result.session;\n } else {\n session = null;\n }\n if (withheld !== false) {\n func(session as InboundGroupSessionData, withheld as IWithheld);\n }\n } catch (e) {\n abortWithException(txn, <Error>e);\n }\n };\n\n const withheldObjectStore = txn.objectStore(\"inbound_group_sessions_withheld\");\n const withheldGetReq = withheldObjectStore.get([senderCurve25519Key, sessionId]);\n withheldGetReq.onsuccess = function (): void {\n try {\n if (withheldGetReq.result) {\n withheld = withheldGetReq.result.session;\n } else {\n withheld = null;\n }\n if (session !== false) {\n func(session as InboundGroupSessionData, withheld as IWithheld);\n }\n } catch (e) {\n abortWithException(txn, <Error>e);\n }\n };\n }\n\n public getAllEndToEndInboundGroupSessions(txn: IDBTransaction, func: (session: ISession | null) => void): void {\n const objectStore = txn.objectStore(\"inbound_group_sessions\");\n const getReq = objectStore.openCursor();\n getReq.onsuccess = function (): void {\n const cursor = getReq.result;\n if (cursor) {\n try {\n func({\n senderKey: cursor.value.senderCurve25519Key,\n sessionId: cursor.value.sessionId,\n sessionData: cursor.value.session,\n });\n } catch (e) {\n abortWithException(txn, <Error>e);\n }\n cursor.continue();\n } else {\n try {\n func(null);\n } catch (e) {\n abortWithException(txn, <Error>e);\n }\n }\n };\n }\n\n public addEndToEndInboundGroupSession(\n senderCurve25519Key: string,\n sessionId: string,\n sessionData: InboundGroupSessionData,\n txn: IDBTransaction,\n ): void {\n const objectStore = txn.objectStore(\"inbound_group_sessions\");\n const addReq = objectStore.add({\n senderCurve25519Key,\n sessionId,\n session: sessionData,\n });\n addReq.onerror = (ev): void => {\n if (addReq.error?.name === \"ConstraintError\") {\n // This stops the error from triggering the txn's onerror\n ev.stopPropagation();\n // ...and this stops it from aborting the transaction\n ev.preventDefault();\n logger.log(\"Ignoring duplicate inbound group session: \" + senderCurve25519Key + \" / \" + sessionId);\n } else {\n abortWithException(txn, new Error(\"Failed to add inbound group session: \" + addReq.error));\n }\n };\n }\n\n public storeEndToEndInboundGroupSession(\n senderCurve25519Key: string,\n sessionId: string,\n sessionData: InboundGroupSessionData,\n txn: IDBTransaction,\n ): void {\n const objectStore = txn.objectStore(\"inbound_group_sessions\");\n objectStore.put({\n senderCurve25519Key,\n sessionId,\n session: sessionData,\n });\n }\n\n public storeEndToEndInboundGroupSessionWithheld(\n senderCurve25519Key: string,\n sessionId: string,\n sessionData: IWithheld,\n txn: IDBTransaction,\n ): void {\n const objectStore = txn.objectStore(\"inbound_group_sessions_withheld\");\n objectStore.put({\n senderCurve25519Key,\n sessionId,\n session: sessionData,\n });\n }\n\n public getEndToEndDeviceData(txn: IDBTransaction, func: (deviceData: IDeviceData | null) => void): void {\n const objectStore = txn.objectStore(\"device_data\");\n const getReq = objectStore.get(\"-\");\n getReq.onsuccess = function (): void {\n try {\n func(getReq.result || null);\n } catch (e) {\n abortWithException(txn, <Error>e);\n }\n };\n }\n\n public storeEndToEndDeviceData(deviceData: IDeviceData, txn: IDBTransaction): void {\n const objectStore = txn.objectStore(\"device_data\");\n objectStore.put(deviceData, \"-\");\n }\n\n public storeEndToEndRoom(roomId: string, roomInfo: IRoomEncryption, txn: IDBTransaction): void {\n const objectStore = txn.objectStore(\"rooms\");\n objectStore.put(roomInfo, roomId);\n }\n\n public getEndToEndRooms(txn: IDBTransaction, func: (rooms: Record<string, IRoomEncryption>) => void): void {\n const rooms: Parameters<Parameters<Backend[\"getEndToEndRooms\"]>[1]>[0] = {};\n const objectStore = txn.objectStore(\"rooms\");\n const getReq = objectStore.openCursor();\n getReq.onsuccess = function (): void {\n const cursor = getReq.result;\n if (cursor) {\n rooms[cursor.key as string] = cursor.value;\n cursor.continue();\n } else {\n try {\n func(rooms);\n } catch (e) {\n abortWithException(txn, <Error>e);\n }\n }\n };\n }\n\n // session backups\n\n public getSessionsNeedingBackup(limit: number): Promise<ISession[]> {\n return new Promise((resolve, reject) => {\n const sessions: ISession[] = [];\n\n const txn = this.db.transaction([\"sessions_needing_backup\", \"inbound_group_sessions\"], \"readonly\");\n txn.onerror = reject;\n txn.oncomplete = function (): void {\n resolve(sessions);\n };\n const objectStore = txn.objectStore(\"sessions_needing_backup\");\n const sessionStore = txn.objectStore(\"inbound_group_sessions\");\n const getReq = objectStore.openCursor();\n getReq.onsuccess = function (): void {\n const cursor = getReq.result;\n if (cursor) {\n const sessionGetReq = sessionStore.get(cursor.key);\n sessionGetReq.onsuccess = function (): void {\n sessions.push({\n senderKey: sessionGetReq.result.senderCurve25519Key,\n sessionId: sessionGetReq.result.sessionId,\n sessionData: sessionGetReq.result.session,\n });\n };\n if (!limit || sessions.length < limit) {\n cursor.continue();\n }\n }\n };\n });\n }\n\n public countSessionsNeedingBackup(txn?: IDBTransaction): Promise<number> {\n if (!txn) {\n txn = this.db.transaction(\"sessions_needing_backup\", \"readonly\");\n }\n const objectStore = txn.objectStore(\"sessions_needing_backup\");\n return new Promise((resolve, reject) => {\n const req = objectStore.count();\n req.onerror = reject;\n req.onsuccess = (): void => resolve(req.result);\n });\n }\n\n public async unmarkSessionsNeedingBackup(sessions: ISession[], txn?: IDBTransaction): Promise<void> {\n if (!txn) {\n txn = this.db.transaction(\"sessions_needing_backup\", \"readwrite\");\n }\n const objectStore = txn.objectStore(\"sessions_needing_backup\");\n await Promise.all(\n sessions.map((session) => {\n return new Promise((resolve, reject) => {\n const req = objectStore.delete([session.senderKey, session.sessionId]);\n req.onsuccess = resolve;\n req.onerror = reject;\n });\n }),\n );\n }\n\n public async markSessionsNeedingBackup(sessions: ISession[], txn?: IDBTransaction): Promise<void> {\n if (!txn) {\n txn = this.db.transaction(\"sessions_needing_backup\", \"readwrite\");\n }\n const objectStore = txn.objectStore(\"sessions_needing_backup\");\n await Promise.all(\n sessions.map((session) => {\n return new Promise((resolve, reject) => {\n const req = objectStore.put({\n senderCurve25519Key: session.senderKey,\n sessionId: session.sessionId,\n });\n req.onsuccess = resolve;\n req.onerror = reject;\n });\n }),\n );\n }\n\n public addSharedHistoryInboundGroupSession(\n roomId: string,\n senderKey: string,\n sessionId: string,\n txn?: IDBTransaction,\n ): void {\n if (!txn) {\n txn = this.db.transaction(\"shared_history_inbound_group_sessions\", \"readwrite\");\n }\n const objectStore = txn.objectStore(\"shared_history_inbound_group_sessions\");\n const req = objectStore.get([roomId]);\n req.onsuccess = (): void => {\n const { sessions } = req.result || { sessions: [] };\n sessions.push([senderKey, sessionId]);\n objectStore.put({ roomId, sessions });\n };\n }\n\n public getSharedHistoryInboundGroupSessions(\n roomId: string,\n txn?: IDBTransaction,\n ): Promise<[senderKey: string, sessionId: string][]> {\n if (!txn) {\n txn = this.db.transaction(\"shared_history_inbound_group_sessions\", \"readonly\");\n }\n const objectStore = txn.objectStore(\"shared_history_inbound_group_sessions\");\n const req = objectStore.get([roomId]);\n return new Promise((resolve, reject) => {\n req.onsuccess = (): void => {\n const { sessions } = req.result || { sessions: [] };\n resolve(sessions);\n };\n req.onerror = reject;\n });\n }\n\n public addParkedSharedHistory(roomId: string, parkedData: ParkedSharedHistory, txn?: IDBTransaction): void {\n if (!txn) {\n txn = this.db.transaction(\"parked_shared_history\", \"readwrite\");\n }\n const objectStore = txn.objectStore(\"parked_shared_history\");\n const req = objectStore.get([roomId]);\n req.onsuccess = (): void => {\n const { parked } = req.result || { parked: [] };\n parked.push(parkedData);\n objectStore.put({ roomId, parked });\n };\n }\n\n public takeParkedSharedHistory(roomId: string, txn?: IDBTransaction): Promise<ParkedSharedHistory[]> {\n if (!txn) {\n txn = this.db.transaction(\"parked_shared_history\", \"readwrite\");\n }\n const cursorReq = txn.objectStore(\"parked_shared_history\").openCursor(roomId);\n return new Promise((resolve, reject) => {\n cursorReq.onsuccess = (): void => {\n const cursor = cursorReq.result;\n if (!cursor) {\n resolve([]);\n return;\n }\n const data = cursor.value;\n cursor.delete();\n resolve(data);\n };\n cursorReq.onerror = reject;\n });\n }\n\n public doTxn<T>(\n mode: Mode,\n stores: string | string[],\n func: (txn: IDBTransaction) => T,\n log: PrefixedLogger = logger,\n ): Promise<T> {\n let startTime: number;\n let description: string;\n if (PROFILE_TRANSACTIONS) {\n const txnId = this.nextTxnId++;\n startTime = Date.now();\n description = `${mode} crypto store transaction ${txnId} in ${stores}`;\n log.debug(`Starting ${description}`);\n }\n const txn = this.db.transaction(stores, mode);\n const promise = promiseifyTxn(txn);\n const result = func(txn);\n if (PROFILE_TRANSACTIONS) {\n promise.then(\n () => {\n const elapsedTime = Date.now() - startTime;\n log.debug(`Finished ${description}, took ${elapsedTime} ms`);\n },\n () => {\n const elapsedTime = Date.now() - startTime;\n log.error(`Failed ${description}, took ${elapsedTime} ms`);\n },\n );\n }\n return promise.then(() => {\n return result;\n });\n }\n}\n\ntype DbMigration = (db: IDBDatabase) => void;\nconst DB_MIGRATIONS: DbMigration[] = [\n (db): void => {\n createDatabase(db);\n },\n (db): void => {\n db.createObjectStore(\"account\");\n },\n (db): void => {\n const sessionsStore = db.createObjectStore(\"sessions\", {\n keyPath: [\"deviceKey\", \"sessionId\"],\n });\n sessionsStore.createIndex(\"deviceKey\", \"deviceKey\");\n },\n (db): void => {\n db.createObjectStore(\"inbound_group_sessions\", {\n keyPath: [\"senderCurve25519Key\", \"sessionId\"],\n });\n },\n (db): void => {\n db.createObjectStore(\"device_data\");\n },\n (db): void => {\n db.createObjectStore(\"rooms\");\n },\n (db): void => {\n db.createObjectStore(\"sessions_needing_backup\", {\n keyPath: [\"senderCurve25519Key\", \"sessionId\"],\n });\n },\n (db): void => {\n db.createObjectStore(\"inbound_group_sessions_withheld\", {\n keyPath: [\"senderCurve25519Key\", \"sessionId\"],\n });\n },\n (db): void => {\n const problemsStore = db.createObjectStore(\"session_problems\", {\n keyPath: [\"deviceKey\", \"time\"],\n });\n problemsStore.createIndex(\"deviceKey\", \"deviceKey\");\n\n db.createObjectStore(\"notified_error_devices\", {\n keyPath: [\"userId\", \"deviceId\"],\n });\n },\n (db): void => {\n db.createObjectStore(\"shared_history_inbound_group_sessions\", {\n keyPath: [\"roomId\"],\n });\n },\n (db): void => {\n db.createObjectStore(\"parked_shared_history\", {\n keyPath: [\"roomId\"],\n });\n },\n // Expand as needed.\n];\nexport const VERSION = DB_MIGRATIONS.length;\n\nexport function upgradeDatabase(db: IDBDatabase, oldVersion: number): void {\n logger.log(`Upgrading IndexedDBCryptoStore from version ${oldVersion}` + ` to ${VERSION}`);\n DB_MIGRATIONS.forEach((migration, index) => {\n if (oldVersion <= index) migration(db);\n });\n}\n\nfunction createDatabase(db: IDBDatabase): void {\n const outgoingRoomKeyRequestsStore = db.createObjectStore(\"outgoingRoomKeyRequests\", { keyPath: \"requestId\" });\n\n // we assume that the RoomKeyRequestBody will have room_id and session_id\n // properties, to make the index efficient.\n outgoingRoomKeyRequestsStore.createIndex(\"session\", [\"requestBody.room_id\", \"requestBody.session_id\"]);\n\n outgoingRoomKeyRequestsStore.createIndex(\"state\", \"state\");\n}\n\ninterface IWrappedIDBTransaction extends IDBTransaction {\n _mx_abortexception: Error; // eslint-disable-line camelcase\n}\n\n/*\n * Aborts a transaction with a given exception\n * The transaction promise will be rejected with this exception.\n */\nfunction abortWithException(txn: IDBTransaction, e: Error): void {\n // We cheekily stick our exception onto the transaction object here\n // We could alternatively make the thing we pass back to the app\n // an object containing the transaction and exception.\n (txn as IWrappedIDBTransaction)._mx_abortexception = e;\n try {\n txn.abort();\n } catch (e) {\n // sometimes we won't be able to abort the transaction\n // (ie. if it's aborted or completed)\n }\n}\n\nfunction promiseifyTxn<T>(txn: IDBTransaction): Promise<T | null> {\n return new Promise((resolve, reject) => {\n txn.oncomplete = (): void => {\n if ((txn as IWrappedIDBTransaction)._mx_abortexception !== undefined) {\n reject((txn as IWrappedIDBTransaction)._mx_abortexception);\n }\n resolve(null);\n };\n txn.onerror = (event): void => {\n if ((txn as IWrappedIDBTransaction)._mx_abortexception !== undefined) {\n reject((txn as IWrappedIDBTransaction)._mx_abortexception);\n } else {\n logger.log(\"Error performing indexeddb txn\", event);\n reject(txn.error);\n }\n };\n txn.onabort = (event): void => {\n if ((txn as IWrappedIDBTransaction)._mx_abortexception !== undefined) {\n reject((txn as IWrappedIDBTransaction)._mx_abortexception);\n } else {\n logger.log(\"Error performing indexeddb txn\", event);\n reject(txn.error);\n }\n };\n });\n}\n"],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store.d.ts
deleted file mode 100644
index 32fcc52..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store.d.ts
+++ /dev/null
@@ -1,360 +0,0 @@
-import { PrefixedLogger } from "../../logger";
-import { CryptoStore, IDeviceData, IProblem, ISession, ISessionInfo, IWithheld, Mode, OutgoingRoomKeyRequest, ParkedSharedHistory, SecretStorePrivateKeys } from "./base";
-import { IRoomKeyRequestBody } from "../index";
-import { ICrossSigningKey } from "../../client";
-import { IOlmDevice } from "../algorithms/megolm";
-import { IRoomEncryption } from "../RoomList";
-import { InboundGroupSessionData } from "../OlmDevice";
-/**
- * Internal module. indexeddb storage for e2e.
- */
-/**
- * An implementation of CryptoStore, which is normally backed by an indexeddb,
- * but with fallback to MemoryCryptoStore.
- */
-export declare class IndexedDBCryptoStore implements CryptoStore {
- private readonly indexedDB;
- private readonly dbName;
- static STORE_ACCOUNT: string;
- static STORE_SESSIONS: string;
- static STORE_INBOUND_GROUP_SESSIONS: string;
- static STORE_INBOUND_GROUP_SESSIONS_WITHHELD: string;
- static STORE_SHARED_HISTORY_INBOUND_GROUP_SESSIONS: string;
- static STORE_PARKED_SHARED_HISTORY: string;
- static STORE_DEVICE_DATA: string;
- static STORE_ROOMS: string;
- static STORE_BACKUP: string;
- static exists(indexedDB: IDBFactory, dbName: string): Promise<boolean>;
- private backendPromise?;
- private backend?;
- /**
- * Create a new IndexedDBCryptoStore
- *
- * @param indexedDB - global indexedDB instance
- * @param dbName - name of db to connect to
- */
- constructor(indexedDB: IDBFactory, dbName: string);
- /**
- * Ensure the database exists and is up-to-date, or fall back to
- * a local storage or in-memory store.
- *
- * This must be called before the store can be used.
- *
- * @returns resolves to either an IndexedDBCryptoStoreBackend.Backend,
- * or a MemoryCryptoStore
- */
- startup(): Promise<CryptoStore>;
- /**
- * Delete all data from this store.
- *
- * @returns resolves when the store has been cleared.
- */
- deleteAllData(): Promise<void>;
- /**
- * Look for an existing outgoing room key request, and if none is found,
- * add a new one
- *
- *
- * @returns resolves to
- * {@link OutgoingRoomKeyRequest}: either the
- * same instance as passed in, or the existing one.
- */
- getOrAddOutgoingRoomKeyRequest(request: OutgoingRoomKeyRequest): Promise<OutgoingRoomKeyRequest>;
- /**
- * Look for an existing room key request
- *
- * @param requestBody - existing request to look for
- *
- * @returns resolves to the matching
- * {@link OutgoingRoomKeyRequest}, or null if
- * not found
- */
- getOutgoingRoomKeyRequest(requestBody: IRoomKeyRequestBody): Promise<OutgoingRoomKeyRequest | null>;
- /**
- * Look for room key requests by state
- *
- * @param wantedStates - list of acceptable states
- *
- * @returns resolves to the a
- * {@link OutgoingRoomKeyRequest}, or null if
- * there are no pending requests in those states. If there are multiple
- * requests in those states, an arbitrary one is chosen.
- */
- getOutgoingRoomKeyRequestByState(wantedStates: number[]): Promise<OutgoingRoomKeyRequest | null>;
- /**
- * Look for room key requests by state –
- * unlike above, return a list of all entries in one state.
- *
- * @returns Returns an array of requests in the given state
- */
- getAllOutgoingRoomKeyRequestsByState(wantedState: number): Promise<OutgoingRoomKeyRequest[]>;
- /**
- * Look for room key requests by target device and state
- *
- * @param userId - Target user ID
- * @param deviceId - Target device ID
- * @param wantedStates - list of acceptable states
- *
- * @returns resolves to a list of all the
- * {@link OutgoingRoomKeyRequest}
- */
- getOutgoingRoomKeyRequestsByTarget(userId: string, deviceId: string, wantedStates: number[]): Promise<OutgoingRoomKeyRequest[]>;
- /**
- * Look for an existing room key request by id and state, and update it if
- * found
- *
- * @param requestId - ID of request to update
- * @param expectedState - state we expect to find the request in
- * @param updates - name/value map of updates to apply
- *
- * @returns resolves to
- * {@link OutgoingRoomKeyRequest}
- * updated request, or null if no matching row was found
- */
- updateOutgoingRoomKeyRequest(requestId: string, expectedState: number, updates: Partial<OutgoingRoomKeyRequest>): Promise<OutgoingRoomKeyRequest | null>;
- /**
- * Look for an existing room key request by id and state, and delete it if
- * found
- *
- * @param requestId - ID of request to update
- * @param expectedState - state we expect to find the request in
- *
- * @returns resolves once the operation is completed
- */
- deleteOutgoingRoomKeyRequest(requestId: string, expectedState: number): Promise<OutgoingRoomKeyRequest | null>;
- getAccount(txn: IDBTransaction, func: (accountPickle: string | null) => void): void;
- /**
- * Write the account pickle to the store.
- * This requires an active transaction. See doTxn().
- *
- * @param txn - An active transaction. See doTxn().
- * @param accountPickle - The new account pickle to store.
- */
- storeAccount(txn: IDBTransaction, accountPickle: string): void;
- /**
- * Get the public part of the cross-signing keys (eg. self-signing key,
- * user signing key).
- *
- * @param txn - An active transaction. See doTxn().
- * @param func - Called with the account keys object:
- * `{ key_type: base64 encoded seed }` where key type = user_signing_key_seed or self_signing_key_seed
- */
- getCrossSigningKeys(txn: IDBTransaction, func: (keys: Record<string, ICrossSigningKey> | null) => void): void;
- /**
- * @param txn - An active transaction. See doTxn().
- * @param func - Called with the private key
- * @param type - A key type
- */
- getSecretStorePrivateKey<K extends keyof SecretStorePrivateKeys>(txn: IDBTransaction, func: (key: SecretStorePrivateKeys[K] | null) => void, type: K): void;
- /**
- * Write the cross-signing keys back to the store
- *
- * @param txn - An active transaction. See doTxn().
- * @param keys - keys object as getCrossSigningKeys()
- */
- storeCrossSigningKeys(txn: IDBTransaction, keys: Record<string, ICrossSigningKey>): void;
- /**
- * Write the cross-signing private keys back to the store
- *
- * @param txn - An active transaction. See doTxn().
- * @param type - The type of cross-signing private key to store
- * @param key - keys object as getCrossSigningKeys()
- */
- storeSecretStorePrivateKey<K extends keyof SecretStorePrivateKeys>(txn: IDBTransaction, type: K, key: SecretStorePrivateKeys[K]): void;
- /**
- * Returns the number of end-to-end sessions in the store
- * @param txn - An active transaction. See doTxn().
- * @param func - Called with the count of sessions
- */
- countEndToEndSessions(txn: IDBTransaction, func: (count: number) => void): void;
- /**
- * Retrieve a specific end-to-end session between the logged-in user
- * and another device.
- * @param deviceKey - The public key of the other device.
- * @param sessionId - The ID of the session to retrieve
- * @param txn - An active transaction. See doTxn().
- * @param func - Called with A map from sessionId
- * to session information object with 'session' key being the
- * Base64 end-to-end session and lastReceivedMessageTs being the
- * timestamp in milliseconds at which the session last received
- * a message.
- */
- getEndToEndSession(deviceKey: string, sessionId: string, txn: IDBTransaction, func: (session: ISessionInfo | null) => void): void;
- /**
- * Retrieve the end-to-end sessions between the logged-in user and another
- * device.
- * @param deviceKey - The public key of the other device.
- * @param txn - An active transaction. See doTxn().
- * @param func - Called with A map from sessionId
- * to session information object with 'session' key being the
- * Base64 end-to-end session and lastReceivedMessageTs being the
- * timestamp in milliseconds at which the session last received
- * a message.
- */
- getEndToEndSessions(deviceKey: string, txn: IDBTransaction, func: (sessions: {
- [sessionId: string]: ISessionInfo;
- }) => void): void;
- /**
- * Retrieve all end-to-end sessions
- * @param txn - An active transaction. See doTxn().
- * @param func - Called one for each session with
- * an object with, deviceKey, lastReceivedMessageTs, sessionId
- * and session keys.
- */
- getAllEndToEndSessions(txn: IDBTransaction, func: (session: ISessionInfo | null) => void): void;
- /**
- * Store a session between the logged-in user and another device
- * @param deviceKey - The public key of the other device.
- * @param sessionId - The ID for this end-to-end session.
- * @param sessionInfo - Session information object
- * @param txn - An active transaction. See doTxn().
- */
- storeEndToEndSession(deviceKey: string, sessionId: string, sessionInfo: ISessionInfo, txn: IDBTransaction): void;
- storeEndToEndSessionProblem(deviceKey: string, type: string, fixed: boolean): Promise<void>;
- getEndToEndSessionProblem(deviceKey: string, timestamp: number): Promise<IProblem | null>;
- filterOutNotifiedErrorDevices(devices: IOlmDevice[]): Promise<IOlmDevice[]>;
- /**
- * Retrieve the end-to-end inbound group session for a given
- * server key and session ID
- * @param senderCurve25519Key - The sender's curve 25519 key
- * @param sessionId - The ID of the session
- * @param txn - An active transaction. See doTxn().
- * @param func - Called with A map from sessionId
- * to Base64 end-to-end session.
- */
- getEndToEndInboundGroupSession(senderCurve25519Key: string, sessionId: string, txn: IDBTransaction, func: (groupSession: InboundGroupSessionData | null, groupSessionWithheld: IWithheld | null) => void): void;
- /**
- * Fetches all inbound group sessions in the store
- * @param txn - An active transaction. See doTxn().
- * @param func - Called once for each group session
- * in the store with an object having keys `{senderKey, sessionId, sessionData}`,
- * then once with null to indicate the end of the list.
- */
- getAllEndToEndInboundGroupSessions(txn: IDBTransaction, func: (session: ISession | null) => void): void;
- /**
- * Adds an end-to-end inbound group session to the store.
- * If there already exists an inbound group session with the same
- * senderCurve25519Key and sessionID, the session will not be added.
- * @param senderCurve25519Key - The sender's curve 25519 key
- * @param sessionId - The ID of the session
- * @param sessionData - The session data structure
- * @param txn - An active transaction. See doTxn().
- */
- addEndToEndInboundGroupSession(senderCurve25519Key: string, sessionId: string, sessionData: InboundGroupSessionData, txn: IDBTransaction): void;
- /**
- * Writes an end-to-end inbound group session to the store.
- * If there already exists an inbound group session with the same
- * senderCurve25519Key and sessionID, it will be overwritten.
- * @param senderCurve25519Key - The sender's curve 25519 key
- * @param sessionId - The ID of the session
- * @param sessionData - The session data structure
- * @param txn - An active transaction. See doTxn().
- */
- storeEndToEndInboundGroupSession(senderCurve25519Key: string, sessionId: string, sessionData: InboundGroupSessionData, txn: IDBTransaction): void;
- storeEndToEndInboundGroupSessionWithheld(senderCurve25519Key: string, sessionId: string, sessionData: IWithheld, txn: IDBTransaction): void;
- /**
- * Store the state of all tracked devices
- * This contains devices for each user, a tracking state for each user
- * and a sync token matching the point in time the snapshot represents.
- * These all need to be written out in full each time such that the snapshot
- * is always consistent, so they are stored in one object.
- *
- * @param txn - An active transaction. See doTxn().
- */
- storeEndToEndDeviceData(deviceData: IDeviceData, txn: IDBTransaction): void;
- /**
- * Get the state of all tracked devices
- *
- * @param txn - An active transaction. See doTxn().
- * @param func - Function called with the
- * device data
- */
- getEndToEndDeviceData(txn: IDBTransaction, func: (deviceData: IDeviceData | null) => void): void;
- /**
- * Store the end-to-end state for a room.
- * @param roomId - The room's ID.
- * @param roomInfo - The end-to-end info for the room.
- * @param txn - An active transaction. See doTxn().
- */
- storeEndToEndRoom(roomId: string, roomInfo: IRoomEncryption, txn: IDBTransaction): void;
- /**
- * Get an object of `roomId->roomInfo` for all e2e rooms in the store
- * @param txn - An active transaction. See doTxn().
- * @param func - Function called with the end-to-end encrypted rooms
- */
- getEndToEndRooms(txn: IDBTransaction, func: (rooms: Record<string, IRoomEncryption>) => void): void;
- /**
- * Get the inbound group sessions that need to be backed up.
- * @param limit - The maximum number of sessions to retrieve. 0
- * for no limit.
- * @returns resolves to an array of inbound group sessions
- */
- getSessionsNeedingBackup(limit: number): Promise<ISession[]>;
- /**
- * Count the inbound group sessions that need to be backed up.
- * @param txn - An active transaction. See doTxn(). (optional)
- * @returns resolves to the number of sessions
- */
- countSessionsNeedingBackup(txn?: IDBTransaction): Promise<number>;
- /**
- * Unmark sessions as needing to be backed up.
- * @param sessions - The sessions that need to be backed up.
- * @param txn - An active transaction. See doTxn(). (optional)
- * @returns resolves when the sessions are unmarked
- */
- unmarkSessionsNeedingBackup(sessions: ISession[], txn?: IDBTransaction): Promise<void>;
- /**
- * Mark sessions as needing to be backed up.
- * @param sessions - The sessions that need to be backed up.
- * @param txn - An active transaction. See doTxn(). (optional)
- * @returns resolves when the sessions are marked
- */
- markSessionsNeedingBackup(sessions: ISession[], txn?: IDBTransaction): Promise<void>;
- /**
- * Add a shared-history group session for a room.
- * @param roomId - The room that the key belongs to
- * @param senderKey - The sender's curve 25519 key
- * @param sessionId - The ID of the session
- * @param txn - An active transaction. See doTxn(). (optional)
- */
- addSharedHistoryInboundGroupSession(roomId: string, senderKey: string, sessionId: string, txn?: IDBTransaction): void;
- /**
- * Get the shared-history group session for a room.
- * @param roomId - The room that the key belongs to
- * @param txn - An active transaction. See doTxn(). (optional)
- * @returns Promise which resolves to an array of [senderKey, sessionId]
- */
- getSharedHistoryInboundGroupSessions(roomId: string, txn?: IDBTransaction): Promise<[senderKey: string, sessionId: string][]>;
- /**
- * Park a shared-history group session for a room we may be invited to later.
- */
- addParkedSharedHistory(roomId: string, parkedData: ParkedSharedHistory, txn?: IDBTransaction): void;
- /**
- * Pop out all shared-history group sessions for a room.
- */
- takeParkedSharedHistory(roomId: string, txn?: IDBTransaction): Promise<ParkedSharedHistory[]>;
- /**
- * Perform a transaction on the crypto store. Any store methods
- * that require a transaction (txn) object to be passed in may
- * only be called within a callback of either this function or
- * one of the store functions operating on the same transaction.
- *
- * @param mode - 'readwrite' if you need to call setter
- * functions with this transaction. Otherwise, 'readonly'.
- * @param stores - List IndexedDBCryptoStore.STORE_*
- * options representing all types of object that will be
- * accessed or written to with this transaction.
- * @param func - Function called with the
- * transaction object: an opaque object that should be passed
- * to store functions.
- * @param log - A possibly customised log
- * @returns Promise that resolves with the result of the `func`
- * when the transaction is complete. If the backend is
- * async (ie. the indexeddb backend) any of the callback
- * functions throwing an exception will cause this promise to
- * reject with that exception. On synchronous backends, the
- * exception will propagate to the caller of the getFoo method.
- */
- doTxn<T>(mode: Mode, stores: Iterable<string>, func: (txn: IDBTransaction) => T, log?: PrefixedLogger): Promise<T>;
-}
-//# sourceMappingURL=indexeddb-crypto-store.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store.d.ts.map
deleted file mode 100644
index d66170a..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"indexeddb-crypto-store.d.ts","sourceRoot":"","sources":["../../../src/crypto/store/indexeddb-crypto-store.ts"],"names":[],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store.js
deleted file mode 100644
index 0f68d63..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store.js
+++ /dev/null
@@ -1,601 +0,0 @@
-"use strict";
-
-var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.IndexedDBCryptoStore = void 0;
-var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
-var _logger = require("../../logger");
-var _localStorageCryptoStore = require("./localStorage-crypto-store");
-var _memoryCryptoStore = require("./memory-crypto-store");
-var IndexedDBCryptoStoreBackend = _interopRequireWildcard(require("./indexeddb-crypto-store-backend"));
-var _errors = require("../../errors");
-var IndexedDBHelpers = _interopRequireWildcard(require("../../indexeddb-helpers"));
-function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
-function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
-/*
-Copyright 2017 - 2021 The Matrix.org Foundation C.I.C.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-/**
- * Internal module. indexeddb storage for e2e.
- */
-
-/**
- * An implementation of CryptoStore, which is normally backed by an indexeddb,
- * but with fallback to MemoryCryptoStore.
- */
-class IndexedDBCryptoStore {
- static exists(indexedDB, dbName) {
- return IndexedDBHelpers.exists(indexedDB, dbName);
- }
- /**
- * Create a new IndexedDBCryptoStore
- *
- * @param indexedDB - global indexedDB instance
- * @param dbName - name of db to connect to
- */
- constructor(indexedDB, dbName) {
- this.indexedDB = indexedDB;
- this.dbName = dbName;
- (0, _defineProperty2.default)(this, "backendPromise", void 0);
- (0, _defineProperty2.default)(this, "backend", void 0);
- }
-
- /**
- * Ensure the database exists and is up-to-date, or fall back to
- * a local storage or in-memory store.
- *
- * This must be called before the store can be used.
- *
- * @returns resolves to either an IndexedDBCryptoStoreBackend.Backend,
- * or a MemoryCryptoStore
- */
- startup() {
- if (this.backendPromise) {
- return this.backendPromise;
- }
- this.backendPromise = new Promise((resolve, reject) => {
- if (!this.indexedDB) {
- reject(new Error("no indexeddb support available"));
- return;
- }
- _logger.logger.log(`connecting to indexeddb ${this.dbName}`);
- const req = this.indexedDB.open(this.dbName, IndexedDBCryptoStoreBackend.VERSION);
- req.onupgradeneeded = ev => {
- const db = req.result;
- const oldVersion = ev.oldVersion;
- IndexedDBCryptoStoreBackend.upgradeDatabase(db, oldVersion);
- };
- req.onblocked = () => {
- _logger.logger.log(`can't yet open IndexedDBCryptoStore because it is open elsewhere`);
- };
- req.onerror = ev => {
- _logger.logger.log("Error connecting to indexeddb", ev);
- reject(req.error);
- };
- req.onsuccess = () => {
- const db = req.result;
- _logger.logger.log(`connected to indexeddb ${this.dbName}`);
- resolve(new IndexedDBCryptoStoreBackend.Backend(db));
- };
- }).then(backend => {
- // Edge has IndexedDB but doesn't support compund keys which we use fairly extensively.
- // Try a dummy query which will fail if the browser doesn't support compund keys, so
- // we can fall back to a different backend.
- return backend.doTxn("readonly", [IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS, IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS_WITHHELD], txn => {
- backend.getEndToEndInboundGroupSession("", "", txn, () => {});
- }).then(() => backend);
- }).catch(e => {
- if (e.name === "VersionError") {
- _logger.logger.warn("Crypto DB is too new for us to use!", e);
- // don't fall back to a different store: the user has crypto data
- // in this db so we should use it or nothing at all.
- throw new _errors.InvalidCryptoStoreError(_errors.InvalidCryptoStoreState.TooNew);
- }
- _logger.logger.warn(`unable to connect to indexeddb ${this.dbName}` + `: falling back to localStorage store: ${e}`);
- try {
- return new _localStorageCryptoStore.LocalStorageCryptoStore(global.localStorage);
- } catch (e) {
- _logger.logger.warn(`unable to open localStorage: falling back to in-memory store: ${e}`);
- return new _memoryCryptoStore.MemoryCryptoStore();
- }
- }).then(backend => {
- this.backend = backend;
- return backend;
- });
- return this.backendPromise;
- }
-
- /**
- * Delete all data from this store.
- *
- * @returns resolves when the store has been cleared.
- */
- deleteAllData() {
- return new Promise((resolve, reject) => {
- if (!this.indexedDB) {
- reject(new Error("no indexeddb support available"));
- return;
- }
- _logger.logger.log(`Removing indexeddb instance: ${this.dbName}`);
- const req = this.indexedDB.deleteDatabase(this.dbName);
- req.onblocked = () => {
- _logger.logger.log(`can't yet delete IndexedDBCryptoStore because it is open elsewhere`);
- };
- req.onerror = ev => {
- _logger.logger.log("Error deleting data from indexeddb", ev);
- reject(req.error);
- };
- req.onsuccess = () => {
- _logger.logger.log(`Removed indexeddb instance: ${this.dbName}`);
- resolve();
- };
- }).catch(e => {
- // in firefox, with indexedDB disabled, this fails with a
- // DOMError. We treat this as non-fatal, so that people can
- // still use the app.
- _logger.logger.warn(`unable to delete IndexedDBCryptoStore: ${e}`);
- });
- }
-
- /**
- * Look for an existing outgoing room key request, and if none is found,
- * add a new one
- *
- *
- * @returns resolves to
- * {@link OutgoingRoomKeyRequest}: either the
- * same instance as passed in, or the existing one.
- */
- getOrAddOutgoingRoomKeyRequest(request) {
- return this.backend.getOrAddOutgoingRoomKeyRequest(request);
- }
-
- /**
- * Look for an existing room key request
- *
- * @param requestBody - existing request to look for
- *
- * @returns resolves to the matching
- * {@link OutgoingRoomKeyRequest}, or null if
- * not found
- */
- getOutgoingRoomKeyRequest(requestBody) {
- return this.backend.getOutgoingRoomKeyRequest(requestBody);
- }
-
- /**
- * Look for room key requests by state
- *
- * @param wantedStates - list of acceptable states
- *
- * @returns resolves to the a
- * {@link OutgoingRoomKeyRequest}, or null if
- * there are no pending requests in those states. If there are multiple
- * requests in those states, an arbitrary one is chosen.
- */
- getOutgoingRoomKeyRequestByState(wantedStates) {
- return this.backend.getOutgoingRoomKeyRequestByState(wantedStates);
- }
-
- /**
- * Look for room key requests by state –
- * unlike above, return a list of all entries in one state.
- *
- * @returns Returns an array of requests in the given state
- */
- getAllOutgoingRoomKeyRequestsByState(wantedState) {
- return this.backend.getAllOutgoingRoomKeyRequestsByState(wantedState);
- }
-
- /**
- * Look for room key requests by target device and state
- *
- * @param userId - Target user ID
- * @param deviceId - Target device ID
- * @param wantedStates - list of acceptable states
- *
- * @returns resolves to a list of all the
- * {@link OutgoingRoomKeyRequest}
- */
- getOutgoingRoomKeyRequestsByTarget(userId, deviceId, wantedStates) {
- return this.backend.getOutgoingRoomKeyRequestsByTarget(userId, deviceId, wantedStates);
- }
-
- /**
- * Look for an existing room key request by id and state, and update it if
- * found
- *
- * @param requestId - ID of request to update
- * @param expectedState - state we expect to find the request in
- * @param updates - name/value map of updates to apply
- *
- * @returns resolves to
- * {@link OutgoingRoomKeyRequest}
- * updated request, or null if no matching row was found
- */
- updateOutgoingRoomKeyRequest(requestId, expectedState, updates) {
- return this.backend.updateOutgoingRoomKeyRequest(requestId, expectedState, updates);
- }
-
- /**
- * Look for an existing room key request by id and state, and delete it if
- * found
- *
- * @param requestId - ID of request to update
- * @param expectedState - state we expect to find the request in
- *
- * @returns resolves once the operation is completed
- */
- deleteOutgoingRoomKeyRequest(requestId, expectedState) {
- return this.backend.deleteOutgoingRoomKeyRequest(requestId, expectedState);
- }
-
- // Olm Account
-
- /*
- * Get the account pickle from the store.
- * This requires an active transaction. See doTxn().
- *
- * @param txn - An active transaction. See doTxn().
- * @param func - Called with the account pickle
- */
- getAccount(txn, func) {
- this.backend.getAccount(txn, func);
- }
-
- /**
- * Write the account pickle to the store.
- * This requires an active transaction. See doTxn().
- *
- * @param txn - An active transaction. See doTxn().
- * @param accountPickle - The new account pickle to store.
- */
- storeAccount(txn, accountPickle) {
- this.backend.storeAccount(txn, accountPickle);
- }
-
- /**
- * Get the public part of the cross-signing keys (eg. self-signing key,
- * user signing key).
- *
- * @param txn - An active transaction. See doTxn().
- * @param func - Called with the account keys object:
- * `{ key_type: base64 encoded seed }` where key type = user_signing_key_seed or self_signing_key_seed
- */
- getCrossSigningKeys(txn, func) {
- this.backend.getCrossSigningKeys(txn, func);
- }
-
- /**
- * @param txn - An active transaction. See doTxn().
- * @param func - Called with the private key
- * @param type - A key type
- */
- getSecretStorePrivateKey(txn, func, type) {
- this.backend.getSecretStorePrivateKey(txn, func, type);
- }
-
- /**
- * Write the cross-signing keys back to the store
- *
- * @param txn - An active transaction. See doTxn().
- * @param keys - keys object as getCrossSigningKeys()
- */
- storeCrossSigningKeys(txn, keys) {
- this.backend.storeCrossSigningKeys(txn, keys);
- }
-
- /**
- * Write the cross-signing private keys back to the store
- *
- * @param txn - An active transaction. See doTxn().
- * @param type - The type of cross-signing private key to store
- * @param key - keys object as getCrossSigningKeys()
- */
- storeSecretStorePrivateKey(txn, type, key) {
- this.backend.storeSecretStorePrivateKey(txn, type, key);
- }
-
- // Olm sessions
-
- /**
- * Returns the number of end-to-end sessions in the store
- * @param txn - An active transaction. See doTxn().
- * @param func - Called with the count of sessions
- */
- countEndToEndSessions(txn, func) {
- this.backend.countEndToEndSessions(txn, func);
- }
-
- /**
- * Retrieve a specific end-to-end session between the logged-in user
- * and another device.
- * @param deviceKey - The public key of the other device.
- * @param sessionId - The ID of the session to retrieve
- * @param txn - An active transaction. See doTxn().
- * @param func - Called with A map from sessionId
- * to session information object with 'session' key being the
- * Base64 end-to-end session and lastReceivedMessageTs being the
- * timestamp in milliseconds at which the session last received
- * a message.
- */
- getEndToEndSession(deviceKey, sessionId, txn, func) {
- this.backend.getEndToEndSession(deviceKey, sessionId, txn, func);
- }
-
- /**
- * Retrieve the end-to-end sessions between the logged-in user and another
- * device.
- * @param deviceKey - The public key of the other device.
- * @param txn - An active transaction. See doTxn().
- * @param func - Called with A map from sessionId
- * to session information object with 'session' key being the
- * Base64 end-to-end session and lastReceivedMessageTs being the
- * timestamp in milliseconds at which the session last received
- * a message.
- */
- getEndToEndSessions(deviceKey, txn, func) {
- this.backend.getEndToEndSessions(deviceKey, txn, func);
- }
-
- /**
- * Retrieve all end-to-end sessions
- * @param txn - An active transaction. See doTxn().
- * @param func - Called one for each session with
- * an object with, deviceKey, lastReceivedMessageTs, sessionId
- * and session keys.
- */
- getAllEndToEndSessions(txn, func) {
- this.backend.getAllEndToEndSessions(txn, func);
- }
-
- /**
- * Store a session between the logged-in user and another device
- * @param deviceKey - The public key of the other device.
- * @param sessionId - The ID for this end-to-end session.
- * @param sessionInfo - Session information object
- * @param txn - An active transaction. See doTxn().
- */
- storeEndToEndSession(deviceKey, sessionId, sessionInfo, txn) {
- this.backend.storeEndToEndSession(deviceKey, sessionId, sessionInfo, txn);
- }
- storeEndToEndSessionProblem(deviceKey, type, fixed) {
- return this.backend.storeEndToEndSessionProblem(deviceKey, type, fixed);
- }
- getEndToEndSessionProblem(deviceKey, timestamp) {
- return this.backend.getEndToEndSessionProblem(deviceKey, timestamp);
- }
- filterOutNotifiedErrorDevices(devices) {
- return this.backend.filterOutNotifiedErrorDevices(devices);
- }
-
- // Inbound group sessions
-
- /**
- * Retrieve the end-to-end inbound group session for a given
- * server key and session ID
- * @param senderCurve25519Key - The sender's curve 25519 key
- * @param sessionId - The ID of the session
- * @param txn - An active transaction. See doTxn().
- * @param func - Called with A map from sessionId
- * to Base64 end-to-end session.
- */
- getEndToEndInboundGroupSession(senderCurve25519Key, sessionId, txn, func) {
- this.backend.getEndToEndInboundGroupSession(senderCurve25519Key, sessionId, txn, func);
- }
-
- /**
- * Fetches all inbound group sessions in the store
- * @param txn - An active transaction. See doTxn().
- * @param func - Called once for each group session
- * in the store with an object having keys `{senderKey, sessionId, sessionData}`,
- * then once with null to indicate the end of the list.
- */
- getAllEndToEndInboundGroupSessions(txn, func) {
- this.backend.getAllEndToEndInboundGroupSessions(txn, func);
- }
-
- /**
- * Adds an end-to-end inbound group session to the store.
- * If there already exists an inbound group session with the same
- * senderCurve25519Key and sessionID, the session will not be added.
- * @param senderCurve25519Key - The sender's curve 25519 key
- * @param sessionId - The ID of the session
- * @param sessionData - The session data structure
- * @param txn - An active transaction. See doTxn().
- */
- addEndToEndInboundGroupSession(senderCurve25519Key, sessionId, sessionData, txn) {
- this.backend.addEndToEndInboundGroupSession(senderCurve25519Key, sessionId, sessionData, txn);
- }
-
- /**
- * Writes an end-to-end inbound group session to the store.
- * If there already exists an inbound group session with the same
- * senderCurve25519Key and sessionID, it will be overwritten.
- * @param senderCurve25519Key - The sender's curve 25519 key
- * @param sessionId - The ID of the session
- * @param sessionData - The session data structure
- * @param txn - An active transaction. See doTxn().
- */
- storeEndToEndInboundGroupSession(senderCurve25519Key, sessionId, sessionData, txn) {
- this.backend.storeEndToEndInboundGroupSession(senderCurve25519Key, sessionId, sessionData, txn);
- }
- storeEndToEndInboundGroupSessionWithheld(senderCurve25519Key, sessionId, sessionData, txn) {
- this.backend.storeEndToEndInboundGroupSessionWithheld(senderCurve25519Key, sessionId, sessionData, txn);
- }
-
- // End-to-end device tracking
-
- /**
- * Store the state of all tracked devices
- * This contains devices for each user, a tracking state for each user
- * and a sync token matching the point in time the snapshot represents.
- * These all need to be written out in full each time such that the snapshot
- * is always consistent, so they are stored in one object.
- *
- * @param txn - An active transaction. See doTxn().
- */
- storeEndToEndDeviceData(deviceData, txn) {
- this.backend.storeEndToEndDeviceData(deviceData, txn);
- }
-
- /**
- * Get the state of all tracked devices
- *
- * @param txn - An active transaction. See doTxn().
- * @param func - Function called with the
- * device data
- */
- getEndToEndDeviceData(txn, func) {
- this.backend.getEndToEndDeviceData(txn, func);
- }
-
- // End to End Rooms
-
- /**
- * Store the end-to-end state for a room.
- * @param roomId - The room's ID.
- * @param roomInfo - The end-to-end info for the room.
- * @param txn - An active transaction. See doTxn().
- */
- storeEndToEndRoom(roomId, roomInfo, txn) {
- this.backend.storeEndToEndRoom(roomId, roomInfo, txn);
- }
-
- /**
- * Get an object of `roomId->roomInfo` for all e2e rooms in the store
- * @param txn - An active transaction. See doTxn().
- * @param func - Function called with the end-to-end encrypted rooms
- */
- getEndToEndRooms(txn, func) {
- this.backend.getEndToEndRooms(txn, func);
- }
-
- // session backups
-
- /**
- * Get the inbound group sessions that need to be backed up.
- * @param limit - The maximum number of sessions to retrieve. 0
- * for no limit.
- * @returns resolves to an array of inbound group sessions
- */
- getSessionsNeedingBackup(limit) {
- return this.backend.getSessionsNeedingBackup(limit);
- }
-
- /**
- * Count the inbound group sessions that need to be backed up.
- * @param txn - An active transaction. See doTxn(). (optional)
- * @returns resolves to the number of sessions
- */
- countSessionsNeedingBackup(txn) {
- return this.backend.countSessionsNeedingBackup(txn);
- }
-
- /**
- * Unmark sessions as needing to be backed up.
- * @param sessions - The sessions that need to be backed up.
- * @param txn - An active transaction. See doTxn(). (optional)
- * @returns resolves when the sessions are unmarked
- */
- unmarkSessionsNeedingBackup(sessions, txn) {
- return this.backend.unmarkSessionsNeedingBackup(sessions, txn);
- }
-
- /**
- * Mark sessions as needing to be backed up.
- * @param sessions - The sessions that need to be backed up.
- * @param txn - An active transaction. See doTxn(). (optional)
- * @returns resolves when the sessions are marked
- */
- markSessionsNeedingBackup(sessions, txn) {
- return this.backend.markSessionsNeedingBackup(sessions, txn);
- }
-
- /**
- * Add a shared-history group session for a room.
- * @param roomId - The room that the key belongs to
- * @param senderKey - The sender's curve 25519 key
- * @param sessionId - The ID of the session
- * @param txn - An active transaction. See doTxn(). (optional)
- */
- addSharedHistoryInboundGroupSession(roomId, senderKey, sessionId, txn) {
- this.backend.addSharedHistoryInboundGroupSession(roomId, senderKey, sessionId, txn);
- }
-
- /**
- * Get the shared-history group session for a room.
- * @param roomId - The room that the key belongs to
- * @param txn - An active transaction. See doTxn(). (optional)
- * @returns Promise which resolves to an array of [senderKey, sessionId]
- */
- getSharedHistoryInboundGroupSessions(roomId, txn) {
- return this.backend.getSharedHistoryInboundGroupSessions(roomId, txn);
- }
-
- /**
- * Park a shared-history group session for a room we may be invited to later.
- */
- addParkedSharedHistory(roomId, parkedData, txn) {
- this.backend.addParkedSharedHistory(roomId, parkedData, txn);
- }
-
- /**
- * Pop out all shared-history group sessions for a room.
- */
- takeParkedSharedHistory(roomId, txn) {
- return this.backend.takeParkedSharedHistory(roomId, txn);
- }
-
- /**
- * Perform a transaction on the crypto store. Any store methods
- * that require a transaction (txn) object to be passed in may
- * only be called within a callback of either this function or
- * one of the store functions operating on the same transaction.
- *
- * @param mode - 'readwrite' if you need to call setter
- * functions with this transaction. Otherwise, 'readonly'.
- * @param stores - List IndexedDBCryptoStore.STORE_*
- * options representing all types of object that will be
- * accessed or written to with this transaction.
- * @param func - Function called with the
- * transaction object: an opaque object that should be passed
- * to store functions.
- * @param log - A possibly customised log
- * @returns Promise that resolves with the result of the `func`
- * when the transaction is complete. If the backend is
- * async (ie. the indexeddb backend) any of the callback
- * functions throwing an exception will cause this promise to
- * reject with that exception. On synchronous backends, the
- * exception will propagate to the caller of the getFoo method.
- */
- doTxn(mode, stores, func, log) {
- return this.backend.doTxn(mode, stores, func, log);
- }
-}
-exports.IndexedDBCryptoStore = IndexedDBCryptoStore;
-(0, _defineProperty2.default)(IndexedDBCryptoStore, "STORE_ACCOUNT", "account");
-(0, _defineProperty2.default)(IndexedDBCryptoStore, "STORE_SESSIONS", "sessions");
-(0, _defineProperty2.default)(IndexedDBCryptoStore, "STORE_INBOUND_GROUP_SESSIONS", "inbound_group_sessions");
-(0, _defineProperty2.default)(IndexedDBCryptoStore, "STORE_INBOUND_GROUP_SESSIONS_WITHHELD", "inbound_group_sessions_withheld");
-(0, _defineProperty2.default)(IndexedDBCryptoStore, "STORE_SHARED_HISTORY_INBOUND_GROUP_SESSIONS", "shared_history_inbound_group_sessions");
-(0, _defineProperty2.default)(IndexedDBCryptoStore, "STORE_PARKED_SHARED_HISTORY", "parked_shared_history");
-(0, _defineProperty2.default)(IndexedDBCryptoStore, "STORE_DEVICE_DATA", "device_data");
-(0, _defineProperty2.default)(IndexedDBCryptoStore, "STORE_ROOMS", "rooms");
-(0, _defineProperty2.default)(IndexedDBCryptoStore, "STORE_BACKUP", "sessions_needing_backup");
-//# sourceMappingURL=indexeddb-crypto-store.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store.js.map
deleted file mode 100644
index 38cad1e..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"indexeddb-crypto-store.js","names":["_logger","require","_localStorageCryptoStore","_memoryCryptoStore","IndexedDBCryptoStoreBackend","_interopRequireWildcard","_errors","IndexedDBHelpers","_getRequireWildcardCache","nodeInterop","WeakMap","cacheBabelInterop","cacheNodeInterop","obj","__esModule","default","cache","has","get","newObj","hasPropertyDescriptor","Object","defineProperty","getOwnPropertyDescriptor","key","prototype","hasOwnProperty","call","desc","set","IndexedDBCryptoStore","exists","indexedDB","dbName","constructor","_defineProperty2","startup","backendPromise","Promise","resolve","reject","Error","logger","log","req","open","VERSION","onupgradeneeded","ev","db","result","oldVersion","upgradeDatabase","onblocked","onerror","error","onsuccess","Backend","then","backend","doTxn","STORE_INBOUND_GROUP_SESSIONS","STORE_INBOUND_GROUP_SESSIONS_WITHHELD","txn","getEndToEndInboundGroupSession","catch","e","name","warn","InvalidCryptoStoreError","InvalidCryptoStoreState","TooNew","LocalStorageCryptoStore","global","localStorage","MemoryCryptoStore","deleteAllData","deleteDatabase","getOrAddOutgoingRoomKeyRequest","request","getOutgoingRoomKeyRequest","requestBody","getOutgoingRoomKeyRequestByState","wantedStates","getAllOutgoingRoomKeyRequestsByState","wantedState","getOutgoingRoomKeyRequestsByTarget","userId","deviceId","updateOutgoingRoomKeyRequest","requestId","expectedState","updates","deleteOutgoingRoomKeyRequest","getAccount","func","storeAccount","accountPickle","getCrossSigningKeys","getSecretStorePrivateKey","type","storeCrossSigningKeys","keys","storeSecretStorePrivateKey","countEndToEndSessions","getEndToEndSession","deviceKey","sessionId","getEndToEndSessions","getAllEndToEndSessions","storeEndToEndSession","sessionInfo","storeEndToEndSessionProblem","fixed","getEndToEndSessionProblem","timestamp","filterOutNotifiedErrorDevices","devices","senderCurve25519Key","getAllEndToEndInboundGroupSessions","addEndToEndInboundGroupSession","sessionData","storeEndToEndInboundGroupSession","storeEndToEndInboundGroupSessionWithheld","storeEndToEndDeviceData","deviceData","getEndToEndDeviceData","storeEndToEndRoom","roomId","roomInfo","getEndToEndRooms","getSessionsNeedingBackup","limit","countSessionsNeedingBackup","unmarkSessionsNeedingBackup","sessions","markSessionsNeedingBackup","addSharedHistoryInboundGroupSession","senderKey","getSharedHistoryInboundGroupSessions","addParkedSharedHistory","parkedData","takeParkedSharedHistory","mode","stores","exports"],"sources":["../../../src/crypto/store/indexeddb-crypto-store.ts"],"sourcesContent":["/*\nCopyright 2017 - 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { logger, PrefixedLogger } from \"../../logger\";\nimport { LocalStorageCryptoStore } from \"./localStorage-crypto-store\";\nimport { MemoryCryptoStore } from \"./memory-crypto-store\";\nimport * as IndexedDBCryptoStoreBackend from \"./indexeddb-crypto-store-backend\";\nimport { InvalidCryptoStoreError, InvalidCryptoStoreState } from \"../../errors\";\nimport * as IndexedDBHelpers from \"../../indexeddb-helpers\";\nimport {\n CryptoStore,\n IDeviceData,\n IProblem,\n ISession,\n ISessionInfo,\n IWithheld,\n Mode,\n OutgoingRoomKeyRequest,\n ParkedSharedHistory,\n SecretStorePrivateKeys,\n} from \"./base\";\nimport { IRoomKeyRequestBody } from \"../index\";\nimport { ICrossSigningKey } from \"../../client\";\nimport { IOlmDevice } from \"../algorithms/megolm\";\nimport { IRoomEncryption } from \"../RoomList\";\nimport { InboundGroupSessionData } from \"../OlmDevice\";\n\n/**\n * Internal module. indexeddb storage for e2e.\n */\n\n/**\n * An implementation of CryptoStore, which is normally backed by an indexeddb,\n * but with fallback to MemoryCryptoStore.\n */\nexport class IndexedDBCryptoStore implements CryptoStore {\n public static STORE_ACCOUNT = \"account\";\n public static STORE_SESSIONS = \"sessions\";\n public static STORE_INBOUND_GROUP_SESSIONS = \"inbound_group_sessions\";\n public static STORE_INBOUND_GROUP_SESSIONS_WITHHELD = \"inbound_group_sessions_withheld\";\n public static STORE_SHARED_HISTORY_INBOUND_GROUP_SESSIONS = \"shared_history_inbound_group_sessions\";\n public static STORE_PARKED_SHARED_HISTORY = \"parked_shared_history\";\n public static STORE_DEVICE_DATA = \"device_data\";\n public static STORE_ROOMS = \"rooms\";\n public static STORE_BACKUP = \"sessions_needing_backup\";\n\n public static exists(indexedDB: IDBFactory, dbName: string): Promise<boolean> {\n return IndexedDBHelpers.exists(indexedDB, dbName);\n }\n\n private backendPromise?: Promise<CryptoStore>;\n private backend?: CryptoStore;\n\n /**\n * Create a new IndexedDBCryptoStore\n *\n * @param indexedDB - global indexedDB instance\n * @param dbName - name of db to connect to\n */\n public constructor(private readonly indexedDB: IDBFactory, private readonly dbName: string) {}\n\n /**\n * Ensure the database exists and is up-to-date, or fall back to\n * a local storage or in-memory store.\n *\n * This must be called before the store can be used.\n *\n * @returns resolves to either an IndexedDBCryptoStoreBackend.Backend,\n * or a MemoryCryptoStore\n */\n public startup(): Promise<CryptoStore> {\n if (this.backendPromise) {\n return this.backendPromise;\n }\n\n this.backendPromise = new Promise<CryptoStore>((resolve, reject) => {\n if (!this.indexedDB) {\n reject(new Error(\"no indexeddb support available\"));\n return;\n }\n\n logger.log(`connecting to indexeddb ${this.dbName}`);\n\n const req = this.indexedDB.open(this.dbName, IndexedDBCryptoStoreBackend.VERSION);\n\n req.onupgradeneeded = (ev): void => {\n const db = req.result;\n const oldVersion = ev.oldVersion;\n IndexedDBCryptoStoreBackend.upgradeDatabase(db, oldVersion);\n };\n\n req.onblocked = (): void => {\n logger.log(`can't yet open IndexedDBCryptoStore because it is open elsewhere`);\n };\n\n req.onerror = (ev): void => {\n logger.log(\"Error connecting to indexeddb\", ev);\n reject(req.error);\n };\n\n req.onsuccess = (): void => {\n const db = req.result;\n\n logger.log(`connected to indexeddb ${this.dbName}`);\n resolve(new IndexedDBCryptoStoreBackend.Backend(db));\n };\n })\n .then((backend) => {\n // Edge has IndexedDB but doesn't support compund keys which we use fairly extensively.\n // Try a dummy query which will fail if the browser doesn't support compund keys, so\n // we can fall back to a different backend.\n return backend\n .doTxn(\n \"readonly\",\n [\n IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS,\n IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS_WITHHELD,\n ],\n (txn) => {\n backend.getEndToEndInboundGroupSession(\"\", \"\", txn, () => {});\n },\n )\n .then(() => backend);\n })\n .catch((e) => {\n if (e.name === \"VersionError\") {\n logger.warn(\"Crypto DB is too new for us to use!\", e);\n // don't fall back to a different store: the user has crypto data\n // in this db so we should use it or nothing at all.\n throw new InvalidCryptoStoreError(InvalidCryptoStoreState.TooNew);\n }\n logger.warn(\n `unable to connect to indexeddb ${this.dbName}` + `: falling back to localStorage store: ${e}`,\n );\n\n try {\n return new LocalStorageCryptoStore(global.localStorage);\n } catch (e) {\n logger.warn(`unable to open localStorage: falling back to in-memory store: ${e}`);\n return new MemoryCryptoStore();\n }\n })\n .then((backend) => {\n this.backend = backend;\n return backend;\n });\n\n return this.backendPromise;\n }\n\n /**\n * Delete all data from this store.\n *\n * @returns resolves when the store has been cleared.\n */\n public deleteAllData(): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n if (!this.indexedDB) {\n reject(new Error(\"no indexeddb support available\"));\n return;\n }\n\n logger.log(`Removing indexeddb instance: ${this.dbName}`);\n const req = this.indexedDB.deleteDatabase(this.dbName);\n\n req.onblocked = (): void => {\n logger.log(`can't yet delete IndexedDBCryptoStore because it is open elsewhere`);\n };\n\n req.onerror = (ev): void => {\n logger.log(\"Error deleting data from indexeddb\", ev);\n reject(req.error);\n };\n\n req.onsuccess = (): void => {\n logger.log(`Removed indexeddb instance: ${this.dbName}`);\n resolve();\n };\n }).catch((e) => {\n // in firefox, with indexedDB disabled, this fails with a\n // DOMError. We treat this as non-fatal, so that people can\n // still use the app.\n logger.warn(`unable to delete IndexedDBCryptoStore: ${e}`);\n });\n }\n\n /**\n * Look for an existing outgoing room key request, and if none is found,\n * add a new one\n *\n *\n * @returns resolves to\n * {@link OutgoingRoomKeyRequest}: either the\n * same instance as passed in, or the existing one.\n */\n public getOrAddOutgoingRoomKeyRequest(request: OutgoingRoomKeyRequest): Promise<OutgoingRoomKeyRequest> {\n return this.backend!.getOrAddOutgoingRoomKeyRequest(request);\n }\n\n /**\n * Look for an existing room key request\n *\n * @param requestBody - existing request to look for\n *\n * @returns resolves to the matching\n * {@link OutgoingRoomKeyRequest}, or null if\n * not found\n */\n public getOutgoingRoomKeyRequest(requestBody: IRoomKeyRequestBody): Promise<OutgoingRoomKeyRequest | null> {\n return this.backend!.getOutgoingRoomKeyRequest(requestBody);\n }\n\n /**\n * Look for room key requests by state\n *\n * @param wantedStates - list of acceptable states\n *\n * @returns resolves to the a\n * {@link OutgoingRoomKeyRequest}, or null if\n * there are no pending requests in those states. If there are multiple\n * requests in those states, an arbitrary one is chosen.\n */\n public getOutgoingRoomKeyRequestByState(wantedStates: number[]): Promise<OutgoingRoomKeyRequest | null> {\n return this.backend!.getOutgoingRoomKeyRequestByState(wantedStates);\n }\n\n /**\n * Look for room key requests by state –\n * unlike above, return a list of all entries in one state.\n *\n * @returns Returns an array of requests in the given state\n */\n public getAllOutgoingRoomKeyRequestsByState(wantedState: number): Promise<OutgoingRoomKeyRequest[]> {\n return this.backend!.getAllOutgoingRoomKeyRequestsByState(wantedState);\n }\n\n /**\n * Look for room key requests by target device and state\n *\n * @param userId - Target user ID\n * @param deviceId - Target device ID\n * @param wantedStates - list of acceptable states\n *\n * @returns resolves to a list of all the\n * {@link OutgoingRoomKeyRequest}\n */\n public getOutgoingRoomKeyRequestsByTarget(\n userId: string,\n deviceId: string,\n wantedStates: number[],\n ): Promise<OutgoingRoomKeyRequest[]> {\n return this.backend!.getOutgoingRoomKeyRequestsByTarget(userId, deviceId, wantedStates);\n }\n\n /**\n * Look for an existing room key request by id and state, and update it if\n * found\n *\n * @param requestId - ID of request to update\n * @param expectedState - state we expect to find the request in\n * @param updates - name/value map of updates to apply\n *\n * @returns resolves to\n * {@link OutgoingRoomKeyRequest}\n * updated request, or null if no matching row was found\n */\n public updateOutgoingRoomKeyRequest(\n requestId: string,\n expectedState: number,\n updates: Partial<OutgoingRoomKeyRequest>,\n ): Promise<OutgoingRoomKeyRequest | null> {\n return this.backend!.updateOutgoingRoomKeyRequest(requestId, expectedState, updates);\n }\n\n /**\n * Look for an existing room key request by id and state, and delete it if\n * found\n *\n * @param requestId - ID of request to update\n * @param expectedState - state we expect to find the request in\n *\n * @returns resolves once the operation is completed\n */\n public deleteOutgoingRoomKeyRequest(\n requestId: string,\n expectedState: number,\n ): Promise<OutgoingRoomKeyRequest | null> {\n return this.backend!.deleteOutgoingRoomKeyRequest(requestId, expectedState);\n }\n\n // Olm Account\n\n /*\n * Get the account pickle from the store.\n * This requires an active transaction. See doTxn().\n *\n * @param txn - An active transaction. See doTxn().\n * @param func - Called with the account pickle\n */\n public getAccount(txn: IDBTransaction, func: (accountPickle: string | null) => void): void {\n this.backend!.getAccount(txn, func);\n }\n\n /**\n * Write the account pickle to the store.\n * This requires an active transaction. See doTxn().\n *\n * @param txn - An active transaction. See doTxn().\n * @param accountPickle - The new account pickle to store.\n */\n public storeAccount(txn: IDBTransaction, accountPickle: string): void {\n this.backend!.storeAccount(txn, accountPickle);\n }\n\n /**\n * Get the public part of the cross-signing keys (eg. self-signing key,\n * user signing key).\n *\n * @param txn - An active transaction. See doTxn().\n * @param func - Called with the account keys object:\n * `{ key_type: base64 encoded seed }` where key type = user_signing_key_seed or self_signing_key_seed\n */\n public getCrossSigningKeys(\n txn: IDBTransaction,\n func: (keys: Record<string, ICrossSigningKey> | null) => void,\n ): void {\n this.backend!.getCrossSigningKeys(txn, func);\n }\n\n /**\n * @param txn - An active transaction. See doTxn().\n * @param func - Called with the private key\n * @param type - A key type\n */\n public getSecretStorePrivateKey<K extends keyof SecretStorePrivateKeys>(\n txn: IDBTransaction,\n func: (key: SecretStorePrivateKeys[K] | null) => void,\n type: K,\n ): void {\n this.backend!.getSecretStorePrivateKey(txn, func, type);\n }\n\n /**\n * Write the cross-signing keys back to the store\n *\n * @param txn - An active transaction. See doTxn().\n * @param keys - keys object as getCrossSigningKeys()\n */\n public storeCrossSigningKeys(txn: IDBTransaction, keys: Record<string, ICrossSigningKey>): void {\n this.backend!.storeCrossSigningKeys(txn, keys);\n }\n\n /**\n * Write the cross-signing private keys back to the store\n *\n * @param txn - An active transaction. See doTxn().\n * @param type - The type of cross-signing private key to store\n * @param key - keys object as getCrossSigningKeys()\n */\n public storeSecretStorePrivateKey<K extends keyof SecretStorePrivateKeys>(\n txn: IDBTransaction,\n type: K,\n key: SecretStorePrivateKeys[K],\n ): void {\n this.backend!.storeSecretStorePrivateKey(txn, type, key);\n }\n\n // Olm sessions\n\n /**\n * Returns the number of end-to-end sessions in the store\n * @param txn - An active transaction. See doTxn().\n * @param func - Called with the count of sessions\n */\n public countEndToEndSessions(txn: IDBTransaction, func: (count: number) => void): void {\n this.backend!.countEndToEndSessions(txn, func);\n }\n\n /**\n * Retrieve a specific end-to-end session between the logged-in user\n * and another device.\n * @param deviceKey - The public key of the other device.\n * @param sessionId - The ID of the session to retrieve\n * @param txn - An active transaction. See doTxn().\n * @param func - Called with A map from sessionId\n * to session information object with 'session' key being the\n * Base64 end-to-end session and lastReceivedMessageTs being the\n * timestamp in milliseconds at which the session last received\n * a message.\n */\n public getEndToEndSession(\n deviceKey: string,\n sessionId: string,\n txn: IDBTransaction,\n func: (session: ISessionInfo | null) => void,\n ): void {\n this.backend!.getEndToEndSession(deviceKey, sessionId, txn, func);\n }\n\n /**\n * Retrieve the end-to-end sessions between the logged-in user and another\n * device.\n * @param deviceKey - The public key of the other device.\n * @param txn - An active transaction. See doTxn().\n * @param func - Called with A map from sessionId\n * to session information object with 'session' key being the\n * Base64 end-to-end session and lastReceivedMessageTs being the\n * timestamp in milliseconds at which the session last received\n * a message.\n */\n public getEndToEndSessions(\n deviceKey: string,\n txn: IDBTransaction,\n func: (sessions: { [sessionId: string]: ISessionInfo }) => void,\n ): void {\n this.backend!.getEndToEndSessions(deviceKey, txn, func);\n }\n\n /**\n * Retrieve all end-to-end sessions\n * @param txn - An active transaction. See doTxn().\n * @param func - Called one for each session with\n * an object with, deviceKey, lastReceivedMessageTs, sessionId\n * and session keys.\n */\n public getAllEndToEndSessions(txn: IDBTransaction, func: (session: ISessionInfo | null) => void): void {\n this.backend!.getAllEndToEndSessions(txn, func);\n }\n\n /**\n * Store a session between the logged-in user and another device\n * @param deviceKey - The public key of the other device.\n * @param sessionId - The ID for this end-to-end session.\n * @param sessionInfo - Session information object\n * @param txn - An active transaction. See doTxn().\n */\n public storeEndToEndSession(\n deviceKey: string,\n sessionId: string,\n sessionInfo: ISessionInfo,\n txn: IDBTransaction,\n ): void {\n this.backend!.storeEndToEndSession(deviceKey, sessionId, sessionInfo, txn);\n }\n\n public storeEndToEndSessionProblem(deviceKey: string, type: string, fixed: boolean): Promise<void> {\n return this.backend!.storeEndToEndSessionProblem(deviceKey, type, fixed);\n }\n\n public getEndToEndSessionProblem(deviceKey: string, timestamp: number): Promise<IProblem | null> {\n return this.backend!.getEndToEndSessionProblem(deviceKey, timestamp);\n }\n\n public filterOutNotifiedErrorDevices(devices: IOlmDevice[]): Promise<IOlmDevice[]> {\n return this.backend!.filterOutNotifiedErrorDevices(devices);\n }\n\n // Inbound group sessions\n\n /**\n * Retrieve the end-to-end inbound group session for a given\n * server key and session ID\n * @param senderCurve25519Key - The sender's curve 25519 key\n * @param sessionId - The ID of the session\n * @param txn - An active transaction. See doTxn().\n * @param func - Called with A map from sessionId\n * to Base64 end-to-end session.\n */\n public getEndToEndInboundGroupSession(\n senderCurve25519Key: string,\n sessionId: string,\n txn: IDBTransaction,\n func: (groupSession: InboundGroupSessionData | null, groupSessionWithheld: IWithheld | null) => void,\n ): void {\n this.backend!.getEndToEndInboundGroupSession(senderCurve25519Key, sessionId, txn, func);\n }\n\n /**\n * Fetches all inbound group sessions in the store\n * @param txn - An active transaction. See doTxn().\n * @param func - Called once for each group session\n * in the store with an object having keys `{senderKey, sessionId, sessionData}`,\n * then once with null to indicate the end of the list.\n */\n public getAllEndToEndInboundGroupSessions(txn: IDBTransaction, func: (session: ISession | null) => void): void {\n this.backend!.getAllEndToEndInboundGroupSessions(txn, func);\n }\n\n /**\n * Adds an end-to-end inbound group session to the store.\n * If there already exists an inbound group session with the same\n * senderCurve25519Key and sessionID, the session will not be added.\n * @param senderCurve25519Key - The sender's curve 25519 key\n * @param sessionId - The ID of the session\n * @param sessionData - The session data structure\n * @param txn - An active transaction. See doTxn().\n */\n public addEndToEndInboundGroupSession(\n senderCurve25519Key: string,\n sessionId: string,\n sessionData: InboundGroupSessionData,\n txn: IDBTransaction,\n ): void {\n this.backend!.addEndToEndInboundGroupSession(senderCurve25519Key, sessionId, sessionData, txn);\n }\n\n /**\n * Writes an end-to-end inbound group session to the store.\n * If there already exists an inbound group session with the same\n * senderCurve25519Key and sessionID, it will be overwritten.\n * @param senderCurve25519Key - The sender's curve 25519 key\n * @param sessionId - The ID of the session\n * @param sessionData - The session data structure\n * @param txn - An active transaction. See doTxn().\n */\n public storeEndToEndInboundGroupSession(\n senderCurve25519Key: string,\n sessionId: string,\n sessionData: InboundGroupSessionData,\n txn: IDBTransaction,\n ): void {\n this.backend!.storeEndToEndInboundGroupSession(senderCurve25519Key, sessionId, sessionData, txn);\n }\n\n public storeEndToEndInboundGroupSessionWithheld(\n senderCurve25519Key: string,\n sessionId: string,\n sessionData: IWithheld,\n txn: IDBTransaction,\n ): void {\n this.backend!.storeEndToEndInboundGroupSessionWithheld(senderCurve25519Key, sessionId, sessionData, txn);\n }\n\n // End-to-end device tracking\n\n /**\n * Store the state of all tracked devices\n * This contains devices for each user, a tracking state for each user\n * and a sync token matching the point in time the snapshot represents.\n * These all need to be written out in full each time such that the snapshot\n * is always consistent, so they are stored in one object.\n *\n * @param txn - An active transaction. See doTxn().\n */\n public storeEndToEndDeviceData(deviceData: IDeviceData, txn: IDBTransaction): void {\n this.backend!.storeEndToEndDeviceData(deviceData, txn);\n }\n\n /**\n * Get the state of all tracked devices\n *\n * @param txn - An active transaction. See doTxn().\n * @param func - Function called with the\n * device data\n */\n public getEndToEndDeviceData(txn: IDBTransaction, func: (deviceData: IDeviceData | null) => void): void {\n this.backend!.getEndToEndDeviceData(txn, func);\n }\n\n // End to End Rooms\n\n /**\n * Store the end-to-end state for a room.\n * @param roomId - The room's ID.\n * @param roomInfo - The end-to-end info for the room.\n * @param txn - An active transaction. See doTxn().\n */\n public storeEndToEndRoom(roomId: string, roomInfo: IRoomEncryption, txn: IDBTransaction): void {\n this.backend!.storeEndToEndRoom(roomId, roomInfo, txn);\n }\n\n /**\n * Get an object of `roomId->roomInfo` for all e2e rooms in the store\n * @param txn - An active transaction. See doTxn().\n * @param func - Function called with the end-to-end encrypted rooms\n */\n public getEndToEndRooms(txn: IDBTransaction, func: (rooms: Record<string, IRoomEncryption>) => void): void {\n this.backend!.getEndToEndRooms(txn, func);\n }\n\n // session backups\n\n /**\n * Get the inbound group sessions that need to be backed up.\n * @param limit - The maximum number of sessions to retrieve. 0\n * for no limit.\n * @returns resolves to an array of inbound group sessions\n */\n public getSessionsNeedingBackup(limit: number): Promise<ISession[]> {\n return this.backend!.getSessionsNeedingBackup(limit);\n }\n\n /**\n * Count the inbound group sessions that need to be backed up.\n * @param txn - An active transaction. See doTxn(). (optional)\n * @returns resolves to the number of sessions\n */\n public countSessionsNeedingBackup(txn?: IDBTransaction): Promise<number> {\n return this.backend!.countSessionsNeedingBackup(txn);\n }\n\n /**\n * Unmark sessions as needing to be backed up.\n * @param sessions - The sessions that need to be backed up.\n * @param txn - An active transaction. See doTxn(). (optional)\n * @returns resolves when the sessions are unmarked\n */\n public unmarkSessionsNeedingBackup(sessions: ISession[], txn?: IDBTransaction): Promise<void> {\n return this.backend!.unmarkSessionsNeedingBackup(sessions, txn);\n }\n\n /**\n * Mark sessions as needing to be backed up.\n * @param sessions - The sessions that need to be backed up.\n * @param txn - An active transaction. See doTxn(). (optional)\n * @returns resolves when the sessions are marked\n */\n public markSessionsNeedingBackup(sessions: ISession[], txn?: IDBTransaction): Promise<void> {\n return this.backend!.markSessionsNeedingBackup(sessions, txn);\n }\n\n /**\n * Add a shared-history group session for a room.\n * @param roomId - The room that the key belongs to\n * @param senderKey - The sender's curve 25519 key\n * @param sessionId - The ID of the session\n * @param txn - An active transaction. See doTxn(). (optional)\n */\n public addSharedHistoryInboundGroupSession(\n roomId: string,\n senderKey: string,\n sessionId: string,\n txn?: IDBTransaction,\n ): void {\n this.backend!.addSharedHistoryInboundGroupSession(roomId, senderKey, sessionId, txn);\n }\n\n /**\n * Get the shared-history group session for a room.\n * @param roomId - The room that the key belongs to\n * @param txn - An active transaction. See doTxn(). (optional)\n * @returns Promise which resolves to an array of [senderKey, sessionId]\n */\n public getSharedHistoryInboundGroupSessions(\n roomId: string,\n txn?: IDBTransaction,\n ): Promise<[senderKey: string, sessionId: string][]> {\n return this.backend!.getSharedHistoryInboundGroupSessions(roomId, txn);\n }\n\n /**\n * Park a shared-history group session for a room we may be invited to later.\n */\n public addParkedSharedHistory(roomId: string, parkedData: ParkedSharedHistory, txn?: IDBTransaction): void {\n this.backend!.addParkedSharedHistory(roomId, parkedData, txn);\n }\n\n /**\n * Pop out all shared-history group sessions for a room.\n */\n public takeParkedSharedHistory(roomId: string, txn?: IDBTransaction): Promise<ParkedSharedHistory[]> {\n return this.backend!.takeParkedSharedHistory(roomId, txn);\n }\n\n /**\n * Perform a transaction on the crypto store. Any store methods\n * that require a transaction (txn) object to be passed in may\n * only be called within a callback of either this function or\n * one of the store functions operating on the same transaction.\n *\n * @param mode - 'readwrite' if you need to call setter\n * functions with this transaction. Otherwise, 'readonly'.\n * @param stores - List IndexedDBCryptoStore.STORE_*\n * options representing all types of object that will be\n * accessed or written to with this transaction.\n * @param func - Function called with the\n * transaction object: an opaque object that should be passed\n * to store functions.\n * @param log - A possibly customised log\n * @returns Promise that resolves with the result of the `func`\n * when the transaction is complete. If the backend is\n * async (ie. the indexeddb backend) any of the callback\n * functions throwing an exception will cause this promise to\n * reject with that exception. On synchronous backends, the\n * exception will propagate to the caller of the getFoo method.\n */\n public doTxn<T>(\n mode: Mode,\n stores: Iterable<string>,\n func: (txn: IDBTransaction) => T,\n log?: PrefixedLogger,\n ): Promise<T> {\n return this.backend!.doTxn<T>(mode, stores, func as (txn: unknown) => T, log);\n }\n}\n"],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/localStorage-crypto-store.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/localStorage-crypto-store.d.ts
deleted file mode 100644
index a13aadf..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/localStorage-crypto-store.d.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-import { MemoryCryptoStore } from "./memory-crypto-store";
-import { IDeviceData, IProblem, ISession, ISessionInfo, IWithheld, Mode, SecretStorePrivateKeys } from "./base";
-import { IOlmDevice } from "../algorithms/megolm";
-import { IRoomEncryption } from "../RoomList";
-import { ICrossSigningKey } from "../../client";
-import { InboundGroupSessionData } from "../OlmDevice";
-export declare class LocalStorageCryptoStore extends MemoryCryptoStore {
- private readonly store;
- static exists(store: Storage): boolean;
- constructor(store: Storage);
- countEndToEndSessions(txn: unknown, func: (count: number) => void): void;
- private _getEndToEndSessions;
- getEndToEndSession(deviceKey: string, sessionId: string, txn: unknown, func: (session: ISessionInfo) => void): void;
- getEndToEndSessions(deviceKey: string, txn: unknown, func: (sessions: {
- [sessionId: string]: ISessionInfo;
- }) => void): void;
- getAllEndToEndSessions(txn: unknown, func: (session: ISessionInfo) => void): void;
- storeEndToEndSession(deviceKey: string, sessionId: string, sessionInfo: ISessionInfo, txn: unknown): void;
- storeEndToEndSessionProblem(deviceKey: string, type: string, fixed: boolean): Promise<void>;
- getEndToEndSessionProblem(deviceKey: string, timestamp: number): Promise<IProblem | null>;
- filterOutNotifiedErrorDevices(devices: IOlmDevice[]): Promise<IOlmDevice[]>;
- getEndToEndInboundGroupSession(senderCurve25519Key: string, sessionId: string, txn: unknown, func: (groupSession: InboundGroupSessionData | null, groupSessionWithheld: IWithheld | null) => void): void;
- getAllEndToEndInboundGroupSessions(txn: unknown, func: (session: ISession | null) => void): void;
- addEndToEndInboundGroupSession(senderCurve25519Key: string, sessionId: string, sessionData: InboundGroupSessionData, txn: unknown): void;
- storeEndToEndInboundGroupSession(senderCurve25519Key: string, sessionId: string, sessionData: InboundGroupSessionData, txn: unknown): void;
- storeEndToEndInboundGroupSessionWithheld(senderCurve25519Key: string, sessionId: string, sessionData: IWithheld, txn: unknown): void;
- getEndToEndDeviceData(txn: unknown, func: (deviceData: IDeviceData | null) => void): void;
- storeEndToEndDeviceData(deviceData: IDeviceData, txn: unknown): void;
- storeEndToEndRoom(roomId: string, roomInfo: IRoomEncryption, txn: unknown): void;
- getEndToEndRooms(txn: unknown, func: (rooms: Record<string, IRoomEncryption>) => void): void;
- getSessionsNeedingBackup(limit: number): Promise<ISession[]>;
- countSessionsNeedingBackup(): Promise<number>;
- unmarkSessionsNeedingBackup(sessions: ISession[]): Promise<void>;
- markSessionsNeedingBackup(sessions: ISession[]): Promise<void>;
- /**
- * Delete all data from this store.
- *
- * @returns Promise which resolves when the store has been cleared.
- */
- deleteAllData(): Promise<void>;
- getAccount(txn: unknown, func: (accountPickle: string | null) => void): void;
- storeAccount(txn: unknown, accountPickle: string): void;
- getCrossSigningKeys(txn: unknown, func: (keys: Record<string, ICrossSigningKey> | null) => void): void;
- getSecretStorePrivateKey<K extends keyof SecretStorePrivateKeys>(txn: unknown, func: (key: SecretStorePrivateKeys[K] | null) => void, type: K): void;
- storeCrossSigningKeys(txn: unknown, keys: Record<string, ICrossSigningKey>): void;
- storeSecretStorePrivateKey<K extends keyof SecretStorePrivateKeys>(txn: unknown, type: K, key: SecretStorePrivateKeys[K]): void;
- doTxn<T>(mode: Mode, stores: Iterable<string>, func: (txn: unknown) => T): Promise<T>;
-}
-//# sourceMappingURL=localStorage-crypto-store.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/localStorage-crypto-store.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/localStorage-crypto-store.d.ts.map
deleted file mode 100644
index e49704d..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/localStorage-crypto-store.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"localStorage-crypto-store.d.ts","sourceRoot":"","sources":["../../../src/crypto/store/localStorage-crypto-store.ts"],"names":[],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/localStorage-crypto-store.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/localStorage-crypto-store.js
deleted file mode 100644
index 03e99a1..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/localStorage-crypto-store.js
+++ /dev/null
@@ -1,333 +0,0 @@
-"use strict";
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.LocalStorageCryptoStore = void 0;
-var _logger = require("../../logger");
-var _memoryCryptoStore = require("./memory-crypto-store");
-var _utils = require("../../utils");
-/*
-Copyright 2017 - 2021 The Matrix.org Foundation C.I.C.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-/**
- * Internal module. Partial localStorage backed storage for e2e.
- * This is not a full crypto store, just the in-memory store with
- * some things backed by localStorage. It exists because indexedDB
- * is broken in Firefox private mode or set to, "will not remember
- * history".
- */
-
-const E2E_PREFIX = "crypto.";
-const KEY_END_TO_END_ACCOUNT = E2E_PREFIX + "account";
-const KEY_CROSS_SIGNING_KEYS = E2E_PREFIX + "cross_signing_keys";
-const KEY_NOTIFIED_ERROR_DEVICES = E2E_PREFIX + "notified_error_devices";
-const KEY_DEVICE_DATA = E2E_PREFIX + "device_data";
-const KEY_INBOUND_SESSION_PREFIX = E2E_PREFIX + "inboundgroupsessions/";
-const KEY_INBOUND_SESSION_WITHHELD_PREFIX = E2E_PREFIX + "inboundgroupsessions.withheld/";
-const KEY_ROOMS_PREFIX = E2E_PREFIX + "rooms/";
-const KEY_SESSIONS_NEEDING_BACKUP = E2E_PREFIX + "sessionsneedingbackup";
-function keyEndToEndSessions(deviceKey) {
- return E2E_PREFIX + "sessions/" + deviceKey;
-}
-function keyEndToEndSessionProblems(deviceKey) {
- return E2E_PREFIX + "session.problems/" + deviceKey;
-}
-function keyEndToEndInboundGroupSession(senderKey, sessionId) {
- return KEY_INBOUND_SESSION_PREFIX + senderKey + "/" + sessionId;
-}
-function keyEndToEndInboundGroupSessionWithheld(senderKey, sessionId) {
- return KEY_INBOUND_SESSION_WITHHELD_PREFIX + senderKey + "/" + sessionId;
-}
-function keyEndToEndRoomsPrefix(roomId) {
- return KEY_ROOMS_PREFIX + roomId;
-}
-class LocalStorageCryptoStore extends _memoryCryptoStore.MemoryCryptoStore {
- static exists(store) {
- const length = store.length;
- for (let i = 0; i < length; i++) {
- var _store$key;
- if ((_store$key = store.key(i)) !== null && _store$key !== void 0 && _store$key.startsWith(E2E_PREFIX)) {
- return true;
- }
- }
- return false;
- }
- constructor(store) {
- super();
- this.store = store;
- }
-
- // Olm Sessions
-
- countEndToEndSessions(txn, func) {
- let count = 0;
- for (let i = 0; i < this.store.length; ++i) {
- var _this$store$key;
- if ((_this$store$key = this.store.key(i)) !== null && _this$store$key !== void 0 && _this$store$key.startsWith(keyEndToEndSessions(""))) ++count;
- }
- func(count);
- }
-
- // eslint-disable-next-line @typescript-eslint/naming-convention
- _getEndToEndSessions(deviceKey) {
- const sessions = getJsonItem(this.store, keyEndToEndSessions(deviceKey));
- const fixedSessions = {};
-
- // fix up any old sessions to be objects rather than just the base64 pickle
- for (const [sid, val] of Object.entries(sessions || {})) {
- if (typeof val === "string") {
- fixedSessions[sid] = {
- session: val
- };
- } else {
- fixedSessions[sid] = val;
- }
- }
- return fixedSessions;
- }
- getEndToEndSession(deviceKey, sessionId, txn, func) {
- const sessions = this._getEndToEndSessions(deviceKey);
- func(sessions[sessionId] || {});
- }
- getEndToEndSessions(deviceKey, txn, func) {
- func(this._getEndToEndSessions(deviceKey) || {});
- }
- getAllEndToEndSessions(txn, func) {
- for (let i = 0; i < this.store.length; ++i) {
- var _this$store$key2;
- if ((_this$store$key2 = this.store.key(i)) !== null && _this$store$key2 !== void 0 && _this$store$key2.startsWith(keyEndToEndSessions(""))) {
- const deviceKey = this.store.key(i).split("/")[1];
- for (const sess of Object.values(this._getEndToEndSessions(deviceKey))) {
- func(sess);
- }
- }
- }
- }
- storeEndToEndSession(deviceKey, sessionId, sessionInfo, txn) {
- const sessions = this._getEndToEndSessions(deviceKey) || {};
- sessions[sessionId] = sessionInfo;
- setJsonItem(this.store, keyEndToEndSessions(deviceKey), sessions);
- }
- async storeEndToEndSessionProblem(deviceKey, type, fixed) {
- const key = keyEndToEndSessionProblems(deviceKey);
- const problems = getJsonItem(this.store, key) || [];
- problems.push({
- type,
- fixed,
- time: Date.now()
- });
- problems.sort((a, b) => {
- return a.time - b.time;
- });
- setJsonItem(this.store, key, problems);
- }
- async getEndToEndSessionProblem(deviceKey, timestamp) {
- const key = keyEndToEndSessionProblems(deviceKey);
- const problems = getJsonItem(this.store, key) || [];
- if (!problems.length) {
- return null;
- }
- const lastProblem = problems[problems.length - 1];
- for (const problem of problems) {
- if (problem.time > timestamp) {
- return Object.assign({}, problem, {
- fixed: lastProblem.fixed
- });
- }
- }
- if (lastProblem.fixed) {
- return null;
- } else {
- return lastProblem;
- }
- }
- async filterOutNotifiedErrorDevices(devices) {
- const notifiedErrorDevices = getJsonItem(this.store, KEY_NOTIFIED_ERROR_DEVICES) || {};
- const ret = [];
- for (const device of devices) {
- const {
- userId,
- deviceInfo
- } = device;
- if (userId in notifiedErrorDevices) {
- if (!(deviceInfo.deviceId in notifiedErrorDevices[userId])) {
- ret.push(device);
- (0, _utils.safeSet)(notifiedErrorDevices[userId], deviceInfo.deviceId, true);
- }
- } else {
- ret.push(device);
- (0, _utils.safeSet)(notifiedErrorDevices, userId, {
- [deviceInfo.deviceId]: true
- });
- }
- }
- setJsonItem(this.store, KEY_NOTIFIED_ERROR_DEVICES, notifiedErrorDevices);
- return ret;
- }
-
- // Inbound Group Sessions
-
- getEndToEndInboundGroupSession(senderCurve25519Key, sessionId, txn, func) {
- func(getJsonItem(this.store, keyEndToEndInboundGroupSession(senderCurve25519Key, sessionId)), getJsonItem(this.store, keyEndToEndInboundGroupSessionWithheld(senderCurve25519Key, sessionId)));
- }
- getAllEndToEndInboundGroupSessions(txn, func) {
- for (let i = 0; i < this.store.length; ++i) {
- const key = this.store.key(i);
- if (key !== null && key !== void 0 && key.startsWith(KEY_INBOUND_SESSION_PREFIX)) {
- // we can't use split, as the components we are trying to split out
- // might themselves contain '/' characters. We rely on the
- // senderKey being a (32-byte) curve25519 key, base64-encoded
- // (hence 43 characters long).
-
- func({
- senderKey: key.slice(KEY_INBOUND_SESSION_PREFIX.length, KEY_INBOUND_SESSION_PREFIX.length + 43),
- sessionId: key.slice(KEY_INBOUND_SESSION_PREFIX.length + 44),
- sessionData: getJsonItem(this.store, key)
- });
- }
- }
- func(null);
- }
- addEndToEndInboundGroupSession(senderCurve25519Key, sessionId, sessionData, txn) {
- const existing = getJsonItem(this.store, keyEndToEndInboundGroupSession(senderCurve25519Key, sessionId));
- if (!existing) {
- this.storeEndToEndInboundGroupSession(senderCurve25519Key, sessionId, sessionData, txn);
- }
- }
- storeEndToEndInboundGroupSession(senderCurve25519Key, sessionId, sessionData, txn) {
- setJsonItem(this.store, keyEndToEndInboundGroupSession(senderCurve25519Key, sessionId), sessionData);
- }
- storeEndToEndInboundGroupSessionWithheld(senderCurve25519Key, sessionId, sessionData, txn) {
- setJsonItem(this.store, keyEndToEndInboundGroupSessionWithheld(senderCurve25519Key, sessionId), sessionData);
- }
- getEndToEndDeviceData(txn, func) {
- func(getJsonItem(this.store, KEY_DEVICE_DATA));
- }
- storeEndToEndDeviceData(deviceData, txn) {
- setJsonItem(this.store, KEY_DEVICE_DATA, deviceData);
- }
- storeEndToEndRoom(roomId, roomInfo, txn) {
- setJsonItem(this.store, keyEndToEndRoomsPrefix(roomId), roomInfo);
- }
- getEndToEndRooms(txn, func) {
- const result = {};
- const prefix = keyEndToEndRoomsPrefix("");
- for (let i = 0; i < this.store.length; ++i) {
- const key = this.store.key(i);
- if (key !== null && key !== void 0 && key.startsWith(prefix)) {
- const roomId = key.slice(prefix.length);
- result[roomId] = getJsonItem(this.store, key);
- }
- }
- func(result);
- }
- getSessionsNeedingBackup(limit) {
- const sessionsNeedingBackup = getJsonItem(this.store, KEY_SESSIONS_NEEDING_BACKUP) || {};
- const sessions = [];
- for (const session in sessionsNeedingBackup) {
- if (Object.prototype.hasOwnProperty.call(sessionsNeedingBackup, session)) {
- // see getAllEndToEndInboundGroupSessions for the magic number explanations
- const senderKey = session.slice(0, 43);
- const sessionId = session.slice(44);
- this.getEndToEndInboundGroupSession(senderKey, sessionId, null, sessionData => {
- sessions.push({
- senderKey: senderKey,
- sessionId: sessionId,
- sessionData: sessionData
- });
- });
- if (limit && sessions.length >= limit) {
- break;
- }
- }
- }
- return Promise.resolve(sessions);
- }
- countSessionsNeedingBackup() {
- const sessionsNeedingBackup = getJsonItem(this.store, KEY_SESSIONS_NEEDING_BACKUP) || {};
- return Promise.resolve(Object.keys(sessionsNeedingBackup).length);
- }
- unmarkSessionsNeedingBackup(sessions) {
- const sessionsNeedingBackup = getJsonItem(this.store, KEY_SESSIONS_NEEDING_BACKUP) || {};
- for (const session of sessions) {
- delete sessionsNeedingBackup[session.senderKey + "/" + session.sessionId];
- }
- setJsonItem(this.store, KEY_SESSIONS_NEEDING_BACKUP, sessionsNeedingBackup);
- return Promise.resolve();
- }
- markSessionsNeedingBackup(sessions) {
- const sessionsNeedingBackup = getJsonItem(this.store, KEY_SESSIONS_NEEDING_BACKUP) || {};
- for (const session of sessions) {
- sessionsNeedingBackup[session.senderKey + "/" + session.sessionId] = true;
- }
- setJsonItem(this.store, KEY_SESSIONS_NEEDING_BACKUP, sessionsNeedingBackup);
- return Promise.resolve();
- }
-
- /**
- * Delete all data from this store.
- *
- * @returns Promise which resolves when the store has been cleared.
- */
- deleteAllData() {
- this.store.removeItem(KEY_END_TO_END_ACCOUNT);
- return Promise.resolve();
- }
-
- // Olm account
-
- getAccount(txn, func) {
- const accountPickle = getJsonItem(this.store, KEY_END_TO_END_ACCOUNT);
- func(accountPickle);
- }
- storeAccount(txn, accountPickle) {
- setJsonItem(this.store, KEY_END_TO_END_ACCOUNT, accountPickle);
- }
- getCrossSigningKeys(txn, func) {
- const keys = getJsonItem(this.store, KEY_CROSS_SIGNING_KEYS);
- func(keys);
- }
- getSecretStorePrivateKey(txn, func, type) {
- const key = getJsonItem(this.store, E2E_PREFIX + `ssss_cache.${type}`);
- func(key);
- }
- storeCrossSigningKeys(txn, keys) {
- setJsonItem(this.store, KEY_CROSS_SIGNING_KEYS, keys);
- }
- storeSecretStorePrivateKey(txn, type, key) {
- setJsonItem(this.store, E2E_PREFIX + `ssss_cache.${type}`, key);
- }
- doTxn(mode, stores, func) {
- return Promise.resolve(func(null));
- }
-}
-exports.LocalStorageCryptoStore = LocalStorageCryptoStore;
-function getJsonItem(store, key) {
- try {
- // if the key is absent, store.getItem() returns null, and
- // JSON.parse(null) === null, so this returns null.
- return JSON.parse(store.getItem(key));
- } catch (e) {
- _logger.logger.log("Error: Failed to get key %s: %s", key, e.message);
- _logger.logger.log(e.stack);
- }
- return null;
-}
-function setJsonItem(store, key, val) {
- store.setItem(key, JSON.stringify(val));
-}
-//# sourceMappingURL=localStorage-crypto-store.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/localStorage-crypto-store.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/localStorage-crypto-store.js.map
deleted file mode 100644
index cb5dc11..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/localStorage-crypto-store.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"localStorage-crypto-store.js","names":["_logger","require","_memoryCryptoStore","_utils","E2E_PREFIX","KEY_END_TO_END_ACCOUNT","KEY_CROSS_SIGNING_KEYS","KEY_NOTIFIED_ERROR_DEVICES","KEY_DEVICE_DATA","KEY_INBOUND_SESSION_PREFIX","KEY_INBOUND_SESSION_WITHHELD_PREFIX","KEY_ROOMS_PREFIX","KEY_SESSIONS_NEEDING_BACKUP","keyEndToEndSessions","deviceKey","keyEndToEndSessionProblems","keyEndToEndInboundGroupSession","senderKey","sessionId","keyEndToEndInboundGroupSessionWithheld","keyEndToEndRoomsPrefix","roomId","LocalStorageCryptoStore","MemoryCryptoStore","exists","store","length","i","_store$key","key","startsWith","constructor","countEndToEndSessions","txn","func","count","_this$store$key","_getEndToEndSessions","sessions","getJsonItem","fixedSessions","sid","val","Object","entries","session","getEndToEndSession","getEndToEndSessions","getAllEndToEndSessions","_this$store$key2","split","sess","values","storeEndToEndSession","sessionInfo","setJsonItem","storeEndToEndSessionProblem","type","fixed","problems","push","time","Date","now","sort","a","b","getEndToEndSessionProblem","timestamp","lastProblem","problem","assign","filterOutNotifiedErrorDevices","devices","notifiedErrorDevices","ret","device","userId","deviceInfo","deviceId","safeSet","getEndToEndInboundGroupSession","senderCurve25519Key","getAllEndToEndInboundGroupSessions","slice","sessionData","addEndToEndInboundGroupSession","existing","storeEndToEndInboundGroupSession","storeEndToEndInboundGroupSessionWithheld","getEndToEndDeviceData","storeEndToEndDeviceData","deviceData","storeEndToEndRoom","roomInfo","getEndToEndRooms","result","prefix","getSessionsNeedingBackup","limit","sessionsNeedingBackup","prototype","hasOwnProperty","call","Promise","resolve","countSessionsNeedingBackup","keys","unmarkSessionsNeedingBackup","markSessionsNeedingBackup","deleteAllData","removeItem","getAccount","accountPickle","storeAccount","getCrossSigningKeys","getSecretStorePrivateKey","storeCrossSigningKeys","storeSecretStorePrivateKey","doTxn","mode","stores","exports","JSON","parse","getItem","e","logger","log","message","stack","setItem","stringify"],"sources":["../../../src/crypto/store/localStorage-crypto-store.ts"],"sourcesContent":["/*\nCopyright 2017 - 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { logger } from \"../../logger\";\nimport { MemoryCryptoStore } from \"./memory-crypto-store\";\nimport { IDeviceData, IProblem, ISession, ISessionInfo, IWithheld, Mode, SecretStorePrivateKeys } from \"./base\";\nimport { IOlmDevice } from \"../algorithms/megolm\";\nimport { IRoomEncryption } from \"../RoomList\";\nimport { ICrossSigningKey } from \"../../client\";\nimport { InboundGroupSessionData } from \"../OlmDevice\";\nimport { safeSet } from \"../../utils\";\n\n/**\n * Internal module. Partial localStorage backed storage for e2e.\n * This is not a full crypto store, just the in-memory store with\n * some things backed by localStorage. It exists because indexedDB\n * is broken in Firefox private mode or set to, \"will not remember\n * history\".\n */\n\nconst E2E_PREFIX = \"crypto.\";\nconst KEY_END_TO_END_ACCOUNT = E2E_PREFIX + \"account\";\nconst KEY_CROSS_SIGNING_KEYS = E2E_PREFIX + \"cross_signing_keys\";\nconst KEY_NOTIFIED_ERROR_DEVICES = E2E_PREFIX + \"notified_error_devices\";\nconst KEY_DEVICE_DATA = E2E_PREFIX + \"device_data\";\nconst KEY_INBOUND_SESSION_PREFIX = E2E_PREFIX + \"inboundgroupsessions/\";\nconst KEY_INBOUND_SESSION_WITHHELD_PREFIX = E2E_PREFIX + \"inboundgroupsessions.withheld/\";\nconst KEY_ROOMS_PREFIX = E2E_PREFIX + \"rooms/\";\nconst KEY_SESSIONS_NEEDING_BACKUP = E2E_PREFIX + \"sessionsneedingbackup\";\n\nfunction keyEndToEndSessions(deviceKey: string): string {\n return E2E_PREFIX + \"sessions/\" + deviceKey;\n}\n\nfunction keyEndToEndSessionProblems(deviceKey: string): string {\n return E2E_PREFIX + \"session.problems/\" + deviceKey;\n}\n\nfunction keyEndToEndInboundGroupSession(senderKey: string, sessionId: string): string {\n return KEY_INBOUND_SESSION_PREFIX + senderKey + \"/\" + sessionId;\n}\n\nfunction keyEndToEndInboundGroupSessionWithheld(senderKey: string, sessionId: string): string {\n return KEY_INBOUND_SESSION_WITHHELD_PREFIX + senderKey + \"/\" + sessionId;\n}\n\nfunction keyEndToEndRoomsPrefix(roomId: string): string {\n return KEY_ROOMS_PREFIX + roomId;\n}\n\nexport class LocalStorageCryptoStore extends MemoryCryptoStore {\n public static exists(store: Storage): boolean {\n const length = store.length;\n for (let i = 0; i < length; i++) {\n if (store.key(i)?.startsWith(E2E_PREFIX)) {\n return true;\n }\n }\n return false;\n }\n\n public constructor(private readonly store: Storage) {\n super();\n }\n\n // Olm Sessions\n\n public countEndToEndSessions(txn: unknown, func: (count: number) => void): void {\n let count = 0;\n for (let i = 0; i < this.store.length; ++i) {\n if (this.store.key(i)?.startsWith(keyEndToEndSessions(\"\"))) ++count;\n }\n func(count);\n }\n\n // eslint-disable-next-line @typescript-eslint/naming-convention\n private _getEndToEndSessions(deviceKey: string): Record<string, ISessionInfo> {\n const sessions = getJsonItem(this.store, keyEndToEndSessions(deviceKey));\n const fixedSessions: Record<string, ISessionInfo> = {};\n\n // fix up any old sessions to be objects rather than just the base64 pickle\n for (const [sid, val] of Object.entries(sessions || {})) {\n if (typeof val === \"string\") {\n fixedSessions[sid] = {\n session: val,\n };\n } else {\n fixedSessions[sid] = val;\n }\n }\n\n return fixedSessions;\n }\n\n public getEndToEndSession(\n deviceKey: string,\n sessionId: string,\n txn: unknown,\n func: (session: ISessionInfo) => void,\n ): void {\n const sessions = this._getEndToEndSessions(deviceKey);\n func(sessions[sessionId] || {});\n }\n\n public getEndToEndSessions(\n deviceKey: string,\n txn: unknown,\n func: (sessions: { [sessionId: string]: ISessionInfo }) => void,\n ): void {\n func(this._getEndToEndSessions(deviceKey) || {});\n }\n\n public getAllEndToEndSessions(txn: unknown, func: (session: ISessionInfo) => void): void {\n for (let i = 0; i < this.store.length; ++i) {\n if (this.store.key(i)?.startsWith(keyEndToEndSessions(\"\"))) {\n const deviceKey = this.store.key(i)!.split(\"/\")[1];\n for (const sess of Object.values(this._getEndToEndSessions(deviceKey))) {\n func(sess);\n }\n }\n }\n }\n\n public storeEndToEndSession(deviceKey: string, sessionId: string, sessionInfo: ISessionInfo, txn: unknown): void {\n const sessions = this._getEndToEndSessions(deviceKey) || {};\n sessions[sessionId] = sessionInfo;\n setJsonItem(this.store, keyEndToEndSessions(deviceKey), sessions);\n }\n\n public async storeEndToEndSessionProblem(deviceKey: string, type: string, fixed: boolean): Promise<void> {\n const key = keyEndToEndSessionProblems(deviceKey);\n const problems = getJsonItem<IProblem[]>(this.store, key) || [];\n problems.push({ type, fixed, time: Date.now() });\n problems.sort((a, b) => {\n return a.time - b.time;\n });\n setJsonItem(this.store, key, problems);\n }\n\n public async getEndToEndSessionProblem(deviceKey: string, timestamp: number): Promise<IProblem | null> {\n const key = keyEndToEndSessionProblems(deviceKey);\n const problems = getJsonItem<IProblem[]>(this.store, key) || [];\n if (!problems.length) {\n return null;\n }\n const lastProblem = problems[problems.length - 1];\n for (const problem of problems) {\n if (problem.time > timestamp) {\n return Object.assign({}, problem, { fixed: lastProblem.fixed });\n }\n }\n if (lastProblem.fixed) {\n return null;\n } else {\n return lastProblem;\n }\n }\n\n public async filterOutNotifiedErrorDevices(devices: IOlmDevice[]): Promise<IOlmDevice[]> {\n const notifiedErrorDevices =\n getJsonItem<MemoryCryptoStore[\"notifiedErrorDevices\"]>(this.store, KEY_NOTIFIED_ERROR_DEVICES) || {};\n const ret: IOlmDevice[] = [];\n\n for (const device of devices) {\n const { userId, deviceInfo } = device;\n if (userId in notifiedErrorDevices) {\n if (!(deviceInfo.deviceId in notifiedErrorDevices[userId])) {\n ret.push(device);\n safeSet(notifiedErrorDevices[userId], deviceInfo.deviceId, true);\n }\n } else {\n ret.push(device);\n safeSet(notifiedErrorDevices, userId, { [deviceInfo.deviceId]: true });\n }\n }\n\n setJsonItem(this.store, KEY_NOTIFIED_ERROR_DEVICES, notifiedErrorDevices);\n\n return ret;\n }\n\n // Inbound Group Sessions\n\n public getEndToEndInboundGroupSession(\n senderCurve25519Key: string,\n sessionId: string,\n txn: unknown,\n func: (groupSession: InboundGroupSessionData | null, groupSessionWithheld: IWithheld | null) => void,\n ): void {\n func(\n getJsonItem(this.store, keyEndToEndInboundGroupSession(senderCurve25519Key, sessionId)),\n getJsonItem(this.store, keyEndToEndInboundGroupSessionWithheld(senderCurve25519Key, sessionId)),\n );\n }\n\n public getAllEndToEndInboundGroupSessions(txn: unknown, func: (session: ISession | null) => void): void {\n for (let i = 0; i < this.store.length; ++i) {\n const key = this.store.key(i);\n if (key?.startsWith(KEY_INBOUND_SESSION_PREFIX)) {\n // we can't use split, as the components we are trying to split out\n // might themselves contain '/' characters. We rely on the\n // senderKey being a (32-byte) curve25519 key, base64-encoded\n // (hence 43 characters long).\n\n func({\n senderKey: key.slice(KEY_INBOUND_SESSION_PREFIX.length, KEY_INBOUND_SESSION_PREFIX.length + 43),\n sessionId: key.slice(KEY_INBOUND_SESSION_PREFIX.length + 44),\n sessionData: getJsonItem(this.store, key)!,\n });\n }\n }\n func(null);\n }\n\n public addEndToEndInboundGroupSession(\n senderCurve25519Key: string,\n sessionId: string,\n sessionData: InboundGroupSessionData,\n txn: unknown,\n ): void {\n const existing = getJsonItem(this.store, keyEndToEndInboundGroupSession(senderCurve25519Key, sessionId));\n if (!existing) {\n this.storeEndToEndInboundGroupSession(senderCurve25519Key, sessionId, sessionData, txn);\n }\n }\n\n public storeEndToEndInboundGroupSession(\n senderCurve25519Key: string,\n sessionId: string,\n sessionData: InboundGroupSessionData,\n txn: unknown,\n ): void {\n setJsonItem(this.store, keyEndToEndInboundGroupSession(senderCurve25519Key, sessionId), sessionData);\n }\n\n public storeEndToEndInboundGroupSessionWithheld(\n senderCurve25519Key: string,\n sessionId: string,\n sessionData: IWithheld,\n txn: unknown,\n ): void {\n setJsonItem(this.store, keyEndToEndInboundGroupSessionWithheld(senderCurve25519Key, sessionId), sessionData);\n }\n\n public getEndToEndDeviceData(txn: unknown, func: (deviceData: IDeviceData | null) => void): void {\n func(getJsonItem(this.store, KEY_DEVICE_DATA));\n }\n\n public storeEndToEndDeviceData(deviceData: IDeviceData, txn: unknown): void {\n setJsonItem(this.store, KEY_DEVICE_DATA, deviceData);\n }\n\n public storeEndToEndRoom(roomId: string, roomInfo: IRoomEncryption, txn: unknown): void {\n setJsonItem(this.store, keyEndToEndRoomsPrefix(roomId), roomInfo);\n }\n\n public getEndToEndRooms(txn: unknown, func: (rooms: Record<string, IRoomEncryption>) => void): void {\n const result: Record<string, IRoomEncryption> = {};\n const prefix = keyEndToEndRoomsPrefix(\"\");\n\n for (let i = 0; i < this.store.length; ++i) {\n const key = this.store.key(i);\n if (key?.startsWith(prefix)) {\n const roomId = key.slice(prefix.length);\n result[roomId] = getJsonItem(this.store, key)!;\n }\n }\n func(result);\n }\n\n public getSessionsNeedingBackup(limit: number): Promise<ISession[]> {\n const sessionsNeedingBackup = getJsonItem<string[]>(this.store, KEY_SESSIONS_NEEDING_BACKUP) || {};\n const sessions: ISession[] = [];\n\n for (const session in sessionsNeedingBackup) {\n if (Object.prototype.hasOwnProperty.call(sessionsNeedingBackup, session)) {\n // see getAllEndToEndInboundGroupSessions for the magic number explanations\n const senderKey = session.slice(0, 43);\n const sessionId = session.slice(44);\n this.getEndToEndInboundGroupSession(senderKey, sessionId, null, (sessionData) => {\n sessions.push({\n senderKey: senderKey,\n sessionId: sessionId,\n sessionData: sessionData!,\n });\n });\n if (limit && sessions.length >= limit) {\n break;\n }\n }\n }\n return Promise.resolve(sessions);\n }\n\n public countSessionsNeedingBackup(): Promise<number> {\n const sessionsNeedingBackup = getJsonItem(this.store, KEY_SESSIONS_NEEDING_BACKUP) || {};\n return Promise.resolve(Object.keys(sessionsNeedingBackup).length);\n }\n\n public unmarkSessionsNeedingBackup(sessions: ISession[]): Promise<void> {\n const sessionsNeedingBackup =\n getJsonItem<{\n [senderKeySessionId: string]: string;\n }>(this.store, KEY_SESSIONS_NEEDING_BACKUP) || {};\n for (const session of sessions) {\n delete sessionsNeedingBackup[session.senderKey + \"/\" + session.sessionId];\n }\n setJsonItem(this.store, KEY_SESSIONS_NEEDING_BACKUP, sessionsNeedingBackup);\n return Promise.resolve();\n }\n\n public markSessionsNeedingBackup(sessions: ISession[]): Promise<void> {\n const sessionsNeedingBackup =\n getJsonItem<{\n [senderKeySessionId: string]: boolean;\n }>(this.store, KEY_SESSIONS_NEEDING_BACKUP) || {};\n for (const session of sessions) {\n sessionsNeedingBackup[session.senderKey + \"/\" + session.sessionId] = true;\n }\n setJsonItem(this.store, KEY_SESSIONS_NEEDING_BACKUP, sessionsNeedingBackup);\n return Promise.resolve();\n }\n\n /**\n * Delete all data from this store.\n *\n * @returns Promise which resolves when the store has been cleared.\n */\n public deleteAllData(): Promise<void> {\n this.store.removeItem(KEY_END_TO_END_ACCOUNT);\n return Promise.resolve();\n }\n\n // Olm account\n\n public getAccount(txn: unknown, func: (accountPickle: string | null) => void): void {\n const accountPickle = getJsonItem<string>(this.store, KEY_END_TO_END_ACCOUNT);\n func(accountPickle);\n }\n\n public storeAccount(txn: unknown, accountPickle: string): void {\n setJsonItem(this.store, KEY_END_TO_END_ACCOUNT, accountPickle);\n }\n\n public getCrossSigningKeys(txn: unknown, func: (keys: Record<string, ICrossSigningKey> | null) => void): void {\n const keys = getJsonItem<Record<string, ICrossSigningKey>>(this.store, KEY_CROSS_SIGNING_KEYS);\n func(keys);\n }\n\n public getSecretStorePrivateKey<K extends keyof SecretStorePrivateKeys>(\n txn: unknown,\n func: (key: SecretStorePrivateKeys[K] | null) => void,\n type: K,\n ): void {\n const key = getJsonItem<SecretStorePrivateKeys[K]>(this.store, E2E_PREFIX + `ssss_cache.${type}`);\n func(key);\n }\n\n public storeCrossSigningKeys(txn: unknown, keys: Record<string, ICrossSigningKey>): void {\n setJsonItem(this.store, KEY_CROSS_SIGNING_KEYS, keys);\n }\n\n public storeSecretStorePrivateKey<K extends keyof SecretStorePrivateKeys>(\n txn: unknown,\n type: K,\n key: SecretStorePrivateKeys[K],\n ): void {\n setJsonItem(this.store, E2E_PREFIX + `ssss_cache.${type}`, key);\n }\n\n public doTxn<T>(mode: Mode, stores: Iterable<string>, func: (txn: unknown) => T): Promise<T> {\n return Promise.resolve(func(null));\n }\n}\n\nfunction getJsonItem<T>(store: Storage, key: string): T | null {\n try {\n // if the key is absent, store.getItem() returns null, and\n // JSON.parse(null) === null, so this returns null.\n return JSON.parse(store.getItem(key)!);\n } catch (e) {\n logger.log(\"Error: Failed to get key %s: %s\", key, (<Error>e).message);\n logger.log((<Error>e).stack);\n }\n return null;\n}\n\nfunction setJsonItem<T>(store: Storage, key: string, val: T): void {\n store.setItem(key, JSON.stringify(val));\n}\n"],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/memory-crypto-store.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/memory-crypto-store.d.ts
deleted file mode 100644
index 9d2c4cd..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/memory-crypto-store.d.ts
+++ /dev/null
@@ -1,144 +0,0 @@
-import { CryptoStore, IDeviceData, IProblem, ISession, ISessionInfo, IWithheld, Mode, OutgoingRoomKeyRequest, ParkedSharedHistory, SecretStorePrivateKeys } from "./base";
-import { IRoomKeyRequestBody } from "../index";
-import { ICrossSigningKey } from "../../client";
-import { IOlmDevice } from "../algorithms/megolm";
-import { IRoomEncryption } from "../RoomList";
-import { InboundGroupSessionData } from "../OlmDevice";
-/**
- * Internal module. in-memory storage for e2e.
- */
-export declare class MemoryCryptoStore implements CryptoStore {
- private outgoingRoomKeyRequests;
- private account;
- private crossSigningKeys;
- private privateKeys;
- private sessions;
- private sessionProblems;
- private notifiedErrorDevices;
- private inboundGroupSessions;
- private inboundGroupSessionsWithheld;
- private deviceData;
- private rooms;
- private sessionsNeedingBackup;
- private sharedHistoryInboundGroupSessions;
- private parkedSharedHistory;
- /**
- * Ensure the database exists and is up-to-date.
- *
- * This must be called before the store can be used.
- *
- * @returns resolves to the store.
- */
- startup(): Promise<CryptoStore>;
- /**
- * Delete all data from this store.
- *
- * @returns Promise which resolves when the store has been cleared.
- */
- deleteAllData(): Promise<void>;
- /**
- * Look for an existing outgoing room key request, and if none is found,
- * add a new one
- *
- *
- * @returns resolves to
- * {@link OutgoingRoomKeyRequest}: either the
- * same instance as passed in, or the existing one.
- */
- getOrAddOutgoingRoomKeyRequest(request: OutgoingRoomKeyRequest): Promise<OutgoingRoomKeyRequest>;
- /**
- * Look for an existing room key request
- *
- * @param requestBody - existing request to look for
- *
- * @returns resolves to the matching
- * {@link OutgoingRoomKeyRequest}, or null if
- * not found
- */
- getOutgoingRoomKeyRequest(requestBody: IRoomKeyRequestBody): Promise<OutgoingRoomKeyRequest | null>;
- /**
- * Looks for existing room key request, and returns the result synchronously.
- *
- * @internal
- *
- * @param requestBody - existing request to look for
- *
- * @returns
- * the matching request, or null if not found
- */
- private _getOutgoingRoomKeyRequest;
- /**
- * Look for room key requests by state
- *
- * @param wantedStates - list of acceptable states
- *
- * @returns resolves to the a
- * {@link OutgoingRoomKeyRequest}, or null if
- * there are no pending requests in those states
- */
- getOutgoingRoomKeyRequestByState(wantedStates: number[]): Promise<OutgoingRoomKeyRequest | null>;
- /**
- *
- * @returns All OutgoingRoomKeyRequests in state
- */
- getAllOutgoingRoomKeyRequestsByState(wantedState: number): Promise<OutgoingRoomKeyRequest[]>;
- getOutgoingRoomKeyRequestsByTarget(userId: string, deviceId: string, wantedStates: number[]): Promise<OutgoingRoomKeyRequest[]>;
- /**
- * Look for an existing room key request by id and state, and update it if
- * found
- *
- * @param requestId - ID of request to update
- * @param expectedState - state we expect to find the request in
- * @param updates - name/value map of updates to apply
- *
- * @returns resolves to
- * {@link OutgoingRoomKeyRequest}
- * updated request, or null if no matching row was found
- */
- updateOutgoingRoomKeyRequest(requestId: string, expectedState: number, updates: Partial<OutgoingRoomKeyRequest>): Promise<OutgoingRoomKeyRequest | null>;
- /**
- * Look for an existing room key request by id and state, and delete it if
- * found
- *
- * @param requestId - ID of request to update
- * @param expectedState - state we expect to find the request in
- *
- * @returns resolves once the operation is completed
- */
- deleteOutgoingRoomKeyRequest(requestId: string, expectedState: number): Promise<OutgoingRoomKeyRequest | null>;
- getAccount(txn: unknown, func: (accountPickle: string | null) => void): void;
- storeAccount(txn: unknown, accountPickle: string): void;
- getCrossSigningKeys(txn: unknown, func: (keys: Record<string, ICrossSigningKey> | null) => void): void;
- getSecretStorePrivateKey<K extends keyof SecretStorePrivateKeys>(txn: unknown, func: (key: SecretStorePrivateKeys[K] | null) => void, type: K): void;
- storeCrossSigningKeys(txn: unknown, keys: Record<string, ICrossSigningKey>): void;
- storeSecretStorePrivateKey<K extends keyof SecretStorePrivateKeys>(txn: unknown, type: K, key: SecretStorePrivateKeys[K]): void;
- countEndToEndSessions(txn: unknown, func: (count: number) => void): void;
- getEndToEndSession(deviceKey: string, sessionId: string, txn: unknown, func: (session: ISessionInfo) => void): void;
- getEndToEndSessions(deviceKey: string, txn: unknown, func: (sessions: {
- [sessionId: string]: ISessionInfo;
- }) => void): void;
- getAllEndToEndSessions(txn: unknown, func: (session: ISessionInfo) => void): void;
- storeEndToEndSession(deviceKey: string, sessionId: string, sessionInfo: ISessionInfo, txn: unknown): void;
- storeEndToEndSessionProblem(deviceKey: string, type: string, fixed: boolean): Promise<void>;
- getEndToEndSessionProblem(deviceKey: string, timestamp: number): Promise<IProblem | null>;
- filterOutNotifiedErrorDevices(devices: IOlmDevice[]): Promise<IOlmDevice[]>;
- getEndToEndInboundGroupSession(senderCurve25519Key: string, sessionId: string, txn: unknown, func: (groupSession: InboundGroupSessionData | null, groupSessionWithheld: IWithheld | null) => void): void;
- getAllEndToEndInboundGroupSessions(txn: unknown, func: (session: ISession | null) => void): void;
- addEndToEndInboundGroupSession(senderCurve25519Key: string, sessionId: string, sessionData: InboundGroupSessionData, txn: unknown): void;
- storeEndToEndInboundGroupSession(senderCurve25519Key: string, sessionId: string, sessionData: InboundGroupSessionData, txn: unknown): void;
- storeEndToEndInboundGroupSessionWithheld(senderCurve25519Key: string, sessionId: string, sessionData: IWithheld, txn: unknown): void;
- getEndToEndDeviceData(txn: unknown, func: (deviceData: IDeviceData | null) => void): void;
- storeEndToEndDeviceData(deviceData: IDeviceData, txn: unknown): void;
- storeEndToEndRoom(roomId: string, roomInfo: IRoomEncryption, txn: unknown): void;
- getEndToEndRooms(txn: unknown, func: (rooms: Record<string, IRoomEncryption>) => void): void;
- getSessionsNeedingBackup(limit: number): Promise<ISession[]>;
- countSessionsNeedingBackup(): Promise<number>;
- unmarkSessionsNeedingBackup(sessions: ISession[]): Promise<void>;
- markSessionsNeedingBackup(sessions: ISession[]): Promise<void>;
- addSharedHistoryInboundGroupSession(roomId: string, senderKey: string, sessionId: string): void;
- getSharedHistoryInboundGroupSessions(roomId: string): Promise<[senderKey: string, sessionId: string][]>;
- addParkedSharedHistory(roomId: string, parkedData: ParkedSharedHistory): void;
- takeParkedSharedHistory(roomId: string): Promise<ParkedSharedHistory[]>;
- doTxn<T>(mode: Mode, stores: Iterable<string>, func: (txn?: unknown) => T): Promise<T>;
-}
-//# sourceMappingURL=memory-crypto-store.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/memory-crypto-store.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/memory-crypto-store.d.ts.map
deleted file mode 100644
index f9c8a15..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/memory-crypto-store.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"memory-crypto-store.d.ts","sourceRoot":"","sources":["../../../src/crypto/store/memory-crypto-store.ts"],"names":[],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/memory-crypto-store.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/memory-crypto-store.js
deleted file mode 100644
index fd52162..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/memory-crypto-store.js
+++ /dev/null
@@ -1,429 +0,0 @@
-"use strict";
-
-var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.MemoryCryptoStore = void 0;
-var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
-var _logger = require("../../logger");
-var utils = _interopRequireWildcard(require("../../utils"));
-function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
-function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
-function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
-function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
-/**
- * Internal module. in-memory storage for e2e.
- */
-
-class MemoryCryptoStore {
- constructor() {
- (0, _defineProperty2.default)(this, "outgoingRoomKeyRequests", []);
- (0, _defineProperty2.default)(this, "account", null);
- (0, _defineProperty2.default)(this, "crossSigningKeys", null);
- (0, _defineProperty2.default)(this, "privateKeys", {});
- (0, _defineProperty2.default)(this, "sessions", {});
- (0, _defineProperty2.default)(this, "sessionProblems", {});
- (0, _defineProperty2.default)(this, "notifiedErrorDevices", {});
- (0, _defineProperty2.default)(this, "inboundGroupSessions", {});
- (0, _defineProperty2.default)(this, "inboundGroupSessionsWithheld", {});
- (0, _defineProperty2.default)(this, "deviceData", null);
- (0, _defineProperty2.default)(this, "rooms", {});
- (0, _defineProperty2.default)(this, "sessionsNeedingBackup", {});
- (0, _defineProperty2.default)(this, "sharedHistoryInboundGroupSessions", {});
- (0, _defineProperty2.default)(this, "parkedSharedHistory", new Map());
- }
- // keyed by room ID
-
- /**
- * Ensure the database exists and is up-to-date.
- *
- * This must be called before the store can be used.
- *
- * @returns resolves to the store.
- */
- async startup() {
- // No startup work to do for the memory store.
- return this;
- }
-
- /**
- * Delete all data from this store.
- *
- * @returns Promise which resolves when the store has been cleared.
- */
- deleteAllData() {
- return Promise.resolve();
- }
-
- /**
- * Look for an existing outgoing room key request, and if none is found,
- * add a new one
- *
- *
- * @returns resolves to
- * {@link OutgoingRoomKeyRequest}: either the
- * same instance as passed in, or the existing one.
- */
- getOrAddOutgoingRoomKeyRequest(request) {
- const requestBody = request.requestBody;
- return utils.promiseTry(() => {
- // first see if we already have an entry for this request.
- const existing = this._getOutgoingRoomKeyRequest(requestBody);
- if (existing) {
- // this entry matches the request - return it.
- _logger.logger.log(`already have key request outstanding for ` + `${requestBody.room_id} / ${requestBody.session_id}: ` + `not sending another`);
- return existing;
- }
-
- // we got to the end of the list without finding a match
- // - add the new request.
- _logger.logger.log(`enqueueing key request for ${requestBody.room_id} / ` + requestBody.session_id);
- this.outgoingRoomKeyRequests.push(request);
- return request;
- });
- }
-
- /**
- * Look for an existing room key request
- *
- * @param requestBody - existing request to look for
- *
- * @returns resolves to the matching
- * {@link OutgoingRoomKeyRequest}, or null if
- * not found
- */
- getOutgoingRoomKeyRequest(requestBody) {
- return Promise.resolve(this._getOutgoingRoomKeyRequest(requestBody));
- }
-
- /**
- * Looks for existing room key request, and returns the result synchronously.
- *
- * @internal
- *
- * @param requestBody - existing request to look for
- *
- * @returns
- * the matching request, or null if not found
- */
- // eslint-disable-next-line @typescript-eslint/naming-convention
- _getOutgoingRoomKeyRequest(requestBody) {
- for (const existing of this.outgoingRoomKeyRequests) {
- if (utils.deepCompare(existing.requestBody, requestBody)) {
- return existing;
- }
- }
- return null;
- }
-
- /**
- * Look for room key requests by state
- *
- * @param wantedStates - list of acceptable states
- *
- * @returns resolves to the a
- * {@link OutgoingRoomKeyRequest}, or null if
- * there are no pending requests in those states
- */
- getOutgoingRoomKeyRequestByState(wantedStates) {
- for (const req of this.outgoingRoomKeyRequests) {
- for (const state of wantedStates) {
- if (req.state === state) {
- return Promise.resolve(req);
- }
- }
- }
- return Promise.resolve(null);
- }
-
- /**
- *
- * @returns All OutgoingRoomKeyRequests in state
- */
- getAllOutgoingRoomKeyRequestsByState(wantedState) {
- return Promise.resolve(this.outgoingRoomKeyRequests.filter(r => r.state == wantedState));
- }
- getOutgoingRoomKeyRequestsByTarget(userId, deviceId, wantedStates) {
- const results = [];
- for (const req of this.outgoingRoomKeyRequests) {
- for (const state of wantedStates) {
- if (req.state === state && req.recipients.some(recipient => recipient.userId === userId && recipient.deviceId === deviceId)) {
- results.push(req);
- }
- }
- }
- return Promise.resolve(results);
- }
-
- /**
- * Look for an existing room key request by id and state, and update it if
- * found
- *
- * @param requestId - ID of request to update
- * @param expectedState - state we expect to find the request in
- * @param updates - name/value map of updates to apply
- *
- * @returns resolves to
- * {@link OutgoingRoomKeyRequest}
- * updated request, or null if no matching row was found
- */
- updateOutgoingRoomKeyRequest(requestId, expectedState, updates) {
- for (const req of this.outgoingRoomKeyRequests) {
- if (req.requestId !== requestId) {
- continue;
- }
- if (req.state !== expectedState) {
- _logger.logger.warn(`Cannot update room key request from ${expectedState} ` + `as it was already updated to ${req.state}`);
- return Promise.resolve(null);
- }
- Object.assign(req, updates);
- return Promise.resolve(req);
- }
- return Promise.resolve(null);
- }
-
- /**
- * Look for an existing room key request by id and state, and delete it if
- * found
- *
- * @param requestId - ID of request to update
- * @param expectedState - state we expect to find the request in
- *
- * @returns resolves once the operation is completed
- */
- deleteOutgoingRoomKeyRequest(requestId, expectedState) {
- for (let i = 0; i < this.outgoingRoomKeyRequests.length; i++) {
- const req = this.outgoingRoomKeyRequests[i];
- if (req.requestId !== requestId) {
- continue;
- }
- if (req.state != expectedState) {
- _logger.logger.warn(`Cannot delete room key request in state ${req.state} ` + `(expected ${expectedState})`);
- return Promise.resolve(null);
- }
- this.outgoingRoomKeyRequests.splice(i, 1);
- return Promise.resolve(req);
- }
- return Promise.resolve(null);
- }
-
- // Olm Account
-
- getAccount(txn, func) {
- func(this.account);
- }
- storeAccount(txn, accountPickle) {
- this.account = accountPickle;
- }
- getCrossSigningKeys(txn, func) {
- func(this.crossSigningKeys);
- }
- getSecretStorePrivateKey(txn, func, type) {
- const result = this.privateKeys[type];
- func(result || null);
- }
- storeCrossSigningKeys(txn, keys) {
- this.crossSigningKeys = keys;
- }
- storeSecretStorePrivateKey(txn, type, key) {
- this.privateKeys[type] = key;
- }
-
- // Olm Sessions
-
- countEndToEndSessions(txn, func) {
- func(Object.keys(this.sessions).length);
- }
- getEndToEndSession(deviceKey, sessionId, txn, func) {
- const deviceSessions = this.sessions[deviceKey] || {};
- func(deviceSessions[sessionId] || null);
- }
- getEndToEndSessions(deviceKey, txn, func) {
- func(this.sessions[deviceKey] || {});
- }
- getAllEndToEndSessions(txn, func) {
- Object.entries(this.sessions).forEach(([deviceKey, deviceSessions]) => {
- Object.entries(deviceSessions).forEach(([sessionId, session]) => {
- func(_objectSpread(_objectSpread({}, session), {}, {
- deviceKey,
- sessionId
- }));
- });
- });
- }
- storeEndToEndSession(deviceKey, sessionId, sessionInfo, txn) {
- let deviceSessions = this.sessions[deviceKey];
- if (deviceSessions === undefined) {
- deviceSessions = {};
- this.sessions[deviceKey] = deviceSessions;
- }
- deviceSessions[sessionId] = sessionInfo;
- }
- async storeEndToEndSessionProblem(deviceKey, type, fixed) {
- const problems = this.sessionProblems[deviceKey] = this.sessionProblems[deviceKey] || [];
- problems.push({
- type,
- fixed,
- time: Date.now()
- });
- problems.sort((a, b) => {
- return a.time - b.time;
- });
- }
- async getEndToEndSessionProblem(deviceKey, timestamp) {
- const problems = this.sessionProblems[deviceKey] || [];
- if (!problems.length) {
- return null;
- }
- const lastProblem = problems[problems.length - 1];
- for (const problem of problems) {
- if (problem.time > timestamp) {
- return Object.assign({}, problem, {
- fixed: lastProblem.fixed
- });
- }
- }
- if (lastProblem.fixed) {
- return null;
- } else {
- return lastProblem;
- }
- }
- async filterOutNotifiedErrorDevices(devices) {
- const notifiedErrorDevices = this.notifiedErrorDevices;
- const ret = [];
- for (const device of devices) {
- const {
- userId,
- deviceInfo
- } = device;
- if (userId in notifiedErrorDevices) {
- if (!(deviceInfo.deviceId in notifiedErrorDevices[userId])) {
- ret.push(device);
- (0, utils.safeSet)(notifiedErrorDevices[userId], deviceInfo.deviceId, true);
- }
- } else {
- ret.push(device);
- (0, utils.safeSet)(notifiedErrorDevices, userId, {
- [deviceInfo.deviceId]: true
- });
- }
- }
- return ret;
- }
-
- // Inbound Group Sessions
-
- getEndToEndInboundGroupSession(senderCurve25519Key, sessionId, txn, func) {
- const k = senderCurve25519Key + "/" + sessionId;
- func(this.inboundGroupSessions[k] || null, this.inboundGroupSessionsWithheld[k] || null);
- }
- getAllEndToEndInboundGroupSessions(txn, func) {
- for (const key of Object.keys(this.inboundGroupSessions)) {
- // we can't use split, as the components we are trying to split out
- // might themselves contain '/' characters. We rely on the
- // senderKey being a (32-byte) curve25519 key, base64-encoded
- // (hence 43 characters long).
-
- func({
- senderKey: key.slice(0, 43),
- sessionId: key.slice(44),
- sessionData: this.inboundGroupSessions[key]
- });
- }
- func(null);
- }
- addEndToEndInboundGroupSession(senderCurve25519Key, sessionId, sessionData, txn) {
- const k = senderCurve25519Key + "/" + sessionId;
- if (this.inboundGroupSessions[k] === undefined) {
- this.inboundGroupSessions[k] = sessionData;
- }
- }
- storeEndToEndInboundGroupSession(senderCurve25519Key, sessionId, sessionData, txn) {
- this.inboundGroupSessions[senderCurve25519Key + "/" + sessionId] = sessionData;
- }
- storeEndToEndInboundGroupSessionWithheld(senderCurve25519Key, sessionId, sessionData, txn) {
- const k = senderCurve25519Key + "/" + sessionId;
- this.inboundGroupSessionsWithheld[k] = sessionData;
- }
-
- // Device Data
-
- getEndToEndDeviceData(txn, func) {
- func(this.deviceData);
- }
- storeEndToEndDeviceData(deviceData, txn) {
- this.deviceData = deviceData;
- }
-
- // E2E rooms
-
- storeEndToEndRoom(roomId, roomInfo, txn) {
- this.rooms[roomId] = roomInfo;
- }
- getEndToEndRooms(txn, func) {
- func(this.rooms);
- }
- getSessionsNeedingBackup(limit) {
- const sessions = [];
- for (const session in this.sessionsNeedingBackup) {
- if (this.inboundGroupSessions[session]) {
- sessions.push({
- senderKey: session.slice(0, 43),
- sessionId: session.slice(44),
- sessionData: this.inboundGroupSessions[session]
- });
- if (limit && session.length >= limit) {
- break;
- }
- }
- }
- return Promise.resolve(sessions);
- }
- countSessionsNeedingBackup() {
- return Promise.resolve(Object.keys(this.sessionsNeedingBackup).length);
- }
- unmarkSessionsNeedingBackup(sessions) {
- for (const session of sessions) {
- const sessionKey = session.senderKey + "/" + session.sessionId;
- delete this.sessionsNeedingBackup[sessionKey];
- }
- return Promise.resolve();
- }
- markSessionsNeedingBackup(sessions) {
- for (const session of sessions) {
- const sessionKey = session.senderKey + "/" + session.sessionId;
- this.sessionsNeedingBackup[sessionKey] = true;
- }
- return Promise.resolve();
- }
- addSharedHistoryInboundGroupSession(roomId, senderKey, sessionId) {
- const sessions = this.sharedHistoryInboundGroupSessions[roomId] || [];
- sessions.push([senderKey, sessionId]);
- this.sharedHistoryInboundGroupSessions[roomId] = sessions;
- }
- getSharedHistoryInboundGroupSessions(roomId) {
- return Promise.resolve(this.sharedHistoryInboundGroupSessions[roomId] || []);
- }
- addParkedSharedHistory(roomId, parkedData) {
- var _this$parkedSharedHis;
- const parked = (_this$parkedSharedHis = this.parkedSharedHistory.get(roomId)) !== null && _this$parkedSharedHis !== void 0 ? _this$parkedSharedHis : [];
- parked.push(parkedData);
- this.parkedSharedHistory.set(roomId, parked);
- }
- takeParkedSharedHistory(roomId) {
- var _this$parkedSharedHis2;
- const parked = (_this$parkedSharedHis2 = this.parkedSharedHistory.get(roomId)) !== null && _this$parkedSharedHis2 !== void 0 ? _this$parkedSharedHis2 : [];
- this.parkedSharedHistory.delete(roomId);
- return Promise.resolve(parked);
- }
-
- // Session key backups
-
- doTxn(mode, stores, func) {
- return Promise.resolve(func(null));
- }
-}
-exports.MemoryCryptoStore = MemoryCryptoStore;
-//# sourceMappingURL=memory-crypto-store.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/memory-crypto-store.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/memory-crypto-store.js.map
deleted file mode 100644
index c976150..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/store/memory-crypto-store.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"memory-crypto-store.js","names":["_logger","require","utils","_interopRequireWildcard","_getRequireWildcardCache","nodeInterop","WeakMap","cacheBabelInterop","cacheNodeInterop","obj","__esModule","default","cache","has","get","newObj","hasPropertyDescriptor","Object","defineProperty","getOwnPropertyDescriptor","key","prototype","hasOwnProperty","call","desc","set","ownKeys","object","enumerableOnly","keys","getOwnPropertySymbols","symbols","filter","sym","enumerable","push","apply","_objectSpread","target","i","arguments","length","source","forEach","_defineProperty2","getOwnPropertyDescriptors","defineProperties","MemoryCryptoStore","constructor","Map","startup","deleteAllData","Promise","resolve","getOrAddOutgoingRoomKeyRequest","request","requestBody","promiseTry","existing","_getOutgoingRoomKeyRequest","logger","log","room_id","session_id","outgoingRoomKeyRequests","getOutgoingRoomKeyRequest","deepCompare","getOutgoingRoomKeyRequestByState","wantedStates","req","state","getAllOutgoingRoomKeyRequestsByState","wantedState","r","getOutgoingRoomKeyRequestsByTarget","userId","deviceId","results","recipients","some","recipient","updateOutgoingRoomKeyRequest","requestId","expectedState","updates","warn","assign","deleteOutgoingRoomKeyRequest","splice","getAccount","txn","func","account","storeAccount","accountPickle","getCrossSigningKeys","crossSigningKeys","getSecretStorePrivateKey","type","result","privateKeys","storeCrossSigningKeys","storeSecretStorePrivateKey","countEndToEndSessions","sessions","getEndToEndSession","deviceKey","sessionId","deviceSessions","getEndToEndSessions","getAllEndToEndSessions","entries","session","storeEndToEndSession","sessionInfo","undefined","storeEndToEndSessionProblem","fixed","problems","sessionProblems","time","Date","now","sort","a","b","getEndToEndSessionProblem","timestamp","lastProblem","problem","filterOutNotifiedErrorDevices","devices","notifiedErrorDevices","ret","device","deviceInfo","safeSet","getEndToEndInboundGroupSession","senderCurve25519Key","k","inboundGroupSessions","inboundGroupSessionsWithheld","getAllEndToEndInboundGroupSessions","senderKey","slice","sessionData","addEndToEndInboundGroupSession","storeEndToEndInboundGroupSession","storeEndToEndInboundGroupSessionWithheld","getEndToEndDeviceData","deviceData","storeEndToEndDeviceData","storeEndToEndRoom","roomId","roomInfo","rooms","getEndToEndRooms","getSessionsNeedingBackup","limit","sessionsNeedingBackup","countSessionsNeedingBackup","unmarkSessionsNeedingBackup","sessionKey","markSessionsNeedingBackup","addSharedHistoryInboundGroupSession","sharedHistoryInboundGroupSessions","getSharedHistoryInboundGroupSessions","addParkedSharedHistory","parkedData","_this$parkedSharedHis","parked","parkedSharedHistory","takeParkedSharedHistory","_this$parkedSharedHis2","delete","doTxn","mode","stores","exports"],"sources":["../../../src/crypto/store/memory-crypto-store.ts"],"sourcesContent":["/*\nCopyright 2017 - 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { logger } from \"../../logger\";\nimport * as utils from \"../../utils\";\nimport {\n CryptoStore,\n IDeviceData,\n IProblem,\n ISession,\n ISessionInfo,\n IWithheld,\n Mode,\n OutgoingRoomKeyRequest,\n ParkedSharedHistory,\n SecretStorePrivateKeys,\n} from \"./base\";\nimport { IRoomKeyRequestBody } from \"../index\";\nimport { ICrossSigningKey } from \"../../client\";\nimport { IOlmDevice } from \"../algorithms/megolm\";\nimport { IRoomEncryption } from \"../RoomList\";\nimport { InboundGroupSessionData } from \"../OlmDevice\";\nimport { safeSet } from \"../../utils\";\n\n/**\n * Internal module. in-memory storage for e2e.\n */\n\nexport class MemoryCryptoStore implements CryptoStore {\n private outgoingRoomKeyRequests: OutgoingRoomKeyRequest[] = [];\n private account: string | null = null;\n private crossSigningKeys: Record<string, ICrossSigningKey> | null = null;\n private privateKeys: Partial<SecretStorePrivateKeys> = {};\n\n private sessions: { [deviceKey: string]: { [sessionId: string]: ISessionInfo } } = {};\n private sessionProblems: { [deviceKey: string]: IProblem[] } = {};\n private notifiedErrorDevices: { [userId: string]: { [deviceId: string]: boolean } } = {};\n private inboundGroupSessions: { [sessionKey: string]: InboundGroupSessionData } = {};\n private inboundGroupSessionsWithheld: Record<string, IWithheld> = {};\n // Opaque device data object\n private deviceData: IDeviceData | null = null;\n private rooms: { [roomId: string]: IRoomEncryption } = {};\n private sessionsNeedingBackup: { [sessionKey: string]: boolean } = {};\n private sharedHistoryInboundGroupSessions: { [roomId: string]: [senderKey: string, sessionId: string][] } = {};\n private parkedSharedHistory = new Map<string, ParkedSharedHistory[]>(); // keyed by room ID\n\n /**\n * Ensure the database exists and is up-to-date.\n *\n * This must be called before the store can be used.\n *\n * @returns resolves to the store.\n */\n public async startup(): Promise<CryptoStore> {\n // No startup work to do for the memory store.\n return this;\n }\n\n /**\n * Delete all data from this store.\n *\n * @returns Promise which resolves when the store has been cleared.\n */\n public deleteAllData(): Promise<void> {\n return Promise.resolve();\n }\n\n /**\n * Look for an existing outgoing room key request, and if none is found,\n * add a new one\n *\n *\n * @returns resolves to\n * {@link OutgoingRoomKeyRequest}: either the\n * same instance as passed in, or the existing one.\n */\n public getOrAddOutgoingRoomKeyRequest(request: OutgoingRoomKeyRequest): Promise<OutgoingRoomKeyRequest> {\n const requestBody = request.requestBody;\n\n return utils.promiseTry(() => {\n // first see if we already have an entry for this request.\n const existing = this._getOutgoingRoomKeyRequest(requestBody);\n\n if (existing) {\n // this entry matches the request - return it.\n logger.log(\n `already have key request outstanding for ` +\n `${requestBody.room_id} / ${requestBody.session_id}: ` +\n `not sending another`,\n );\n return existing;\n }\n\n // we got to the end of the list without finding a match\n // - add the new request.\n logger.log(`enqueueing key request for ${requestBody.room_id} / ` + requestBody.session_id);\n this.outgoingRoomKeyRequests.push(request);\n return request;\n });\n }\n\n /**\n * Look for an existing room key request\n *\n * @param requestBody - existing request to look for\n *\n * @returns resolves to the matching\n * {@link OutgoingRoomKeyRequest}, or null if\n * not found\n */\n public getOutgoingRoomKeyRequest(requestBody: IRoomKeyRequestBody): Promise<OutgoingRoomKeyRequest | null> {\n return Promise.resolve(this._getOutgoingRoomKeyRequest(requestBody));\n }\n\n /**\n * Looks for existing room key request, and returns the result synchronously.\n *\n * @internal\n *\n * @param requestBody - existing request to look for\n *\n * @returns\n * the matching request, or null if not found\n */\n // eslint-disable-next-line @typescript-eslint/naming-convention\n private _getOutgoingRoomKeyRequest(requestBody: IRoomKeyRequestBody): OutgoingRoomKeyRequest | null {\n for (const existing of this.outgoingRoomKeyRequests) {\n if (utils.deepCompare(existing.requestBody, requestBody)) {\n return existing;\n }\n }\n return null;\n }\n\n /**\n * Look for room key requests by state\n *\n * @param wantedStates - list of acceptable states\n *\n * @returns resolves to the a\n * {@link OutgoingRoomKeyRequest}, or null if\n * there are no pending requests in those states\n */\n public getOutgoingRoomKeyRequestByState(wantedStates: number[]): Promise<OutgoingRoomKeyRequest | null> {\n for (const req of this.outgoingRoomKeyRequests) {\n for (const state of wantedStates) {\n if (req.state === state) {\n return Promise.resolve(req);\n }\n }\n }\n return Promise.resolve(null);\n }\n\n /**\n *\n * @returns All OutgoingRoomKeyRequests in state\n */\n public getAllOutgoingRoomKeyRequestsByState(wantedState: number): Promise<OutgoingRoomKeyRequest[]> {\n return Promise.resolve(this.outgoingRoomKeyRequests.filter((r) => r.state == wantedState));\n }\n\n public getOutgoingRoomKeyRequestsByTarget(\n userId: string,\n deviceId: string,\n wantedStates: number[],\n ): Promise<OutgoingRoomKeyRequest[]> {\n const results: OutgoingRoomKeyRequest[] = [];\n\n for (const req of this.outgoingRoomKeyRequests) {\n for (const state of wantedStates) {\n if (\n req.state === state &&\n req.recipients.some((recipient) => recipient.userId === userId && recipient.deviceId === deviceId)\n ) {\n results.push(req);\n }\n }\n }\n return Promise.resolve(results);\n }\n\n /**\n * Look for an existing room key request by id and state, and update it if\n * found\n *\n * @param requestId - ID of request to update\n * @param expectedState - state we expect to find the request in\n * @param updates - name/value map of updates to apply\n *\n * @returns resolves to\n * {@link OutgoingRoomKeyRequest}\n * updated request, or null if no matching row was found\n */\n public updateOutgoingRoomKeyRequest(\n requestId: string,\n expectedState: number,\n updates: Partial<OutgoingRoomKeyRequest>,\n ): Promise<OutgoingRoomKeyRequest | null> {\n for (const req of this.outgoingRoomKeyRequests) {\n if (req.requestId !== requestId) {\n continue;\n }\n\n if (req.state !== expectedState) {\n logger.warn(\n `Cannot update room key request from ${expectedState} ` +\n `as it was already updated to ${req.state}`,\n );\n return Promise.resolve(null);\n }\n Object.assign(req, updates);\n return Promise.resolve(req);\n }\n\n return Promise.resolve(null);\n }\n\n /**\n * Look for an existing room key request by id and state, and delete it if\n * found\n *\n * @param requestId - ID of request to update\n * @param expectedState - state we expect to find the request in\n *\n * @returns resolves once the operation is completed\n */\n public deleteOutgoingRoomKeyRequest(\n requestId: string,\n expectedState: number,\n ): Promise<OutgoingRoomKeyRequest | null> {\n for (let i = 0; i < this.outgoingRoomKeyRequests.length; i++) {\n const req = this.outgoingRoomKeyRequests[i];\n\n if (req.requestId !== requestId) {\n continue;\n }\n\n if (req.state != expectedState) {\n logger.warn(`Cannot delete room key request in state ${req.state} ` + `(expected ${expectedState})`);\n return Promise.resolve(null);\n }\n\n this.outgoingRoomKeyRequests.splice(i, 1);\n return Promise.resolve(req);\n }\n\n return Promise.resolve(null);\n }\n\n // Olm Account\n\n public getAccount(txn: unknown, func: (accountPickle: string | null) => void): void {\n func(this.account);\n }\n\n public storeAccount(txn: unknown, accountPickle: string): void {\n this.account = accountPickle;\n }\n\n public getCrossSigningKeys(txn: unknown, func: (keys: Record<string, ICrossSigningKey> | null) => void): void {\n func(this.crossSigningKeys);\n }\n\n public getSecretStorePrivateKey<K extends keyof SecretStorePrivateKeys>(\n txn: unknown,\n func: (key: SecretStorePrivateKeys[K] | null) => void,\n type: K,\n ): void {\n const result = this.privateKeys[type] as SecretStorePrivateKeys[K] | undefined;\n func(result || null);\n }\n\n public storeCrossSigningKeys(txn: unknown, keys: Record<string, ICrossSigningKey>): void {\n this.crossSigningKeys = keys;\n }\n\n public storeSecretStorePrivateKey<K extends keyof SecretStorePrivateKeys>(\n txn: unknown,\n type: K,\n key: SecretStorePrivateKeys[K],\n ): void {\n this.privateKeys[type] = key;\n }\n\n // Olm Sessions\n\n public countEndToEndSessions(txn: unknown, func: (count: number) => void): void {\n func(Object.keys(this.sessions).length);\n }\n\n public getEndToEndSession(\n deviceKey: string,\n sessionId: string,\n txn: unknown,\n func: (session: ISessionInfo) => void,\n ): void {\n const deviceSessions = this.sessions[deviceKey] || {};\n func(deviceSessions[sessionId] || null);\n }\n\n public getEndToEndSessions(\n deviceKey: string,\n txn: unknown,\n func: (sessions: { [sessionId: string]: ISessionInfo }) => void,\n ): void {\n func(this.sessions[deviceKey] || {});\n }\n\n public getAllEndToEndSessions(txn: unknown, func: (session: ISessionInfo) => void): void {\n Object.entries(this.sessions).forEach(([deviceKey, deviceSessions]) => {\n Object.entries(deviceSessions).forEach(([sessionId, session]) => {\n func({\n ...session,\n deviceKey,\n sessionId,\n });\n });\n });\n }\n\n public storeEndToEndSession(deviceKey: string, sessionId: string, sessionInfo: ISessionInfo, txn: unknown): void {\n let deviceSessions = this.sessions[deviceKey];\n if (deviceSessions === undefined) {\n deviceSessions = {};\n this.sessions[deviceKey] = deviceSessions;\n }\n deviceSessions[sessionId] = sessionInfo;\n }\n\n public async storeEndToEndSessionProblem(deviceKey: string, type: string, fixed: boolean): Promise<void> {\n const problems = (this.sessionProblems[deviceKey] = this.sessionProblems[deviceKey] || []);\n problems.push({ type, fixed, time: Date.now() });\n problems.sort((a, b) => {\n return a.time - b.time;\n });\n }\n\n public async getEndToEndSessionProblem(deviceKey: string, timestamp: number): Promise<IProblem | null> {\n const problems = this.sessionProblems[deviceKey] || [];\n if (!problems.length) {\n return null;\n }\n const lastProblem = problems[problems.length - 1];\n for (const problem of problems) {\n if (problem.time > timestamp) {\n return Object.assign({}, problem, { fixed: lastProblem.fixed });\n }\n }\n if (lastProblem.fixed) {\n return null;\n } else {\n return lastProblem;\n }\n }\n\n public async filterOutNotifiedErrorDevices(devices: IOlmDevice[]): Promise<IOlmDevice[]> {\n const notifiedErrorDevices = this.notifiedErrorDevices;\n const ret: IOlmDevice[] = [];\n\n for (const device of devices) {\n const { userId, deviceInfo } = device;\n if (userId in notifiedErrorDevices) {\n if (!(deviceInfo.deviceId in notifiedErrorDevices[userId])) {\n ret.push(device);\n safeSet(notifiedErrorDevices[userId], deviceInfo.deviceId, true);\n }\n } else {\n ret.push(device);\n safeSet(notifiedErrorDevices, userId, { [deviceInfo.deviceId]: true });\n }\n }\n\n return ret;\n }\n\n // Inbound Group Sessions\n\n public getEndToEndInboundGroupSession(\n senderCurve25519Key: string,\n sessionId: string,\n txn: unknown,\n func: (groupSession: InboundGroupSessionData | null, groupSessionWithheld: IWithheld | null) => void,\n ): void {\n const k = senderCurve25519Key + \"/\" + sessionId;\n func(this.inboundGroupSessions[k] || null, this.inboundGroupSessionsWithheld[k] || null);\n }\n\n public getAllEndToEndInboundGroupSessions(txn: unknown, func: (session: ISession | null) => void): void {\n for (const key of Object.keys(this.inboundGroupSessions)) {\n // we can't use split, as the components we are trying to split out\n // might themselves contain '/' characters. We rely on the\n // senderKey being a (32-byte) curve25519 key, base64-encoded\n // (hence 43 characters long).\n\n func({\n senderKey: key.slice(0, 43),\n sessionId: key.slice(44),\n sessionData: this.inboundGroupSessions[key],\n });\n }\n func(null);\n }\n\n public addEndToEndInboundGroupSession(\n senderCurve25519Key: string,\n sessionId: string,\n sessionData: InboundGroupSessionData,\n txn: unknown,\n ): void {\n const k = senderCurve25519Key + \"/\" + sessionId;\n if (this.inboundGroupSessions[k] === undefined) {\n this.inboundGroupSessions[k] = sessionData;\n }\n }\n\n public storeEndToEndInboundGroupSession(\n senderCurve25519Key: string,\n sessionId: string,\n sessionData: InboundGroupSessionData,\n txn: unknown,\n ): void {\n this.inboundGroupSessions[senderCurve25519Key + \"/\" + sessionId] = sessionData;\n }\n\n public storeEndToEndInboundGroupSessionWithheld(\n senderCurve25519Key: string,\n sessionId: string,\n sessionData: IWithheld,\n txn: unknown,\n ): void {\n const k = senderCurve25519Key + \"/\" + sessionId;\n this.inboundGroupSessionsWithheld[k] = sessionData;\n }\n\n // Device Data\n\n public getEndToEndDeviceData(txn: unknown, func: (deviceData: IDeviceData | null) => void): void {\n func(this.deviceData);\n }\n\n public storeEndToEndDeviceData(deviceData: IDeviceData, txn: unknown): void {\n this.deviceData = deviceData;\n }\n\n // E2E rooms\n\n public storeEndToEndRoom(roomId: string, roomInfo: IRoomEncryption, txn: unknown): void {\n this.rooms[roomId] = roomInfo;\n }\n\n public getEndToEndRooms(txn: unknown, func: (rooms: Record<string, IRoomEncryption>) => void): void {\n func(this.rooms);\n }\n\n public getSessionsNeedingBackup(limit: number): Promise<ISession[]> {\n const sessions: ISession[] = [];\n for (const session in this.sessionsNeedingBackup) {\n if (this.inboundGroupSessions[session]) {\n sessions.push({\n senderKey: session.slice(0, 43),\n sessionId: session.slice(44),\n sessionData: this.inboundGroupSessions[session],\n });\n if (limit && session.length >= limit) {\n break;\n }\n }\n }\n return Promise.resolve(sessions);\n }\n\n public countSessionsNeedingBackup(): Promise<number> {\n return Promise.resolve(Object.keys(this.sessionsNeedingBackup).length);\n }\n\n public unmarkSessionsNeedingBackup(sessions: ISession[]): Promise<void> {\n for (const session of sessions) {\n const sessionKey = session.senderKey + \"/\" + session.sessionId;\n delete this.sessionsNeedingBackup[sessionKey];\n }\n return Promise.resolve();\n }\n\n public markSessionsNeedingBackup(sessions: ISession[]): Promise<void> {\n for (const session of sessions) {\n const sessionKey = session.senderKey + \"/\" + session.sessionId;\n this.sessionsNeedingBackup[sessionKey] = true;\n }\n return Promise.resolve();\n }\n\n public addSharedHistoryInboundGroupSession(roomId: string, senderKey: string, sessionId: string): void {\n const sessions = this.sharedHistoryInboundGroupSessions[roomId] || [];\n sessions.push([senderKey, sessionId]);\n this.sharedHistoryInboundGroupSessions[roomId] = sessions;\n }\n\n public getSharedHistoryInboundGroupSessions(roomId: string): Promise<[senderKey: string, sessionId: string][]> {\n return Promise.resolve(this.sharedHistoryInboundGroupSessions[roomId] || []);\n }\n\n public addParkedSharedHistory(roomId: string, parkedData: ParkedSharedHistory): void {\n const parked = this.parkedSharedHistory.get(roomId) ?? [];\n parked.push(parkedData);\n this.parkedSharedHistory.set(roomId, parked);\n }\n\n public takeParkedSharedHistory(roomId: string): Promise<ParkedSharedHistory[]> {\n const parked = this.parkedSharedHistory.get(roomId) ?? [];\n this.parkedSharedHistory.delete(roomId);\n return Promise.resolve(parked);\n }\n\n // Session key backups\n\n public doTxn<T>(mode: Mode, stores: Iterable<string>, func: (txn?: unknown) => T): Promise<T> {\n return Promise.resolve(func(null));\n }\n}\n"],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Base.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Base.d.ts
deleted file mode 100644
index 413728c..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Base.d.ts
+++ /dev/null
@@ -1,87 +0,0 @@
-/**
- * Base class for verification methods.
- */
-import { MatrixEvent } from "../../models/event";
-import { DeviceInfo } from "../deviceinfo";
-import { KeysDuringVerification } from "../CrossSigning";
-import { IVerificationChannel } from "./request/Channel";
-import { MatrixClient } from "../../client";
-import { VerificationRequest } from "./request/VerificationRequest";
-import { ListenerMap, TypedEventEmitter } from "../../models/typed-event-emitter";
-export declare class SwitchStartEventError extends Error {
- readonly startEvent: MatrixEvent | null;
- constructor(startEvent: MatrixEvent | null);
-}
-export type KeyVerifier = (keyId: string, device: DeviceInfo, keyInfo: string) => void;
-export declare enum VerificationEvent {
- Cancel = "cancel"
-}
-export type VerificationEventHandlerMap = {
- [VerificationEvent.Cancel]: (e: Error | MatrixEvent) => void;
-};
-export declare class VerificationBase<Events extends string, Arguments extends ListenerMap<Events | VerificationEvent>> extends TypedEventEmitter<Events | VerificationEvent, Arguments, VerificationEventHandlerMap> {
- readonly channel: IVerificationChannel;
- readonly baseApis: MatrixClient;
- readonly userId: string;
- readonly deviceId: string;
- startEvent: MatrixEvent | null;
- readonly request: VerificationRequest;
- private cancelled;
- private _done;
- private promise;
- private transactionTimeoutTimer;
- protected expectedEvent?: string;
- private resolve?;
- private reject?;
- private resolveEvent?;
- private rejectEvent?;
- private started?;
- /**
- * Base class for verification methods.
- *
- * <p>Once a verifier object is created, the verification can be started by
- * calling the verify() method, which will return a promise that will
- * resolve when the verification is completed, or reject if it could not
- * complete.</p>
- *
- * <p>Subclasses must have a NAME class property.</p>
- *
- * @param channel - the verification channel to send verification messages over.
- * TODO: Channel types
- *
- * @param baseApis - base matrix api interface
- *
- * @param userId - the user ID that is being verified
- *
- * @param deviceId - the device ID that is being verified
- *
- * @param startEvent - the m.key.verification.start event that
- * initiated this verification, if any
- *
- * @param request - the key verification request object related to
- * this verification, if any
- */
- constructor(channel: IVerificationChannel, baseApis: MatrixClient, userId: string, deviceId: string, startEvent: MatrixEvent | null, request: VerificationRequest);
- get initiatedByMe(): boolean;
- get hasBeenCancelled(): boolean;
- private resetTimer;
- private endTimer;
- protected send(type: string, uncompletedContent: Record<string, any>): Promise<void>;
- protected waitForEvent(type: string): Promise<MatrixEvent>;
- canSwitchStartEvent(event: MatrixEvent): boolean;
- switchStartEvent(event: MatrixEvent): void;
- handleEvent(e: MatrixEvent): void;
- done(): Promise<KeysDuringVerification | void>;
- cancel(e: Error | MatrixEvent): void;
- /**
- * Begin the key verification
- *
- * @returns Promise which resolves when the verification has
- * completed.
- */
- verify(): Promise<void>;
- protected doVerification?: () => Promise<void>;
- protected verifyKeys(userId: string, keys: Record<string, string>, verifier: KeyVerifier): Promise<void>;
- get events(): string[] | undefined;
-}
-//# sourceMappingURL=Base.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Base.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Base.d.ts.map
deleted file mode 100644
index 30d70f8..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Base.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"Base.d.ts","sourceRoot":"","sources":["../../../src/crypto/verification/Base.ts"],"names":[],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Base.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Base.js
deleted file mode 100644
index 31150dc..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Base.js
+++ /dev/null
@@ -1,347 +0,0 @@
-"use strict";
-
-var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.VerificationEvent = exports.VerificationBase = exports.SwitchStartEventError = void 0;
-var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
-var _event = require("../../models/event");
-var _event2 = require("../../@types/event");
-var _logger = require("../../logger");
-var _deviceinfo = require("../deviceinfo");
-var _Error = require("./Error");
-var _CrossSigning = require("../CrossSigning");
-var _typedEventEmitter = require("../../models/typed-event-emitter");
-/*
-Copyright 2018 New Vector Ltd
-Copyright 2020 The Matrix.org Foundation C.I.C.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-/**
- * Base class for verification methods.
- */
-
-const timeoutException = new Error("Verification timed out");
-class SwitchStartEventError extends Error {
- constructor(startEvent) {
- super();
- this.startEvent = startEvent;
- }
-}
-exports.SwitchStartEventError = SwitchStartEventError;
-let VerificationEvent;
-exports.VerificationEvent = VerificationEvent;
-(function (VerificationEvent) {
- VerificationEvent["Cancel"] = "cancel";
-})(VerificationEvent || (exports.VerificationEvent = VerificationEvent = {}));
-class VerificationBase extends _typedEventEmitter.TypedEventEmitter {
- /**
- * Base class for verification methods.
- *
- * <p>Once a verifier object is created, the verification can be started by
- * calling the verify() method, which will return a promise that will
- * resolve when the verification is completed, or reject if it could not
- * complete.</p>
- *
- * <p>Subclasses must have a NAME class property.</p>
- *
- * @param channel - the verification channel to send verification messages over.
- * TODO: Channel types
- *
- * @param baseApis - base matrix api interface
- *
- * @param userId - the user ID that is being verified
- *
- * @param deviceId - the device ID that is being verified
- *
- * @param startEvent - the m.key.verification.start event that
- * initiated this verification, if any
- *
- * @param request - the key verification request object related to
- * this verification, if any
- */
- constructor(channel, baseApis, userId, deviceId, startEvent, request) {
- super();
- this.channel = channel;
- this.baseApis = baseApis;
- this.userId = userId;
- this.deviceId = deviceId;
- this.startEvent = startEvent;
- this.request = request;
- (0, _defineProperty2.default)(this, "cancelled", false);
- (0, _defineProperty2.default)(this, "_done", false);
- (0, _defineProperty2.default)(this, "promise", null);
- (0, _defineProperty2.default)(this, "transactionTimeoutTimer", null);
- (0, _defineProperty2.default)(this, "expectedEvent", void 0);
- (0, _defineProperty2.default)(this, "resolve", void 0);
- (0, _defineProperty2.default)(this, "reject", void 0);
- (0, _defineProperty2.default)(this, "resolveEvent", void 0);
- (0, _defineProperty2.default)(this, "rejectEvent", void 0);
- (0, _defineProperty2.default)(this, "started", void 0);
- (0, _defineProperty2.default)(this, "doVerification", void 0);
- }
- get initiatedByMe() {
- // if there is no start event yet,
- // we probably want to send it,
- // which happens if we initiate
- if (!this.startEvent) {
- return true;
- }
- const sender = this.startEvent.getSender();
- const content = this.startEvent.getContent();
- return sender === this.baseApis.getUserId() && content.from_device === this.baseApis.getDeviceId();
- }
- get hasBeenCancelled() {
- return this.cancelled;
- }
- resetTimer() {
- _logger.logger.info("Refreshing/starting the verification transaction timeout timer");
- if (this.transactionTimeoutTimer !== null) {
- clearTimeout(this.transactionTimeoutTimer);
- }
- this.transactionTimeoutTimer = setTimeout(() => {
- if (!this._done && !this.cancelled) {
- _logger.logger.info("Triggering verification timeout");
- this.cancel(timeoutException);
- }
- }, 10 * 60 * 1000); // 10 minutes
- }
-
- endTimer() {
- if (this.transactionTimeoutTimer !== null) {
- clearTimeout(this.transactionTimeoutTimer);
- this.transactionTimeoutTimer = null;
- }
- }
- send(type, uncompletedContent) {
- return this.channel.send(type, uncompletedContent);
- }
- waitForEvent(type) {
- if (this._done) {
- return Promise.reject(new Error("Verification is already done"));
- }
- const existingEvent = this.request.getEventFromOtherParty(type);
- if (existingEvent) {
- return Promise.resolve(existingEvent);
- }
- this.expectedEvent = type;
- return new Promise((resolve, reject) => {
- this.resolveEvent = resolve;
- this.rejectEvent = reject;
- });
- }
- canSwitchStartEvent(event) {
- return false;
- }
- switchStartEvent(event) {
- if (this.canSwitchStartEvent(event)) {
- _logger.logger.log("Verification Base: switching verification start event", {
- restartingFlow: !!this.rejectEvent
- });
- if (this.rejectEvent) {
- const reject = this.rejectEvent;
- this.rejectEvent = undefined;
- reject(new SwitchStartEventError(event));
- } else {
- this.startEvent = event;
- }
- }
- }
- handleEvent(e) {
- if (this._done) {
- return;
- } else if (e.getType() === this.expectedEvent) {
- // if we receive an expected m.key.verification.done, then just
- // ignore it, since we don't need to do anything about it
- if (this.expectedEvent !== _event2.EventType.KeyVerificationDone) {
- var _this$resolveEvent;
- this.expectedEvent = undefined;
- this.rejectEvent = undefined;
- this.resetTimer();
- (_this$resolveEvent = this.resolveEvent) === null || _this$resolveEvent === void 0 ? void 0 : _this$resolveEvent.call(this, e);
- }
- } else if (e.getType() === _event2.EventType.KeyVerificationCancel) {
- const reject = this.reject;
- this.reject = undefined;
- // there is only promise to reject if verify has been called
- if (reject) {
- const content = e.getContent();
- const {
- reason,
- code
- } = content;
- reject(new Error(`Other side cancelled verification ` + `because ${reason} (${code})`));
- }
- } else if (this.expectedEvent) {
- // only cancel if there is an event expected.
- // if there is no event expected, it means verify() wasn't called
- // and we're just replaying the timeline events when syncing
- // after a refresh when the events haven't been stored in the cache yet.
- const exception = new Error("Unexpected message: expecting " + this.expectedEvent + " but got " + e.getType());
- this.expectedEvent = undefined;
- if (this.rejectEvent) {
- const reject = this.rejectEvent;
- this.rejectEvent = undefined;
- reject(exception);
- }
- this.cancel(exception);
- }
- }
- async done() {
- this.endTimer(); // always kill the activity timer
- if (!this._done) {
- var _this$resolve;
- this.request.onVerifierFinished();
- (_this$resolve = this.resolve) === null || _this$resolve === void 0 ? void 0 : _this$resolve.call(this);
- return (0, _CrossSigning.requestKeysDuringVerification)(this.baseApis, this.userId, this.deviceId);
- }
- }
- cancel(e) {
- this.endTimer(); // always kill the activity timer
- if (!this._done) {
- this.cancelled = true;
- this.request.onVerifierCancelled();
- if (this.userId && this.deviceId) {
- // send a cancellation to the other user (if it wasn't
- // cancelled by the other user)
- if (e === timeoutException) {
- const timeoutEvent = (0, _Error.newTimeoutError)();
- this.send(timeoutEvent.getType(), timeoutEvent.getContent());
- } else if (e instanceof _event.MatrixEvent) {
- const sender = e.getSender();
- if (sender !== this.userId) {
- const content = e.getContent();
- if (e.getType() === _event2.EventType.KeyVerificationCancel) {
- content.code = content.code || "m.unknown";
- content.reason = content.reason || content.body || "Unknown reason";
- this.send(_event2.EventType.KeyVerificationCancel, content);
- } else {
- this.send(_event2.EventType.KeyVerificationCancel, {
- code: "m.unknown",
- reason: content.body || "Unknown reason"
- });
- }
- }
- } else {
- this.send(_event2.EventType.KeyVerificationCancel, {
- code: "m.unknown",
- reason: e.toString()
- });
- }
- }
- if (this.promise !== null) {
- // when we cancel without a promise, we end up with a promise
- // but no reject function. If cancel is called again, we'd error.
- if (this.reject) this.reject(e);
- } else {
- // FIXME: this causes an "Uncaught promise" console message
- // if nothing ends up chaining this promise.
- this.promise = Promise.reject(e);
- }
- // Also emit a 'cancel' event that the app can listen for to detect cancellation
- // before calling verify()
- this.emit(VerificationEvent.Cancel, e);
- }
- }
-
- /**
- * Begin the key verification
- *
- * @returns Promise which resolves when the verification has
- * completed.
- */
- verify() {
- if (this.promise) return this.promise;
- this.promise = new Promise((resolve, reject) => {
- this.resolve = (...args) => {
- this._done = true;
- this.endTimer();
- resolve(...args);
- };
- this.reject = e => {
- this._done = true;
- this.endTimer();
- reject(e);
- };
- });
- if (this.doVerification && !this.started) {
- this.started = true;
- this.resetTimer(); // restart the timeout
- new Promise((resolve, reject) => {
- var _deviceList$getStored;
- const crossSignId = (_deviceList$getStored = this.baseApis.crypto.deviceList.getStoredCrossSigningForUser(this.userId)) === null || _deviceList$getStored === void 0 ? void 0 : _deviceList$getStored.getId();
- if (crossSignId === this.deviceId) {
- reject(new Error("Device ID is the same as the cross-signing ID"));
- }
- resolve();
- }).then(() => this.doVerification()).then(this.done.bind(this), this.cancel.bind(this));
- }
- return this.promise;
- }
- async verifyKeys(userId, keys, verifier) {
- // we try to verify all the keys that we're told about, but we might
- // not know about all of them, so keep track of the keys that we know
- // about, and ignore the rest
- const verifiedDevices = [];
- for (const [keyId, keyInfo] of Object.entries(keys)) {
- const deviceId = keyId.split(":", 2)[1];
- const device = this.baseApis.getStoredDevice(userId, deviceId);
- if (device) {
- verifier(keyId, device, keyInfo);
- verifiedDevices.push([deviceId, keyId, device.keys[keyId]]);
- } else {
- const crossSigningInfo = this.baseApis.crypto.deviceList.getStoredCrossSigningForUser(userId);
- if (crossSigningInfo && crossSigningInfo.getId() === deviceId) {
- verifier(keyId, _deviceinfo.DeviceInfo.fromStorage({
- keys: {
- [keyId]: deviceId
- }
- }, deviceId), keyInfo);
- verifiedDevices.push([deviceId, keyId, deviceId]);
- } else {
- _logger.logger.warn(`verification: Could not find device ${deviceId} to verify`);
- }
- }
- }
-
- // if none of the keys could be verified, then error because the app
- // should be informed about that
- if (!verifiedDevices.length) {
- throw new Error("No devices could be verified");
- }
- _logger.logger.info("Verification completed! Marking devices verified: ", verifiedDevices);
- // TODO: There should probably be a batch version of this, otherwise it's going
- // to upload each signature in a separate API call which is silly because the
- // API supports as many signatures as you like.
- for (const [deviceId, keyId, key] of verifiedDevices) {
- await this.baseApis.crypto.setDeviceVerification(userId, deviceId, true, null, null, {
- [keyId]: key
- });
- }
-
- // if one of the user's own devices is being marked as verified / unverified,
- // check the key backup status, since whether or not we use this depends on
- // whether it has a signature from a verified device
- if (userId == this.baseApis.credentials.userId) {
- await this.baseApis.checkKeyBackup();
- }
- }
- get events() {
- return undefined;
- }
-}
-exports.VerificationBase = VerificationBase;
-//# sourceMappingURL=Base.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Base.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Base.js.map
deleted file mode 100644
index 058d197..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Base.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"Base.js","names":["_event","require","_event2","_logger","_deviceinfo","_Error","_CrossSigning","_typedEventEmitter","timeoutException","Error","SwitchStartEventError","constructor","startEvent","exports","VerificationEvent","VerificationBase","TypedEventEmitter","channel","baseApis","userId","deviceId","request","_defineProperty2","default","initiatedByMe","sender","getSender","content","getContent","getUserId","from_device","getDeviceId","hasBeenCancelled","cancelled","resetTimer","logger","info","transactionTimeoutTimer","clearTimeout","setTimeout","_done","cancel","endTimer","send","type","uncompletedContent","waitForEvent","Promise","reject","existingEvent","getEventFromOtherParty","resolve","expectedEvent","resolveEvent","rejectEvent","canSwitchStartEvent","event","switchStartEvent","log","restartingFlow","undefined","handleEvent","e","getType","EventType","KeyVerificationDone","_this$resolveEvent","call","KeyVerificationCancel","reason","code","exception","done","_this$resolve","onVerifierFinished","requestKeysDuringVerification","onVerifierCancelled","timeoutEvent","newTimeoutError","MatrixEvent","body","toString","promise","emit","Cancel","verify","args","doVerification","started","_deviceList$getStored","crossSignId","crypto","deviceList","getStoredCrossSigningForUser","getId","then","bind","verifyKeys","keys","verifier","verifiedDevices","keyId","keyInfo","Object","entries","split","device","getStoredDevice","push","crossSigningInfo","DeviceInfo","fromStorage","warn","length","key","setDeviceVerification","credentials","checkKeyBackup","events"],"sources":["../../../src/crypto/verification/Base.ts"],"sourcesContent":["/*\nCopyright 2018 New Vector Ltd\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n/**\n * Base class for verification methods.\n */\n\nimport { MatrixEvent } from \"../../models/event\";\nimport { EventType } from \"../../@types/event\";\nimport { logger } from \"../../logger\";\nimport { DeviceInfo } from \"../deviceinfo\";\nimport { newTimeoutError } from \"./Error\";\nimport { KeysDuringVerification, requestKeysDuringVerification } from \"../CrossSigning\";\nimport { IVerificationChannel } from \"./request/Channel\";\nimport { MatrixClient } from \"../../client\";\nimport { VerificationRequest } from \"./request/VerificationRequest\";\nimport { ListenerMap, TypedEventEmitter } from \"../../models/typed-event-emitter\";\n\nconst timeoutException = new Error(\"Verification timed out\");\n\nexport class SwitchStartEventError extends Error {\n public constructor(public readonly startEvent: MatrixEvent | null) {\n super();\n }\n}\n\nexport type KeyVerifier = (keyId: string, device: DeviceInfo, keyInfo: string) => void;\n\nexport enum VerificationEvent {\n Cancel = \"cancel\",\n}\n\nexport type VerificationEventHandlerMap = {\n [VerificationEvent.Cancel]: (e: Error | MatrixEvent) => void;\n};\n\nexport class VerificationBase<\n Events extends string,\n Arguments extends ListenerMap<Events | VerificationEvent>,\n> extends TypedEventEmitter<Events | VerificationEvent, Arguments, VerificationEventHandlerMap> {\n private cancelled = false;\n private _done = false;\n private promise: Promise<void> | null = null;\n private transactionTimeoutTimer: ReturnType<typeof setTimeout> | null = null;\n protected expectedEvent?: string;\n private resolve?: () => void;\n private reject?: (e: Error | MatrixEvent) => void;\n private resolveEvent?: (e: MatrixEvent) => void;\n private rejectEvent?: (e: Error) => void;\n private started?: boolean;\n\n /**\n * Base class for verification methods.\n *\n * <p>Once a verifier object is created, the verification can be started by\n * calling the verify() method, which will return a promise that will\n * resolve when the verification is completed, or reject if it could not\n * complete.</p>\n *\n * <p>Subclasses must have a NAME class property.</p>\n *\n * @param channel - the verification channel to send verification messages over.\n * TODO: Channel types\n *\n * @param baseApis - base matrix api interface\n *\n * @param userId - the user ID that is being verified\n *\n * @param deviceId - the device ID that is being verified\n *\n * @param startEvent - the m.key.verification.start event that\n * initiated this verification, if any\n *\n * @param request - the key verification request object related to\n * this verification, if any\n */\n public constructor(\n public readonly channel: IVerificationChannel,\n public readonly baseApis: MatrixClient,\n public readonly userId: string,\n public readonly deviceId: string,\n public startEvent: MatrixEvent | null,\n public readonly request: VerificationRequest,\n ) {\n super();\n }\n\n public get initiatedByMe(): boolean {\n // if there is no start event yet,\n // we probably want to send it,\n // which happens if we initiate\n if (!this.startEvent) {\n return true;\n }\n const sender = this.startEvent.getSender();\n const content = this.startEvent.getContent();\n return sender === this.baseApis.getUserId() && content.from_device === this.baseApis.getDeviceId();\n }\n\n public get hasBeenCancelled(): boolean {\n return this.cancelled;\n }\n\n private resetTimer(): void {\n logger.info(\"Refreshing/starting the verification transaction timeout timer\");\n if (this.transactionTimeoutTimer !== null) {\n clearTimeout(this.transactionTimeoutTimer);\n }\n this.transactionTimeoutTimer = setTimeout(() => {\n if (!this._done && !this.cancelled) {\n logger.info(\"Triggering verification timeout\");\n this.cancel(timeoutException);\n }\n }, 10 * 60 * 1000); // 10 minutes\n }\n\n private endTimer(): void {\n if (this.transactionTimeoutTimer !== null) {\n clearTimeout(this.transactionTimeoutTimer);\n this.transactionTimeoutTimer = null;\n }\n }\n\n protected send(type: string, uncompletedContent: Record<string, any>): Promise<void> {\n return this.channel.send(type, uncompletedContent);\n }\n\n protected waitForEvent(type: string): Promise<MatrixEvent> {\n if (this._done) {\n return Promise.reject(new Error(\"Verification is already done\"));\n }\n const existingEvent = this.request.getEventFromOtherParty(type);\n if (existingEvent) {\n return Promise.resolve(existingEvent);\n }\n\n this.expectedEvent = type;\n return new Promise((resolve, reject) => {\n this.resolveEvent = resolve;\n this.rejectEvent = reject;\n });\n }\n\n public canSwitchStartEvent(event: MatrixEvent): boolean {\n return false;\n }\n\n public switchStartEvent(event: MatrixEvent): void {\n if (this.canSwitchStartEvent(event)) {\n logger.log(\"Verification Base: switching verification start event\", { restartingFlow: !!this.rejectEvent });\n if (this.rejectEvent) {\n const reject = this.rejectEvent;\n this.rejectEvent = undefined;\n reject(new SwitchStartEventError(event));\n } else {\n this.startEvent = event;\n }\n }\n }\n\n public handleEvent(e: MatrixEvent): void {\n if (this._done) {\n return;\n } else if (e.getType() === this.expectedEvent) {\n // if we receive an expected m.key.verification.done, then just\n // ignore it, since we don't need to do anything about it\n if (this.expectedEvent !== EventType.KeyVerificationDone) {\n this.expectedEvent = undefined;\n this.rejectEvent = undefined;\n this.resetTimer();\n this.resolveEvent?.(e);\n }\n } else if (e.getType() === EventType.KeyVerificationCancel) {\n const reject = this.reject;\n this.reject = undefined;\n // there is only promise to reject if verify has been called\n if (reject) {\n const content = e.getContent();\n const { reason, code } = content;\n reject(new Error(`Other side cancelled verification ` + `because ${reason} (${code})`));\n }\n } else if (this.expectedEvent) {\n // only cancel if there is an event expected.\n // if there is no event expected, it means verify() wasn't called\n // and we're just replaying the timeline events when syncing\n // after a refresh when the events haven't been stored in the cache yet.\n const exception = new Error(\n \"Unexpected message: expecting \" + this.expectedEvent + \" but got \" + e.getType(),\n );\n this.expectedEvent = undefined;\n if (this.rejectEvent) {\n const reject = this.rejectEvent;\n this.rejectEvent = undefined;\n reject(exception);\n }\n this.cancel(exception);\n }\n }\n\n public async done(): Promise<KeysDuringVerification | void> {\n this.endTimer(); // always kill the activity timer\n if (!this._done) {\n this.request.onVerifierFinished();\n this.resolve?.();\n return requestKeysDuringVerification(this.baseApis, this.userId, this.deviceId);\n }\n }\n\n public cancel(e: Error | MatrixEvent): void {\n this.endTimer(); // always kill the activity timer\n if (!this._done) {\n this.cancelled = true;\n this.request.onVerifierCancelled();\n if (this.userId && this.deviceId) {\n // send a cancellation to the other user (if it wasn't\n // cancelled by the other user)\n if (e === timeoutException) {\n const timeoutEvent = newTimeoutError();\n this.send(timeoutEvent.getType(), timeoutEvent.getContent());\n } else if (e instanceof MatrixEvent) {\n const sender = e.getSender();\n if (sender !== this.userId) {\n const content = e.getContent();\n if (e.getType() === EventType.KeyVerificationCancel) {\n content.code = content.code || \"m.unknown\";\n content.reason = content.reason || content.body || \"Unknown reason\";\n this.send(EventType.KeyVerificationCancel, content);\n } else {\n this.send(EventType.KeyVerificationCancel, {\n code: \"m.unknown\",\n reason: content.body || \"Unknown reason\",\n });\n }\n }\n } else {\n this.send(EventType.KeyVerificationCancel, {\n code: \"m.unknown\",\n reason: e.toString(),\n });\n }\n }\n if (this.promise !== null) {\n // when we cancel without a promise, we end up with a promise\n // but no reject function. If cancel is called again, we'd error.\n if (this.reject) this.reject(e);\n } else {\n // FIXME: this causes an \"Uncaught promise\" console message\n // if nothing ends up chaining this promise.\n this.promise = Promise.reject(e);\n }\n // Also emit a 'cancel' event that the app can listen for to detect cancellation\n // before calling verify()\n this.emit(VerificationEvent.Cancel, e);\n }\n }\n\n /**\n * Begin the key verification\n *\n * @returns Promise which resolves when the verification has\n * completed.\n */\n public verify(): Promise<void> {\n if (this.promise) return this.promise;\n\n this.promise = new Promise((resolve, reject) => {\n this.resolve = (...args): void => {\n this._done = true;\n this.endTimer();\n resolve(...args);\n };\n this.reject = (e: Error | MatrixEvent): void => {\n this._done = true;\n this.endTimer();\n reject(e);\n };\n });\n if (this.doVerification && !this.started) {\n this.started = true;\n this.resetTimer(); // restart the timeout\n new Promise<void>((resolve, reject) => {\n const crossSignId = this.baseApis.crypto!.deviceList.getStoredCrossSigningForUser(this.userId)?.getId();\n if (crossSignId === this.deviceId) {\n reject(new Error(\"Device ID is the same as the cross-signing ID\"));\n }\n resolve();\n })\n .then(() => this.doVerification!())\n .then(this.done.bind(this), this.cancel.bind(this));\n }\n return this.promise;\n }\n\n protected doVerification?: () => Promise<void>;\n\n protected async verifyKeys(userId: string, keys: Record<string, string>, verifier: KeyVerifier): Promise<void> {\n // we try to verify all the keys that we're told about, but we might\n // not know about all of them, so keep track of the keys that we know\n // about, and ignore the rest\n const verifiedDevices: [string, string, string][] = [];\n\n for (const [keyId, keyInfo] of Object.entries(keys)) {\n const deviceId = keyId.split(\":\", 2)[1];\n const device = this.baseApis.getStoredDevice(userId, deviceId);\n if (device) {\n verifier(keyId, device, keyInfo);\n verifiedDevices.push([deviceId, keyId, device.keys[keyId]]);\n } else {\n const crossSigningInfo = this.baseApis.crypto!.deviceList.getStoredCrossSigningForUser(userId);\n if (crossSigningInfo && crossSigningInfo.getId() === deviceId) {\n verifier(\n keyId,\n DeviceInfo.fromStorage(\n {\n keys: {\n [keyId]: deviceId,\n },\n },\n deviceId,\n ),\n keyInfo,\n );\n verifiedDevices.push([deviceId, keyId, deviceId]);\n } else {\n logger.warn(`verification: Could not find device ${deviceId} to verify`);\n }\n }\n }\n\n // if none of the keys could be verified, then error because the app\n // should be informed about that\n if (!verifiedDevices.length) {\n throw new Error(\"No devices could be verified\");\n }\n\n logger.info(\"Verification completed! Marking devices verified: \", verifiedDevices);\n // TODO: There should probably be a batch version of this, otherwise it's going\n // to upload each signature in a separate API call which is silly because the\n // API supports as many signatures as you like.\n for (const [deviceId, keyId, key] of verifiedDevices) {\n await this.baseApis.crypto!.setDeviceVerification(userId, deviceId, true, null, null, { [keyId]: key });\n }\n\n // if one of the user's own devices is being marked as verified / unverified,\n // check the key backup status, since whether or not we use this depends on\n // whether it has a signature from a verified device\n if (userId == this.baseApis.credentials.userId) {\n await this.baseApis.checkKeyBackup();\n }\n }\n\n public get events(): string[] | undefined {\n return undefined;\n }\n}\n"],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Error.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Error.d.ts
deleted file mode 100644
index b8fac30..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Error.d.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * Error messages.
- */
-import { MatrixEvent } from "../../models/event";
-export declare function newVerificationError(code: string, reason: string, extraData?: Record<string, any>): MatrixEvent;
-export declare function errorFactory(code: string, reason: string): (extraData?: Record<string, any>) => MatrixEvent;
-/**
- * The verification was cancelled by the user.
- */
-export declare const newUserCancelledError: (extraData?: Record<string, any>) => MatrixEvent;
-/**
- * The verification timed out.
- */
-export declare const newTimeoutError: (extraData?: Record<string, any>) => MatrixEvent;
-/**
- * An unknown method was selected.
- */
-export declare const newUnknownMethodError: (extraData?: Record<string, any>) => MatrixEvent;
-/**
- * An unexpected message was sent.
- */
-export declare const newUnexpectedMessageError: (extraData?: Record<string, any>) => MatrixEvent;
-/**
- * The key does not match.
- */
-export declare const newKeyMismatchError: (extraData?: Record<string, any>) => MatrixEvent;
-/**
- * An invalid message was sent.
- */
-export declare const newInvalidMessageError: (extraData?: Record<string, any>) => MatrixEvent;
-export declare function errorFromEvent(event: MatrixEvent): {
- code: string;
- reason: string;
-};
-//# sourceMappingURL=Error.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Error.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Error.d.ts.map
deleted file mode 100644
index 63a87b1..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Error.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"Error.d.ts","sourceRoot":"","sources":["../../../src/crypto/verification/Error.ts"],"names":[],"mappings":"AAgBA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGjD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,WAAW,CAM/G;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,WAAW,CAI3G;AAED;;GAEG;AACH,eAAO,MAAM,qBAAqB,eATuC,OAAO,MAAM,EAAE,GAAG,CAAC,KAAK,WASjB,CAAC;AAEjF;;GAEG;AACH,eAAO,MAAM,eAAe,eAd6C,OAAO,MAAM,EAAE,GAAG,CAAC,KAAK,WAc5B,CAAC;AAEtE;;GAEG;AACH,eAAO,MAAM,qBAAqB,eAnBuC,OAAO,MAAM,EAAE,GAAG,CAAC,KAAK,WAmBV,CAAC;AAExF;;GAEG;AACH,eAAO,MAAM,yBAAyB,eAxBmC,OAAO,MAAM,EAAE,GAAG,CAAC,KAAK,WAwBE,CAAC;AAEpG;;GAEG;AACH,eAAO,MAAM,mBAAmB,eA7ByC,OAAO,MAAM,EAAE,GAAG,CAAC,KAAK,WA6BhB,CAAC;AAElF;;GAEG;AACH,eAAO,MAAM,sBAAsB,eAlCsC,OAAO,MAAM,EAAE,GAAG,CAAC,KAAK,WAkCP,CAAC;AAE3F,wBAAgB,cAAc,CAAC,KAAK,EAAE,WAAW,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAQnF"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Error.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Error.js
deleted file mode 100644
index 3b4c690..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Error.js
+++ /dev/null
@@ -1,101 +0,0 @@
-"use strict";
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.errorFactory = errorFactory;
-exports.errorFromEvent = errorFromEvent;
-exports.newUserCancelledError = exports.newUnknownMethodError = exports.newUnexpectedMessageError = exports.newTimeoutError = exports.newKeyMismatchError = exports.newInvalidMessageError = void 0;
-exports.newVerificationError = newVerificationError;
-var _event = require("../../models/event");
-var _event2 = require("../../@types/event");
-/*
-Copyright 2018 - 2021 The Matrix.org Foundation C.I.C.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-/**
- * Error messages.
- */
-
-function newVerificationError(code, reason, extraData) {
- const content = Object.assign({}, {
- code,
- reason
- }, extraData);
- return new _event.MatrixEvent({
- type: _event2.EventType.KeyVerificationCancel,
- content
- });
-}
-function errorFactory(code, reason) {
- return function (extraData) {
- return newVerificationError(code, reason, extraData);
- };
-}
-
-/**
- * The verification was cancelled by the user.
- */
-const newUserCancelledError = errorFactory("m.user", "Cancelled by user");
-
-/**
- * The verification timed out.
- */
-exports.newUserCancelledError = newUserCancelledError;
-const newTimeoutError = errorFactory("m.timeout", "Timed out");
-
-/**
- * An unknown method was selected.
- */
-exports.newTimeoutError = newTimeoutError;
-const newUnknownMethodError = errorFactory("m.unknown_method", "Unknown method");
-
-/**
- * An unexpected message was sent.
- */
-exports.newUnknownMethodError = newUnknownMethodError;
-const newUnexpectedMessageError = errorFactory("m.unexpected_message", "Unexpected message");
-
-/**
- * The key does not match.
- */
-exports.newUnexpectedMessageError = newUnexpectedMessageError;
-const newKeyMismatchError = errorFactory("m.key_mismatch", "Key mismatch");
-
-/**
- * An invalid message was sent.
- */
-exports.newKeyMismatchError = newKeyMismatchError;
-const newInvalidMessageError = errorFactory("m.invalid_message", "Invalid message");
-exports.newInvalidMessageError = newInvalidMessageError;
-function errorFromEvent(event) {
- const content = event.getContent();
- if (content) {
- const {
- code,
- reason
- } = content;
- return {
- code,
- reason
- };
- } else {
- return {
- code: "Unknown error",
- reason: "m.unknown"
- };
- }
-}
-//# sourceMappingURL=Error.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Error.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Error.js.map
deleted file mode 100644
index 955658f..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Error.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"Error.js","names":["_event","require","_event2","newVerificationError","code","reason","extraData","content","Object","assign","MatrixEvent","type","EventType","KeyVerificationCancel","errorFactory","newUserCancelledError","exports","newTimeoutError","newUnknownMethodError","newUnexpectedMessageError","newKeyMismatchError","newInvalidMessageError","errorFromEvent","event","getContent"],"sources":["../../../src/crypto/verification/Error.ts"],"sourcesContent":["/*\nCopyright 2018 - 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n/**\n * Error messages.\n */\n\nimport { MatrixEvent } from \"../../models/event\";\nimport { EventType } from \"../../@types/event\";\n\nexport function newVerificationError(code: string, reason: string, extraData?: Record<string, any>): MatrixEvent {\n const content = Object.assign({}, { code, reason }, extraData);\n return new MatrixEvent({\n type: EventType.KeyVerificationCancel,\n content,\n });\n}\n\nexport function errorFactory(code: string, reason: string): (extraData?: Record<string, any>) => MatrixEvent {\n return function (extraData?: Record<string, any>) {\n return newVerificationError(code, reason, extraData);\n };\n}\n\n/**\n * The verification was cancelled by the user.\n */\nexport const newUserCancelledError = errorFactory(\"m.user\", \"Cancelled by user\");\n\n/**\n * The verification timed out.\n */\nexport const newTimeoutError = errorFactory(\"m.timeout\", \"Timed out\");\n\n/**\n * An unknown method was selected.\n */\nexport const newUnknownMethodError = errorFactory(\"m.unknown_method\", \"Unknown method\");\n\n/**\n * An unexpected message was sent.\n */\nexport const newUnexpectedMessageError = errorFactory(\"m.unexpected_message\", \"Unexpected message\");\n\n/**\n * The key does not match.\n */\nexport const newKeyMismatchError = errorFactory(\"m.key_mismatch\", \"Key mismatch\");\n\n/**\n * An invalid message was sent.\n */\nexport const newInvalidMessageError = errorFactory(\"m.invalid_message\", \"Invalid message\");\n\nexport function errorFromEvent(event: MatrixEvent): { code: string; reason: string } {\n const content = event.getContent();\n if (content) {\n const { code, reason } = content;\n return { code, reason };\n } else {\n return { code: \"Unknown error\", reason: \"m.unknown\" };\n }\n}\n"],"mappings":";;;;;;;;;AAoBA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,OAAA,GAAAD,OAAA;AArBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAKO,SAASE,oBAAoBA,CAACC,IAAY,EAAEC,MAAc,EAAEC,SAA+B,EAAe;EAC7G,MAAMC,OAAO,GAAGC,MAAM,CAACC,MAAM,CAAC,CAAC,CAAC,EAAE;IAAEL,IAAI;IAAEC;EAAO,CAAC,EAAEC,SAAS,CAAC;EAC9D,OAAO,IAAII,kBAAW,CAAC;IACnBC,IAAI,EAAEC,iBAAS,CAACC,qBAAqB;IACrCN;EACJ,CAAC,CAAC;AACN;AAEO,SAASO,YAAYA,CAACV,IAAY,EAAEC,MAAc,EAAoD;EACzG,OAAO,UAAUC,SAA+B,EAAE;IAC9C,OAAOH,oBAAoB,CAACC,IAAI,EAAEC,MAAM,EAAEC,SAAS,CAAC;EACxD,CAAC;AACL;;AAEA;AACA;AACA;AACO,MAAMS,qBAAqB,GAAGD,YAAY,CAAC,QAAQ,EAAE,mBAAmB,CAAC;;AAEhF;AACA;AACA;AAFAE,OAAA,CAAAD,qBAAA,GAAAA,qBAAA;AAGO,MAAME,eAAe,GAAGH,YAAY,CAAC,WAAW,EAAE,WAAW,CAAC;;AAErE;AACA;AACA;AAFAE,OAAA,CAAAC,eAAA,GAAAA,eAAA;AAGO,MAAMC,qBAAqB,GAAGJ,YAAY,CAAC,kBAAkB,EAAE,gBAAgB,CAAC;;AAEvF;AACA;AACA;AAFAE,OAAA,CAAAE,qBAAA,GAAAA,qBAAA;AAGO,MAAMC,yBAAyB,GAAGL,YAAY,CAAC,sBAAsB,EAAE,oBAAoB,CAAC;;AAEnG;AACA;AACA;AAFAE,OAAA,CAAAG,yBAAA,GAAAA,yBAAA;AAGO,MAAMC,mBAAmB,GAAGN,YAAY,CAAC,gBAAgB,EAAE,cAAc,CAAC;;AAEjF;AACA;AACA;AAFAE,OAAA,CAAAI,mBAAA,GAAAA,mBAAA;AAGO,MAAMC,sBAAsB,GAAGP,YAAY,CAAC,mBAAmB,EAAE,iBAAiB,CAAC;AAACE,OAAA,CAAAK,sBAAA,GAAAA,sBAAA;AAEpF,SAASC,cAAcA,CAACC,KAAkB,EAAoC;EACjF,MAAMhB,OAAO,GAAGgB,KAAK,CAACC,UAAU,EAAE;EAClC,IAAIjB,OAAO,EAAE;IACT,MAAM;MAAEH,IAAI;MAAEC;IAAO,CAAC,GAAGE,OAAO;IAChC,OAAO;MAAEH,IAAI;MAAEC;IAAO,CAAC;EAC3B,CAAC,MAAM;IACH,OAAO;MAAED,IAAI,EAAE,eAAe;MAAEC,MAAM,EAAE;IAAY,CAAC;EACzD;AACJ"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/IllegalMethod.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/IllegalMethod.d.ts
deleted file mode 100644
index b0b08b1..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/IllegalMethod.d.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-/**
- * Verification method that is illegal to have (cannot possibly
- * do verification with this method).
- */
-import { VerificationBase as Base, VerificationEvent, VerificationEventHandlerMap } from "./Base";
-import { IVerificationChannel } from "./request/Channel";
-import { MatrixClient } from "../../client";
-import { MatrixEvent } from "../../models/event";
-import { VerificationRequest } from "./request/VerificationRequest";
-export declare class IllegalMethod extends Base<VerificationEvent, VerificationEventHandlerMap> {
- static factory(channel: IVerificationChannel, baseApis: MatrixClient, userId: string, deviceId: string, startEvent: MatrixEvent, request: VerificationRequest): IllegalMethod;
- static get NAME(): string;
- protected doVerification: () => Promise<void>;
-}
-//# sourceMappingURL=IllegalMethod.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/IllegalMethod.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/IllegalMethod.d.ts.map
deleted file mode 100644
index f06ce4b..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/IllegalMethod.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"IllegalMethod.d.ts","sourceRoot":"","sources":["../../../src/crypto/verification/IllegalMethod.ts"],"names":[],"mappings":"AAgBA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,IAAI,IAAI,EAAE,iBAAiB,EAAE,2BAA2B,EAAE,MAAM,QAAQ,CAAC;AAClG,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAEpE,qBAAa,aAAc,SAAQ,IAAI,CAAC,iBAAiB,EAAE,2BAA2B,CAAC;WACrE,OAAO,CACjB,OAAO,EAAE,oBAAoB,EAC7B,QAAQ,EAAE,YAAY,EACtB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,WAAW,EACvB,OAAO,EAAE,mBAAmB,GAC7B,aAAa;IAKhB,WAAkB,IAAI,IAAI,MAAM,CAI/B;IAED,SAAS,CAAC,cAAc,QAAa,QAAQ,IAAI,CAAC,CAEhD;CACL"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/IllegalMethod.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/IllegalMethod.js
deleted file mode 100644
index c67a675..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/IllegalMethod.js
+++ /dev/null
@@ -1,50 +0,0 @@
-"use strict";
-
-var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.IllegalMethod = void 0;
-var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
-var _Base = require("./Base");
-/*
-Copyright 2020 The Matrix.org Foundation C.I.C.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-/**
- * Verification method that is illegal to have (cannot possibly
- * do verification with this method).
- */
-
-class IllegalMethod extends _Base.VerificationBase {
- constructor(...args) {
- super(...args);
- (0, _defineProperty2.default)(this, "doVerification", async () => {
- throw new Error("Verification is not possible with this method");
- });
- }
- static factory(channel, baseApis, userId, deviceId, startEvent, request) {
- return new IllegalMethod(channel, baseApis, userId, deviceId, startEvent, request);
- }
-
- // eslint-disable-next-line @typescript-eslint/naming-convention
- static get NAME() {
- // Typically the name will be something else, but to complete
- // the contract we offer a default one here.
- return "org.matrix.illegal_method";
- }
-}
-exports.IllegalMethod = IllegalMethod;
-//# sourceMappingURL=IllegalMethod.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/IllegalMethod.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/IllegalMethod.js.map
deleted file mode 100644
index df32c4a..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/IllegalMethod.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"IllegalMethod.js","names":["_Base","require","IllegalMethod","Base","constructor","args","_defineProperty2","default","Error","factory","channel","baseApis","userId","deviceId","startEvent","request","NAME","exports"],"sources":["../../../src/crypto/verification/IllegalMethod.ts"],"sourcesContent":["/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n/**\n * Verification method that is illegal to have (cannot possibly\n * do verification with this method).\n */\n\nimport { VerificationBase as Base, VerificationEvent, VerificationEventHandlerMap } from \"./Base\";\nimport { IVerificationChannel } from \"./request/Channel\";\nimport { MatrixClient } from \"../../client\";\nimport { MatrixEvent } from \"../../models/event\";\nimport { VerificationRequest } from \"./request/VerificationRequest\";\n\nexport class IllegalMethod extends Base<VerificationEvent, VerificationEventHandlerMap> {\n public static factory(\n channel: IVerificationChannel,\n baseApis: MatrixClient,\n userId: string,\n deviceId: string,\n startEvent: MatrixEvent,\n request: VerificationRequest,\n ): IllegalMethod {\n return new IllegalMethod(channel, baseApis, userId, deviceId, startEvent, request);\n }\n\n // eslint-disable-next-line @typescript-eslint/naming-convention\n public static get NAME(): string {\n // Typically the name will be something else, but to complete\n // the contract we offer a default one here.\n return \"org.matrix.illegal_method\";\n }\n\n protected doVerification = async (): Promise<void> => {\n throw new Error(\"Verification is not possible with this method\");\n };\n}\n"],"mappings":";;;;;;;;AAqBA,IAAAA,KAAA,GAAAC,OAAA;AArBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAQO,MAAMC,aAAa,SAASC,sBAAI,CAAiD;EAAAC,YAAA,GAAAC,IAAA;IAAA,SAAAA,IAAA;IAAA,IAAAC,gBAAA,CAAAC,OAAA,0BAmBzD,YAA2B;MAClD,MAAM,IAAIC,KAAK,CAAC,+CAA+C,CAAC;IACpE,CAAC;EAAA;EApBD,OAAcC,OAAOA,CACjBC,OAA6B,EAC7BC,QAAsB,EACtBC,MAAc,EACdC,QAAgB,EAChBC,UAAuB,EACvBC,OAA4B,EACf;IACb,OAAO,IAAIb,aAAa,CAACQ,OAAO,EAAEC,QAAQ,EAAEC,MAAM,EAAEC,QAAQ,EAAEC,UAAU,EAAEC,OAAO,CAAC;EACtF;;EAEA;EACA,WAAkBC,IAAIA,CAAA,EAAW;IAC7B;IACA;IACA,OAAO,2BAA2B;EACtC;AAKJ;AAACC,OAAA,CAAAf,aAAA,GAAAA,aAAA"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/QRCode.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/QRCode.d.ts
deleted file mode 100644
index 0286f45..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/QRCode.d.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-/// <reference types="node" />
-/**
- * QR code key verification.
- */
-import { VerificationBase as Base, VerificationEventHandlerMap } from "./Base";
-import { VerificationRequest } from "./request/VerificationRequest";
-import { MatrixClient } from "../../client";
-import { IVerificationChannel } from "./request/Channel";
-import { MatrixEvent } from "../../models/event";
-export declare const SHOW_QR_CODE_METHOD = "m.qr_code.show.v1";
-export declare const SCAN_QR_CODE_METHOD = "m.qr_code.scan.v1";
-interface IReciprocateQr {
- confirm(): void;
- cancel(): void;
-}
-export declare enum QrCodeEvent {
- ShowReciprocateQr = "show_reciprocate_qr"
-}
-type EventHandlerMap = {
- [QrCodeEvent.ShowReciprocateQr]: (qr: IReciprocateQr) => void;
-} & VerificationEventHandlerMap;
-export declare class ReciprocateQRCode extends Base<QrCodeEvent, EventHandlerMap> {
- reciprocateQREvent?: IReciprocateQr;
- static factory(channel: IVerificationChannel, baseApis: MatrixClient, userId: string, deviceId: string, startEvent: MatrixEvent, request: VerificationRequest): ReciprocateQRCode;
- static get NAME(): string;
- protected doVerification: () => Promise<void>;
-}
-declare enum Mode {
- VerifyOtherUser = 0,
- VerifySelfTrusted = 1,
- VerifySelfUntrusted = 2
-}
-export declare class QRCodeData {
- readonly mode: Mode;
- private readonly sharedSecret;
- readonly otherUserMasterKey: string | null;
- readonly otherDeviceKey: string | null;
- readonly myMasterKey: string | null;
- private readonly buffer;
- constructor(mode: Mode, sharedSecret: string, otherUserMasterKey: string | null, otherDeviceKey: string | null, myMasterKey: string | null, buffer: Buffer);
- static create(request: VerificationRequest, client: MatrixClient): Promise<QRCodeData>;
- /**
- * The unpadded base64 encoded shared secret.
- */
- get encodedSharedSecret(): string;
- getBuffer(): Buffer;
- private static generateSharedSecret;
- private static getOtherDeviceKey;
- private static determineMode;
- private static generateQrData;
- private static generateBuffer;
-}
-export {};
-//# sourceMappingURL=QRCode.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/QRCode.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/QRCode.d.ts.map
deleted file mode 100644
index b76c304..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/QRCode.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"QRCode.d.ts","sourceRoot":"","sources":["../../../src/crypto/verification/QRCode.ts"],"names":[],"mappings":";AAgBA;;GAEG;AAEH,OAAO,EAAE,gBAAgB,IAAI,IAAI,EAAE,2BAA2B,EAAE,MAAM,QAAQ,CAAC;AAI/E,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,eAAO,MAAM,mBAAmB,sBAAsB,CAAC;AACvD,eAAO,MAAM,mBAAmB,sBAAsB,CAAC;AAEvD,UAAU,cAAc;IACpB,OAAO,IAAI,IAAI,CAAC;IAChB,MAAM,IAAI,IAAI,CAAC;CAClB;AAED,oBAAY,WAAW;IACnB,iBAAiB,wBAAwB;CAC5C;AAED,KAAK,eAAe,GAAG;IACnB,CAAC,WAAW,CAAC,iBAAiB,CAAC,EAAE,CAAC,EAAE,EAAE,cAAc,KAAK,IAAI,CAAC;CACjE,GAAG,2BAA2B,CAAC;AAEhC,qBAAa,iBAAkB,SAAQ,IAAI,CAAC,WAAW,EAAE,eAAe,CAAC;IAC9D,kBAAkB,CAAC,EAAE,cAAc,CAAC;WAE7B,OAAO,CACjB,OAAO,EAAE,oBAAoB,EAC7B,QAAQ,EAAE,YAAY,EACtB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,WAAW,EACvB,OAAO,EAAE,mBAAmB,GAC7B,iBAAiB;IAKpB,WAAkB,IAAI,IAAI,MAAM,CAE/B;IAED,SAAS,CAAC,cAAc,QAAa,QAAQ,IAAI,CAAC,CA+DhD;CACL;AAKD,aAAK,IAAI;IACL,eAAe,IAAO;IACtB,iBAAiB,IAAO;IACxB,mBAAmB,IAAO;CAC7B;AAYD,qBAAa,UAAU;aAEC,IAAI,EAAE,IAAI;IAC1B,OAAO,CAAC,QAAQ,CAAC,YAAY;aAEb,kBAAkB,EAAE,MAAM,GAAG,IAAI;aAEjC,cAAc,EAAE,MAAM,GAAG,IAAI;aAE7B,WAAW,EAAE,MAAM,GAAG,IAAI;IAC1C,OAAO,CAAC,QAAQ,CAAC,MAAM;gBARP,IAAI,EAAE,IAAI,EACT,YAAY,EAAE,MAAM,EAErB,kBAAkB,EAAE,MAAM,GAAG,IAAI,EAEjC,cAAc,EAAE,MAAM,GAAG,IAAI,EAE7B,WAAW,EAAE,MAAM,GAAG,IAAI,EACzB,MAAM,EAAE,MAAM;WAGf,MAAM,CAAC,OAAO,EAAE,mBAAmB,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC;IA6BnG;;OAEG;IACH,IAAW,mBAAmB,IAAI,MAAM,CAEvC;IAEM,SAAS,IAAI,MAAM;IAI1B,OAAO,CAAC,MAAM,CAAC,oBAAoB;mBAMd,iBAAiB;IAUtC,OAAO,CAAC,MAAM,CAAC,aAAa;IAiB5B,OAAO,CAAC,MAAM,CAAC,cAAc;IAyC7B,OAAO,CAAC,MAAM,CAAC,cAAc;CAkChC"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/QRCode.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/QRCode.js
deleted file mode 100644
index 6e6ba1c..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/QRCode.js
+++ /dev/null
@@ -1,272 +0,0 @@
-"use strict";
-
-var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.SHOW_QR_CODE_METHOD = exports.SCAN_QR_CODE_METHOD = exports.ReciprocateQRCode = exports.QrCodeEvent = exports.QRCodeData = void 0;
-var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
-var _Base = require("./Base");
-var _Error = require("./Error");
-var _olmlib = require("../olmlib");
-var _logger = require("../../logger");
-/*
-Copyright 2018 - 2021 The Matrix.org Foundation C.I.C.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-/**
- * QR code key verification.
- */
-
-const SHOW_QR_CODE_METHOD = "m.qr_code.show.v1";
-exports.SHOW_QR_CODE_METHOD = SHOW_QR_CODE_METHOD;
-const SCAN_QR_CODE_METHOD = "m.qr_code.scan.v1";
-exports.SCAN_QR_CODE_METHOD = SCAN_QR_CODE_METHOD;
-let QrCodeEvent;
-exports.QrCodeEvent = QrCodeEvent;
-(function (QrCodeEvent) {
- QrCodeEvent["ShowReciprocateQr"] = "show_reciprocate_qr";
-})(QrCodeEvent || (exports.QrCodeEvent = QrCodeEvent = {}));
-class ReciprocateQRCode extends _Base.VerificationBase {
- constructor(...args) {
- super(...args);
- (0, _defineProperty2.default)(this, "reciprocateQREvent", void 0);
- (0, _defineProperty2.default)(this, "doVerification", async () => {
- if (!this.startEvent) {
- // TODO: Support scanning QR codes
- throw new Error("It is not currently possible to start verification" + "with this method yet.");
- }
- const {
- qrCodeData
- } = this.request;
- // 1. check the secret
- if (this.startEvent.getContent()["secret"] !== (qrCodeData === null || qrCodeData === void 0 ? void 0 : qrCodeData.encodedSharedSecret)) {
- throw (0, _Error.newKeyMismatchError)();
- }
-
- // 2. ask if other user shows shield as well
- await new Promise((resolve, reject) => {
- this.reciprocateQREvent = {
- confirm: resolve,
- cancel: () => reject((0, _Error.newUserCancelledError)())
- };
- this.emit(QrCodeEvent.ShowReciprocateQr, this.reciprocateQREvent);
- });
-
- // 3. determine key to sign / mark as trusted
- const keys = {};
- switch (qrCodeData === null || qrCodeData === void 0 ? void 0 : qrCodeData.mode) {
- case Mode.VerifyOtherUser:
- {
- // add master key to keys to be signed, only if we're not doing self-verification
- const masterKey = qrCodeData.otherUserMasterKey;
- keys[`ed25519:${masterKey}`] = masterKey;
- break;
- }
- case Mode.VerifySelfTrusted:
- {
- const deviceId = this.request.targetDevice.deviceId;
- keys[`ed25519:${deviceId}`] = qrCodeData.otherDeviceKey;
- break;
- }
- case Mode.VerifySelfUntrusted:
- {
- const masterKey = qrCodeData.myMasterKey;
- keys[`ed25519:${masterKey}`] = masterKey;
- break;
- }
- }
-
- // 4. sign the key (or mark own MSK as verified in case of MODE_VERIFY_SELF_TRUSTED)
- await this.verifyKeys(this.userId, keys, (keyId, device, keyInfo) => {
- // make sure the device has the expected keys
- const targetKey = keys[keyId];
- if (!targetKey) throw (0, _Error.newKeyMismatchError)();
- if (keyInfo !== targetKey) {
- _logger.logger.error("key ID from key info does not match");
- throw (0, _Error.newKeyMismatchError)();
- }
- for (const deviceKeyId in device.keys) {
- if (!deviceKeyId.startsWith("ed25519")) continue;
- const deviceTargetKey = keys[deviceKeyId];
- if (!deviceTargetKey) throw (0, _Error.newKeyMismatchError)();
- if (device.keys[deviceKeyId] !== deviceTargetKey) {
- _logger.logger.error("master key does not match");
- throw (0, _Error.newKeyMismatchError)();
- }
- }
- });
- });
- }
- static factory(channel, baseApis, userId, deviceId, startEvent, request) {
- return new ReciprocateQRCode(channel, baseApis, userId, deviceId, startEvent, request);
- }
-
- // eslint-disable-next-line @typescript-eslint/naming-convention
- static get NAME() {
- return "m.reciprocate.v1";
- }
-}
-exports.ReciprocateQRCode = ReciprocateQRCode;
-const CODE_VERSION = 0x02; // the version of binary QR codes we support
-const BINARY_PREFIX = "MATRIX"; // ASCII, used to prefix the binary format
-var Mode; // We do not trust the master key
-(function (Mode) {
- Mode[Mode["VerifyOtherUser"] = 0] = "VerifyOtherUser";
- Mode[Mode["VerifySelfTrusted"] = 1] = "VerifySelfTrusted";
- Mode[Mode["VerifySelfUntrusted"] = 2] = "VerifySelfUntrusted";
-})(Mode || (Mode = {}));
-class QRCodeData {
- constructor(mode, sharedSecret,
- // only set when mode is MODE_VERIFY_OTHER_USER, master key of other party at time of generating QR code
- otherUserMasterKey,
- // only set when mode is MODE_VERIFY_SELF_TRUSTED, device key of other party at time of generating QR code
- otherDeviceKey,
- // only set when mode is MODE_VERIFY_SELF_UNTRUSTED, own master key at time of generating QR code
- myMasterKey, buffer) {
- this.mode = mode;
- this.sharedSecret = sharedSecret;
- this.otherUserMasterKey = otherUserMasterKey;
- this.otherDeviceKey = otherDeviceKey;
- this.myMasterKey = myMasterKey;
- this.buffer = buffer;
- }
- static async create(request, client) {
- const sharedSecret = QRCodeData.generateSharedSecret();
- const mode = QRCodeData.determineMode(request, client);
- let otherUserMasterKey = null;
- let otherDeviceKey = null;
- let myMasterKey = null;
- if (mode === Mode.VerifyOtherUser) {
- const otherUserCrossSigningInfo = client.getStoredCrossSigningForUser(request.otherUserId);
- otherUserMasterKey = otherUserCrossSigningInfo.getId("master");
- } else if (mode === Mode.VerifySelfTrusted) {
- otherDeviceKey = await QRCodeData.getOtherDeviceKey(request, client);
- } else if (mode === Mode.VerifySelfUntrusted) {
- const myUserId = client.getUserId();
- const myCrossSigningInfo = client.getStoredCrossSigningForUser(myUserId);
- myMasterKey = myCrossSigningInfo.getId("master");
- }
- const qrData = QRCodeData.generateQrData(request, client, mode, sharedSecret, otherUserMasterKey, otherDeviceKey, myMasterKey);
- const buffer = QRCodeData.generateBuffer(qrData);
- return new QRCodeData(mode, sharedSecret, otherUserMasterKey, otherDeviceKey, myMasterKey, buffer);
- }
-
- /**
- * The unpadded base64 encoded shared secret.
- */
- get encodedSharedSecret() {
- return this.sharedSecret;
- }
- getBuffer() {
- return this.buffer;
- }
- static generateSharedSecret() {
- const secretBytes = new Uint8Array(11);
- global.crypto.getRandomValues(secretBytes);
- return (0, _olmlib.encodeUnpaddedBase64)(secretBytes);
- }
- static async getOtherDeviceKey(request, client) {
- const myUserId = client.getUserId();
- const otherDevice = request.targetDevice;
- const device = otherDevice.deviceId ? client.getStoredDevice(myUserId, otherDevice.deviceId) : undefined;
- if (!device) {
- throw new Error("could not find device " + (otherDevice === null || otherDevice === void 0 ? void 0 : otherDevice.deviceId));
- }
- return device.getFingerprint();
- }
- static determineMode(request, client) {
- const myUserId = client.getUserId();
- const otherUserId = request.otherUserId;
- let mode = Mode.VerifyOtherUser;
- if (myUserId === otherUserId) {
- // Mode changes depending on whether or not we trust the master cross signing key
- const myTrust = client.checkUserTrust(myUserId);
- if (myTrust.isCrossSigningVerified()) {
- mode = Mode.VerifySelfTrusted;
- } else {
- mode = Mode.VerifySelfUntrusted;
- }
- }
- return mode;
- }
- static generateQrData(request, client, mode, encodedSharedSecret, otherUserMasterKey, otherDeviceKey, myMasterKey) {
- const myUserId = client.getUserId();
- const transactionId = request.channel.transactionId;
- const qrData = {
- prefix: BINARY_PREFIX,
- version: CODE_VERSION,
- mode,
- transactionId,
- firstKeyB64: "",
- // worked out shortly
- secondKeyB64: "",
- // worked out shortly
- secretB64: encodedSharedSecret
- };
- const myCrossSigningInfo = client.getStoredCrossSigningForUser(myUserId);
- if (mode === Mode.VerifyOtherUser) {
- // First key is our master cross signing key
- qrData.firstKeyB64 = myCrossSigningInfo.getId("master");
- // Second key is the other user's master cross signing key
- qrData.secondKeyB64 = otherUserMasterKey;
- } else if (mode === Mode.VerifySelfTrusted) {
- // First key is our master cross signing key
- qrData.firstKeyB64 = myCrossSigningInfo.getId("master");
- qrData.secondKeyB64 = otherDeviceKey;
- } else if (mode === Mode.VerifySelfUntrusted) {
- // First key is our device's key
- qrData.firstKeyB64 = client.getDeviceEd25519Key();
- // Second key is what we think our master cross signing key is
- qrData.secondKeyB64 = myMasterKey;
- }
- return qrData;
- }
- static generateBuffer(qrData) {
- let buf = Buffer.alloc(0); // we'll concat our way through life
-
- const appendByte = b => {
- const tmpBuf = Buffer.from([b]);
- buf = Buffer.concat([buf, tmpBuf]);
- };
- const appendInt = i => {
- const tmpBuf = Buffer.alloc(2);
- tmpBuf.writeInt16BE(i, 0);
- buf = Buffer.concat([buf, tmpBuf]);
- };
- const appendStr = (s, enc, withLengthPrefix = true) => {
- const tmpBuf = Buffer.from(s, enc);
- if (withLengthPrefix) appendInt(tmpBuf.byteLength);
- buf = Buffer.concat([buf, tmpBuf]);
- };
- const appendEncBase64 = b64 => {
- const b = (0, _olmlib.decodeBase64)(b64);
- const tmpBuf = Buffer.from(b);
- buf = Buffer.concat([buf, tmpBuf]);
- };
-
- // Actually build the buffer for the QR code
- appendStr(qrData.prefix, "ascii", false);
- appendByte(qrData.version);
- appendByte(qrData.mode);
- appendStr(qrData.transactionId, "utf-8");
- appendEncBase64(qrData.firstKeyB64);
- appendEncBase64(qrData.secondKeyB64);
- appendEncBase64(qrData.secretB64);
- return buf;
- }
-}
-exports.QRCodeData = QRCodeData;
-//# sourceMappingURL=QRCode.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/QRCode.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/QRCode.js.map
deleted file mode 100644
index 4f2ac08..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/QRCode.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"QRCode.js","names":["_Base","require","_Error","_olmlib","_logger","SHOW_QR_CODE_METHOD","exports","SCAN_QR_CODE_METHOD","QrCodeEvent","ReciprocateQRCode","Base","constructor","args","_defineProperty2","default","startEvent","Error","qrCodeData","request","getContent","encodedSharedSecret","newKeyMismatchError","Promise","resolve","reject","reciprocateQREvent","confirm","cancel","newUserCancelledError","emit","ShowReciprocateQr","keys","mode","Mode","VerifyOtherUser","masterKey","otherUserMasterKey","VerifySelfTrusted","deviceId","targetDevice","otherDeviceKey","VerifySelfUntrusted","myMasterKey","verifyKeys","userId","keyId","device","keyInfo","targetKey","logger","error","deviceKeyId","startsWith","deviceTargetKey","factory","channel","baseApis","NAME","CODE_VERSION","BINARY_PREFIX","QRCodeData","sharedSecret","buffer","create","client","generateSharedSecret","determineMode","otherUserCrossSigningInfo","getStoredCrossSigningForUser","otherUserId","getId","getOtherDeviceKey","myUserId","getUserId","myCrossSigningInfo","qrData","generateQrData","generateBuffer","getBuffer","secretBytes","Uint8Array","global","crypto","getRandomValues","encodeUnpaddedBase64","otherDevice","getStoredDevice","undefined","getFingerprint","myTrust","checkUserTrust","isCrossSigningVerified","transactionId","prefix","version","firstKeyB64","secondKeyB64","secretB64","getDeviceEd25519Key","buf","Buffer","alloc","appendByte","b","tmpBuf","from","concat","appendInt","i","writeInt16BE","appendStr","s","enc","withLengthPrefix","byteLength","appendEncBase64","b64","decodeBase64"],"sources":["../../../src/crypto/verification/QRCode.ts"],"sourcesContent":["/*\nCopyright 2018 - 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n/**\n * QR code key verification.\n */\n\nimport { VerificationBase as Base, VerificationEventHandlerMap } from \"./Base\";\nimport { newKeyMismatchError, newUserCancelledError } from \"./Error\";\nimport { decodeBase64, encodeUnpaddedBase64 } from \"../olmlib\";\nimport { logger } from \"../../logger\";\nimport { VerificationRequest } from \"./request/VerificationRequest\";\nimport { MatrixClient } from \"../../client\";\nimport { IVerificationChannel } from \"./request/Channel\";\nimport { MatrixEvent } from \"../../models/event\";\n\nexport const SHOW_QR_CODE_METHOD = \"m.qr_code.show.v1\";\nexport const SCAN_QR_CODE_METHOD = \"m.qr_code.scan.v1\";\n\ninterface IReciprocateQr {\n confirm(): void;\n cancel(): void;\n}\n\nexport enum QrCodeEvent {\n ShowReciprocateQr = \"show_reciprocate_qr\",\n}\n\ntype EventHandlerMap = {\n [QrCodeEvent.ShowReciprocateQr]: (qr: IReciprocateQr) => void;\n} & VerificationEventHandlerMap;\n\nexport class ReciprocateQRCode extends Base<QrCodeEvent, EventHandlerMap> {\n public reciprocateQREvent?: IReciprocateQr;\n\n public static factory(\n channel: IVerificationChannel,\n baseApis: MatrixClient,\n userId: string,\n deviceId: string,\n startEvent: MatrixEvent,\n request: VerificationRequest,\n ): ReciprocateQRCode {\n return new ReciprocateQRCode(channel, baseApis, userId, deviceId, startEvent, request);\n }\n\n // eslint-disable-next-line @typescript-eslint/naming-convention\n public static get NAME(): string {\n return \"m.reciprocate.v1\";\n }\n\n protected doVerification = async (): Promise<void> => {\n if (!this.startEvent) {\n // TODO: Support scanning QR codes\n throw new Error(\"It is not currently possible to start verification\" + \"with this method yet.\");\n }\n\n const { qrCodeData } = this.request;\n // 1. check the secret\n if (this.startEvent.getContent()[\"secret\"] !== qrCodeData?.encodedSharedSecret) {\n throw newKeyMismatchError();\n }\n\n // 2. ask if other user shows shield as well\n await new Promise<void>((resolve, reject) => {\n this.reciprocateQREvent = {\n confirm: resolve,\n cancel: () => reject(newUserCancelledError()),\n };\n this.emit(QrCodeEvent.ShowReciprocateQr, this.reciprocateQREvent);\n });\n\n // 3. determine key to sign / mark as trusted\n const keys: Record<string, string> = {};\n\n switch (qrCodeData?.mode) {\n case Mode.VerifyOtherUser: {\n // add master key to keys to be signed, only if we're not doing self-verification\n const masterKey = qrCodeData.otherUserMasterKey;\n keys[`ed25519:${masterKey}`] = masterKey!;\n break;\n }\n case Mode.VerifySelfTrusted: {\n const deviceId = this.request.targetDevice.deviceId;\n keys[`ed25519:${deviceId}`] = qrCodeData.otherDeviceKey!;\n break;\n }\n case Mode.VerifySelfUntrusted: {\n const masterKey = qrCodeData.myMasterKey;\n keys[`ed25519:${masterKey}`] = masterKey!;\n break;\n }\n }\n\n // 4. sign the key (or mark own MSK as verified in case of MODE_VERIFY_SELF_TRUSTED)\n await this.verifyKeys(this.userId, keys, (keyId, device, keyInfo) => {\n // make sure the device has the expected keys\n const targetKey = keys[keyId];\n if (!targetKey) throw newKeyMismatchError();\n\n if (keyInfo !== targetKey) {\n logger.error(\"key ID from key info does not match\");\n throw newKeyMismatchError();\n }\n for (const deviceKeyId in device.keys) {\n if (!deviceKeyId.startsWith(\"ed25519\")) continue;\n const deviceTargetKey = keys[deviceKeyId];\n if (!deviceTargetKey) throw newKeyMismatchError();\n if (device.keys[deviceKeyId] !== deviceTargetKey) {\n logger.error(\"master key does not match\");\n throw newKeyMismatchError();\n }\n }\n });\n };\n}\n\nconst CODE_VERSION = 0x02; // the version of binary QR codes we support\nconst BINARY_PREFIX = \"MATRIX\"; // ASCII, used to prefix the binary format\n\nenum Mode {\n VerifyOtherUser = 0x00, // Verifying someone who isn't us\n VerifySelfTrusted = 0x01, // We trust the master key\n VerifySelfUntrusted = 0x02, // We do not trust the master key\n}\n\ninterface IQrData {\n prefix: string;\n version: number;\n mode: Mode;\n transactionId?: string;\n firstKeyB64: string;\n secondKeyB64: string;\n secretB64: string;\n}\n\nexport class QRCodeData {\n public constructor(\n public readonly mode: Mode,\n private readonly sharedSecret: string,\n // only set when mode is MODE_VERIFY_OTHER_USER, master key of other party at time of generating QR code\n public readonly otherUserMasterKey: string | null,\n // only set when mode is MODE_VERIFY_SELF_TRUSTED, device key of other party at time of generating QR code\n public readonly otherDeviceKey: string | null,\n // only set when mode is MODE_VERIFY_SELF_UNTRUSTED, own master key at time of generating QR code\n public readonly myMasterKey: string | null,\n private readonly buffer: Buffer,\n ) {}\n\n public static async create(request: VerificationRequest, client: MatrixClient): Promise<QRCodeData> {\n const sharedSecret = QRCodeData.generateSharedSecret();\n const mode = QRCodeData.determineMode(request, client);\n let otherUserMasterKey: string | null = null;\n let otherDeviceKey: string | null = null;\n let myMasterKey: string | null = null;\n if (mode === Mode.VerifyOtherUser) {\n const otherUserCrossSigningInfo = client.getStoredCrossSigningForUser(request.otherUserId);\n otherUserMasterKey = otherUserCrossSigningInfo!.getId(\"master\");\n } else if (mode === Mode.VerifySelfTrusted) {\n otherDeviceKey = await QRCodeData.getOtherDeviceKey(request, client);\n } else if (mode === Mode.VerifySelfUntrusted) {\n const myUserId = client.getUserId()!;\n const myCrossSigningInfo = client.getStoredCrossSigningForUser(myUserId);\n myMasterKey = myCrossSigningInfo!.getId(\"master\");\n }\n const qrData = QRCodeData.generateQrData(\n request,\n client,\n mode,\n sharedSecret,\n otherUserMasterKey!,\n otherDeviceKey!,\n myMasterKey!,\n );\n const buffer = QRCodeData.generateBuffer(qrData);\n return new QRCodeData(mode, sharedSecret, otherUserMasterKey, otherDeviceKey, myMasterKey, buffer);\n }\n\n /**\n * The unpadded base64 encoded shared secret.\n */\n public get encodedSharedSecret(): string {\n return this.sharedSecret;\n }\n\n public getBuffer(): Buffer {\n return this.buffer;\n }\n\n private static generateSharedSecret(): string {\n const secretBytes = new Uint8Array(11);\n global.crypto.getRandomValues(secretBytes);\n return encodeUnpaddedBase64(secretBytes);\n }\n\n private static async getOtherDeviceKey(request: VerificationRequest, client: MatrixClient): Promise<string> {\n const myUserId = client.getUserId()!;\n const otherDevice = request.targetDevice;\n const device = otherDevice.deviceId ? client.getStoredDevice(myUserId, otherDevice.deviceId) : undefined;\n if (!device) {\n throw new Error(\"could not find device \" + otherDevice?.deviceId);\n }\n return device.getFingerprint();\n }\n\n private static determineMode(request: VerificationRequest, client: MatrixClient): Mode {\n const myUserId = client.getUserId();\n const otherUserId = request.otherUserId;\n\n let mode = Mode.VerifyOtherUser;\n if (myUserId === otherUserId) {\n // Mode changes depending on whether or not we trust the master cross signing key\n const myTrust = client.checkUserTrust(myUserId);\n if (myTrust.isCrossSigningVerified()) {\n mode = Mode.VerifySelfTrusted;\n } else {\n mode = Mode.VerifySelfUntrusted;\n }\n }\n return mode;\n }\n\n private static generateQrData(\n request: VerificationRequest,\n client: MatrixClient,\n mode: Mode,\n encodedSharedSecret: string,\n otherUserMasterKey?: string,\n otherDeviceKey?: string,\n myMasterKey?: string,\n ): IQrData {\n const myUserId = client.getUserId()!;\n const transactionId = request.channel.transactionId;\n const qrData: IQrData = {\n prefix: BINARY_PREFIX,\n version: CODE_VERSION,\n mode,\n transactionId,\n firstKeyB64: \"\", // worked out shortly\n secondKeyB64: \"\", // worked out shortly\n secretB64: encodedSharedSecret,\n };\n\n const myCrossSigningInfo = client.getStoredCrossSigningForUser(myUserId);\n\n if (mode === Mode.VerifyOtherUser) {\n // First key is our master cross signing key\n qrData.firstKeyB64 = myCrossSigningInfo!.getId(\"master\")!;\n // Second key is the other user's master cross signing key\n qrData.secondKeyB64 = otherUserMasterKey!;\n } else if (mode === Mode.VerifySelfTrusted) {\n // First key is our master cross signing key\n qrData.firstKeyB64 = myCrossSigningInfo!.getId(\"master\")!;\n qrData.secondKeyB64 = otherDeviceKey!;\n } else if (mode === Mode.VerifySelfUntrusted) {\n // First key is our device's key\n qrData.firstKeyB64 = client.getDeviceEd25519Key()!;\n // Second key is what we think our master cross signing key is\n qrData.secondKeyB64 = myMasterKey!;\n }\n return qrData;\n }\n\n private static generateBuffer(qrData: IQrData): Buffer {\n let buf = Buffer.alloc(0); // we'll concat our way through life\n\n const appendByte = (b: number): void => {\n const tmpBuf = Buffer.from([b]);\n buf = Buffer.concat([buf, tmpBuf]);\n };\n const appendInt = (i: number): void => {\n const tmpBuf = Buffer.alloc(2);\n tmpBuf.writeInt16BE(i, 0);\n buf = Buffer.concat([buf, tmpBuf]);\n };\n const appendStr = (s: string, enc: BufferEncoding, withLengthPrefix = true): void => {\n const tmpBuf = Buffer.from(s, enc);\n if (withLengthPrefix) appendInt(tmpBuf.byteLength);\n buf = Buffer.concat([buf, tmpBuf]);\n };\n const appendEncBase64 = (b64: string): void => {\n const b = decodeBase64(b64);\n const tmpBuf = Buffer.from(b);\n buf = Buffer.concat([buf, tmpBuf]);\n };\n\n // Actually build the buffer for the QR code\n appendStr(qrData.prefix, \"ascii\", false);\n appendByte(qrData.version);\n appendByte(qrData.mode);\n appendStr(qrData.transactionId!, \"utf-8\");\n appendEncBase64(qrData.firstKeyB64);\n appendEncBase64(qrData.secondKeyB64);\n appendEncBase64(qrData.secretB64);\n\n return buf;\n }\n}\n"],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SAS.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SAS.d.ts
deleted file mode 100644
index 0854f13..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SAS.d.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import { VerificationBase as Base, VerificationEventHandlerMap } from "./Base";
-import { MatrixEvent } from "../../models/event";
-type EmojiMapping = [emoji: string, name: string];
-export interface IGeneratedSas {
- decimal?: [number, number, number];
- emoji?: EmojiMapping[];
-}
-export interface ISasEvent {
- sas: IGeneratedSas;
- confirm(): Promise<void>;
- cancel(): void;
- mismatch(): void;
-}
-export declare enum SasEvent {
- ShowSas = "show_sas"
-}
-type EventHandlerMap = {
- [SasEvent.ShowSas]: (sas: ISasEvent) => void;
-} & VerificationEventHandlerMap;
-export declare class SAS extends Base<SasEvent, EventHandlerMap> {
- private waitingForAccept?;
- ourSASPubKey?: string;
- theirSASPubKey?: string;
- sasEvent?: ISasEvent;
- static get NAME(): string;
- get events(): string[];
- protected doVerification: () => Promise<void>;
- canSwitchStartEvent(event: MatrixEvent): boolean;
- private sendStart;
- private verifyAndCheckMAC;
- private doSendVerification;
- private doRespondVerification;
- private sendMAC;
- private checkMAC;
-}
-export {};
-//# sourceMappingURL=SAS.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SAS.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SAS.d.ts.map
deleted file mode 100644
index 7e02a7b..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SAS.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"SAS.d.ts","sourceRoot":"","sources":["../../../src/crypto/verification/SAS.ts"],"names":[],"mappings":"AAuBA,OAAO,EAAE,gBAAgB,IAAI,IAAI,EAAyB,2BAA2B,EAAE,MAAM,QAAQ,CAAC;AAStG,OAAO,EAAY,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAc3D,KAAK,YAAY,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AAyFlD,MAAM,WAAW,aAAa;IAC1B,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,KAAK,CAAC,EAAE,YAAY,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,SAAS;IACtB,GAAG,EAAE,aAAa,CAAC;IACnB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,MAAM,IAAI,IAAI,CAAC;IACf,QAAQ,IAAI,IAAI,CAAC;CACpB;AA6ED,oBAAY,QAAQ;IAChB,OAAO,aAAa;CACvB;AAED,KAAK,eAAe,GAAG;IACnB,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,KAAK,IAAI,CAAC;CAChD,GAAG,2BAA2B,CAAC;AAEhC,qBAAa,GAAI,SAAQ,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC;IACpD,OAAO,CAAC,gBAAgB,CAAC,CAAU;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,SAAS,CAAC;IAG5B,WAAkB,IAAI,IAAI,MAAM,CAE/B;IAED,IAAW,MAAM,IAAI,MAAM,EAAE,CAE5B;IAED,SAAS,CAAC,cAAc,QAAa,QAAQ,IAAI,CAAC,CAyBhD;IAEK,mBAAmB,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO;YAQzC,SAAS;YAcT,iBAAiB;YAsCjB,kBAAkB;YAiElB,qBAAqB;IA8CnC,OAAO,CAAC,OAAO;YA0BD,QAAQ;CAsBzB"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SAS.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SAS.js
deleted file mode 100644
index 781e203..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SAS.js
+++ /dev/null
@@ -1,453 +0,0 @@
-"use strict";
-
-var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.SasEvent = exports.SAS = void 0;
-var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
-var _anotherJson = _interopRequireDefault(require("another-json"));
-var _Base = require("./Base");
-var _Error = require("./Error");
-var _logger = require("../../logger");
-var _SASDecimal = require("./SASDecimal");
-var _event = require("../../@types/event");
-/*
-Copyright 2018 - 2021 The Matrix.org Foundation C.I.C.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-/**
- * Short Authentication String (SAS) verification.
- */
-
-const START_TYPE = _event.EventType.KeyVerificationStart;
-const EVENTS = [_event.EventType.KeyVerificationAccept, _event.EventType.KeyVerificationKey, _event.EventType.KeyVerificationMac];
-let olmutil;
-const newMismatchedSASError = (0, _Error.errorFactory)("m.mismatched_sas", "Mismatched short authentication string");
-const newMismatchedCommitmentError = (0, _Error.errorFactory)("m.mismatched_commitment", "Mismatched commitment");
-const emojiMapping = [["🐶", "dog"],
-// 0
-["🐱", "cat"],
-// 1
-["🦁", "lion"],
-// 2
-["🐎", "horse"],
-// 3
-["🦄", "unicorn"],
-// 4
-["🐷", "pig"],
-// 5
-["🐘", "elephant"],
-// 6
-["🐰", "rabbit"],
-// 7
-["🐼", "panda"],
-// 8
-["🐓", "rooster"],
-// 9
-["🐧", "penguin"],
-// 10
-["🐢", "turtle"],
-// 11
-["🐟", "fish"],
-// 12
-["🐙", "octopus"],
-// 13
-["🦋", "butterfly"],
-// 14
-["🌷", "flower"],
-// 15
-["🌳", "tree"],
-// 16
-["🌵", "cactus"],
-// 17
-["🍄", "mushroom"],
-// 18
-["🌏", "globe"],
-// 19
-["🌙", "moon"],
-// 20
-["☁️", "cloud"],
-// 21
-["🔥", "fire"],
-// 22
-["🍌", "banana"],
-// 23
-["🍎", "apple"],
-// 24
-["🍓", "strawberry"],
-// 25
-["🌽", "corn"],
-// 26
-["🍕", "pizza"],
-// 27
-["🎂", "cake"],
-// 28
-["❤️", "heart"],
-// 29
-["🙂", "smiley"],
-// 30
-["🤖", "robot"],
-// 31
-["🎩", "hat"],
-// 32
-["👓", "glasses"],
-// 33
-["🔧", "spanner"],
-// 34
-["🎅", "santa"],
-// 35
-["👍", "thumbs up"],
-// 36
-["☂️", "umbrella"],
-// 37
-["⌛", "hourglass"],
-// 38
-["⏰", "clock"],
-// 39
-["🎁", "gift"],
-// 40
-["💡", "light bulb"],
-// 41
-["📕", "book"],
-// 42
-["✏️", "pencil"],
-// 43
-["📎", "paperclip"],
-// 44
-["✂️", "scissors"],
-// 45
-["🔒", "lock"],
-// 46
-["🔑", "key"],
-// 47
-["🔨", "hammer"],
-// 48
-["☎️", "telephone"],
-// 49
-["🏁", "flag"],
-// 50
-["🚂", "train"],
-// 51
-["🚲", "bicycle"],
-// 52
-["✈️", "aeroplane"],
-// 53
-["🚀", "rocket"],
-// 54
-["🏆", "trophy"],
-// 55
-["⚽", "ball"],
-// 56
-["🎸", "guitar"],
-// 57
-["🎺", "trumpet"],
-// 58
-["🔔", "bell"],
-// 59
-["⚓️", "anchor"],
-// 60
-["🎧", "headphones"],
-// 61
-["📁", "folder"],
-// 62
-["📌", "pin"] // 63
-];
-
-function generateEmojiSas(sasBytes) {
- const emojis = [
- // just like base64 encoding
- sasBytes[0] >> 2, (sasBytes[0] & 0x3) << 4 | sasBytes[1] >> 4, (sasBytes[1] & 0xf) << 2 | sasBytes[2] >> 6, sasBytes[2] & 0x3f, sasBytes[3] >> 2, (sasBytes[3] & 0x3) << 4 | sasBytes[4] >> 4, (sasBytes[4] & 0xf) << 2 | sasBytes[5] >> 6];
- return emojis.map(num => emojiMapping[num]);
-}
-const sasGenerators = {
- decimal: _SASDecimal.generateDecimalSas,
- emoji: generateEmojiSas
-};
-function generateSas(sasBytes, methods) {
- const sas = {};
- for (const method of methods) {
- if (method in sasGenerators) {
- // @ts-ignore - ts doesn't like us mixing types like this
- sas[method] = sasGenerators[method](Array.from(sasBytes));
- }
- }
- return sas;
-}
-const macMethods = {
- "hkdf-hmac-sha256": "calculate_mac",
- "org.matrix.msc3783.hkdf-hmac-sha256": "calculate_mac_fixed_base64",
- "hkdf-hmac-sha256.v2": "calculate_mac_fixed_base64",
- "hmac-sha256": "calculate_mac_long_kdf"
-};
-function calculateMAC(olmSAS, method) {
- return function (input, info) {
- const mac = olmSAS[macMethods[method]](input, info);
- _logger.logger.log("SAS calculateMAC:", method, [input, info], mac);
- return mac;
- };
-}
-const calculateKeyAgreement = {
- // eslint-disable-next-line @typescript-eslint/naming-convention
- "curve25519-hkdf-sha256": function (sas, olmSAS, bytes) {
- const ourInfo = `${sas.baseApis.getUserId()}|${sas.baseApis.deviceId}|` + `${sas.ourSASPubKey}|`;
- const theirInfo = `${sas.userId}|${sas.deviceId}|${sas.theirSASPubKey}|`;
- const sasInfo = "MATRIX_KEY_VERIFICATION_SAS|" + (sas.initiatedByMe ? ourInfo + theirInfo : theirInfo + ourInfo) + sas.channel.transactionId;
- return olmSAS.generate_bytes(sasInfo, bytes);
- },
- "curve25519": function (sas, olmSAS, bytes) {
- const ourInfo = `${sas.baseApis.getUserId()}${sas.baseApis.deviceId}`;
- const theirInfo = `${sas.userId}${sas.deviceId}`;
- const sasInfo = "MATRIX_KEY_VERIFICATION_SAS" + (sas.initiatedByMe ? ourInfo + theirInfo : theirInfo + ourInfo) + sas.channel.transactionId;
- return olmSAS.generate_bytes(sasInfo, bytes);
- }
-};
-/* lists of algorithms/methods that are supported. The key agreement, hashes,
- * and MAC lists should be sorted in order of preference (most preferred
- * first).
- */
-const KEY_AGREEMENT_LIST = ["curve25519-hkdf-sha256", "curve25519"];
-const HASHES_LIST = ["sha256"];
-const MAC_LIST = ["hkdf-hmac-sha256.v2", "org.matrix.msc3783.hkdf-hmac-sha256", "hkdf-hmac-sha256", "hmac-sha256"];
-const SAS_LIST = Object.keys(sasGenerators);
-const KEY_AGREEMENT_SET = new Set(KEY_AGREEMENT_LIST);
-const HASHES_SET = new Set(HASHES_LIST);
-const MAC_SET = new Set(MAC_LIST);
-const SAS_SET = new Set(SAS_LIST);
-function intersection(anArray, aSet) {
- return Array.isArray(anArray) ? anArray.filter(x => aSet.has(x)) : [];
-}
-let SasEvent;
-exports.SasEvent = SasEvent;
-(function (SasEvent) {
- SasEvent["ShowSas"] = "show_sas";
-})(SasEvent || (exports.SasEvent = SasEvent = {}));
-class SAS extends _Base.VerificationBase {
- constructor(...args) {
- super(...args);
- (0, _defineProperty2.default)(this, "waitingForAccept", void 0);
- (0, _defineProperty2.default)(this, "ourSASPubKey", void 0);
- (0, _defineProperty2.default)(this, "theirSASPubKey", void 0);
- (0, _defineProperty2.default)(this, "sasEvent", void 0);
- (0, _defineProperty2.default)(this, "doVerification", async () => {
- await global.Olm.init();
- olmutil = olmutil || new global.Olm.Utility();
-
- // make sure user's keys are downloaded
- await this.baseApis.downloadKeys([this.userId]);
- let retry = false;
- do {
- try {
- if (this.initiatedByMe) {
- return await this.doSendVerification();
- } else {
- return await this.doRespondVerification();
- }
- } catch (err) {
- if (err instanceof _Base.SwitchStartEventError) {
- // this changes what initiatedByMe returns
- this.startEvent = err.startEvent;
- retry = true;
- } else {
- throw err;
- }
- }
- } while (retry);
- });
- }
- // eslint-disable-next-line @typescript-eslint/naming-convention
- static get NAME() {
- return "m.sas.v1";
- }
- get events() {
- return EVENTS;
- }
- canSwitchStartEvent(event) {
- if (event.getType() !== START_TYPE) {
- return false;
- }
- const content = event.getContent();
- return (content === null || content === void 0 ? void 0 : content.method) === SAS.NAME && !!this.waitingForAccept;
- }
- async sendStart() {
- const startContent = this.channel.completeContent(START_TYPE, {
- method: SAS.NAME,
- from_device: this.baseApis.deviceId,
- key_agreement_protocols: KEY_AGREEMENT_LIST,
- hashes: HASHES_LIST,
- message_authentication_codes: MAC_LIST,
- // FIXME: allow app to specify what SAS methods can be used
- short_authentication_string: SAS_LIST
- });
- await this.channel.sendCompleted(START_TYPE, startContent);
- return startContent;
- }
- async verifyAndCheckMAC(keyAgreement, sasMethods, olmSAS, macMethod) {
- const sasBytes = calculateKeyAgreement[keyAgreement](this, olmSAS, 6);
- const verifySAS = new Promise((resolve, reject) => {
- this.sasEvent = {
- sas: generateSas(sasBytes, sasMethods),
- confirm: async () => {
- try {
- await this.sendMAC(olmSAS, macMethod);
- resolve();
- } catch (err) {
- reject(err);
- }
- },
- cancel: () => reject((0, _Error.newUserCancelledError)()),
- mismatch: () => reject(newMismatchedSASError())
- };
- this.emit(SasEvent.ShowSas, this.sasEvent);
- });
- const [e] = await Promise.all([this.waitForEvent(_event.EventType.KeyVerificationMac).then(e => {
- // we don't expect any more messages from the other
- // party, and they may send a m.key.verification.done
- // when they're done on their end
- this.expectedEvent = _event.EventType.KeyVerificationDone;
- return e;
- }), verifySAS]);
- const content = e.getContent();
- await this.checkMAC(olmSAS, content, macMethod);
- }
- async doSendVerification() {
- this.waitingForAccept = true;
- let startContent;
- if (this.startEvent) {
- startContent = this.channel.completedContentFromEvent(this.startEvent);
- } else {
- startContent = await this.sendStart();
- }
-
- // we might have switched to a different start event,
- // but was we didn't call _waitForEvent there was no
- // call that could throw yet. So check manually that
- // we're still on the initiator side
- if (!this.initiatedByMe) {
- throw new _Base.SwitchStartEventError(this.startEvent);
- }
- let e;
- try {
- e = await this.waitForEvent(_event.EventType.KeyVerificationAccept);
- } finally {
- this.waitingForAccept = false;
- }
- let content = e.getContent();
- const sasMethods = intersection(content.short_authentication_string, SAS_SET);
- if (!(KEY_AGREEMENT_SET.has(content.key_agreement_protocol) && HASHES_SET.has(content.hash) && MAC_SET.has(content.message_authentication_code) && sasMethods.length)) {
- throw (0, _Error.newUnknownMethodError)();
- }
- if (typeof content.commitment !== "string") {
- throw (0, _Error.newInvalidMessageError)();
- }
- const keyAgreement = content.key_agreement_protocol;
- const macMethod = content.message_authentication_code;
- const hashCommitment = content.commitment;
- const olmSAS = new global.Olm.SAS();
- try {
- this.ourSASPubKey = olmSAS.get_pubkey();
- await this.send(_event.EventType.KeyVerificationKey, {
- key: this.ourSASPubKey
- });
- e = await this.waitForEvent(_event.EventType.KeyVerificationKey);
- // FIXME: make sure event is properly formed
- content = e.getContent();
- const commitmentStr = content.key + _anotherJson.default.stringify(startContent);
- // TODO: use selected hash function (when we support multiple)
- if (olmutil.sha256(commitmentStr) !== hashCommitment) {
- throw newMismatchedCommitmentError();
- }
- this.theirSASPubKey = content.key;
- olmSAS.set_their_key(content.key);
- await this.verifyAndCheckMAC(keyAgreement, sasMethods, olmSAS, macMethod);
- } finally {
- olmSAS.free();
- }
- }
- async doRespondVerification() {
- // as m.related_to is not included in the encrypted content in e2e rooms,
- // we need to make sure it is added
- let content = this.channel.completedContentFromEvent(this.startEvent);
-
- // Note: we intersect using our pre-made lists, rather than the sets,
- // so that the result will be in our order of preference. Then
- // fetching the first element from the array will give our preferred
- // method out of the ones offered by the other party.
- const keyAgreement = intersection(KEY_AGREEMENT_LIST, new Set(content.key_agreement_protocols))[0];
- const hashMethod = intersection(HASHES_LIST, new Set(content.hashes))[0];
- const macMethod = intersection(MAC_LIST, new Set(content.message_authentication_codes))[0];
- // FIXME: allow app to specify what SAS methods can be used
- const sasMethods = intersection(content.short_authentication_string, SAS_SET);
- if (!(keyAgreement !== undefined && hashMethod !== undefined && macMethod !== undefined && sasMethods.length)) {
- throw (0, _Error.newUnknownMethodError)();
- }
- const olmSAS = new global.Olm.SAS();
- try {
- const commitmentStr = olmSAS.get_pubkey() + _anotherJson.default.stringify(content);
- await this.send(_event.EventType.KeyVerificationAccept, {
- key_agreement_protocol: keyAgreement,
- hash: hashMethod,
- message_authentication_code: macMethod,
- short_authentication_string: sasMethods,
- // TODO: use selected hash function (when we support multiple)
- commitment: olmutil.sha256(commitmentStr)
- });
- const e = await this.waitForEvent(_event.EventType.KeyVerificationKey);
- // FIXME: make sure event is properly formed
- content = e.getContent();
- this.theirSASPubKey = content.key;
- olmSAS.set_their_key(content.key);
- this.ourSASPubKey = olmSAS.get_pubkey();
- await this.send(_event.EventType.KeyVerificationKey, {
- key: this.ourSASPubKey
- });
- await this.verifyAndCheckMAC(keyAgreement, sasMethods, olmSAS, macMethod);
- } finally {
- olmSAS.free();
- }
- }
- sendMAC(olmSAS, method) {
- const mac = {};
- const keyList = [];
- const baseInfo = "MATRIX_KEY_VERIFICATION_MAC" + this.baseApis.getUserId() + this.baseApis.deviceId + this.userId + this.deviceId + this.channel.transactionId;
- const deviceKeyId = `ed25519:${this.baseApis.deviceId}`;
- mac[deviceKeyId] = calculateMAC(olmSAS, method)(this.baseApis.getDeviceEd25519Key(), baseInfo + deviceKeyId);
- keyList.push(deviceKeyId);
- const crossSigningId = this.baseApis.getCrossSigningId();
- if (crossSigningId) {
- const crossSigningKeyId = `ed25519:${crossSigningId}`;
- mac[crossSigningKeyId] = calculateMAC(olmSAS, method)(crossSigningId, baseInfo + crossSigningKeyId);
- keyList.push(crossSigningKeyId);
- }
- const keys = calculateMAC(olmSAS, method)(keyList.sort().join(","), baseInfo + "KEY_IDS");
- return this.send(_event.EventType.KeyVerificationMac, {
- mac,
- keys
- });
- }
- async checkMAC(olmSAS, content, method) {
- const baseInfo = "MATRIX_KEY_VERIFICATION_MAC" + this.userId + this.deviceId + this.baseApis.getUserId() + this.baseApis.deviceId + this.channel.transactionId;
- if (content.keys !== calculateMAC(olmSAS, method)(Object.keys(content.mac).sort().join(","), baseInfo + "KEY_IDS")) {
- throw (0, _Error.newKeyMismatchError)();
- }
- await this.verifyKeys(this.userId, content.mac, (keyId, device, keyInfo) => {
- if (keyInfo !== calculateMAC(olmSAS, method)(device.keys[keyId], baseInfo + keyId)) {
- throw (0, _Error.newKeyMismatchError)();
- }
- });
- }
-}
-exports.SAS = SAS;
-//# sourceMappingURL=SAS.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SAS.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SAS.js.map
deleted file mode 100644
index be47b3f..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SAS.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"SAS.js","names":["_anotherJson","_interopRequireDefault","require","_Base","_Error","_logger","_SASDecimal","_event","START_TYPE","EventType","KeyVerificationStart","EVENTS","KeyVerificationAccept","KeyVerificationKey","KeyVerificationMac","olmutil","newMismatchedSASError","errorFactory","newMismatchedCommitmentError","emojiMapping","generateEmojiSas","sasBytes","emojis","map","num","sasGenerators","decimal","generateDecimalSas","emoji","generateSas","methods","sas","method","Array","from","macMethods","calculateMAC","olmSAS","input","info","mac","logger","log","calculateKeyAgreement","curve25519-hkdf-sha256","bytes","ourInfo","baseApis","getUserId","deviceId","ourSASPubKey","theirInfo","userId","theirSASPubKey","sasInfo","initiatedByMe","channel","transactionId","generate_bytes","curve25519","KEY_AGREEMENT_LIST","HASHES_LIST","MAC_LIST","SAS_LIST","Object","keys","KEY_AGREEMENT_SET","Set","HASHES_SET","MAC_SET","SAS_SET","intersection","anArray","aSet","isArray","filter","x","has","SasEvent","exports","SAS","Base","constructor","args","_defineProperty2","default","global","Olm","init","Utility","downloadKeys","retry","doSendVerification","doRespondVerification","err","SwitchStartEventError","startEvent","NAME","events","canSwitchStartEvent","event","getType","content","getContent","waitingForAccept","sendStart","startContent","completeContent","from_device","key_agreement_protocols","hashes","message_authentication_codes","short_authentication_string","sendCompleted","verifyAndCheckMAC","keyAgreement","sasMethods","macMethod","verifySAS","Promise","resolve","reject","sasEvent","confirm","sendMAC","cancel","newUserCancelledError","mismatch","emit","ShowSas","e","all","waitForEvent","then","expectedEvent","KeyVerificationDone","checkMAC","completedContentFromEvent","key_agreement_protocol","hash","message_authentication_code","length","newUnknownMethodError","commitment","newInvalidMessageError","hashCommitment","get_pubkey","send","key","commitmentStr","anotherjson","stringify","sha256","set_their_key","free","hashMethod","undefined","keyList","baseInfo","deviceKeyId","getDeviceEd25519Key","push","crossSigningId","getCrossSigningId","crossSigningKeyId","sort","join","newKeyMismatchError","verifyKeys","keyId","device","keyInfo"],"sources":["../../../src/crypto/verification/SAS.ts"],"sourcesContent":["/*\nCopyright 2018 - 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n/**\n * Short Authentication String (SAS) verification.\n */\n\nimport anotherjson from \"another-json\";\nimport { Utility, SAS as OlmSAS } from \"@matrix-org/olm\";\n\nimport { VerificationBase as Base, SwitchStartEventError, VerificationEventHandlerMap } from \"./Base\";\nimport {\n errorFactory,\n newInvalidMessageError,\n newKeyMismatchError,\n newUnknownMethodError,\n newUserCancelledError,\n} from \"./Error\";\nimport { logger } from \"../../logger\";\nimport { IContent, MatrixEvent } from \"../../models/event\";\nimport { generateDecimalSas } from \"./SASDecimal\";\nimport { EventType } from \"../../@types/event\";\n\nconst START_TYPE = EventType.KeyVerificationStart;\n\nconst EVENTS = [EventType.KeyVerificationAccept, EventType.KeyVerificationKey, EventType.KeyVerificationMac];\n\nlet olmutil: Utility;\n\nconst newMismatchedSASError = errorFactory(\"m.mismatched_sas\", \"Mismatched short authentication string\");\n\nconst newMismatchedCommitmentError = errorFactory(\"m.mismatched_commitment\", \"Mismatched commitment\");\n\ntype EmojiMapping = [emoji: string, name: string];\n\nconst emojiMapping: EmojiMapping[] = [\n [\"🐶\", \"dog\"], // 0\n [\"🐱\", \"cat\"], // 1\n [\"🦁\", \"lion\"], // 2\n [\"🐎\", \"horse\"], // 3\n [\"🦄\", \"unicorn\"], // 4\n [\"🐷\", \"pig\"], // 5\n [\"🐘\", \"elephant\"], // 6\n [\"🐰\", \"rabbit\"], // 7\n [\"🐼\", \"panda\"], // 8\n [\"🐓\", \"rooster\"], // 9\n [\"🐧\", \"penguin\"], // 10\n [\"🐢\", \"turtle\"], // 11\n [\"🐟\", \"fish\"], // 12\n [\"🐙\", \"octopus\"], // 13\n [\"🦋\", \"butterfly\"], // 14\n [\"🌷\", \"flower\"], // 15\n [\"🌳\", \"tree\"], // 16\n [\"🌵\", \"cactus\"], // 17\n [\"🍄\", \"mushroom\"], // 18\n [\"🌏\", \"globe\"], // 19\n [\"🌙\", \"moon\"], // 20\n [\"☁️\", \"cloud\"], // 21\n [\"🔥\", \"fire\"], // 22\n [\"🍌\", \"banana\"], // 23\n [\"🍎\", \"apple\"], // 24\n [\"🍓\", \"strawberry\"], // 25\n [\"🌽\", \"corn\"], // 26\n [\"🍕\", \"pizza\"], // 27\n [\"🎂\", \"cake\"], // 28\n [\"❤️\", \"heart\"], // 29\n [\"🙂\", \"smiley\"], // 30\n [\"🤖\", \"robot\"], // 31\n [\"🎩\", \"hat\"], // 32\n [\"👓\", \"glasses\"], // 33\n [\"🔧\", \"spanner\"], // 34\n [\"🎅\", \"santa\"], // 35\n [\"👍\", \"thumbs up\"], // 36\n [\"☂️\", \"umbrella\"], // 37\n [\"⌛\", \"hourglass\"], // 38\n [\"⏰\", \"clock\"], // 39\n [\"🎁\", \"gift\"], // 40\n [\"💡\", \"light bulb\"], // 41\n [\"📕\", \"book\"], // 42\n [\"✏️\", \"pencil\"], // 43\n [\"📎\", \"paperclip\"], // 44\n [\"✂️\", \"scissors\"], // 45\n [\"🔒\", \"lock\"], // 46\n [\"🔑\", \"key\"], // 47\n [\"🔨\", \"hammer\"], // 48\n [\"☎️\", \"telephone\"], // 49\n [\"🏁\", \"flag\"], // 50\n [\"🚂\", \"train\"], // 51\n [\"🚲\", \"bicycle\"], // 52\n [\"✈️\", \"aeroplane\"], // 53\n [\"🚀\", \"rocket\"], // 54\n [\"🏆\", \"trophy\"], // 55\n [\"⚽\", \"ball\"], // 56\n [\"🎸\", \"guitar\"], // 57\n [\"🎺\", \"trumpet\"], // 58\n [\"🔔\", \"bell\"], // 59\n [\"⚓️\", \"anchor\"], // 60\n [\"🎧\", \"headphones\"], // 61\n [\"📁\", \"folder\"], // 62\n [\"📌\", \"pin\"], // 63\n];\n\nfunction generateEmojiSas(sasBytes: number[]): EmojiMapping[] {\n const emojis = [\n // just like base64 encoding\n sasBytes[0] >> 2,\n ((sasBytes[0] & 0x3) << 4) | (sasBytes[1] >> 4),\n ((sasBytes[1] & 0xf) << 2) | (sasBytes[2] >> 6),\n sasBytes[2] & 0x3f,\n sasBytes[3] >> 2,\n ((sasBytes[3] & 0x3) << 4) | (sasBytes[4] >> 4),\n ((sasBytes[4] & 0xf) << 2) | (sasBytes[5] >> 6),\n ];\n\n return emojis.map((num) => emojiMapping[num]);\n}\n\nconst sasGenerators = {\n decimal: generateDecimalSas,\n emoji: generateEmojiSas,\n} as const;\n\nexport interface IGeneratedSas {\n decimal?: [number, number, number];\n emoji?: EmojiMapping[];\n}\n\nexport interface ISasEvent {\n sas: IGeneratedSas;\n confirm(): Promise<void>;\n cancel(): void;\n mismatch(): void;\n}\n\nfunction generateSas(sasBytes: Uint8Array, methods: string[]): IGeneratedSas {\n const sas: IGeneratedSas = {};\n for (const method of methods) {\n if (method in sasGenerators) {\n // @ts-ignore - ts doesn't like us mixing types like this\n sas[method] = sasGenerators[method](Array.from(sasBytes));\n }\n }\n return sas;\n}\n\nconst macMethods = {\n \"hkdf-hmac-sha256\": \"calculate_mac\",\n \"org.matrix.msc3783.hkdf-hmac-sha256\": \"calculate_mac_fixed_base64\",\n \"hkdf-hmac-sha256.v2\": \"calculate_mac_fixed_base64\",\n \"hmac-sha256\": \"calculate_mac_long_kdf\",\n} as const;\n\ntype MacMethod = keyof typeof macMethods;\n\nfunction calculateMAC(olmSAS: OlmSAS, method: MacMethod) {\n return function (input: string, info: string): string {\n const mac = olmSAS[macMethods[method]](input, info);\n logger.log(\"SAS calculateMAC:\", method, [input, info], mac);\n return mac;\n };\n}\n\nconst calculateKeyAgreement = {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n \"curve25519-hkdf-sha256\": function (sas: SAS, olmSAS: OlmSAS, bytes: number): Uint8Array {\n const ourInfo = `${sas.baseApis.getUserId()}|${sas.baseApis.deviceId}|` + `${sas.ourSASPubKey}|`;\n const theirInfo = `${sas.userId}|${sas.deviceId}|${sas.theirSASPubKey}|`;\n const sasInfo =\n \"MATRIX_KEY_VERIFICATION_SAS|\" +\n (sas.initiatedByMe ? ourInfo + theirInfo : theirInfo + ourInfo) +\n sas.channel.transactionId;\n return olmSAS.generate_bytes(sasInfo, bytes);\n },\n \"curve25519\": function (sas: SAS, olmSAS: OlmSAS, bytes: number): Uint8Array {\n const ourInfo = `${sas.baseApis.getUserId()}${sas.baseApis.deviceId}`;\n const theirInfo = `${sas.userId}${sas.deviceId}`;\n const sasInfo =\n \"MATRIX_KEY_VERIFICATION_SAS\" +\n (sas.initiatedByMe ? ourInfo + theirInfo : theirInfo + ourInfo) +\n sas.channel.transactionId;\n return olmSAS.generate_bytes(sasInfo, bytes);\n },\n} as const;\n\ntype KeyAgreement = keyof typeof calculateKeyAgreement;\n\n/* lists of algorithms/methods that are supported. The key agreement, hashes,\n * and MAC lists should be sorted in order of preference (most preferred\n * first).\n */\nconst KEY_AGREEMENT_LIST: KeyAgreement[] = [\"curve25519-hkdf-sha256\", \"curve25519\"];\nconst HASHES_LIST = [\"sha256\"];\nconst MAC_LIST: MacMethod[] = [\n \"hkdf-hmac-sha256.v2\",\n \"org.matrix.msc3783.hkdf-hmac-sha256\",\n \"hkdf-hmac-sha256\",\n \"hmac-sha256\",\n];\nconst SAS_LIST = Object.keys(sasGenerators);\n\nconst KEY_AGREEMENT_SET = new Set(KEY_AGREEMENT_LIST);\nconst HASHES_SET = new Set(HASHES_LIST);\nconst MAC_SET = new Set(MAC_LIST);\nconst SAS_SET = new Set(SAS_LIST);\n\nfunction intersection<T>(anArray: T[], aSet: Set<T>): T[] {\n return Array.isArray(anArray) ? anArray.filter((x) => aSet.has(x)) : [];\n}\n\nexport enum SasEvent {\n ShowSas = \"show_sas\",\n}\n\ntype EventHandlerMap = {\n [SasEvent.ShowSas]: (sas: ISasEvent) => void;\n} & VerificationEventHandlerMap;\n\nexport class SAS extends Base<SasEvent, EventHandlerMap> {\n private waitingForAccept?: boolean;\n public ourSASPubKey?: string;\n public theirSASPubKey?: string;\n public sasEvent?: ISasEvent;\n\n // eslint-disable-next-line @typescript-eslint/naming-convention\n public static get NAME(): string {\n return \"m.sas.v1\";\n }\n\n public get events(): string[] {\n return EVENTS;\n }\n\n protected doVerification = async (): Promise<void> => {\n await global.Olm.init();\n olmutil = olmutil || new global.Olm.Utility();\n\n // make sure user's keys are downloaded\n await this.baseApis.downloadKeys([this.userId]);\n\n let retry = false;\n do {\n try {\n if (this.initiatedByMe) {\n return await this.doSendVerification();\n } else {\n return await this.doRespondVerification();\n }\n } catch (err) {\n if (err instanceof SwitchStartEventError) {\n // this changes what initiatedByMe returns\n this.startEvent = err.startEvent;\n retry = true;\n } else {\n throw err;\n }\n }\n } while (retry);\n };\n\n public canSwitchStartEvent(event: MatrixEvent): boolean {\n if (event.getType() !== START_TYPE) {\n return false;\n }\n const content = event.getContent();\n return content?.method === SAS.NAME && !!this.waitingForAccept;\n }\n\n private async sendStart(): Promise<Record<string, any>> {\n const startContent = this.channel.completeContent(START_TYPE, {\n method: SAS.NAME,\n from_device: this.baseApis.deviceId,\n key_agreement_protocols: KEY_AGREEMENT_LIST,\n hashes: HASHES_LIST,\n message_authentication_codes: MAC_LIST,\n // FIXME: allow app to specify what SAS methods can be used\n short_authentication_string: SAS_LIST,\n });\n await this.channel.sendCompleted(START_TYPE, startContent);\n return startContent;\n }\n\n private async verifyAndCheckMAC(\n keyAgreement: KeyAgreement,\n sasMethods: string[],\n olmSAS: OlmSAS,\n macMethod: MacMethod,\n ): Promise<void> {\n const sasBytes = calculateKeyAgreement[keyAgreement](this, olmSAS, 6);\n const verifySAS = new Promise<void>((resolve, reject) => {\n this.sasEvent = {\n sas: generateSas(sasBytes, sasMethods),\n confirm: async (): Promise<void> => {\n try {\n await this.sendMAC(olmSAS, macMethod);\n resolve();\n } catch (err) {\n reject(err);\n }\n },\n cancel: () => reject(newUserCancelledError()),\n mismatch: () => reject(newMismatchedSASError()),\n };\n this.emit(SasEvent.ShowSas, this.sasEvent);\n });\n\n const [e] = await Promise.all([\n this.waitForEvent(EventType.KeyVerificationMac).then((e) => {\n // we don't expect any more messages from the other\n // party, and they may send a m.key.verification.done\n // when they're done on their end\n this.expectedEvent = EventType.KeyVerificationDone;\n return e;\n }),\n verifySAS,\n ]);\n const content = e.getContent();\n await this.checkMAC(olmSAS, content, macMethod);\n }\n\n private async doSendVerification(): Promise<void> {\n this.waitingForAccept = true;\n let startContent;\n if (this.startEvent) {\n startContent = this.channel.completedContentFromEvent(this.startEvent);\n } else {\n startContent = await this.sendStart();\n }\n\n // we might have switched to a different start event,\n // but was we didn't call _waitForEvent there was no\n // call that could throw yet. So check manually that\n // we're still on the initiator side\n if (!this.initiatedByMe) {\n throw new SwitchStartEventError(this.startEvent);\n }\n\n let e: MatrixEvent;\n try {\n e = await this.waitForEvent(EventType.KeyVerificationAccept);\n } finally {\n this.waitingForAccept = false;\n }\n let content = e.getContent();\n const sasMethods = intersection(content.short_authentication_string, SAS_SET);\n if (\n !(\n KEY_AGREEMENT_SET.has(content.key_agreement_protocol) &&\n HASHES_SET.has(content.hash) &&\n MAC_SET.has(content.message_authentication_code) &&\n sasMethods.length\n )\n ) {\n throw newUnknownMethodError();\n }\n if (typeof content.commitment !== \"string\") {\n throw newInvalidMessageError();\n }\n const keyAgreement = content.key_agreement_protocol;\n const macMethod = content.message_authentication_code;\n const hashCommitment = content.commitment;\n const olmSAS = new global.Olm.SAS();\n try {\n this.ourSASPubKey = olmSAS.get_pubkey();\n await this.send(EventType.KeyVerificationKey, {\n key: this.ourSASPubKey,\n });\n\n e = await this.waitForEvent(EventType.KeyVerificationKey);\n // FIXME: make sure event is properly formed\n content = e.getContent();\n const commitmentStr = content.key + anotherjson.stringify(startContent);\n // TODO: use selected hash function (when we support multiple)\n if (olmutil.sha256(commitmentStr) !== hashCommitment) {\n throw newMismatchedCommitmentError();\n }\n this.theirSASPubKey = content.key;\n olmSAS.set_their_key(content.key);\n\n await this.verifyAndCheckMAC(keyAgreement, sasMethods, olmSAS, macMethod);\n } finally {\n olmSAS.free();\n }\n }\n\n private async doRespondVerification(): Promise<void> {\n // as m.related_to is not included in the encrypted content in e2e rooms,\n // we need to make sure it is added\n let content = this.channel.completedContentFromEvent(this.startEvent!);\n\n // Note: we intersect using our pre-made lists, rather than the sets,\n // so that the result will be in our order of preference. Then\n // fetching the first element from the array will give our preferred\n // method out of the ones offered by the other party.\n const keyAgreement = intersection(KEY_AGREEMENT_LIST, new Set(content.key_agreement_protocols))[0];\n const hashMethod = intersection(HASHES_LIST, new Set(content.hashes))[0];\n const macMethod = intersection(MAC_LIST, new Set(content.message_authentication_codes))[0];\n // FIXME: allow app to specify what SAS methods can be used\n const sasMethods = intersection(content.short_authentication_string, SAS_SET);\n if (!(keyAgreement !== undefined && hashMethod !== undefined && macMethod !== undefined && sasMethods.length)) {\n throw newUnknownMethodError();\n }\n\n const olmSAS = new global.Olm.SAS();\n try {\n const commitmentStr = olmSAS.get_pubkey() + anotherjson.stringify(content);\n await this.send(EventType.KeyVerificationAccept, {\n key_agreement_protocol: keyAgreement,\n hash: hashMethod,\n message_authentication_code: macMethod,\n short_authentication_string: sasMethods,\n // TODO: use selected hash function (when we support multiple)\n commitment: olmutil.sha256(commitmentStr),\n });\n\n const e = await this.waitForEvent(EventType.KeyVerificationKey);\n // FIXME: make sure event is properly formed\n content = e.getContent();\n this.theirSASPubKey = content.key;\n olmSAS.set_their_key(content.key);\n this.ourSASPubKey = olmSAS.get_pubkey();\n await this.send(EventType.KeyVerificationKey, {\n key: this.ourSASPubKey,\n });\n\n await this.verifyAndCheckMAC(keyAgreement, sasMethods, olmSAS, macMethod);\n } finally {\n olmSAS.free();\n }\n }\n\n private sendMAC(olmSAS: OlmSAS, method: MacMethod): Promise<void> {\n const mac: Record<string, string> = {};\n const keyList: string[] = [];\n const baseInfo =\n \"MATRIX_KEY_VERIFICATION_MAC\" +\n this.baseApis.getUserId() +\n this.baseApis.deviceId +\n this.userId +\n this.deviceId +\n this.channel.transactionId;\n\n const deviceKeyId = `ed25519:${this.baseApis.deviceId}`;\n mac[deviceKeyId] = calculateMAC(olmSAS, method)(this.baseApis.getDeviceEd25519Key()!, baseInfo + deviceKeyId);\n keyList.push(deviceKeyId);\n\n const crossSigningId = this.baseApis.getCrossSigningId();\n if (crossSigningId) {\n const crossSigningKeyId = `ed25519:${crossSigningId}`;\n mac[crossSigningKeyId] = calculateMAC(olmSAS, method)(crossSigningId, baseInfo + crossSigningKeyId);\n keyList.push(crossSigningKeyId);\n }\n\n const keys = calculateMAC(olmSAS, method)(keyList.sort().join(\",\"), baseInfo + \"KEY_IDS\");\n return this.send(EventType.KeyVerificationMac, { mac, keys });\n }\n\n private async checkMAC(olmSAS: OlmSAS, content: IContent, method: MacMethod): Promise<void> {\n const baseInfo =\n \"MATRIX_KEY_VERIFICATION_MAC\" +\n this.userId +\n this.deviceId +\n this.baseApis.getUserId() +\n this.baseApis.deviceId +\n this.channel.transactionId;\n\n if (\n content.keys !==\n calculateMAC(olmSAS, method)(Object.keys(content.mac).sort().join(\",\"), baseInfo + \"KEY_IDS\")\n ) {\n throw newKeyMismatchError();\n }\n\n await this.verifyKeys(this.userId, content.mac, (keyId, device, keyInfo) => {\n if (keyInfo !== calculateMAC(olmSAS, method)(device.keys[keyId], baseInfo + keyId)) {\n throw newKeyMismatchError();\n }\n });\n }\n}\n"],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SASDecimal.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SASDecimal.d.ts
deleted file mode 100644
index 673b56a..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SASDecimal.d.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-/**
- * Implementation of decimal encoding of SAS as per:
- * https://spec.matrix.org/v1.4/client-server-api/#sas-method-decimal
- * @param sasBytes - the five bytes generated by HKDF
- * @returns the derived three numbers between 1000 and 9191 inclusive
- */
-export declare function generateDecimalSas(sasBytes: number[]): [number, number, number];
-//# sourceMappingURL=SASDecimal.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SASDecimal.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SASDecimal.d.ts.map
deleted file mode 100644
index bc7a0fa..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SASDecimal.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"SASDecimal.d.ts","sourceRoot":"","sources":["../../../src/crypto/verification/SASDecimal.ts"],"names":[],"mappings":"AAgBA;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAc/E"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SASDecimal.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SASDecimal.js
deleted file mode 100644
index 5ed2ea7..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SASDecimal.js
+++ /dev/null
@@ -1,40 +0,0 @@
-"use strict";
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.generateDecimalSas = generateDecimalSas;
-/*
-Copyright 2018 - 2022 The Matrix.org Foundation C.I.C.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-/**
- * Implementation of decimal encoding of SAS as per:
- * https://spec.matrix.org/v1.4/client-server-api/#sas-method-decimal
- * @param sasBytes - the five bytes generated by HKDF
- * @returns the derived three numbers between 1000 and 9191 inclusive
- */
-function generateDecimalSas(sasBytes) {
- /*
- * +--------+--------+--------+--------+--------+
- * | Byte 0 | Byte 1 | Byte 2 | Byte 3 | Byte 4 |
- * +--------+--------+--------+--------+--------+
- * bits: 87654321 87654321 87654321 87654321 87654321
- * \____________/\_____________/\____________/
- * 1st number 2nd number 3rd number
- */
- return [(sasBytes[0] << 5 | sasBytes[1] >> 3) + 1000, ((sasBytes[1] & 0x7) << 10 | sasBytes[2] << 2 | sasBytes[3] >> 6) + 1000, ((sasBytes[3] & 0x3f) << 7 | sasBytes[4] >> 1) + 1000];
-}
-//# sourceMappingURL=SASDecimal.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SASDecimal.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SASDecimal.js.map
deleted file mode 100644
index 5138d2b..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SASDecimal.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"SASDecimal.js","names":["generateDecimalSas","sasBytes"],"sources":["../../../src/crypto/verification/SASDecimal.ts"],"sourcesContent":["/*\nCopyright 2018 - 2022 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n/**\n * Implementation of decimal encoding of SAS as per:\n * https://spec.matrix.org/v1.4/client-server-api/#sas-method-decimal\n * @param sasBytes - the five bytes generated by HKDF\n * @returns the derived three numbers between 1000 and 9191 inclusive\n */\nexport function generateDecimalSas(sasBytes: number[]): [number, number, number] {\n /*\n * +--------+--------+--------+--------+--------+\n * | Byte 0 | Byte 1 | Byte 2 | Byte 3 | Byte 4 |\n * +--------+--------+--------+--------+--------+\n * bits: 87654321 87654321 87654321 87654321 87654321\n * \\____________/\\_____________/\\____________/\n * 1st number 2nd number 3rd number\n */\n return [\n ((sasBytes[0] << 5) | (sasBytes[1] >> 3)) + 1000,\n (((sasBytes[1] & 0x7) << 10) | (sasBytes[2] << 2) | (sasBytes[3] >> 6)) + 1000,\n (((sasBytes[3] & 0x3f) << 7) | (sasBytes[4] >> 1)) + 1000,\n ];\n}\n"],"mappings":";;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACO,SAASA,kBAAkBA,CAACC,QAAkB,EAA4B;EAC7E;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;EACI,OAAO,CACH,CAAEA,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAKA,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAE,IAAI,IAAI,EAChD,CAAE,CAACA,QAAQ,CAAC,CAAC,CAAC,GAAG,GAAG,KAAK,EAAE,GAAKA,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAE,GAAIA,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAE,IAAI,IAAI,EAC9E,CAAE,CAACA,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,KAAK,CAAC,GAAKA,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAE,IAAI,IAAI,CAC5D;AACL"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/Channel.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/Channel.d.ts
deleted file mode 100644
index f9948e2..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/Channel.d.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import { MatrixEvent } from "../../../models/event";
-import { VerificationRequest } from "./VerificationRequest";
-export interface IVerificationChannel {
- request?: VerificationRequest;
- readonly userId?: string;
- readonly roomId?: string;
- readonly deviceId?: string;
- readonly transactionId?: string;
- readonly receiveStartFromOtherDevices?: boolean;
- getTimestamp(event: MatrixEvent): number;
- send(type: string, uncompletedContent: Record<string, any>): Promise<void>;
- completeContent(type: string, content: Record<string, any>): Record<string, any>;
- sendCompleted(type: string, content: Record<string, any>): Promise<void>;
- completedContentFromEvent(event: MatrixEvent): Record<string, any>;
- canCreateRequest(type: string): boolean;
- handleEvent(event: MatrixEvent, request: VerificationRequest, isLiveEvent: boolean): Promise<void>;
-}
-//# sourceMappingURL=Channel.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/Channel.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/Channel.d.ts.map
deleted file mode 100644
index 9951a5f..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/Channel.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"Channel.d.ts","sourceRoot":"","sources":["../../../../src/crypto/verification/request/Channel.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,MAAM,WAAW,oBAAoB;IACjC,OAAO,CAAC,EAAE,mBAAmB,CAAC;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,4BAA4B,CAAC,EAAE,OAAO,CAAC;IAChD,YAAY,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAAC;IACzC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3E,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACjF,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzE,yBAAyB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACnE,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACxC,WAAW,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACtG"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/Channel.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/Channel.js
deleted file mode 100644
index 93fbf04..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/Channel.js
+++ /dev/null
@@ -1,6 +0,0 @@
-"use strict";
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-//# sourceMappingURL=Channel.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/Channel.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/Channel.js.map
deleted file mode 100644
index 9d7004f..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/Channel.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"Channel.js","names":[],"sources":["../../../../src/crypto/verification/request/Channel.ts"],"sourcesContent":["/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { MatrixEvent } from \"../../../models/event\";\nimport { VerificationRequest } from \"./VerificationRequest\";\n\nexport interface IVerificationChannel {\n request?: VerificationRequest;\n readonly userId?: string;\n readonly roomId?: string;\n readonly deviceId?: string;\n readonly transactionId?: string;\n readonly receiveStartFromOtherDevices?: boolean;\n getTimestamp(event: MatrixEvent): number;\n send(type: string, uncompletedContent: Record<string, any>): Promise<void>;\n completeContent(type: string, content: Record<string, any>): Record<string, any>;\n sendCompleted(type: string, content: Record<string, any>): Promise<void>;\n completedContentFromEvent(event: MatrixEvent): Record<string, any>;\n canCreateRequest(type: string): boolean;\n handleEvent(event: MatrixEvent, request: VerificationRequest, isLiveEvent: boolean): Promise<void>;\n}\n"],"mappings":""} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/InRoomChannel.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/InRoomChannel.d.ts
deleted file mode 100644
index c646c90..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/InRoomChannel.d.ts
+++ /dev/null
@@ -1,113 +0,0 @@
-import { VerificationRequest } from "./VerificationRequest";
-import { IVerificationChannel } from "./Channel";
-import { MatrixClient } from "../../../client";
-import { MatrixEvent } from "../../../models/event";
-import { IRequestsMap } from "../..";
-/**
- * A key verification channel that sends verification events in the timeline of a room.
- * Uses the event id of the initial m.key.verification.request event as a transaction id.
- */
-export declare class InRoomChannel implements IVerificationChannel {
- private readonly client;
- readonly roomId: string;
- userId?: string | undefined;
- private requestEventId?;
- /**
- * @param client - the matrix client, to send messages with and get current user & device from.
- * @param roomId - id of the room where verification events should be posted in, should be a DM with the given user.
- * @param userId - id of user that the verification request is directed at, should be present in the room.
- */
- constructor(client: MatrixClient, roomId: string, userId?: string | undefined);
- get receiveStartFromOtherDevices(): boolean;
- /** The transaction id generated/used by this verification channel */
- get transactionId(): string | undefined;
- static getOtherPartyUserId(event: MatrixEvent, client: MatrixClient): string | undefined;
- /**
- * @param event - the event to get the timestamp of
- * @returns the timestamp when the event was sent
- */
- getTimestamp(event: MatrixEvent): number;
- /**
- * Checks whether the given event type should be allowed to initiate a new VerificationRequest over this channel
- * @param type - the event type to check
- * @returns boolean flag
- */
- static canCreateRequest(type: string): boolean;
- canCreateRequest(type: string): boolean;
- /**
- * Extract the transaction id used by a given key verification event, if any
- * @param event - the event
- * @returns the transaction id
- */
- static getTransactionId(event: MatrixEvent): string | undefined;
- /**
- * Checks whether this event is a well-formed key verification event.
- * This only does checks that don't rely on the current state of a potentially already channel
- * so we can prevent channels being created by invalid events.
- * `handleEvent` can do more checks and choose to ignore invalid events.
- * @param event - the event to validate
- * @param client - the client to get the current user and device id from
- * @returns whether the event is valid and should be passed to handleEvent
- */
- static validateEvent(event: MatrixEvent, client: MatrixClient): boolean;
- /**
- * As m.key.verification.request events are as m.room.message events with the InRoomChannel
- * to have a fallback message in non-supporting clients, we map the real event type
- * to the symbolic one to keep things in unison with ToDeviceChannel
- * @param event - the event to get the type of
- * @returns the "symbolic" event type
- */
- static getEventType(event: MatrixEvent): string;
- /**
- * Changes the state of the channel, request, and verifier in response to a key verification event.
- * @param event - to handle
- * @param request - the request to forward handling to
- * @param isLiveEvent - whether this is an even received through sync or not
- * @returns a promise that resolves when any requests as an answer to the passed-in event are sent.
- */
- handleEvent(event: MatrixEvent, request: VerificationRequest, isLiveEvent?: boolean): Promise<void>;
- /**
- * Adds the transaction id (relation) back to a received event
- * so it has the same format as returned by `completeContent` before sending.
- * The relation can not appear on the event content because of encryption,
- * relations are excluded from encryption.
- * @param event - the received event
- * @returns the content object with the relation added again
- */
- completedContentFromEvent(event: MatrixEvent): Record<string, any>;
- /**
- * Add all the fields to content needed for sending it over this channel.
- * This is public so verification methods (SAS uses this) can get the exact
- * content that will be sent independent of the used channel,
- * as they need to calculate the hash of it.
- * @param type - the event type
- * @param content - the (incomplete) content
- * @returns the complete content, as it will be sent.
- */
- completeContent(type: string, content: Record<string, any>): Record<string, any>;
- /**
- * Send an event over the channel with the content not having gone through `completeContent`.
- * @param type - the event type
- * @param uncompletedContent - the (incomplete) content
- * @returns the promise of the request
- */
- send(type: string, uncompletedContent: Record<string, any>): Promise<void>;
- /**
- * Send an event over the channel with the content having gone through `completeContent` already.
- * @param type - the event type
- * @returns the promise of the request
- */
- sendCompleted(type: string, content: Record<string, any>): Promise<void>;
-}
-export declare class InRoomRequests implements IRequestsMap {
- private requestsByRoomId;
- getRequest(event: MatrixEvent): VerificationRequest | undefined;
- getRequestByChannel(channel: InRoomChannel): VerificationRequest | undefined;
- private getRequestByTxnId;
- setRequest(event: MatrixEvent, request: VerificationRequest): void;
- setRequestByChannel(channel: IVerificationChannel, request: VerificationRequest): void;
- private doSetRequest;
- removeRequest(event: MatrixEvent): void;
- findRequestInProgress(roomId: string): VerificationRequest | undefined;
-}
-//# sourceMappingURL=InRoomChannel.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/InRoomChannel.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/InRoomChannel.d.ts.map
deleted file mode 100644
index 05c308c..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/InRoomChannel.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"InRoomChannel.d.ts","sourceRoot":"","sources":["../../../../src/crypto/verification/request/InRoomChannel.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,mBAAmB,EAAwC,MAAM,uBAAuB,CAAC;AAElG,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAEjD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAMrC;;;GAGG;AACH,qBAAa,aAAc,YAAW,oBAAoB;IAQnC,OAAO,CAAC,QAAQ,CAAC,MAAM;aAAgC,MAAM,EAAE,MAAM;IAAS,MAAM,CAAC;IAPxG,OAAO,CAAC,cAAc,CAAC,CAAS;IAEhC;;;;OAIG;gBACiC,MAAM,EAAE,YAAY,EAAkB,MAAM,EAAE,MAAM,EAAS,MAAM,CAAC,oBAAQ;IAEhH,IAAW,4BAA4B,IAAI,OAAO,CAEjD;IAED,qEAAqE;IACrE,IAAW,aAAa,IAAI,MAAM,GAAG,SAAS,CAE7C;WAEa,mBAAmB,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,GAAG,MAAM,GAAG,SAAS;IAiB/F;;;OAGG;IACI,YAAY,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM;IAI/C;;;;OAIG;WACW,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI9C,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI9C;;;;OAIG;WACW,gBAAgB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS;IAWtE;;;;;;;;OAQG;WACW,aAAa,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO;IA8B9E;;;;;;OAMG;WACW,YAAY,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM;IAkBtD;;;;;;OAMG;IACU,WAAW,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,mBAAmB,EAAE,WAAW,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAuC9G;;;;;;;OAOG;IACI,yBAAyB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAQzE;;;;;;;;OAQG;IACI,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IA4BvF;;;;;OAKG;IACI,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAKjF;;;;OAIG;IACU,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;CAUxF;AAED,qBAAa,cAAe,YAAW,YAAY;IAC/C,OAAO,CAAC,gBAAgB,CAAuD;IAExE,UAAU,CAAC,KAAK,EAAE,WAAW,GAAG,mBAAmB,GAAG,SAAS;IAM/D,mBAAmB,CAAC,OAAO,EAAE,aAAa,GAAG,mBAAmB,GAAG,SAAS;IAInF,OAAO,CAAC,iBAAiB;IAOlB,UAAU,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,mBAAmB,GAAG,IAAI;IAIlE,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,EAAE,OAAO,EAAE,mBAAmB,GAAG,IAAI;IAI7F,OAAO,CAAC,YAAY;IASb,aAAa,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAWvC,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,mBAAmB,GAAG,SAAS;CAUhF"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/InRoomChannel.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/InRoomChannel.js
deleted file mode 100644
index 480e980..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/InRoomChannel.js
+++ /dev/null
@@ -1,344 +0,0 @@
-"use strict";
-
-var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.InRoomRequests = exports.InRoomChannel = void 0;
-var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
-var _VerificationRequest = require("./VerificationRequest");
-var _logger = require("../../../logger");
-var _event = require("../../../@types/event");
-/*
-Copyright 2018 New Vector Ltd
-Copyright 2019 The Matrix.org Foundation C.I.C.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-const MESSAGE_TYPE = _event.EventType.RoomMessage;
-const M_REFERENCE = "m.reference";
-const M_RELATES_TO = "m.relates_to";
-
-/**
- * A key verification channel that sends verification events in the timeline of a room.
- * Uses the event id of the initial m.key.verification.request event as a transaction id.
- */
-class InRoomChannel {
- /**
- * @param client - the matrix client, to send messages with and get current user & device from.
- * @param roomId - id of the room where verification events should be posted in, should be a DM with the given user.
- * @param userId - id of user that the verification request is directed at, should be present in the room.
- */
- constructor(client, roomId, userId) {
- this.client = client;
- this.roomId = roomId;
- this.userId = userId;
- (0, _defineProperty2.default)(this, "requestEventId", void 0);
- }
- get receiveStartFromOtherDevices() {
- return true;
- }
-
- /** The transaction id generated/used by this verification channel */
- get transactionId() {
- return this.requestEventId;
- }
- static getOtherPartyUserId(event, client) {
- const type = InRoomChannel.getEventType(event);
- if (type !== _VerificationRequest.REQUEST_TYPE) {
- return;
- }
- const ownUserId = client.getUserId();
- const sender = event.getSender();
- const content = event.getContent();
- const receiver = content.to;
- if (sender === ownUserId) {
- return receiver;
- } else if (receiver === ownUserId) {
- return sender;
- }
- }
-
- /**
- * @param event - the event to get the timestamp of
- * @returns the timestamp when the event was sent
- */
- getTimestamp(event) {
- return event.getTs();
- }
-
- /**
- * Checks whether the given event type should be allowed to initiate a new VerificationRequest over this channel
- * @param type - the event type to check
- * @returns boolean flag
- */
- static canCreateRequest(type) {
- return type === _VerificationRequest.REQUEST_TYPE;
- }
- canCreateRequest(type) {
- return InRoomChannel.canCreateRequest(type);
- }
-
- /**
- * Extract the transaction id used by a given key verification event, if any
- * @param event - the event
- * @returns the transaction id
- */
- static getTransactionId(event) {
- if (InRoomChannel.getEventType(event) === _VerificationRequest.REQUEST_TYPE) {
- return event.getId();
- } else {
- const relation = event.getRelation();
- if ((relation === null || relation === void 0 ? void 0 : relation.rel_type) === M_REFERENCE) {
- return relation.event_id;
- }
- }
- }
-
- /**
- * Checks whether this event is a well-formed key verification event.
- * This only does checks that don't rely on the current state of a potentially already channel
- * so we can prevent channels being created by invalid events.
- * `handleEvent` can do more checks and choose to ignore invalid events.
- * @param event - the event to validate
- * @param client - the client to get the current user and device id from
- * @returns whether the event is valid and should be passed to handleEvent
- */
- static validateEvent(event, client) {
- const txnId = InRoomChannel.getTransactionId(event);
- if (typeof txnId !== "string" || txnId.length === 0) {
- return false;
- }
- const type = InRoomChannel.getEventType(event);
- const content = event.getContent();
-
- // from here on we're fairly sure that this is supposed to be
- // part of a verification request, so be noisy when rejecting something
- if (type === _VerificationRequest.REQUEST_TYPE) {
- if (!content || typeof content.to !== "string" || !content.to.length) {
- _logger.logger.log("InRoomChannel: validateEvent: " + "no valid to " + (content && content.to));
- return false;
- }
-
- // ignore requests that are not direct to or sent by the syncing user
- if (!InRoomChannel.getOtherPartyUserId(event, client)) {
- _logger.logger.log("InRoomChannel: validateEvent: " + `not directed to or sent by me: ${event.getSender()}` + `, ${content && content.to}`);
- return false;
- }
- }
- return _VerificationRequest.VerificationRequest.validateEvent(type, event, client);
- }
-
- /**
- * As m.key.verification.request events are as m.room.message events with the InRoomChannel
- * to have a fallback message in non-supporting clients, we map the real event type
- * to the symbolic one to keep things in unison with ToDeviceChannel
- * @param event - the event to get the type of
- * @returns the "symbolic" event type
- */
- static getEventType(event) {
- const type = event.getType();
- if (type === MESSAGE_TYPE) {
- const content = event.getContent();
- if (content) {
- const {
- msgtype
- } = content;
- if (msgtype === _VerificationRequest.REQUEST_TYPE) {
- return _VerificationRequest.REQUEST_TYPE;
- }
- }
- }
- if (type && type !== _VerificationRequest.REQUEST_TYPE) {
- return type;
- } else {
- return "";
- }
- }
-
- /**
- * Changes the state of the channel, request, and verifier in response to a key verification event.
- * @param event - to handle
- * @param request - the request to forward handling to
- * @param isLiveEvent - whether this is an even received through sync or not
- * @returns a promise that resolves when any requests as an answer to the passed-in event are sent.
- */
- async handleEvent(event, request, isLiveEvent = false) {
- // prevent processing the same event multiple times, as under
- // some circumstances Room.timeline can get emitted twice for the same event
- if (request.hasEventId(event.getId())) {
- return;
- }
- const type = InRoomChannel.getEventType(event);
- // do validations that need state (roomId, userId),
- // ignore if invalid
-
- if (event.getRoomId() !== this.roomId) {
- return;
- }
- // set userId if not set already
- if (!this.userId) {
- const userId = InRoomChannel.getOtherPartyUserId(event, this.client);
- if (userId) {
- this.userId = userId;
- }
- }
- // ignore events not sent by us or the other party
- const ownUserId = this.client.getUserId();
- const sender = event.getSender();
- if (this.userId) {
- if (sender !== ownUserId && sender !== this.userId) {
- _logger.logger.log(`InRoomChannel: ignoring verification event from non-participating sender ${sender}`);
- return;
- }
- }
- if (!this.requestEventId) {
- this.requestEventId = InRoomChannel.getTransactionId(event);
- }
- const isRemoteEcho = !!event.getUnsigned().transaction_id;
- const isSentByUs = event.getSender() === this.client.getUserId();
- return request.handleEvent(type, event, isLiveEvent, isRemoteEcho, isSentByUs);
- }
-
- /**
- * Adds the transaction id (relation) back to a received event
- * so it has the same format as returned by `completeContent` before sending.
- * The relation can not appear on the event content because of encryption,
- * relations are excluded from encryption.
- * @param event - the received event
- * @returns the content object with the relation added again
- */
- completedContentFromEvent(event) {
- // ensure m.related_to is included in e2ee rooms
- // as the field is excluded from encryption
- const content = Object.assign({}, event.getContent());
- content[M_RELATES_TO] = event.getRelation();
- return content;
- }
-
- /**
- * Add all the fields to content needed for sending it over this channel.
- * This is public so verification methods (SAS uses this) can get the exact
- * content that will be sent independent of the used channel,
- * as they need to calculate the hash of it.
- * @param type - the event type
- * @param content - the (incomplete) content
- * @returns the complete content, as it will be sent.
- */
- completeContent(type, content) {
- content = Object.assign({}, content);
- if (type === _VerificationRequest.REQUEST_TYPE || type === _VerificationRequest.READY_TYPE || type === _VerificationRequest.START_TYPE) {
- content.from_device = this.client.getDeviceId();
- }
- if (type === _VerificationRequest.REQUEST_TYPE) {
- // type is mapped to m.room.message in the send method
- content = {
- body: this.client.getUserId() + " is requesting to verify " + "your key, but your client does not support in-chat key " + "verification. You will need to use legacy key " + "verification to verify keys.",
- msgtype: _VerificationRequest.REQUEST_TYPE,
- to: this.userId,
- from_device: content.from_device,
- methods: content.methods
- };
- } else {
- content[M_RELATES_TO] = {
- rel_type: M_REFERENCE,
- event_id: this.transactionId
- };
- }
- return content;
- }
-
- /**
- * Send an event over the channel with the content not having gone through `completeContent`.
- * @param type - the event type
- * @param uncompletedContent - the (incomplete) content
- * @returns the promise of the request
- */
- send(type, uncompletedContent) {
- const content = this.completeContent(type, uncompletedContent);
- return this.sendCompleted(type, content);
- }
-
- /**
- * Send an event over the channel with the content having gone through `completeContent` already.
- * @param type - the event type
- * @returns the promise of the request
- */
- async sendCompleted(type, content) {
- let sendType = type;
- if (type === _VerificationRequest.REQUEST_TYPE) {
- sendType = MESSAGE_TYPE;
- }
- const response = await this.client.sendEvent(this.roomId, sendType, content);
- if (type === _VerificationRequest.REQUEST_TYPE) {
- this.requestEventId = response.event_id;
- }
- }
-}
-exports.InRoomChannel = InRoomChannel;
-class InRoomRequests {
- constructor() {
- (0, _defineProperty2.default)(this, "requestsByRoomId", new Map());
- }
- getRequest(event) {
- const roomId = event.getRoomId();
- const txnId = InRoomChannel.getTransactionId(event);
- return this.getRequestByTxnId(roomId, txnId);
- }
- getRequestByChannel(channel) {
- return this.getRequestByTxnId(channel.roomId, channel.transactionId);
- }
- getRequestByTxnId(roomId, txnId) {
- const requestsByTxnId = this.requestsByRoomId.get(roomId);
- if (requestsByTxnId) {
- return requestsByTxnId.get(txnId);
- }
- }
- setRequest(event, request) {
- this.doSetRequest(event.getRoomId(), InRoomChannel.getTransactionId(event), request);
- }
- setRequestByChannel(channel, request) {
- this.doSetRequest(channel.roomId, channel.transactionId, request);
- }
- doSetRequest(roomId, txnId, request) {
- let requestsByTxnId = this.requestsByRoomId.get(roomId);
- if (!requestsByTxnId) {
- requestsByTxnId = new Map();
- this.requestsByRoomId.set(roomId, requestsByTxnId);
- }
- requestsByTxnId.set(txnId, request);
- }
- removeRequest(event) {
- const roomId = event.getRoomId();
- const requestsByTxnId = this.requestsByRoomId.get(roomId);
- if (requestsByTxnId) {
- requestsByTxnId.delete(InRoomChannel.getTransactionId(event));
- if (requestsByTxnId.size === 0) {
- this.requestsByRoomId.delete(roomId);
- }
- }
- }
- findRequestInProgress(roomId) {
- const requestsByTxnId = this.requestsByRoomId.get(roomId);
- if (requestsByTxnId) {
- for (const request of requestsByTxnId.values()) {
- if (request.pending) {
- return request;
- }
- }
- }
- }
-}
-exports.InRoomRequests = InRoomRequests;
-//# sourceMappingURL=InRoomChannel.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/InRoomChannel.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/InRoomChannel.js.map
deleted file mode 100644
index 5b61e18..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/InRoomChannel.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"InRoomChannel.js","names":["_VerificationRequest","require","_logger","_event","MESSAGE_TYPE","EventType","RoomMessage","M_REFERENCE","M_RELATES_TO","InRoomChannel","constructor","client","roomId","userId","_defineProperty2","default","receiveStartFromOtherDevices","transactionId","requestEventId","getOtherPartyUserId","event","type","getEventType","REQUEST_TYPE","ownUserId","getUserId","sender","getSender","content","getContent","receiver","to","getTimestamp","getTs","canCreateRequest","getTransactionId","getId","relation","getRelation","rel_type","event_id","validateEvent","txnId","length","logger","log","VerificationRequest","getType","msgtype","handleEvent","request","isLiveEvent","hasEventId","getRoomId","isRemoteEcho","getUnsigned","transaction_id","isSentByUs","completedContentFromEvent","Object","assign","completeContent","READY_TYPE","START_TYPE","from_device","getDeviceId","body","methods","send","uncompletedContent","sendCompleted","sendType","response","sendEvent","exports","InRoomRequests","Map","getRequest","getRequestByTxnId","getRequestByChannel","channel","requestsByTxnId","requestsByRoomId","get","setRequest","doSetRequest","setRequestByChannel","set","removeRequest","delete","size","findRequestInProgress","values","pending"],"sources":["../../../../src/crypto/verification/request/InRoomChannel.ts"],"sourcesContent":["/*\nCopyright 2018 New Vector Ltd\nCopyright 2019 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { VerificationRequest, REQUEST_TYPE, READY_TYPE, START_TYPE } from \"./VerificationRequest\";\nimport { logger } from \"../../../logger\";\nimport { IVerificationChannel } from \"./Channel\";\nimport { EventType } from \"../../../@types/event\";\nimport { MatrixClient } from \"../../../client\";\nimport { MatrixEvent } from \"../../../models/event\";\nimport { IRequestsMap } from \"../..\";\n\nconst MESSAGE_TYPE = EventType.RoomMessage;\nconst M_REFERENCE = \"m.reference\";\nconst M_RELATES_TO = \"m.relates_to\";\n\n/**\n * A key verification channel that sends verification events in the timeline of a room.\n * Uses the event id of the initial m.key.verification.request event as a transaction id.\n */\nexport class InRoomChannel implements IVerificationChannel {\n private requestEventId?: string;\n\n /**\n * @param client - the matrix client, to send messages with and get current user & device from.\n * @param roomId - id of the room where verification events should be posted in, should be a DM with the given user.\n * @param userId - id of user that the verification request is directed at, should be present in the room.\n */\n public constructor(private readonly client: MatrixClient, public readonly roomId: string, public userId?: string) {}\n\n public get receiveStartFromOtherDevices(): boolean {\n return true;\n }\n\n /** The transaction id generated/used by this verification channel */\n public get transactionId(): string | undefined {\n return this.requestEventId;\n }\n\n public static getOtherPartyUserId(event: MatrixEvent, client: MatrixClient): string | undefined {\n const type = InRoomChannel.getEventType(event);\n if (type !== REQUEST_TYPE) {\n return;\n }\n const ownUserId = client.getUserId();\n const sender = event.getSender();\n const content = event.getContent();\n const receiver = content.to;\n\n if (sender === ownUserId) {\n return receiver;\n } else if (receiver === ownUserId) {\n return sender;\n }\n }\n\n /**\n * @param event - the event to get the timestamp of\n * @returns the timestamp when the event was sent\n */\n public getTimestamp(event: MatrixEvent): number {\n return event.getTs();\n }\n\n /**\n * Checks whether the given event type should be allowed to initiate a new VerificationRequest over this channel\n * @param type - the event type to check\n * @returns boolean flag\n */\n public static canCreateRequest(type: string): boolean {\n return type === REQUEST_TYPE;\n }\n\n public canCreateRequest(type: string): boolean {\n return InRoomChannel.canCreateRequest(type);\n }\n\n /**\n * Extract the transaction id used by a given key verification event, if any\n * @param event - the event\n * @returns the transaction id\n */\n public static getTransactionId(event: MatrixEvent): string | undefined {\n if (InRoomChannel.getEventType(event) === REQUEST_TYPE) {\n return event.getId();\n } else {\n const relation = event.getRelation();\n if (relation?.rel_type === M_REFERENCE) {\n return relation.event_id;\n }\n }\n }\n\n /**\n * Checks whether this event is a well-formed key verification event.\n * This only does checks that don't rely on the current state of a potentially already channel\n * so we can prevent channels being created by invalid events.\n * `handleEvent` can do more checks and choose to ignore invalid events.\n * @param event - the event to validate\n * @param client - the client to get the current user and device id from\n * @returns whether the event is valid and should be passed to handleEvent\n */\n public static validateEvent(event: MatrixEvent, client: MatrixClient): boolean {\n const txnId = InRoomChannel.getTransactionId(event);\n if (typeof txnId !== \"string\" || txnId.length === 0) {\n return false;\n }\n const type = InRoomChannel.getEventType(event);\n const content = event.getContent();\n\n // from here on we're fairly sure that this is supposed to be\n // part of a verification request, so be noisy when rejecting something\n if (type === REQUEST_TYPE) {\n if (!content || typeof content.to !== \"string\" || !content.to.length) {\n logger.log(\"InRoomChannel: validateEvent: \" + \"no valid to \" + (content && content.to));\n return false;\n }\n\n // ignore requests that are not direct to or sent by the syncing user\n if (!InRoomChannel.getOtherPartyUserId(event, client)) {\n logger.log(\n \"InRoomChannel: validateEvent: \" +\n `not directed to or sent by me: ${event.getSender()}` +\n `, ${content && content.to}`,\n );\n return false;\n }\n }\n\n return VerificationRequest.validateEvent(type, event, client);\n }\n\n /**\n * As m.key.verification.request events are as m.room.message events with the InRoomChannel\n * to have a fallback message in non-supporting clients, we map the real event type\n * to the symbolic one to keep things in unison with ToDeviceChannel\n * @param event - the event to get the type of\n * @returns the \"symbolic\" event type\n */\n public static getEventType(event: MatrixEvent): string {\n const type = event.getType();\n if (type === MESSAGE_TYPE) {\n const content = event.getContent();\n if (content) {\n const { msgtype } = content;\n if (msgtype === REQUEST_TYPE) {\n return REQUEST_TYPE;\n }\n }\n }\n if (type && type !== REQUEST_TYPE) {\n return type;\n } else {\n return \"\";\n }\n }\n\n /**\n * Changes the state of the channel, request, and verifier in response to a key verification event.\n * @param event - to handle\n * @param request - the request to forward handling to\n * @param isLiveEvent - whether this is an even received through sync or not\n * @returns a promise that resolves when any requests as an answer to the passed-in event are sent.\n */\n public async handleEvent(event: MatrixEvent, request: VerificationRequest, isLiveEvent = false): Promise<void> {\n // prevent processing the same event multiple times, as under\n // some circumstances Room.timeline can get emitted twice for the same event\n if (request.hasEventId(event.getId()!)) {\n return;\n }\n const type = InRoomChannel.getEventType(event);\n // do validations that need state (roomId, userId),\n // ignore if invalid\n\n if (event.getRoomId() !== this.roomId) {\n return;\n }\n // set userId if not set already\n if (!this.userId) {\n const userId = InRoomChannel.getOtherPartyUserId(event, this.client);\n if (userId) {\n this.userId = userId;\n }\n }\n // ignore events not sent by us or the other party\n const ownUserId = this.client.getUserId();\n const sender = event.getSender();\n if (this.userId) {\n if (sender !== ownUserId && sender !== this.userId) {\n logger.log(`InRoomChannel: ignoring verification event from non-participating sender ${sender}`);\n return;\n }\n }\n if (!this.requestEventId) {\n this.requestEventId = InRoomChannel.getTransactionId(event);\n }\n\n const isRemoteEcho = !!event.getUnsigned().transaction_id;\n const isSentByUs = event.getSender() === this.client.getUserId();\n\n return request.handleEvent(type, event, isLiveEvent, isRemoteEcho, isSentByUs);\n }\n\n /**\n * Adds the transaction id (relation) back to a received event\n * so it has the same format as returned by `completeContent` before sending.\n * The relation can not appear on the event content because of encryption,\n * relations are excluded from encryption.\n * @param event - the received event\n * @returns the content object with the relation added again\n */\n public completedContentFromEvent(event: MatrixEvent): Record<string, any> {\n // ensure m.related_to is included in e2ee rooms\n // as the field is excluded from encryption\n const content = Object.assign({}, event.getContent());\n content[M_RELATES_TO] = event.getRelation()!;\n return content;\n }\n\n /**\n * Add all the fields to content needed for sending it over this channel.\n * This is public so verification methods (SAS uses this) can get the exact\n * content that will be sent independent of the used channel,\n * as they need to calculate the hash of it.\n * @param type - the event type\n * @param content - the (incomplete) content\n * @returns the complete content, as it will be sent.\n */\n public completeContent(type: string, content: Record<string, any>): Record<string, any> {\n content = Object.assign({}, content);\n if (type === REQUEST_TYPE || type === READY_TYPE || type === START_TYPE) {\n content.from_device = this.client.getDeviceId();\n }\n if (type === REQUEST_TYPE) {\n // type is mapped to m.room.message in the send method\n content = {\n body:\n this.client.getUserId() +\n \" is requesting to verify \" +\n \"your key, but your client does not support in-chat key \" +\n \"verification. You will need to use legacy key \" +\n \"verification to verify keys.\",\n msgtype: REQUEST_TYPE,\n to: this.userId,\n from_device: content.from_device,\n methods: content.methods,\n };\n } else {\n content[M_RELATES_TO] = {\n rel_type: M_REFERENCE,\n event_id: this.transactionId,\n };\n }\n return content;\n }\n\n /**\n * Send an event over the channel with the content not having gone through `completeContent`.\n * @param type - the event type\n * @param uncompletedContent - the (incomplete) content\n * @returns the promise of the request\n */\n public send(type: string, uncompletedContent: Record<string, any>): Promise<void> {\n const content = this.completeContent(type, uncompletedContent);\n return this.sendCompleted(type, content);\n }\n\n /**\n * Send an event over the channel with the content having gone through `completeContent` already.\n * @param type - the event type\n * @returns the promise of the request\n */\n public async sendCompleted(type: string, content: Record<string, any>): Promise<void> {\n let sendType = type;\n if (type === REQUEST_TYPE) {\n sendType = MESSAGE_TYPE;\n }\n const response = await this.client.sendEvent(this.roomId, sendType, content);\n if (type === REQUEST_TYPE) {\n this.requestEventId = response.event_id;\n }\n }\n}\n\nexport class InRoomRequests implements IRequestsMap {\n private requestsByRoomId = new Map<string, Map<string, VerificationRequest>>();\n\n public getRequest(event: MatrixEvent): VerificationRequest | undefined {\n const roomId = event.getRoomId()!;\n const txnId = InRoomChannel.getTransactionId(event)!;\n return this.getRequestByTxnId(roomId, txnId);\n }\n\n public getRequestByChannel(channel: InRoomChannel): VerificationRequest | undefined {\n return this.getRequestByTxnId(channel.roomId, channel.transactionId!);\n }\n\n private getRequestByTxnId(roomId: string, txnId: string): VerificationRequest | undefined {\n const requestsByTxnId = this.requestsByRoomId.get(roomId);\n if (requestsByTxnId) {\n return requestsByTxnId.get(txnId);\n }\n }\n\n public setRequest(event: MatrixEvent, request: VerificationRequest): void {\n this.doSetRequest(event.getRoomId()!, InRoomChannel.getTransactionId(event)!, request);\n }\n\n public setRequestByChannel(channel: IVerificationChannel, request: VerificationRequest): void {\n this.doSetRequest(channel.roomId!, channel.transactionId!, request);\n }\n\n private doSetRequest(roomId: string, txnId: string, request: VerificationRequest): void {\n let requestsByTxnId = this.requestsByRoomId.get(roomId);\n if (!requestsByTxnId) {\n requestsByTxnId = new Map();\n this.requestsByRoomId.set(roomId, requestsByTxnId);\n }\n requestsByTxnId.set(txnId, request);\n }\n\n public removeRequest(event: MatrixEvent): void {\n const roomId = event.getRoomId()!;\n const requestsByTxnId = this.requestsByRoomId.get(roomId);\n if (requestsByTxnId) {\n requestsByTxnId.delete(InRoomChannel.getTransactionId(event)!);\n if (requestsByTxnId.size === 0) {\n this.requestsByRoomId.delete(roomId);\n }\n }\n }\n\n public findRequestInProgress(roomId: string): VerificationRequest | undefined {\n const requestsByTxnId = this.requestsByRoomId.get(roomId);\n if (requestsByTxnId) {\n for (const request of requestsByTxnId.values()) {\n if (request.pending) {\n return request;\n }\n }\n }\n }\n}\n"],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/ToDeviceChannel.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/ToDeviceChannel.d.ts
deleted file mode 100644
index f7e97e8..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/ToDeviceChannel.d.ts
+++ /dev/null
@@ -1,105 +0,0 @@
-import { VerificationRequest } from "./VerificationRequest";
-import { MatrixEvent } from "../../../models/event";
-import { IVerificationChannel } from "./Channel";
-import { MatrixClient } from "../../../client";
-import { IRequestsMap } from "../..";
-export type Request = VerificationRequest<ToDeviceChannel>;
-/**
- * A key verification channel that sends verification events over to_device messages.
- * Generates its own transaction ids.
- */
-export declare class ToDeviceChannel implements IVerificationChannel {
- private readonly client;
- readonly userId: string;
- private readonly devices;
- transactionId?: string | undefined;
- deviceId?: string | undefined;
- request?: VerificationRequest;
- constructor(client: MatrixClient, userId: string, devices: string[], transactionId?: string | undefined, deviceId?: string | undefined);
- isToDevices(devices: string[]): boolean;
- static getEventType(event: MatrixEvent): string;
- /**
- * Extract the transaction id used by a given key verification event, if any
- * @param event - the event
- * @returns the transaction id
- */
- static getTransactionId(event: MatrixEvent): string;
- /**
- * Checks whether the given event type should be allowed to initiate a new VerificationRequest over this channel
- * @param type - the event type to check
- * @returns boolean flag
- */
- static canCreateRequest(type: string): boolean;
- canCreateRequest(type: string): boolean;
- /**
- * Checks whether this event is a well-formed key verification event.
- * This only does checks that don't rely on the current state of a potentially already channel
- * so we can prevent channels being created by invalid events.
- * `handleEvent` can do more checks and choose to ignore invalid events.
- * @param event - the event to validate
- * @param client - the client to get the current user and device id from
- * @returns whether the event is valid and should be passed to handleEvent
- */
- static validateEvent(event: MatrixEvent, client: MatrixClient): boolean;
- /**
- * @param event - the event to get the timestamp of
- * @returns the timestamp when the event was sent
- */
- getTimestamp(event: MatrixEvent): number;
- /**
- * Changes the state of the channel, request, and verifier in response to a key verification event.
- * @param event - to handle
- * @param request - the request to forward handling to
- * @param isLiveEvent - whether this is an even received through sync or not
- * @returns a promise that resolves when any requests as an answer to the passed-in event are sent.
- */
- handleEvent(event: MatrixEvent, request: Request, isLiveEvent?: boolean): Promise<void>;
- /**
- * See {@link InRoomChannel#completedContentFromEvent} for why this is needed.
- * @param event - the received event
- * @returns the content object
- */
- completedContentFromEvent(event: MatrixEvent): Record<string, any>;
- /**
- * Add all the fields to content needed for sending it over this channel.
- * This is public so verification methods (SAS uses this) can get the exact
- * content that will be sent independent of the used channel,
- * as they need to calculate the hash of it.
- * @param type - the event type
- * @param content - the (incomplete) content
- * @returns the complete content, as it will be sent.
- */
- completeContent(type: string, content: Record<string, any>): Record<string, any>;
- /**
- * Send an event over the channel with the content not having gone through `completeContent`.
- * @param type - the event type
- * @param uncompletedContent - the (incomplete) content
- * @returns the promise of the request
- */
- send(type: string, uncompletedContent?: Record<string, any>): Promise<void>;
- /**
- * Send an event over the channel with the content having gone through `completeContent` already.
- * @param type - the event type
- * @returns the promise of the request
- */
- sendCompleted(type: string, content: Record<string, any>): Promise<void>;
- private sendToDevices;
- /**
- * Allow Crypto module to create and know the transaction id before the .start event gets sent.
- * @returns the transaction id
- */
- static makeTransactionId(): string;
-}
-export declare class ToDeviceRequests implements IRequestsMap {
- private requestsByUserId;
- getRequest(event: MatrixEvent): Request | undefined;
- getRequestByChannel(channel: ToDeviceChannel): Request | undefined;
- getRequestBySenderAndTxnId(sender: string, txnId: string): Request | undefined;
- setRequest(event: MatrixEvent, request: Request): void;
- setRequestByChannel(channel: ToDeviceChannel, request: Request): void;
- setRequestBySenderAndTxnId(sender: string, txnId: string, request: Request): void;
- removeRequest(event: MatrixEvent): void;
- findRequestInProgress(userId: string, devices: string[]): Request | undefined;
- getRequestsInProgress(userId: string): Request[];
-}
-//# sourceMappingURL=ToDeviceChannel.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/ToDeviceChannel.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/ToDeviceChannel.d.ts.map
deleted file mode 100644
index f6a0de2..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/ToDeviceChannel.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"ToDeviceChannel.d.ts","sourceRoot":"","sources":["../../../../src/crypto/verification/request/ToDeviceChannel.ts"],"names":[],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/ToDeviceChannel.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/ToDeviceChannel.js
deleted file mode 100644
index 3f6e48c..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/ToDeviceChannel.js
+++ /dev/null
@@ -1,324 +0,0 @@
-"use strict";
-
-var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.ToDeviceRequests = exports.ToDeviceChannel = void 0;
-var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
-var _randomstring = require("../../../randomstring");
-var _logger = require("../../../logger");
-var _VerificationRequest = require("./VerificationRequest");
-var _Error = require("../Error");
-var _event = require("../../../models/event");
-/*
-Copyright 2018 New Vector Ltd
-Copyright 2019 The Matrix.org Foundation C.I.C.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-/**
- * A key verification channel that sends verification events over to_device messages.
- * Generates its own transaction ids.
- */
-class ToDeviceChannel {
- // userId and devices of user we're about to verify
- constructor(client, userId, devices, transactionId, deviceId) {
- this.client = client;
- this.userId = userId;
- this.devices = devices;
- this.transactionId = transactionId;
- this.deviceId = deviceId;
- (0, _defineProperty2.default)(this, "request", void 0);
- }
- isToDevices(devices) {
- if (devices.length === this.devices.length) {
- for (const device of devices) {
- if (!this.devices.includes(device)) {
- return false;
- }
- }
- return true;
- } else {
- return false;
- }
- }
- static getEventType(event) {
- return event.getType();
- }
-
- /**
- * Extract the transaction id used by a given key verification event, if any
- * @param event - the event
- * @returns the transaction id
- */
- static getTransactionId(event) {
- const content = event.getContent();
- return content && content.transaction_id;
- }
-
- /**
- * Checks whether the given event type should be allowed to initiate a new VerificationRequest over this channel
- * @param type - the event type to check
- * @returns boolean flag
- */
- static canCreateRequest(type) {
- return type === _VerificationRequest.REQUEST_TYPE || type === _VerificationRequest.START_TYPE;
- }
- canCreateRequest(type) {
- return ToDeviceChannel.canCreateRequest(type);
- }
-
- /**
- * Checks whether this event is a well-formed key verification event.
- * This only does checks that don't rely on the current state of a potentially already channel
- * so we can prevent channels being created by invalid events.
- * `handleEvent` can do more checks and choose to ignore invalid events.
- * @param event - the event to validate
- * @param client - the client to get the current user and device id from
- * @returns whether the event is valid and should be passed to handleEvent
- */
- static validateEvent(event, client) {
- if (event.isCancelled()) {
- _logger.logger.warn("Ignoring flagged verification request from " + event.getSender());
- return false;
- }
- const content = event.getContent();
- if (!content) {
- _logger.logger.warn("ToDeviceChannel.validateEvent: invalid: no content");
- return false;
- }
- if (!content.transaction_id) {
- _logger.logger.warn("ToDeviceChannel.validateEvent: invalid: no transaction_id");
- return false;
- }
- const type = event.getType();
- if (type === _VerificationRequest.REQUEST_TYPE) {
- if (!Number.isFinite(content.timestamp)) {
- _logger.logger.warn("ToDeviceChannel.validateEvent: invalid: no timestamp");
- return false;
- }
- if (event.getSender() === client.getUserId() && content.from_device == client.getDeviceId()) {
- // ignore requests from ourselves, because it doesn't make sense for a
- // device to verify itself
- _logger.logger.warn("ToDeviceChannel.validateEvent: invalid: from own device");
- return false;
- }
- }
- return _VerificationRequest.VerificationRequest.validateEvent(type, event, client);
- }
-
- /**
- * @param event - the event to get the timestamp of
- * @returns the timestamp when the event was sent
- */
- getTimestamp(event) {
- const content = event.getContent();
- return content && content.timestamp;
- }
-
- /**
- * Changes the state of the channel, request, and verifier in response to a key verification event.
- * @param event - to handle
- * @param request - the request to forward handling to
- * @param isLiveEvent - whether this is an even received through sync or not
- * @returns a promise that resolves when any requests as an answer to the passed-in event are sent.
- */
- async handleEvent(event, request, isLiveEvent = false) {
- const type = event.getType();
- const content = event.getContent();
- if (type === _VerificationRequest.REQUEST_TYPE || type === _VerificationRequest.READY_TYPE || type === _VerificationRequest.START_TYPE) {
- if (!this.transactionId) {
- this.transactionId = content.transaction_id;
- }
- const deviceId = content.from_device;
- // adopt deviceId if not set before and valid
- if (!this.deviceId && this.devices.includes(deviceId)) {
- this.deviceId = deviceId;
- }
- // if no device id or different from adopted one, cancel with sender
- if (!this.deviceId || this.deviceId !== deviceId) {
- // also check that message came from the device we sent the request to earlier on
- // and do send a cancel message to that device
- // (but don't cancel the request for the device we should be talking to)
- const cancelContent = this.completeContent(_VerificationRequest.CANCEL_TYPE, (0, _Error.errorFromEvent)((0, _Error.newUnexpectedMessageError)()));
- return this.sendToDevices(_VerificationRequest.CANCEL_TYPE, cancelContent, [deviceId]);
- }
- }
- const wasStarted = request.phase === _VerificationRequest.PHASE_STARTED || request.phase === _VerificationRequest.PHASE_READY;
- await request.handleEvent(event.getType(), event, isLiveEvent, false, false);
- const isStarted = request.phase === _VerificationRequest.PHASE_STARTED || request.phase === _VerificationRequest.PHASE_READY;
- const isAcceptingEvent = type === _VerificationRequest.START_TYPE || type === _VerificationRequest.READY_TYPE;
- // the request has picked a ready or start event, tell the other devices about it
- if (isAcceptingEvent && !wasStarted && isStarted && this.deviceId) {
- const nonChosenDevices = this.devices.filter(d => d !== this.deviceId && d !== this.client.getDeviceId());
- if (nonChosenDevices.length) {
- const message = this.completeContent(_VerificationRequest.CANCEL_TYPE, {
- code: "m.accepted",
- reason: "Verification request accepted by another device"
- });
- await this.sendToDevices(_VerificationRequest.CANCEL_TYPE, message, nonChosenDevices);
- }
- }
- }
-
- /**
- * See {@link InRoomChannel#completedContentFromEvent} for why this is needed.
- * @param event - the received event
- * @returns the content object
- */
- completedContentFromEvent(event) {
- return event.getContent();
- }
-
- /**
- * Add all the fields to content needed for sending it over this channel.
- * This is public so verification methods (SAS uses this) can get the exact
- * content that will be sent independent of the used channel,
- * as they need to calculate the hash of it.
- * @param type - the event type
- * @param content - the (incomplete) content
- * @returns the complete content, as it will be sent.
- */
- completeContent(type, content) {
- // make a copy
- content = Object.assign({}, content);
- if (this.transactionId) {
- content.transaction_id = this.transactionId;
- }
- if (type === _VerificationRequest.REQUEST_TYPE || type === _VerificationRequest.READY_TYPE || type === _VerificationRequest.START_TYPE) {
- content.from_device = this.client.getDeviceId();
- }
- if (type === _VerificationRequest.REQUEST_TYPE) {
- content.timestamp = Date.now();
- }
- return content;
- }
-
- /**
- * Send an event over the channel with the content not having gone through `completeContent`.
- * @param type - the event type
- * @param uncompletedContent - the (incomplete) content
- * @returns the promise of the request
- */
- send(type, uncompletedContent = {}) {
- // create transaction id when sending request
- if ((type === _VerificationRequest.REQUEST_TYPE || type === _VerificationRequest.START_TYPE) && !this.transactionId) {
- this.transactionId = ToDeviceChannel.makeTransactionId();
- }
- const content = this.completeContent(type, uncompletedContent);
- return this.sendCompleted(type, content);
- }
-
- /**
- * Send an event over the channel with the content having gone through `completeContent` already.
- * @param type - the event type
- * @returns the promise of the request
- */
- async sendCompleted(type, content) {
- let result;
- if (type === _VerificationRequest.REQUEST_TYPE || type === _VerificationRequest.CANCEL_TYPE && !this.deviceId) {
- result = await this.sendToDevices(type, content, this.devices);
- } else {
- result = await this.sendToDevices(type, content, [this.deviceId]);
- }
- // the VerificationRequest state machine requires remote echos of the event
- // the client sends itself, so we fake this for to_device messages
- const remoteEchoEvent = new _event.MatrixEvent({
- sender: this.client.getUserId(),
- content,
- type
- });
- await this.request.handleEvent(type, remoteEchoEvent, /*isLiveEvent=*/true, /*isRemoteEcho=*/true, /*isSentByUs=*/true);
- return result;
- }
- async sendToDevices(type, content, devices) {
- if (devices.length) {
- const deviceMessages = new Map();
- for (const deviceId of devices) {
- deviceMessages.set(deviceId, content);
- }
- await this.client.sendToDevice(type, new Map([[this.userId, deviceMessages]]));
- }
- }
-
- /**
- * Allow Crypto module to create and know the transaction id before the .start event gets sent.
- * @returns the transaction id
- */
- static makeTransactionId() {
- return (0, _randomstring.randomString)(32);
- }
-}
-exports.ToDeviceChannel = ToDeviceChannel;
-class ToDeviceRequests {
- constructor() {
- (0, _defineProperty2.default)(this, "requestsByUserId", new Map());
- }
- getRequest(event) {
- return this.getRequestBySenderAndTxnId(event.getSender(), ToDeviceChannel.getTransactionId(event));
- }
- getRequestByChannel(channel) {
- return this.getRequestBySenderAndTxnId(channel.userId, channel.transactionId);
- }
- getRequestBySenderAndTxnId(sender, txnId) {
- const requestsByTxnId = this.requestsByUserId.get(sender);
- if (requestsByTxnId) {
- return requestsByTxnId.get(txnId);
- }
- }
- setRequest(event, request) {
- this.setRequestBySenderAndTxnId(event.getSender(), ToDeviceChannel.getTransactionId(event), request);
- }
- setRequestByChannel(channel, request) {
- this.setRequestBySenderAndTxnId(channel.userId, channel.transactionId, request);
- }
- setRequestBySenderAndTxnId(sender, txnId, request) {
- let requestsByTxnId = this.requestsByUserId.get(sender);
- if (!requestsByTxnId) {
- requestsByTxnId = new Map();
- this.requestsByUserId.set(sender, requestsByTxnId);
- }
- requestsByTxnId.set(txnId, request);
- }
- removeRequest(event) {
- const userId = event.getSender();
- const requestsByTxnId = this.requestsByUserId.get(userId);
- if (requestsByTxnId) {
- requestsByTxnId.delete(ToDeviceChannel.getTransactionId(event));
- if (requestsByTxnId.size === 0) {
- this.requestsByUserId.delete(userId);
- }
- }
- }
- findRequestInProgress(userId, devices) {
- const requestsByTxnId = this.requestsByUserId.get(userId);
- if (requestsByTxnId) {
- for (const request of requestsByTxnId.values()) {
- if (request.pending && request.channel.isToDevices(devices)) {
- return request;
- }
- }
- }
- }
- getRequestsInProgress(userId) {
- const requestsByTxnId = this.requestsByUserId.get(userId);
- if (requestsByTxnId) {
- return Array.from(requestsByTxnId.values()).filter(r => r.pending);
- }
- return [];
- }
-}
-exports.ToDeviceRequests = ToDeviceRequests;
-//# sourceMappingURL=ToDeviceChannel.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/ToDeviceChannel.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/ToDeviceChannel.js.map
deleted file mode 100644
index 52bb286..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/ToDeviceChannel.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"ToDeviceChannel.js","names":["_randomstring","require","_logger","_VerificationRequest","_Error","_event","ToDeviceChannel","constructor","client","userId","devices","transactionId","deviceId","_defineProperty2","default","isToDevices","length","device","includes","getEventType","event","getType","getTransactionId","content","getContent","transaction_id","canCreateRequest","type","REQUEST_TYPE","START_TYPE","validateEvent","isCancelled","logger","warn","getSender","Number","isFinite","timestamp","getUserId","from_device","getDeviceId","VerificationRequest","getTimestamp","handleEvent","request","isLiveEvent","READY_TYPE","cancelContent","completeContent","CANCEL_TYPE","errorFromEvent","newUnexpectedMessageError","sendToDevices","wasStarted","phase","PHASE_STARTED","PHASE_READY","isStarted","isAcceptingEvent","nonChosenDevices","filter","d","message","code","reason","completedContentFromEvent","Object","assign","Date","now","send","uncompletedContent","makeTransactionId","sendCompleted","result","remoteEchoEvent","MatrixEvent","sender","deviceMessages","Map","set","sendToDevice","randomString","exports","ToDeviceRequests","getRequest","getRequestBySenderAndTxnId","getRequestByChannel","channel","txnId","requestsByTxnId","requestsByUserId","get","setRequest","setRequestBySenderAndTxnId","setRequestByChannel","removeRequest","delete","size","findRequestInProgress","values","pending","getRequestsInProgress","Array","from","r"],"sources":["../../../../src/crypto/verification/request/ToDeviceChannel.ts"],"sourcesContent":["/*\nCopyright 2018 New Vector Ltd\nCopyright 2019 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { randomString } from \"../../../randomstring\";\nimport { logger } from \"../../../logger\";\nimport {\n CANCEL_TYPE,\n PHASE_STARTED,\n PHASE_READY,\n REQUEST_TYPE,\n READY_TYPE,\n START_TYPE,\n VerificationRequest,\n} from \"./VerificationRequest\";\nimport { errorFromEvent, newUnexpectedMessageError } from \"../Error\";\nimport { MatrixEvent } from \"../../../models/event\";\nimport { IVerificationChannel } from \"./Channel\";\nimport { MatrixClient } from \"../../../client\";\nimport { IRequestsMap } from \"../..\";\n\nexport type Request = VerificationRequest<ToDeviceChannel>;\n\n/**\n * A key verification channel that sends verification events over to_device messages.\n * Generates its own transaction ids.\n */\nexport class ToDeviceChannel implements IVerificationChannel {\n public request?: VerificationRequest;\n\n // userId and devices of user we're about to verify\n public constructor(\n private readonly client: MatrixClient,\n public readonly userId: string,\n private readonly devices: string[],\n public transactionId?: string,\n public deviceId?: string,\n ) {}\n\n public isToDevices(devices: string[]): boolean {\n if (devices.length === this.devices.length) {\n for (const device of devices) {\n if (!this.devices.includes(device)) {\n return false;\n }\n }\n return true;\n } else {\n return false;\n }\n }\n\n public static getEventType(event: MatrixEvent): string {\n return event.getType();\n }\n\n /**\n * Extract the transaction id used by a given key verification event, if any\n * @param event - the event\n * @returns the transaction id\n */\n public static getTransactionId(event: MatrixEvent): string {\n const content = event.getContent();\n return content && content.transaction_id;\n }\n\n /**\n * Checks whether the given event type should be allowed to initiate a new VerificationRequest over this channel\n * @param type - the event type to check\n * @returns boolean flag\n */\n public static canCreateRequest(type: string): boolean {\n return type === REQUEST_TYPE || type === START_TYPE;\n }\n\n public canCreateRequest(type: string): boolean {\n return ToDeviceChannel.canCreateRequest(type);\n }\n\n /**\n * Checks whether this event is a well-formed key verification event.\n * This only does checks that don't rely on the current state of a potentially already channel\n * so we can prevent channels being created by invalid events.\n * `handleEvent` can do more checks and choose to ignore invalid events.\n * @param event - the event to validate\n * @param client - the client to get the current user and device id from\n * @returns whether the event is valid and should be passed to handleEvent\n */\n public static validateEvent(event: MatrixEvent, client: MatrixClient): boolean {\n if (event.isCancelled()) {\n logger.warn(\"Ignoring flagged verification request from \" + event.getSender());\n return false;\n }\n const content = event.getContent();\n if (!content) {\n logger.warn(\"ToDeviceChannel.validateEvent: invalid: no content\");\n return false;\n }\n\n if (!content.transaction_id) {\n logger.warn(\"ToDeviceChannel.validateEvent: invalid: no transaction_id\");\n return false;\n }\n\n const type = event.getType();\n\n if (type === REQUEST_TYPE) {\n if (!Number.isFinite(content.timestamp)) {\n logger.warn(\"ToDeviceChannel.validateEvent: invalid: no timestamp\");\n return false;\n }\n if (event.getSender() === client.getUserId() && content.from_device == client.getDeviceId()) {\n // ignore requests from ourselves, because it doesn't make sense for a\n // device to verify itself\n logger.warn(\"ToDeviceChannel.validateEvent: invalid: from own device\");\n return false;\n }\n }\n\n return VerificationRequest.validateEvent(type, event, client);\n }\n\n /**\n * @param event - the event to get the timestamp of\n * @returns the timestamp when the event was sent\n */\n public getTimestamp(event: MatrixEvent): number {\n const content = event.getContent();\n return content && content.timestamp;\n }\n\n /**\n * Changes the state of the channel, request, and verifier in response to a key verification event.\n * @param event - to handle\n * @param request - the request to forward handling to\n * @param isLiveEvent - whether this is an even received through sync or not\n * @returns a promise that resolves when any requests as an answer to the passed-in event are sent.\n */\n public async handleEvent(event: MatrixEvent, request: Request, isLiveEvent = false): Promise<void> {\n const type = event.getType();\n const content = event.getContent();\n if (type === REQUEST_TYPE || type === READY_TYPE || type === START_TYPE) {\n if (!this.transactionId) {\n this.transactionId = content.transaction_id;\n }\n const deviceId = content.from_device;\n // adopt deviceId if not set before and valid\n if (!this.deviceId && this.devices.includes(deviceId)) {\n this.deviceId = deviceId;\n }\n // if no device id or different from adopted one, cancel with sender\n if (!this.deviceId || this.deviceId !== deviceId) {\n // also check that message came from the device we sent the request to earlier on\n // and do send a cancel message to that device\n // (but don't cancel the request for the device we should be talking to)\n const cancelContent = this.completeContent(CANCEL_TYPE, errorFromEvent(newUnexpectedMessageError()));\n return this.sendToDevices(CANCEL_TYPE, cancelContent, [deviceId]);\n }\n }\n const wasStarted = request.phase === PHASE_STARTED || request.phase === PHASE_READY;\n\n await request.handleEvent(event.getType(), event, isLiveEvent, false, false);\n\n const isStarted = request.phase === PHASE_STARTED || request.phase === PHASE_READY;\n\n const isAcceptingEvent = type === START_TYPE || type === READY_TYPE;\n // the request has picked a ready or start event, tell the other devices about it\n if (isAcceptingEvent && !wasStarted && isStarted && this.deviceId) {\n const nonChosenDevices = this.devices.filter((d) => d !== this.deviceId && d !== this.client.getDeviceId());\n if (nonChosenDevices.length) {\n const message = this.completeContent(CANCEL_TYPE, {\n code: \"m.accepted\",\n reason: \"Verification request accepted by another device\",\n });\n await this.sendToDevices(CANCEL_TYPE, message, nonChosenDevices);\n }\n }\n }\n\n /**\n * See {@link InRoomChannel#completedContentFromEvent} for why this is needed.\n * @param event - the received event\n * @returns the content object\n */\n public completedContentFromEvent(event: MatrixEvent): Record<string, any> {\n return event.getContent();\n }\n\n /**\n * Add all the fields to content needed for sending it over this channel.\n * This is public so verification methods (SAS uses this) can get the exact\n * content that will be sent independent of the used channel,\n * as they need to calculate the hash of it.\n * @param type - the event type\n * @param content - the (incomplete) content\n * @returns the complete content, as it will be sent.\n */\n public completeContent(type: string, content: Record<string, any>): Record<string, any> {\n // make a copy\n content = Object.assign({}, content);\n if (this.transactionId) {\n content.transaction_id = this.transactionId;\n }\n if (type === REQUEST_TYPE || type === READY_TYPE || type === START_TYPE) {\n content.from_device = this.client.getDeviceId();\n }\n if (type === REQUEST_TYPE) {\n content.timestamp = Date.now();\n }\n return content;\n }\n\n /**\n * Send an event over the channel with the content not having gone through `completeContent`.\n * @param type - the event type\n * @param uncompletedContent - the (incomplete) content\n * @returns the promise of the request\n */\n public send(type: string, uncompletedContent: Record<string, any> = {}): Promise<void> {\n // create transaction id when sending request\n if ((type === REQUEST_TYPE || type === START_TYPE) && !this.transactionId) {\n this.transactionId = ToDeviceChannel.makeTransactionId();\n }\n const content = this.completeContent(type, uncompletedContent);\n return this.sendCompleted(type, content);\n }\n\n /**\n * Send an event over the channel with the content having gone through `completeContent` already.\n * @param type - the event type\n * @returns the promise of the request\n */\n public async sendCompleted(type: string, content: Record<string, any>): Promise<void> {\n let result;\n if (type === REQUEST_TYPE || (type === CANCEL_TYPE && !this.deviceId)) {\n result = await this.sendToDevices(type, content, this.devices);\n } else {\n result = await this.sendToDevices(type, content, [this.deviceId!]);\n }\n // the VerificationRequest state machine requires remote echos of the event\n // the client sends itself, so we fake this for to_device messages\n const remoteEchoEvent = new MatrixEvent({\n sender: this.client.getUserId()!,\n content,\n type,\n });\n await this.request!.handleEvent(\n type,\n remoteEchoEvent,\n /*isLiveEvent=*/ true,\n /*isRemoteEcho=*/ true,\n /*isSentByUs=*/ true,\n );\n return result;\n }\n\n private async sendToDevices(type: string, content: Record<string, any>, devices: string[]): Promise<void> {\n if (devices.length) {\n const deviceMessages: Map<string, Record<string, any>> = new Map();\n for (const deviceId of devices) {\n deviceMessages.set(deviceId, content);\n }\n\n await this.client.sendToDevice(type, new Map([[this.userId, deviceMessages]]));\n }\n }\n\n /**\n * Allow Crypto module to create and know the transaction id before the .start event gets sent.\n * @returns the transaction id\n */\n public static makeTransactionId(): string {\n return randomString(32);\n }\n}\n\nexport class ToDeviceRequests implements IRequestsMap {\n private requestsByUserId = new Map<string, Map<string, Request>>();\n\n public getRequest(event: MatrixEvent): Request | undefined {\n return this.getRequestBySenderAndTxnId(event.getSender()!, ToDeviceChannel.getTransactionId(event));\n }\n\n public getRequestByChannel(channel: ToDeviceChannel): Request | undefined {\n return this.getRequestBySenderAndTxnId(channel.userId, channel.transactionId!);\n }\n\n public getRequestBySenderAndTxnId(sender: string, txnId: string): Request | undefined {\n const requestsByTxnId = this.requestsByUserId.get(sender);\n if (requestsByTxnId) {\n return requestsByTxnId.get(txnId);\n }\n }\n\n public setRequest(event: MatrixEvent, request: Request): void {\n this.setRequestBySenderAndTxnId(event.getSender()!, ToDeviceChannel.getTransactionId(event), request);\n }\n\n public setRequestByChannel(channel: ToDeviceChannel, request: Request): void {\n this.setRequestBySenderAndTxnId(channel.userId, channel.transactionId!, request);\n }\n\n public setRequestBySenderAndTxnId(sender: string, txnId: string, request: Request): void {\n let requestsByTxnId = this.requestsByUserId.get(sender);\n if (!requestsByTxnId) {\n requestsByTxnId = new Map();\n this.requestsByUserId.set(sender, requestsByTxnId);\n }\n requestsByTxnId.set(txnId, request);\n }\n\n public removeRequest(event: MatrixEvent): void {\n const userId = event.getSender()!;\n const requestsByTxnId = this.requestsByUserId.get(userId);\n if (requestsByTxnId) {\n requestsByTxnId.delete(ToDeviceChannel.getTransactionId(event));\n if (requestsByTxnId.size === 0) {\n this.requestsByUserId.delete(userId);\n }\n }\n }\n\n public findRequestInProgress(userId: string, devices: string[]): Request | undefined {\n const requestsByTxnId = this.requestsByUserId.get(userId);\n if (requestsByTxnId) {\n for (const request of requestsByTxnId.values()) {\n if (request.pending && request.channel.isToDevices(devices)) {\n return request;\n }\n }\n }\n }\n\n public getRequestsInProgress(userId: string): Request[] {\n const requestsByTxnId = this.requestsByUserId.get(userId);\n if (requestsByTxnId) {\n return Array.from(requestsByTxnId.values()).filter((r) => r.pending);\n }\n return [];\n }\n}\n"],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/VerificationRequest.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/VerificationRequest.d.ts
deleted file mode 100644
index 8d16b31..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/VerificationRequest.d.ts
+++ /dev/null
@@ -1,208 +0,0 @@
-import { QRCodeData } from "../QRCode";
-import { IVerificationChannel } from "./Channel";
-import { MatrixClient } from "../../../client";
-import { MatrixEvent } from "../../../models/event";
-import { VerificationBase } from "../Base";
-import { VerificationMethod } from "../../index";
-import { TypedEventEmitter } from "../../../models/typed-event-emitter";
-export declare const EVENT_PREFIX = "m.key.verification.";
-export declare const REQUEST_TYPE: string;
-export declare const START_TYPE: string;
-export declare const CANCEL_TYPE: string;
-export declare const DONE_TYPE: string;
-export declare const READY_TYPE: string;
-export declare enum Phase {
- Unsent = 1,
- Requested = 2,
- Ready = 3,
- Started = 4,
- Cancelled = 5,
- Done = 6
-}
-export declare const PHASE_UNSENT = Phase.Unsent;
-export declare const PHASE_REQUESTED = Phase.Requested;
-export declare const PHASE_READY = Phase.Ready;
-export declare const PHASE_STARTED = Phase.Started;
-export declare const PHASE_CANCELLED = Phase.Cancelled;
-export declare const PHASE_DONE = Phase.Done;
-interface ITargetDevice {
- userId?: string;
- deviceId?: string;
-}
-export declare enum VerificationRequestEvent {
- Change = "change"
-}
-type EventHandlerMap = {
- /**
- * Fires whenever the state of the request object has changed.
- */
- [VerificationRequestEvent.Change]: () => void;
-};
-/**
- * State machine for verification requests.
- * Things that differ based on what channel is used to
- * send and receive verification events are put in `InRoomChannel` or `ToDeviceChannel`.
- */
-export declare class VerificationRequest<C extends IVerificationChannel = IVerificationChannel> extends TypedEventEmitter<VerificationRequestEvent, EventHandlerMap> {
- readonly channel: C;
- private readonly verificationMethods;
- private readonly client;
- private eventsByUs;
- private eventsByThem;
- private _observeOnly;
- private timeoutTimer;
- private _accepting;
- private _declining;
- private verifierHasFinished;
- private _cancelled;
- private _chosenMethod;
- private _qrCodeData;
- private requestReceivedAt;
- private commonMethods;
- private _phase;
- _cancellingUserId?: string;
- private _verifier?;
- constructor(channel: C, verificationMethods: Map<VerificationMethod, typeof VerificationBase>, client: MatrixClient);
- /**
- * Stateless validation logic not specific to the channel.
- * Invoked by the same static method in either channel.
- * @param type - the "symbolic" event type, as returned by the `getEventType` function on the channel.
- * @param event - the event to validate. Don't call getType() on it but use the `type` parameter instead.
- * @param client - the client to get the current user and device id from
- * @returns whether the event is valid and should be passed to handleEvent
- */
- static validateEvent(type: string, event: MatrixEvent, client: MatrixClient): boolean;
- get invalid(): boolean;
- /** returns whether the phase is PHASE_REQUESTED */
- get requested(): boolean;
- /** returns whether the phase is PHASE_CANCELLED */
- get cancelled(): boolean;
- /** returns whether the phase is PHASE_READY */
- get ready(): boolean;
- /** returns whether the phase is PHASE_STARTED */
- get started(): boolean;
- /** returns whether the phase is PHASE_DONE */
- get done(): boolean;
- /** once the phase is PHASE_STARTED (and !initiatedByMe) or PHASE_READY: common methods supported by both sides */
- get methods(): VerificationMethod[];
- /** the method picked in the .start event */
- get chosenMethod(): VerificationMethod | null;
- calculateEventTimeout(event: MatrixEvent): number;
- /** The current remaining amount of ms before the request should be automatically cancelled */
- get timeout(): number;
- /**
- * The key verification request event.
- * @returns The request event, or falsey if not found.
- */
- get requestEvent(): MatrixEvent | undefined;
- /** current phase of the request. Some properties might only be defined in a current phase. */
- get phase(): Phase;
- /** The verifier to do the actual verification, once the method has been established. Only defined when the `phase` is PHASE_STARTED. */
- get verifier(): VerificationBase<any, any> | undefined;
- get canAccept(): boolean;
- get accepting(): boolean;
- get declining(): boolean;
- /** whether this request has sent it's initial event and needs more events to complete */
- get pending(): boolean;
- /** Only set after a .ready if the other party can scan a QR code */
- get qrCodeData(): QRCodeData | null;
- /** Checks whether the other party supports a given verification method.
- * This is useful when setting up the QR code UI, as it is somewhat asymmetrical:
- * if the other party supports SCAN_QR, we should show a QR code in the UI, and vice versa.
- * For methods that need to be supported by both ends, use the `methods` property.
- * @param method - the method to check
- * @param force - to check even if the phase is not ready or started yet, internal usage
- * @returns whether or not the other party said the supported the method */
- otherPartySupportsMethod(method: string, force?: boolean): boolean;
- /** Whether this request was initiated by the syncing user.
- * For InRoomChannel, this is who sent the .request event.
- * For ToDeviceChannel, this is who sent the .start event
- */
- get initiatedByMe(): boolean;
- /** The id of the user that initiated the request */
- get requestingUserId(): string;
- /** The id of the user that (will) receive(d) the request */
- get receivingUserId(): string;
- /** The user id of the other party in this request */
- get otherUserId(): string;
- get isSelfVerification(): boolean;
- /**
- * The id of the user that cancelled the request,
- * only defined when phase is PHASE_CANCELLED
- */
- get cancellingUserId(): string | undefined;
- /**
- * The cancellation code e.g m.user which is responsible for cancelling this verification
- */
- get cancellationCode(): string;
- get observeOnly(): boolean;
- /**
- * Gets which device the verification should be started with
- * given the events sent so far in the verification. This is the
- * same algorithm used to determine which device to send the
- * verification to when no specific device is specified.
- * @returns The device information
- */
- get targetDevice(): ITargetDevice;
- beginKeyVerification(method: VerificationMethod, targetDevice?: ITargetDevice | null): VerificationBase<any, any>;
- /**
- * sends the initial .request event.
- * @returns resolves when the event has been sent.
- */
- sendRequest(): Promise<void>;
- /**
- * Cancels the request, sending a cancellation to the other party
- * @param reason - the error reason to send the cancellation with
- * @param code - the error code to send the cancellation with
- * @returns resolves when the event has been sent.
- */
- cancel({ reason, code }?: {
- reason?: string | undefined;
- code?: string | undefined;
- }): Promise<void>;
- /**
- * Accepts the request, sending a .ready event to the other party
- * @returns resolves when the event has been sent.
- */
- accept(): Promise<void>;
- /**
- * Can be used to listen for state changes until the callback returns true.
- * @param fn - callback to evaluate whether the request is in the desired state.
- * Takes the request as an argument.
- * @returns that resolves once the callback returns true
- * @throws Error when the request is cancelled
- */
- waitFor(fn: (request: VerificationRequest) => boolean): Promise<VerificationRequest>;
- private setPhase;
- private getEventByEither;
- private getEventBy;
- private calculatePhaseTransitions;
- private transitionToPhase;
- private applyPhaseTransitions;
- private isWinningStartRace;
- hasEventId(eventId: string): boolean;
- /**
- * Changes the state of the request and verifier in response to a key verification event.
- * @param type - the "symbolic" event type, as returned by the `getEventType` function on the channel.
- * @param event - the event to handle. Don't call getType() on it but use the `type` parameter instead.
- * @param isLiveEvent - whether this is an even received through sync or not
- * @param isRemoteEcho - whether this is the remote echo of an event sent by the same device
- * @param isSentByUs - whether this event is sent by a party that can accept and/or observe the request like one of our peers.
- * For InRoomChannel this means any device for the syncing user. For ToDeviceChannel, just the syncing device.
- * @returns a promise that resolves when any requests as an answer to the passed-in event are sent.
- */
- handleEvent(type: string, event: MatrixEvent, isLiveEvent: boolean, isRemoteEcho: boolean, isSentByUs: boolean): Promise<void>;
- private setupTimeout;
- private cancelOnTimeout;
- private cancelOnError;
- private adjustObserveOnly;
- private addEvent;
- private createVerifier;
- private wasSentByOwnUser;
- private wasSentByOwnDevice;
- onVerifierCancelled(): void;
- onVerifierFinished(): void;
- getEventFromOtherParty(type: string): MatrixEvent | undefined;
-}
-export {};
-//# sourceMappingURL=VerificationRequest.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/VerificationRequest.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/VerificationRequest.d.ts.map
deleted file mode 100644
index 37ca935..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/VerificationRequest.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"VerificationRequest.d.ts","sourceRoot":"","sources":["../../../../src/crypto/verification/request/VerificationRequest.ts"],"names":[],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/VerificationRequest.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/VerificationRequest.js
deleted file mode 100644
index f6e4dc0..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/VerificationRequest.js
+++ /dev/null
@@ -1,876 +0,0 @@
-"use strict";
-
-var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.VerificationRequestEvent = exports.VerificationRequest = exports.START_TYPE = exports.REQUEST_TYPE = exports.READY_TYPE = exports.Phase = exports.PHASE_UNSENT = exports.PHASE_STARTED = exports.PHASE_REQUESTED = exports.PHASE_READY = exports.PHASE_DONE = exports.PHASE_CANCELLED = exports.EVENT_PREFIX = exports.DONE_TYPE = exports.CANCEL_TYPE = void 0;
-var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
-var _logger = require("../../../logger");
-var _Error = require("../Error");
-var _QRCode = require("../QRCode");
-var _event = require("../../../@types/event");
-var _typedEventEmitter = require("../../../models/typed-event-emitter");
-/*
-Copyright 2018 - 2021 The Matrix.org Foundation C.I.C.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-// How long after the event's timestamp that the request times out
-const TIMEOUT_FROM_EVENT_TS = 10 * 60 * 1000; // 10 minutes
-
-// How long after we receive the event that the request times out
-const TIMEOUT_FROM_EVENT_RECEIPT = 2 * 60 * 1000; // 2 minutes
-
-// to avoid almost expired verification notifications
-// from showing a notification and almost immediately
-// disappearing, also ignore verification requests that
-// are this amount of time away from expiring.
-const VERIFICATION_REQUEST_MARGIN = 3 * 1000; // 3 seconds
-
-const EVENT_PREFIX = "m.key.verification.";
-exports.EVENT_PREFIX = EVENT_PREFIX;
-const REQUEST_TYPE = EVENT_PREFIX + "request";
-exports.REQUEST_TYPE = REQUEST_TYPE;
-const START_TYPE = EVENT_PREFIX + "start";
-exports.START_TYPE = START_TYPE;
-const CANCEL_TYPE = EVENT_PREFIX + "cancel";
-exports.CANCEL_TYPE = CANCEL_TYPE;
-const DONE_TYPE = EVENT_PREFIX + "done";
-exports.DONE_TYPE = DONE_TYPE;
-const READY_TYPE = EVENT_PREFIX + "ready";
-exports.READY_TYPE = READY_TYPE;
-let Phase; // Legacy export fields
-exports.Phase = Phase;
-(function (Phase) {
- Phase[Phase["Unsent"] = 1] = "Unsent";
- Phase[Phase["Requested"] = 2] = "Requested";
- Phase[Phase["Ready"] = 3] = "Ready";
- Phase[Phase["Started"] = 4] = "Started";
- Phase[Phase["Cancelled"] = 5] = "Cancelled";
- Phase[Phase["Done"] = 6] = "Done";
-})(Phase || (exports.Phase = Phase = {}));
-const PHASE_UNSENT = Phase.Unsent;
-exports.PHASE_UNSENT = PHASE_UNSENT;
-const PHASE_REQUESTED = Phase.Requested;
-exports.PHASE_REQUESTED = PHASE_REQUESTED;
-const PHASE_READY = Phase.Ready;
-exports.PHASE_READY = PHASE_READY;
-const PHASE_STARTED = Phase.Started;
-exports.PHASE_STARTED = PHASE_STARTED;
-const PHASE_CANCELLED = Phase.Cancelled;
-exports.PHASE_CANCELLED = PHASE_CANCELLED;
-const PHASE_DONE = Phase.Done;
-exports.PHASE_DONE = PHASE_DONE;
-let VerificationRequestEvent;
-exports.VerificationRequestEvent = VerificationRequestEvent;
-(function (VerificationRequestEvent) {
- VerificationRequestEvent["Change"] = "change";
-})(VerificationRequestEvent || (exports.VerificationRequestEvent = VerificationRequestEvent = {}));
-/**
- * State machine for verification requests.
- * Things that differ based on what channel is used to
- * send and receive verification events are put in `InRoomChannel` or `ToDeviceChannel`.
- */
-class VerificationRequest extends _typedEventEmitter.TypedEventEmitter {
- // we keep a copy of the QR Code data (including other user master key) around
- // for QR reciprocate verification, to protect against
- // cross-signing identity reset between the .ready and .start event
- // and signing the wrong key after .start
-
- // The timestamp when we received the request event from the other side
-
- // Used in tests only
-
- constructor(channel, verificationMethods, client) {
- super();
- this.channel = channel;
- this.verificationMethods = verificationMethods;
- this.client = client;
- (0, _defineProperty2.default)(this, "eventsByUs", new Map());
- (0, _defineProperty2.default)(this, "eventsByThem", new Map());
- (0, _defineProperty2.default)(this, "_observeOnly", false);
- (0, _defineProperty2.default)(this, "timeoutTimer", null);
- (0, _defineProperty2.default)(this, "_accepting", false);
- (0, _defineProperty2.default)(this, "_declining", false);
- (0, _defineProperty2.default)(this, "verifierHasFinished", false);
- (0, _defineProperty2.default)(this, "_cancelled", false);
- (0, _defineProperty2.default)(this, "_chosenMethod", null);
- (0, _defineProperty2.default)(this, "_qrCodeData", null);
- (0, _defineProperty2.default)(this, "requestReceivedAt", null);
- (0, _defineProperty2.default)(this, "commonMethods", []);
- (0, _defineProperty2.default)(this, "_phase", void 0);
- (0, _defineProperty2.default)(this, "_cancellingUserId", void 0);
- (0, _defineProperty2.default)(this, "_verifier", void 0);
- (0, _defineProperty2.default)(this, "cancelOnTimeout", async () => {
- try {
- if (this.initiatedByMe) {
- await this.cancel({
- reason: "Other party didn't accept in time",
- code: "m.timeout"
- });
- } else {
- await this.cancel({
- reason: "User didn't accept in time",
- code: "m.timeout"
- });
- }
- } catch (err) {
- _logger.logger.error("Error while cancelling verification request", err);
- }
- });
- this.channel.request = this;
- this.setPhase(PHASE_UNSENT, false);
- }
-
- /**
- * Stateless validation logic not specific to the channel.
- * Invoked by the same static method in either channel.
- * @param type - the "symbolic" event type, as returned by the `getEventType` function on the channel.
- * @param event - the event to validate. Don't call getType() on it but use the `type` parameter instead.
- * @param client - the client to get the current user and device id from
- * @returns whether the event is valid and should be passed to handleEvent
- */
- static validateEvent(type, event, client) {
- const content = event.getContent();
- if (!type || !type.startsWith(EVENT_PREFIX)) {
- return false;
- }
-
- // from here on we're fairly sure that this is supposed to be
- // part of a verification request, so be noisy when rejecting something
- if (!content) {
- _logger.logger.log("VerificationRequest: validateEvent: no content");
- return false;
- }
- if (type === REQUEST_TYPE || type === READY_TYPE) {
- if (!Array.isArray(content.methods)) {
- _logger.logger.log("VerificationRequest: validateEvent: " + "fail because methods");
- return false;
- }
- }
- if (type === REQUEST_TYPE || type === READY_TYPE || type === START_TYPE) {
- if (typeof content.from_device !== "string" || content.from_device.length === 0) {
- _logger.logger.log("VerificationRequest: validateEvent: " + "fail because from_device");
- return false;
- }
- }
- return true;
- }
- get invalid() {
- return this.phase === PHASE_UNSENT;
- }
-
- /** returns whether the phase is PHASE_REQUESTED */
- get requested() {
- return this.phase === PHASE_REQUESTED;
- }
-
- /** returns whether the phase is PHASE_CANCELLED */
- get cancelled() {
- return this.phase === PHASE_CANCELLED;
- }
-
- /** returns whether the phase is PHASE_READY */
- get ready() {
- return this.phase === PHASE_READY;
- }
-
- /** returns whether the phase is PHASE_STARTED */
- get started() {
- return this.phase === PHASE_STARTED;
- }
-
- /** returns whether the phase is PHASE_DONE */
- get done() {
- return this.phase === PHASE_DONE;
- }
-
- /** once the phase is PHASE_STARTED (and !initiatedByMe) or PHASE_READY: common methods supported by both sides */
- get methods() {
- return this.commonMethods;
- }
-
- /** the method picked in the .start event */
- get chosenMethod() {
- return this._chosenMethod;
- }
- calculateEventTimeout(event) {
- let effectiveExpiresAt = this.channel.getTimestamp(event) + TIMEOUT_FROM_EVENT_TS;
- if (this.requestReceivedAt && !this.initiatedByMe && this.phase <= PHASE_REQUESTED) {
- const expiresAtByReceipt = this.requestReceivedAt + TIMEOUT_FROM_EVENT_RECEIPT;
- effectiveExpiresAt = Math.min(effectiveExpiresAt, expiresAtByReceipt);
- }
- return Math.max(0, effectiveExpiresAt - Date.now());
- }
-
- /** The current remaining amount of ms before the request should be automatically cancelled */
- get timeout() {
- const requestEvent = this.getEventByEither(REQUEST_TYPE);
- if (requestEvent) {
- return this.calculateEventTimeout(requestEvent);
- }
- return 0;
- }
-
- /**
- * The key verification request event.
- * @returns The request event, or falsey if not found.
- */
- get requestEvent() {
- return this.getEventByEither(REQUEST_TYPE);
- }
-
- /** current phase of the request. Some properties might only be defined in a current phase. */
- get phase() {
- return this._phase;
- }
-
- /** The verifier to do the actual verification, once the method has been established. Only defined when the `phase` is PHASE_STARTED. */
- get verifier() {
- return this._verifier;
- }
- get canAccept() {
- return this.phase < PHASE_READY && !this._accepting && !this._declining;
- }
- get accepting() {
- return this._accepting;
- }
- get declining() {
- return this._declining;
- }
-
- /** whether this request has sent it's initial event and needs more events to complete */
- get pending() {
- return !this.observeOnly && this._phase !== PHASE_DONE && this._phase !== PHASE_CANCELLED;
- }
-
- /** Only set after a .ready if the other party can scan a QR code */
- get qrCodeData() {
- return this._qrCodeData;
- }
-
- /** Checks whether the other party supports a given verification method.
- * This is useful when setting up the QR code UI, as it is somewhat asymmetrical:
- * if the other party supports SCAN_QR, we should show a QR code in the UI, and vice versa.
- * For methods that need to be supported by both ends, use the `methods` property.
- * @param method - the method to check
- * @param force - to check even if the phase is not ready or started yet, internal usage
- * @returns whether or not the other party said the supported the method */
- otherPartySupportsMethod(method, force = false) {
- if (!force && !this.ready && !this.started) {
- return false;
- }
- const theirMethodEvent = this.eventsByThem.get(REQUEST_TYPE) || this.eventsByThem.get(READY_TYPE);
- if (!theirMethodEvent) {
- // if we started straight away with .start event,
- // we are assuming that the other side will support the
- // chosen method, so return true for that.
- if (this.started && this.initiatedByMe) {
- const myStartEvent = this.eventsByUs.get(START_TYPE);
- const content = myStartEvent && myStartEvent.getContent();
- const myStartMethod = content && content.method;
- return method == myStartMethod;
- }
- return false;
- }
- const content = theirMethodEvent.getContent();
- if (!content) {
- return false;
- }
- const {
- methods
- } = content;
- if (!Array.isArray(methods)) {
- return false;
- }
- return methods.includes(method);
- }
-
- /** Whether this request was initiated by the syncing user.
- * For InRoomChannel, this is who sent the .request event.
- * For ToDeviceChannel, this is who sent the .start event
- */
- get initiatedByMe() {
- // event created by us but no remote echo has been received yet
- const noEventsYet = this.eventsByUs.size + this.eventsByThem.size === 0;
- if (this._phase === PHASE_UNSENT && noEventsYet) {
- return true;
- }
- const hasMyRequest = this.eventsByUs.has(REQUEST_TYPE);
- const hasTheirRequest = this.eventsByThem.has(REQUEST_TYPE);
- if (hasMyRequest && !hasTheirRequest) {
- return true;
- }
- if (!hasMyRequest && hasTheirRequest) {
- return false;
- }
- const hasMyStart = this.eventsByUs.has(START_TYPE);
- const hasTheirStart = this.eventsByThem.has(START_TYPE);
- if (hasMyStart && !hasTheirStart) {
- return true;
- }
- return false;
- }
-
- /** The id of the user that initiated the request */
- get requestingUserId() {
- if (this.initiatedByMe) {
- return this.client.getUserId();
- } else {
- return this.otherUserId;
- }
- }
-
- /** The id of the user that (will) receive(d) the request */
- get receivingUserId() {
- if (this.initiatedByMe) {
- return this.otherUserId;
- } else {
- return this.client.getUserId();
- }
- }
-
- /** The user id of the other party in this request */
- get otherUserId() {
- return this.channel.userId;
- }
- get isSelfVerification() {
- return this.client.getUserId() === this.otherUserId;
- }
-
- /**
- * The id of the user that cancelled the request,
- * only defined when phase is PHASE_CANCELLED
- */
- get cancellingUserId() {
- const myCancel = this.eventsByUs.get(CANCEL_TYPE);
- const theirCancel = this.eventsByThem.get(CANCEL_TYPE);
- if (myCancel && (!theirCancel || myCancel.getId() < theirCancel.getId())) {
- return myCancel.getSender();
- }
- if (theirCancel) {
- return theirCancel.getSender();
- }
- return undefined;
- }
-
- /**
- * The cancellation code e.g m.user which is responsible for cancelling this verification
- */
- get cancellationCode() {
- const ev = this.getEventByEither(CANCEL_TYPE);
- return ev ? ev.getContent().code : null;
- }
- get observeOnly() {
- return this._observeOnly;
- }
-
- /**
- * Gets which device the verification should be started with
- * given the events sent so far in the verification. This is the
- * same algorithm used to determine which device to send the
- * verification to when no specific device is specified.
- * @returns The device information
- */
- get targetDevice() {
- const theirFirstEvent = this.eventsByThem.get(REQUEST_TYPE) || this.eventsByThem.get(READY_TYPE) || this.eventsByThem.get(START_TYPE);
- const theirFirstContent = theirFirstEvent === null || theirFirstEvent === void 0 ? void 0 : theirFirstEvent.getContent();
- const fromDevice = theirFirstContent === null || theirFirstContent === void 0 ? void 0 : theirFirstContent.from_device;
- return {
- userId: this.otherUserId,
- deviceId: fromDevice
- };
- }
-
- /* Start the key verification, creating a verifier and sending a .start event.
- * If no previous events have been sent, pass in `targetDevice` to set who to direct this request to.
- * @param method - the name of the verification method to use.
- * @param targetDevice.userId the id of the user to direct this request to
- * @param targetDevice.deviceId the id of the device to direct this request to
- * @returns the verifier of the given method
- */
- beginKeyVerification(method, targetDevice = null) {
- // need to allow also when unsent in case of to_device
- if (!this.observeOnly && !this._verifier) {
- const validStartPhase = this.phase === PHASE_REQUESTED || this.phase === PHASE_READY || this.phase === PHASE_UNSENT && this.channel.canCreateRequest(START_TYPE);
- if (validStartPhase) {
- // when called on a request that was initiated with .request event
- // check the method is supported by both sides
- if (this.commonMethods.length && !this.commonMethods.includes(method)) {
- throw (0, _Error.newUnknownMethodError)();
- }
- this._verifier = this.createVerifier(method, null, targetDevice);
- if (!this._verifier) {
- throw (0, _Error.newUnknownMethodError)();
- }
- this._chosenMethod = method;
- }
- }
- return this._verifier;
- }
-
- /**
- * sends the initial .request event.
- * @returns resolves when the event has been sent.
- */
- async sendRequest() {
- if (!this.observeOnly && this._phase === PHASE_UNSENT) {
- const methods = [...this.verificationMethods.keys()];
- await this.channel.send(REQUEST_TYPE, {
- methods
- });
- }
- }
-
- /**
- * Cancels the request, sending a cancellation to the other party
- * @param reason - the error reason to send the cancellation with
- * @param code - the error code to send the cancellation with
- * @returns resolves when the event has been sent.
- */
- async cancel({
- reason = "User declined",
- code = "m.user"
- } = {}) {
- if (!this.observeOnly && this._phase !== PHASE_CANCELLED) {
- this._declining = true;
- this.emit(VerificationRequestEvent.Change);
- if (this._verifier) {
- return this._verifier.cancel((0, _Error.errorFactory)(code, reason)());
- } else {
- this._cancellingUserId = this.client.getUserId();
- await this.channel.send(CANCEL_TYPE, {
- code,
- reason
- });
- }
- }
- }
-
- /**
- * Accepts the request, sending a .ready event to the other party
- * @returns resolves when the event has been sent.
- */
- async accept() {
- if (!this.observeOnly && this.phase === PHASE_REQUESTED && !this.initiatedByMe) {
- const methods = [...this.verificationMethods.keys()];
- this._accepting = true;
- this.emit(VerificationRequestEvent.Change);
- await this.channel.send(READY_TYPE, {
- methods
- });
- }
- }
-
- /**
- * Can be used to listen for state changes until the callback returns true.
- * @param fn - callback to evaluate whether the request is in the desired state.
- * Takes the request as an argument.
- * @returns that resolves once the callback returns true
- * @throws Error when the request is cancelled
- */
- waitFor(fn) {
- return new Promise((resolve, reject) => {
- const check = () => {
- let handled = false;
- if (fn(this)) {
- resolve(this);
- handled = true;
- } else if (this.cancelled) {
- reject(new Error("cancelled"));
- handled = true;
- }
- if (handled) {
- this.off(VerificationRequestEvent.Change, check);
- }
- return handled;
- };
- if (!check()) {
- this.on(VerificationRequestEvent.Change, check);
- }
- });
- }
- setPhase(phase, notify = true) {
- this._phase = phase;
- if (notify) {
- this.emit(VerificationRequestEvent.Change);
- }
- }
- getEventByEither(type) {
- return this.eventsByThem.get(type) || this.eventsByUs.get(type);
- }
- getEventBy(type, byThem = false) {
- if (byThem) {
- return this.eventsByThem.get(type);
- } else {
- return this.eventsByUs.get(type);
- }
- }
- calculatePhaseTransitions() {
- const transitions = [{
- phase: PHASE_UNSENT
- }];
- const phase = () => transitions[transitions.length - 1].phase;
-
- // always pass by .request first to be sure channel.userId has been set
- const hasRequestByThem = this.eventsByThem.has(REQUEST_TYPE);
- const requestEvent = this.getEventBy(REQUEST_TYPE, hasRequestByThem);
- if (requestEvent) {
- transitions.push({
- phase: PHASE_REQUESTED,
- event: requestEvent
- });
- }
- const readyEvent = requestEvent && this.getEventBy(READY_TYPE, !hasRequestByThem);
- if (readyEvent && phase() === PHASE_REQUESTED) {
- transitions.push({
- phase: PHASE_READY,
- event: readyEvent
- });
- }
- let startEvent;
- if (readyEvent || !requestEvent) {
- const theirStartEvent = this.eventsByThem.get(START_TYPE);
- const ourStartEvent = this.eventsByUs.get(START_TYPE);
- // any party can send .start after a .ready or unsent
- if (theirStartEvent && ourStartEvent) {
- startEvent = theirStartEvent.getSender() < ourStartEvent.getSender() ? theirStartEvent : ourStartEvent;
- } else {
- startEvent = theirStartEvent ? theirStartEvent : ourStartEvent;
- }
- } else {
- startEvent = this.getEventBy(START_TYPE, !hasRequestByThem);
- }
- if (startEvent) {
- const fromRequestPhase = phase() === PHASE_REQUESTED && (requestEvent === null || requestEvent === void 0 ? void 0 : requestEvent.getSender()) !== startEvent.getSender();
- const fromUnsentPhase = phase() === PHASE_UNSENT && this.channel.canCreateRequest(START_TYPE);
- if (fromRequestPhase || phase() === PHASE_READY || fromUnsentPhase) {
- transitions.push({
- phase: PHASE_STARTED,
- event: startEvent
- });
- }
- }
- const ourDoneEvent = this.eventsByUs.get(DONE_TYPE);
- if (this.verifierHasFinished || ourDoneEvent && phase() === PHASE_STARTED) {
- transitions.push({
- phase: PHASE_DONE
- });
- }
- const cancelEvent = this.getEventByEither(CANCEL_TYPE);
- if ((this._cancelled || cancelEvent) && phase() !== PHASE_DONE) {
- transitions.push({
- phase: PHASE_CANCELLED,
- event: cancelEvent
- });
- return transitions;
- }
- return transitions;
- }
- transitionToPhase(transition) {
- const {
- phase,
- event
- } = transition;
- // get common methods
- if (phase === PHASE_REQUESTED || phase === PHASE_READY) {
- if (!this.wasSentByOwnDevice(event)) {
- const content = event.getContent();
- this.commonMethods = content.methods.filter(m => this.verificationMethods.has(m));
- }
- }
- // detect if we're not a party in the request, and we should just observe
- if (!this.observeOnly) {
- // if requested or accepted by one of my other devices
- if (phase === PHASE_REQUESTED || phase === PHASE_STARTED || phase === PHASE_READY) {
- if (this.channel.receiveStartFromOtherDevices && this.wasSentByOwnUser(event) && !this.wasSentByOwnDevice(event)) {
- this._observeOnly = true;
- }
- }
- }
- // create verifier
- if (phase === PHASE_STARTED) {
- const {
- method
- } = event.getContent();
- if (!this._verifier && !this.observeOnly) {
- this._verifier = this.createVerifier(method, event);
- if (!this._verifier) {
- this.cancel({
- code: "m.unknown_method",
- reason: `Unknown method: ${method}`
- });
- } else {
- this._chosenMethod = method;
- }
- }
- }
- }
- applyPhaseTransitions() {
- const transitions = this.calculatePhaseTransitions();
- const existingIdx = transitions.findIndex(t => t.phase === this.phase);
- // trim off phases we already went through, if any
- const newTransitions = transitions.slice(existingIdx + 1);
- // transition to all new phases
- for (const transition of newTransitions) {
- this.transitionToPhase(transition);
- }
- return newTransitions;
- }
- isWinningStartRace(newEvent) {
- if (newEvent.getType() !== START_TYPE) {
- return false;
- }
- const oldEvent = this._verifier.startEvent;
- let oldRaceIdentifier;
- if (this.isSelfVerification) {
- // if the verifier does not have a startEvent,
- // it is because it's still sending and we are on the initator side
- // we know we are sending a .start event because we already
- // have a verifier (checked in calling method)
- if (oldEvent) {
- const oldContent = oldEvent.getContent();
- oldRaceIdentifier = oldContent && oldContent.from_device;
- } else {
- oldRaceIdentifier = this.client.getDeviceId();
- }
- } else {
- if (oldEvent) {
- oldRaceIdentifier = oldEvent.getSender();
- } else {
- oldRaceIdentifier = this.client.getUserId();
- }
- }
- let newRaceIdentifier;
- if (this.isSelfVerification) {
- const newContent = newEvent.getContent();
- newRaceIdentifier = newContent && newContent.from_device;
- } else {
- newRaceIdentifier = newEvent.getSender();
- }
- return newRaceIdentifier < oldRaceIdentifier;
- }
- hasEventId(eventId) {
- for (const event of this.eventsByUs.values()) {
- if (event.getId() === eventId) {
- return true;
- }
- }
- for (const event of this.eventsByThem.values()) {
- if (event.getId() === eventId) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Changes the state of the request and verifier in response to a key verification event.
- * @param type - the "symbolic" event type, as returned by the `getEventType` function on the channel.
- * @param event - the event to handle. Don't call getType() on it but use the `type` parameter instead.
- * @param isLiveEvent - whether this is an even received through sync or not
- * @param isRemoteEcho - whether this is the remote echo of an event sent by the same device
- * @param isSentByUs - whether this event is sent by a party that can accept and/or observe the request like one of our peers.
- * For InRoomChannel this means any device for the syncing user. For ToDeviceChannel, just the syncing device.
- * @returns a promise that resolves when any requests as an answer to the passed-in event are sent.
- */
- async handleEvent(type, event, isLiveEvent, isRemoteEcho, isSentByUs) {
- // if reached phase cancelled or done, ignore anything else that comes
- if (this.done || this.cancelled) {
- return;
- }
- const wasObserveOnly = this._observeOnly;
- this.adjustObserveOnly(event, isLiveEvent);
- if (!this.observeOnly && !isRemoteEcho) {
- if (await this.cancelOnError(type, event)) {
- return;
- }
- }
-
- // This assumes verification won't need to send an event with
- // the same type for the same party twice.
- // This is true for QR and SAS verification, and was
- // added here to prevent verification getting cancelled
- // when the server duplicates an event (https://github.com/matrix-org/synapse/issues/3365)
- const isDuplicateEvent = isSentByUs ? this.eventsByUs.has(type) : this.eventsByThem.has(type);
- if (isDuplicateEvent) {
- return;
- }
- const oldPhase = this.phase;
- this.addEvent(type, event, isSentByUs);
-
- // this will create if needed the verifier so needs to happen before calling it
- const newTransitions = this.applyPhaseTransitions();
- try {
- // only pass events from the other side to the verifier,
- // no remote echos of our own events
- if (this._verifier && !this.observeOnly) {
- const newEventWinsRace = this.isWinningStartRace(event);
- if (this._verifier.canSwitchStartEvent(event) && newEventWinsRace) {
- this._verifier.switchStartEvent(event);
- } else if (!isRemoteEcho) {
- var _this$_verifier$event;
- if (type === CANCEL_TYPE || (_this$_verifier$event = this._verifier.events) !== null && _this$_verifier$event !== void 0 && _this$_verifier$event.includes(type)) {
- this._verifier.handleEvent(event);
- }
- }
- }
- if (newTransitions.length) {
- // create QRCodeData if the other side can scan
- // important this happens before emitting a phase change,
- // so listeners can rely on it being there already
- // We only do this for live events because it is important that
- // we sign the keys that were in the QR code, and not the keys
- // we happen to have at some later point in time.
- if (isLiveEvent && newTransitions.some(t => t.phase === PHASE_READY)) {
- const shouldGenerateQrCode = this.otherPartySupportsMethod(_QRCode.SCAN_QR_CODE_METHOD, true);
- if (shouldGenerateQrCode) {
- this._qrCodeData = await _QRCode.QRCodeData.create(this, this.client);
- }
- }
- const lastTransition = newTransitions[newTransitions.length - 1];
- const {
- phase
- } = lastTransition;
- this.setupTimeout(phase);
- // set phase as last thing as this emits the "change" event
- this.setPhase(phase);
- } else if (this._observeOnly !== wasObserveOnly) {
- this.emit(VerificationRequestEvent.Change);
- }
- } finally {
- // log events we processed so we can see from rageshakes what events were added to a request
- _logger.logger.log(`Verification request ${this.channel.transactionId}: ` + `${type} event with id:${event.getId()}, ` + `content:${JSON.stringify(event.getContent())} ` + `deviceId:${this.channel.deviceId}, ` + `sender:${event.getSender()}, isSentByUs:${isSentByUs}, ` + `isLiveEvent:${isLiveEvent}, isRemoteEcho:${isRemoteEcho}, ` + `phase:${oldPhase}=>${this.phase}, ` + `observeOnly:${wasObserveOnly}=>${this._observeOnly}`);
- }
- }
- setupTimeout(phase) {
- const shouldTimeout = !this.timeoutTimer && !this.observeOnly && phase === PHASE_REQUESTED;
- if (shouldTimeout) {
- this.timeoutTimer = setTimeout(this.cancelOnTimeout, this.timeout);
- }
- if (this.timeoutTimer) {
- const shouldClear = phase === PHASE_STARTED || phase === PHASE_READY || phase === PHASE_DONE || phase === PHASE_CANCELLED;
- if (shouldClear) {
- clearTimeout(this.timeoutTimer);
- this.timeoutTimer = null;
- }
- }
- }
- async cancelOnError(type, event) {
- if (type === START_TYPE) {
- const method = event.getContent().method;
- if (!this.verificationMethods.has(method)) {
- await this.cancel((0, _Error.errorFromEvent)((0, _Error.newUnknownMethodError)()));
- return true;
- }
- }
- const isUnexpectedRequest = type === REQUEST_TYPE && this.phase !== PHASE_UNSENT;
- const isUnexpectedReady = type === READY_TYPE && this.phase !== PHASE_REQUESTED && this.phase !== PHASE_STARTED;
- // only if phase has passed from PHASE_UNSENT should we cancel, because events
- // are allowed to come in in any order (at least with InRoomChannel). So we only know
- // we're dealing with a valid request we should participate in once we've moved to PHASE_REQUESTED.
- // Before that, we could be looking at somebody else's verification request and we just
- // happen to be in the room
- if (this.phase !== PHASE_UNSENT && (isUnexpectedRequest || isUnexpectedReady)) {
- _logger.logger.warn(`Cancelling, unexpected ${type} verification ` + `event from ${event.getSender()}`);
- const reason = `Unexpected ${type} event in phase ${this.phase}`;
- await this.cancel((0, _Error.errorFromEvent)((0, _Error.newUnexpectedMessageError)({
- reason
- })));
- return true;
- }
- return false;
- }
- adjustObserveOnly(event, isLiveEvent = false) {
- // don't send out events for historical requests
- if (!isLiveEvent) {
- this._observeOnly = true;
- }
- if (this.calculateEventTimeout(event) < VERIFICATION_REQUEST_MARGIN) {
- this._observeOnly = true;
- }
- }
- addEvent(type, event, isSentByUs = false) {
- if (isSentByUs) {
- this.eventsByUs.set(type, event);
- } else {
- this.eventsByThem.set(type, event);
- }
-
- // once we know the userId of the other party (from the .request event)
- // see if any event by anyone else crept into this.eventsByThem
- if (type === REQUEST_TYPE) {
- for (const [type, event] of this.eventsByThem.entries()) {
- if (event.getSender() !== this.otherUserId) {
- this.eventsByThem.delete(type);
- }
- }
- // also remember when we received the request event
- this.requestReceivedAt = Date.now();
- }
- }
- createVerifier(method, startEvent = null, targetDevice = null) {
- if (!targetDevice) {
- targetDevice = this.targetDevice;
- }
- const {
- userId,
- deviceId
- } = targetDevice;
- const VerifierCtor = this.verificationMethods.get(method);
- if (!VerifierCtor) {
- _logger.logger.warn("could not find verifier constructor for method", method);
- return;
- }
- return new VerifierCtor(this.channel, this.client, userId, deviceId, startEvent, this);
- }
- wasSentByOwnUser(event) {
- return (event === null || event === void 0 ? void 0 : event.getSender()) === this.client.getUserId();
- }
-
- // only for .request, .ready or .start
- wasSentByOwnDevice(event) {
- if (!this.wasSentByOwnUser(event)) {
- return false;
- }
- const content = event.getContent();
- if (!content || content.from_device !== this.client.getDeviceId()) {
- return false;
- }
- return true;
- }
- onVerifierCancelled() {
- this._cancelled = true;
- // move to cancelled phase
- const newTransitions = this.applyPhaseTransitions();
- if (newTransitions.length) {
- this.setPhase(newTransitions[newTransitions.length - 1].phase);
- }
- }
- onVerifierFinished() {
- this.channel.send(_event.EventType.KeyVerificationDone, {});
- this.verifierHasFinished = true;
- // move to .done phase
- const newTransitions = this.applyPhaseTransitions();
- if (newTransitions.length) {
- this.setPhase(newTransitions[newTransitions.length - 1].phase);
- }
- }
- getEventFromOtherParty(type) {
- return this.eventsByThem.get(type);
- }
-}
-exports.VerificationRequest = VerificationRequest;
-//# sourceMappingURL=VerificationRequest.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/VerificationRequest.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/VerificationRequest.js.map
deleted file mode 100644
index 4d110ef..0000000
--- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/VerificationRequest.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"VerificationRequest.js","names":["_logger","require","_Error","_QRCode","_event","_typedEventEmitter","TIMEOUT_FROM_EVENT_TS","TIMEOUT_FROM_EVENT_RECEIPT","VERIFICATION_REQUEST_MARGIN","EVENT_PREFIX","exports","REQUEST_TYPE","START_TYPE","CANCEL_TYPE","DONE_TYPE","READY_TYPE","Phase","PHASE_UNSENT","Unsent","PHASE_REQUESTED","Requested","PHASE_READY","Ready","PHASE_STARTED","Started","PHASE_CANCELLED","Cancelled","PHASE_DONE","Done","VerificationRequestEvent","VerificationRequest","TypedEventEmitter","constructor","channel","verificationMethods","client","_defineProperty2","default","Map","initiatedByMe","cancel","reason","code","err","logger","error","request","setPhase","validateEvent","type","event","content","getContent","startsWith","log","Array","isArray","methods","from_device","length","invalid","phase","requested","cancelled","ready","started","done","commonMethods","chosenMethod","_chosenMethod","calculateEventTimeout","effectiveExpiresAt","getTimestamp","requestReceivedAt","expiresAtByReceipt","Math","min","max","Date","now","timeout","requestEvent","getEventByEither","_phase","verifier","_verifier","canAccept","_accepting","_declining","accepting","declining","pending","observeOnly","qrCodeData","_qrCodeData","otherPartySupportsMethod","method","force","theirMethodEvent","eventsByThem","get","myStartEvent","eventsByUs","myStartMethod","includes","noEventsYet","size","hasMyRequest","has","hasTheirRequest","hasMyStart","hasTheirStart","requestingUserId","getUserId","otherUserId","receivingUserId","userId","isSelfVerification","cancellingUserId","myCancel","theirCancel","getId","getSender","undefined","cancellationCode","ev","_observeOnly","targetDevice","theirFirstEvent","theirFirstContent","fromDevice","deviceId","beginKeyVerification","validStartPhase","canCreateRequest","newUnknownMethodError","createVerifier","sendRequest","keys","send","emit","Change","errorFactory","_cancellingUserId","accept","waitFor","fn","Promise","resolve","reject","check","handled","Error","off","on","notify","getEventBy","byThem","calculatePhaseTransitions","transitions","hasRequestByThem","push","readyEvent","startEvent","theirStartEvent","ourStartEvent","fromRequestPhase","fromUnsentPhase","ourDoneEvent","verifierHasFinished","cancelEvent","_cancelled","transitionToPhase","transition","wasSentByOwnDevice","filter","m","receiveStartFromOtherDevices","wasSentByOwnUser","applyPhaseTransitions","existingIdx","findIndex","t","newTransitions","slice","isWinningStartRace","newEvent","getType","oldEvent","oldRaceIdentifier","oldContent","getDeviceId","newRaceIdentifier","newContent","hasEventId","eventId","values","handleEvent","isLiveEvent","isRemoteEcho","isSentByUs","wasObserveOnly","adjustObserveOnly","cancelOnError","isDuplicateEvent","oldPhase","addEvent","newEventWinsRace","canSwitchStartEvent","switchStartEvent","_this$_verifier$event","events","some","shouldGenerateQrCode","SCAN_QR_CODE_METHOD","QRCodeData","create","lastTransition","setupTimeout","transactionId","JSON","stringify","shouldTimeout","timeoutTimer","setTimeout","cancelOnTimeout","shouldClear","clearTimeout","errorFromEvent","isUnexpectedRequest","isUnexpectedReady","warn","newUnexpectedMessageError","set","entries","delete","VerifierCtor","onVerifierCancelled","onVerifierFinished","EventType","KeyVerificationDone","getEventFromOtherParty"],"sources":["../../../../src/crypto/verification/request/VerificationRequest.ts"],"sourcesContent":["/*\nCopyright 2018 - 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { logger } from \"../../../logger\";\nimport { errorFactory, errorFromEvent, newUnexpectedMessageError, newUnknownMethodError } from \"../Error\";\nimport { QRCodeData, SCAN_QR_CODE_METHOD } from \"../QRCode\";\nimport { IVerificationChannel } from \"./Channel\";\nimport { MatrixClient } from \"../../../client\";\nimport { MatrixEvent } from \"../../../models/event\";\nimport { EventType } from \"../../../@types/event\";\nimport { VerificationBase } from \"../Base\";\nimport { VerificationMethod } from \"../../index\";\nimport { TypedEventEmitter } from \"../../../models/typed-event-emitter\";\n\n// How long after the event's timestamp that the request times out\nconst TIMEOUT_FROM_EVENT_TS = 10 * 60 * 1000; // 10 minutes\n\n// How long after we receive the event that the request times out\nconst TIMEOUT_FROM_EVENT_RECEIPT = 2 * 60 * 1000; // 2 minutes\n\n// to avoid almost expired verification notifications\n// from showing a notification and almost immediately\n// disappearing, also ignore verification requests that\n// are this amount of time away from expiring.\nconst VERIFICATION_REQUEST_MARGIN = 3 * 1000; // 3 seconds\n\nexport const EVENT_PREFIX = \"m.key.verification.\";\nexport const REQUEST_TYPE = EVENT_PREFIX + \"request\";\nexport const START_TYPE = EVENT_PREFIX + \"start\";\nexport const CANCEL_TYPE = EVENT_PREFIX + \"cancel\";\nexport const DONE_TYPE = EVENT_PREFIX + \"done\";\nexport const READY_TYPE = EVENT_PREFIX + \"ready\";\n\nexport enum Phase {\n Unsent = 1,\n Requested,\n Ready,\n Started,\n Cancelled,\n Done,\n}\n\n// Legacy export fields\nexport const PHASE_UNSENT = Phase.Unsent;\nexport const PHASE_REQUESTED = Phase.Requested;\nexport const PHASE_READY = Phase.Ready;\nexport const PHASE_STARTED = Phase.Started;\nexport const PHASE_CANCELLED = Phase.Cancelled;\nexport const PHASE_DONE = Phase.Done;\n\ninterface ITargetDevice {\n userId?: string;\n deviceId?: string;\n}\n\ninterface ITransition {\n phase: Phase;\n event?: MatrixEvent;\n}\n\nexport enum VerificationRequestEvent {\n Change = \"change\",\n}\n\ntype EventHandlerMap = {\n /**\n * Fires whenever the state of the request object has changed.\n */\n [VerificationRequestEvent.Change]: () => void;\n};\n\n/**\n * State machine for verification requests.\n * Things that differ based on what channel is used to\n * send and receive verification events are put in `InRoomChannel` or `ToDeviceChannel`.\n */\nexport class VerificationRequest<C extends IVerificationChannel = IVerificationChannel> extends TypedEventEmitter<\n VerificationRequestEvent,\n EventHandlerMap\n> {\n private eventsByUs = new Map<string, MatrixEvent>();\n private eventsByThem = new Map<string, MatrixEvent>();\n private _observeOnly = false;\n private timeoutTimer: ReturnType<typeof setTimeout> | null = null;\n private _accepting = false;\n private _declining = false;\n private verifierHasFinished = false;\n private _cancelled = false;\n private _chosenMethod: VerificationMethod | null = null;\n // we keep a copy of the QR Code data (including other user master key) around\n // for QR reciprocate verification, to protect against\n // cross-signing identity reset between the .ready and .start event\n // and signing the wrong key after .start\n private _qrCodeData: QRCodeData | null = null;\n\n // The timestamp when we received the request event from the other side\n private requestReceivedAt: number | null = null;\n\n private commonMethods: VerificationMethod[] = [];\n private _phase!: Phase;\n public _cancellingUserId?: string; // Used in tests only\n private _verifier?: VerificationBase<any, any>;\n\n public constructor(\n public readonly channel: C,\n private readonly verificationMethods: Map<VerificationMethod, typeof VerificationBase>,\n private readonly client: MatrixClient,\n ) {\n super();\n this.channel.request = this;\n this.setPhase(PHASE_UNSENT, false);\n }\n\n /**\n * Stateless validation logic not specific to the channel.\n * Invoked by the same static method in either channel.\n * @param type - the \"symbolic\" event type, as returned by the `getEventType` function on the channel.\n * @param event - the event to validate. Don't call getType() on it but use the `type` parameter instead.\n * @param client - the client to get the current user and device id from\n * @returns whether the event is valid and should be passed to handleEvent\n */\n public static validateEvent(type: string, event: MatrixEvent, client: MatrixClient): boolean {\n const content = event.getContent();\n\n if (!type || !type.startsWith(EVENT_PREFIX)) {\n return false;\n }\n\n // from here on we're fairly sure that this is supposed to be\n // part of a verification request, so be noisy when rejecting something\n if (!content) {\n logger.log(\"VerificationRequest: validateEvent: no content\");\n return false;\n }\n\n if (type === REQUEST_TYPE || type === READY_TYPE) {\n if (!Array.isArray(content.methods)) {\n logger.log(\"VerificationRequest: validateEvent: \" + \"fail because methods\");\n return false;\n }\n }\n\n if (type === REQUEST_TYPE || type === READY_TYPE || type === START_TYPE) {\n if (typeof content.from_device !== \"string\" || content.from_device.length === 0) {\n logger.log(\"VerificationRequest: validateEvent: \" + \"fail because from_device\");\n return false;\n }\n }\n\n return true;\n }\n\n public get invalid(): boolean {\n return this.phase === PHASE_UNSENT;\n }\n\n /** returns whether the phase is PHASE_REQUESTED */\n public get requested(): boolean {\n return this.phase === PHASE_REQUESTED;\n }\n\n /** returns whether the phase is PHASE_CANCELLED */\n public get cancelled(): boolean {\n return this.phase === PHASE_CANCELLED;\n }\n\n /** returns whether the phase is PHASE_READY */\n public get ready(): boolean {\n return this.phase === PHASE_READY;\n }\n\n /** returns whether the phase is PHASE_STARTED */\n public get started(): boolean {\n return this.phase === PHASE_STARTED;\n }\n\n /** returns whether the phase is PHASE_DONE */\n public get done(): boolean {\n return this.phase === PHASE_DONE;\n }\n\n /** once the phase is PHASE_STARTED (and !initiatedByMe) or PHASE_READY: common methods supported by both sides */\n public get methods(): VerificationMethod[] {\n return this.commonMethods;\n }\n\n /** the method picked in the .start event */\n public get chosenMethod(): VerificationMethod | null {\n return this._chosenMethod;\n }\n\n public calculateEventTimeout(event: MatrixEvent): number {\n let effectiveExpiresAt = this.channel.getTimestamp(event) + TIMEOUT_FROM_EVENT_TS;\n\n if (this.requestReceivedAt && !this.initiatedByMe && this.phase <= PHASE_REQUESTED) {\n const expiresAtByReceipt = this.requestReceivedAt + TIMEOUT_FROM_EVENT_RECEIPT;\n effectiveExpiresAt = Math.min(effectiveExpiresAt, expiresAtByReceipt);\n }\n\n return Math.max(0, effectiveExpiresAt - Date.now());\n }\n\n /** The current remaining amount of ms before the request should be automatically cancelled */\n public get timeout(): number {\n const requestEvent = this.getEventByEither(REQUEST_TYPE);\n if (requestEvent) {\n return this.calculateEventTimeout(requestEvent);\n }\n return 0;\n }\n\n /**\n * The key verification request event.\n * @returns The request event, or falsey if not found.\n */\n public get requestEvent(): MatrixEvent | undefined {\n return this.getEventByEither(REQUEST_TYPE);\n }\n\n /** current phase of the request. Some properties might only be defined in a current phase. */\n public get phase(): Phase {\n return this._phase;\n }\n\n /** The verifier to do the actual verification, once the method has been established. Only defined when the `phase` is PHASE_STARTED. */\n public get verifier(): VerificationBase<any, any> | undefined {\n return this._verifier;\n }\n\n public get canAccept(): boolean {\n return this.phase < PHASE_READY && !this._accepting && !this._declining;\n }\n\n public get accepting(): boolean {\n return this._accepting;\n }\n\n public get declining(): boolean {\n return this._declining;\n }\n\n /** whether this request has sent it's initial event and needs more events to complete */\n public get pending(): boolean {\n return !this.observeOnly && this._phase !== PHASE_DONE && this._phase !== PHASE_CANCELLED;\n }\n\n /** Only set after a .ready if the other party can scan a QR code */\n public get qrCodeData(): QRCodeData | null {\n return this._qrCodeData;\n }\n\n /** Checks whether the other party supports a given verification method.\n * This is useful when setting up the QR code UI, as it is somewhat asymmetrical:\n * if the other party supports SCAN_QR, we should show a QR code in the UI, and vice versa.\n * For methods that need to be supported by both ends, use the `methods` property.\n * @param method - the method to check\n * @param force - to check even if the phase is not ready or started yet, internal usage\n * @returns whether or not the other party said the supported the method */\n public otherPartySupportsMethod(method: string, force = false): boolean {\n if (!force && !this.ready && !this.started) {\n return false;\n }\n const theirMethodEvent = this.eventsByThem.get(REQUEST_TYPE) || this.eventsByThem.get(READY_TYPE);\n if (!theirMethodEvent) {\n // if we started straight away with .start event,\n // we are assuming that the other side will support the\n // chosen method, so return true for that.\n if (this.started && this.initiatedByMe) {\n const myStartEvent = this.eventsByUs.get(START_TYPE);\n const content = myStartEvent && myStartEvent.getContent();\n const myStartMethod = content && content.method;\n return method == myStartMethod;\n }\n return false;\n }\n const content = theirMethodEvent.getContent();\n if (!content) {\n return false;\n }\n const { methods } = content;\n if (!Array.isArray(methods)) {\n return false;\n }\n\n return methods.includes(method);\n }\n\n /** Whether this request was initiated by the syncing user.\n * For InRoomChannel, this is who sent the .request event.\n * For ToDeviceChannel, this is who sent the .start event\n */\n public get initiatedByMe(): boolean {\n // event created by us but no remote echo has been received yet\n const noEventsYet = this.eventsByUs.size + this.eventsByThem.size === 0;\n if (this._phase === PHASE_UNSENT && noEventsYet) {\n return true;\n }\n const hasMyRequest = this.eventsByUs.has(REQUEST_TYPE);\n const hasTheirRequest = this.eventsByThem.has(REQUEST_TYPE);\n if (hasMyRequest && !hasTheirRequest) {\n return true;\n }\n if (!hasMyRequest && hasTheirRequest) {\n return false;\n }\n const hasMyStart = this.eventsByUs.has(START_TYPE);\n const hasTheirStart = this.eventsByThem.has(START_TYPE);\n if (hasMyStart && !hasTheirStart) {\n return true;\n }\n return false;\n }\n\n /** The id of the user that initiated the request */\n public get requestingUserId(): string {\n if (this.initiatedByMe) {\n return this.client.getUserId()!;\n } else {\n return this.otherUserId;\n }\n }\n\n /** The id of the user that (will) receive(d) the request */\n public get receivingUserId(): string {\n if (this.initiatedByMe) {\n return this.otherUserId;\n } else {\n return this.client.getUserId()!;\n }\n }\n\n /** The user id of the other party in this request */\n public get otherUserId(): string {\n return this.channel.userId!;\n }\n\n public get isSelfVerification(): boolean {\n return this.client.getUserId() === this.otherUserId;\n }\n\n /**\n * The id of the user that cancelled the request,\n * only defined when phase is PHASE_CANCELLED\n */\n public get cancellingUserId(): string | undefined {\n const myCancel = this.eventsByUs.get(CANCEL_TYPE);\n const theirCancel = this.eventsByThem.get(CANCEL_TYPE);\n\n if (myCancel && (!theirCancel || myCancel.getId()! < theirCancel.getId()!)) {\n return myCancel.getSender();\n }\n if (theirCancel) {\n return theirCancel.getSender();\n }\n return undefined;\n }\n\n /**\n * The cancellation code e.g m.user which is responsible for cancelling this verification\n */\n public get cancellationCode(): string {\n const ev = this.getEventByEither(CANCEL_TYPE);\n return ev ? ev.getContent().code : null;\n }\n\n public get observeOnly(): boolean {\n return this._observeOnly;\n }\n\n /**\n * Gets which device the verification should be started with\n * given the events sent so far in the verification. This is the\n * same algorithm used to determine which device to send the\n * verification to when no specific device is specified.\n * @returns The device information\n */\n public get targetDevice(): ITargetDevice {\n const theirFirstEvent =\n this.eventsByThem.get(REQUEST_TYPE) ||\n this.eventsByThem.get(READY_TYPE) ||\n this.eventsByThem.get(START_TYPE);\n const theirFirstContent = theirFirstEvent?.getContent();\n const fromDevice = theirFirstContent?.from_device;\n return {\n userId: this.otherUserId,\n deviceId: fromDevice,\n };\n }\n\n /* Start the key verification, creating a verifier and sending a .start event.\n * If no previous events have been sent, pass in `targetDevice` to set who to direct this request to.\n * @param method - the name of the verification method to use.\n * @param targetDevice.userId the id of the user to direct this request to\n * @param targetDevice.deviceId the id of the device to direct this request to\n * @returns the verifier of the given method\n */\n public beginKeyVerification(\n method: VerificationMethod,\n targetDevice: ITargetDevice | null = null,\n ): VerificationBase<any, any> {\n // need to allow also when unsent in case of to_device\n if (!this.observeOnly && !this._verifier) {\n const validStartPhase =\n this.phase === PHASE_REQUESTED ||\n this.phase === PHASE_READY ||\n (this.phase === PHASE_UNSENT && this.channel.canCreateRequest(START_TYPE));\n if (validStartPhase) {\n // when called on a request that was initiated with .request event\n // check the method is supported by both sides\n if (this.commonMethods.length && !this.commonMethods.includes(method)) {\n throw newUnknownMethodError();\n }\n this._verifier = this.createVerifier(method, null, targetDevice);\n if (!this._verifier) {\n throw newUnknownMethodError();\n }\n this._chosenMethod = method;\n }\n }\n return this._verifier!;\n }\n\n /**\n * sends the initial .request event.\n * @returns resolves when the event has been sent.\n */\n public async sendRequest(): Promise<void> {\n if (!this.observeOnly && this._phase === PHASE_UNSENT) {\n const methods = [...this.verificationMethods.keys()];\n await this.channel.send(REQUEST_TYPE, { methods });\n }\n }\n\n /**\n * Cancels the request, sending a cancellation to the other party\n * @param reason - the error reason to send the cancellation with\n * @param code - the error code to send the cancellation with\n * @returns resolves when the event has been sent.\n */\n public async cancel({ reason = \"User declined\", code = \"m.user\" } = {}): Promise<void> {\n if (!this.observeOnly && this._phase !== PHASE_CANCELLED) {\n this._declining = true;\n this.emit(VerificationRequestEvent.Change);\n if (this._verifier) {\n return this._verifier.cancel(errorFactory(code, reason)());\n } else {\n this._cancellingUserId = this.client.getUserId()!;\n await this.channel.send(CANCEL_TYPE, { code, reason });\n }\n }\n }\n\n /**\n * Accepts the request, sending a .ready event to the other party\n * @returns resolves when the event has been sent.\n */\n public async accept(): Promise<void> {\n if (!this.observeOnly && this.phase === PHASE_REQUESTED && !this.initiatedByMe) {\n const methods = [...this.verificationMethods.keys()];\n this._accepting = true;\n this.emit(VerificationRequestEvent.Change);\n await this.channel.send(READY_TYPE, { methods });\n }\n }\n\n /**\n * Can be used to listen for state changes until the callback returns true.\n * @param fn - callback to evaluate whether the request is in the desired state.\n * Takes the request as an argument.\n * @returns that resolves once the callback returns true\n * @throws Error when the request is cancelled\n */\n public waitFor(fn: (request: VerificationRequest) => boolean): Promise<VerificationRequest> {\n return new Promise((resolve, reject) => {\n const check = (): boolean => {\n let handled = false;\n if (fn(this)) {\n resolve(this);\n handled = true;\n } else if (this.cancelled) {\n reject(new Error(\"cancelled\"));\n handled = true;\n }\n if (handled) {\n this.off(VerificationRequestEvent.Change, check);\n }\n return handled;\n };\n if (!check()) {\n this.on(VerificationRequestEvent.Change, check);\n }\n });\n }\n\n private setPhase(phase: Phase, notify = true): void {\n this._phase = phase;\n if (notify) {\n this.emit(VerificationRequestEvent.Change);\n }\n }\n\n private getEventByEither(type: string): MatrixEvent | undefined {\n return this.eventsByThem.get(type) || this.eventsByUs.get(type);\n }\n\n private getEventBy(type: string, byThem = false): MatrixEvent | undefined {\n if (byThem) {\n return this.eventsByThem.get(type);\n } else {\n return this.eventsByUs.get(type);\n }\n }\n\n private calculatePhaseTransitions(): ITransition[] {\n const transitions: ITransition[] = [{ phase: PHASE_UNSENT }];\n const phase = (): Phase => transitions[transitions.length - 1].phase;\n\n // always pass by .request first to be sure channel.userId has been set\n const hasRequestByThem = this.eventsByThem.has(REQUEST_TYPE);\n const requestEvent = this.getEventBy(REQUEST_TYPE, hasRequestByThem);\n if (requestEvent) {\n transitions.push({ phase: PHASE_REQUESTED, event: requestEvent });\n }\n\n const readyEvent = requestEvent && this.getEventBy(READY_TYPE, !hasRequestByThem);\n if (readyEvent && phase() === PHASE_REQUESTED) {\n transitions.push({ phase: PHASE_READY, event: readyEvent });\n }\n\n let startEvent: MatrixEvent | undefined;\n if (readyEvent || !requestEvent) {\n const theirStartEvent = this.eventsByThem.get(START_TYPE);\n const ourStartEvent = this.eventsByUs.get(START_TYPE);\n // any party can send .start after a .ready or unsent\n if (theirStartEvent && ourStartEvent) {\n startEvent =\n theirStartEvent.getSender()! < ourStartEvent.getSender()! ? theirStartEvent : ourStartEvent;\n } else {\n startEvent = theirStartEvent ? theirStartEvent : ourStartEvent;\n }\n } else {\n startEvent = this.getEventBy(START_TYPE, !hasRequestByThem);\n }\n if (startEvent) {\n const fromRequestPhase =\n phase() === PHASE_REQUESTED && requestEvent?.getSender() !== startEvent.getSender();\n const fromUnsentPhase = phase() === PHASE_UNSENT && this.channel.canCreateRequest(START_TYPE);\n if (fromRequestPhase || phase() === PHASE_READY || fromUnsentPhase) {\n transitions.push({ phase: PHASE_STARTED, event: startEvent });\n }\n }\n\n const ourDoneEvent = this.eventsByUs.get(DONE_TYPE);\n if (this.verifierHasFinished || (ourDoneEvent && phase() === PHASE_STARTED)) {\n transitions.push({ phase: PHASE_DONE });\n }\n\n const cancelEvent = this.getEventByEither(CANCEL_TYPE);\n if ((this._cancelled || cancelEvent) && phase() !== PHASE_DONE) {\n transitions.push({ phase: PHASE_CANCELLED, event: cancelEvent });\n return transitions;\n }\n\n return transitions;\n }\n\n private transitionToPhase(transition: ITransition): void {\n const { phase, event } = transition;\n // get common methods\n if (phase === PHASE_REQUESTED || phase === PHASE_READY) {\n if (!this.wasSentByOwnDevice(event)) {\n const content = event!.getContent<{\n methods: string[];\n }>();\n this.commonMethods = content.methods.filter((m) => this.verificationMethods.has(m));\n }\n }\n // detect if we're not a party in the request, and we should just observe\n if (!this.observeOnly) {\n // if requested or accepted by one of my other devices\n if (phase === PHASE_REQUESTED || phase === PHASE_STARTED || phase === PHASE_READY) {\n if (\n this.channel.receiveStartFromOtherDevices &&\n this.wasSentByOwnUser(event) &&\n !this.wasSentByOwnDevice(event)\n ) {\n this._observeOnly = true;\n }\n }\n }\n // create verifier\n if (phase === PHASE_STARTED) {\n const { method } = event!.getContent();\n if (!this._verifier && !this.observeOnly) {\n this._verifier = this.createVerifier(method, event);\n if (!this._verifier) {\n this.cancel({\n code: \"m.unknown_method\",\n reason: `Unknown method: ${method}`,\n });\n } else {\n this._chosenMethod = method;\n }\n }\n }\n }\n\n private applyPhaseTransitions(): ITransition[] {\n const transitions = this.calculatePhaseTransitions();\n const existingIdx = transitions.findIndex((t) => t.phase === this.phase);\n // trim off phases we already went through, if any\n const newTransitions = transitions.slice(existingIdx + 1);\n // transition to all new phases\n for (const transition of newTransitions) {\n this.transitionToPhase(transition);\n }\n return newTransitions;\n }\n\n private isWinningStartRace(newEvent: MatrixEvent): boolean {\n if (newEvent.getType() !== START_TYPE) {\n return false;\n }\n const oldEvent = this._verifier!.startEvent;\n\n let oldRaceIdentifier;\n if (this.isSelfVerification) {\n // if the verifier does not have a startEvent,\n // it is because it's still sending and we are on the initator side\n // we know we are sending a .start event because we already\n // have a verifier (checked in calling method)\n if (oldEvent) {\n const oldContent = oldEvent.getContent();\n oldRaceIdentifier = oldContent && oldContent.from_device;\n } else {\n oldRaceIdentifier = this.client.getDeviceId();\n }\n } else {\n if (oldEvent) {\n oldRaceIdentifier = oldEvent.getSender();\n } else {\n oldRaceIdentifier = this.client.getUserId();\n }\n }\n\n let newRaceIdentifier;\n if (this.isSelfVerification) {\n const newContent = newEvent.getContent();\n newRaceIdentifier = newContent && newContent.from_device;\n } else {\n newRaceIdentifier = newEvent.getSender();\n }\n return newRaceIdentifier < oldRaceIdentifier;\n }\n\n public hasEventId(eventId: string): boolean {\n for (const event of this.eventsByUs.values()) {\n if (event.getId() === eventId) {\n return true;\n }\n }\n for (const event of this.eventsByThem.values()) {\n if (event.getId() === eventId) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Changes the state of the request and verifier in response to a key verification event.\n * @param type - the \"symbolic\" event type, as returned by the `getEventType` function on the channel.\n * @param event - the event to handle. Don't call getType() on it but use the `type` parameter instead.\n * @param isLiveEvent - whether this is an even received through sync or not\n * @param isRemoteEcho - whether this is the remote echo of an event sent by the same device\n * @param isSentByUs - whether this event is sent by a party that can accept and/or observe the request like one of our peers.\n * For InRoomChannel this means any device for the syncing user. For ToDeviceChannel, just the syncing device.\n * @returns a promise that resolves when any requests as an answer to the passed-in event are sent.\n */\n public async handleEvent(\n type: string,\n event: MatrixEvent,\n isLiveEvent: boolean,\n isRemoteEcho: boolean,\n isSentByUs: boolean,\n ): Promise<void> {\n // if reached phase cancelled or done, ignore anything else that comes\n if (this.done || this.cancelled) {\n return;\n }\n const wasObserveOnly = this._observeOnly;\n\n this.adjustObserveOnly(event, isLiveEvent);\n\n if (!this.observeOnly && !isRemoteEcho) {\n if (await this.cancelOnError(type, event)) {\n return;\n }\n }\n\n // This assumes verification won't need to send an event with\n // the same type for the same party twice.\n // This is true for QR and SAS verification, and was\n // added here to prevent verification getting cancelled\n // when the server duplicates an event (https://github.com/matrix-org/synapse/issues/3365)\n const isDuplicateEvent = isSentByUs ? this.eventsByUs.has(type) : this.eventsByThem.has(type);\n if (isDuplicateEvent) {\n return;\n }\n\n const oldPhase = this.phase;\n this.addEvent(type, event, isSentByUs);\n\n // this will create if needed the verifier so needs to happen before calling it\n const newTransitions = this.applyPhaseTransitions();\n try {\n // only pass events from the other side to the verifier,\n // no remote echos of our own events\n if (this._verifier && !this.observeOnly) {\n const newEventWinsRace = this.isWinningStartRace(event);\n if (this._verifier.canSwitchStartEvent(event) && newEventWinsRace) {\n this._verifier.switchStartEvent(event);\n } else if (!isRemoteEcho) {\n if (type === CANCEL_TYPE || this._verifier.events?.includes(type)) {\n this._verifier.handleEvent(event);\n }\n }\n }\n\n if (newTransitions.length) {\n // create QRCodeData if the other side can scan\n // important this happens before emitting a phase change,\n // so listeners can rely on it being there already\n // We only do this for live events because it is important that\n // we sign the keys that were in the QR code, and not the keys\n // we happen to have at some later point in time.\n if (isLiveEvent && newTransitions.some((t) => t.phase === PHASE_READY)) {\n const shouldGenerateQrCode = this.otherPartySupportsMethod(SCAN_QR_CODE_METHOD, true);\n if (shouldGenerateQrCode) {\n this._qrCodeData = await QRCodeData.create(this, this.client);\n }\n }\n\n const lastTransition = newTransitions[newTransitions.length - 1];\n const { phase } = lastTransition;\n\n this.setupTimeout(phase);\n // set phase as last thing as this emits the \"change\" event\n this.setPhase(phase);\n } else if (this._observeOnly !== wasObserveOnly) {\n this.emit(VerificationRequestEvent.Change);\n }\n } finally {\n // log events we processed so we can see from rageshakes what events were added to a request\n logger.log(\n `Verification request ${this.channel.transactionId}: ` +\n `${type} event with id:${event.getId()}, ` +\n `content:${JSON.stringify(event.getContent())} ` +\n `deviceId:${this.channel.deviceId}, ` +\n `sender:${event.getSender()}, isSentByUs:${isSentByUs}, ` +\n `isLiveEvent:${isLiveEvent}, isRemoteEcho:${isRemoteEcho}, ` +\n `phase:${oldPhase}=>${this.phase}, ` +\n `observeOnly:${wasObserveOnly}=>${this._observeOnly}`,\n );\n }\n }\n\n private setupTimeout(phase: Phase): void {\n const shouldTimeout = !this.timeoutTimer && !this.observeOnly && phase === PHASE_REQUESTED;\n\n if (shouldTimeout) {\n this.timeoutTimer = setTimeout(this.cancelOnTimeout, this.timeout);\n }\n if (this.timeoutTimer) {\n const shouldClear =\n phase === PHASE_STARTED || phase === PHASE_READY || phase === PHASE_DONE || phase === PHASE_CANCELLED;\n if (shouldClear) {\n clearTimeout(this.timeoutTimer);\n this.timeoutTimer = null;\n }\n }\n }\n\n private cancelOnTimeout = async (): Promise<void> => {\n try {\n if (this.initiatedByMe) {\n await this.cancel({\n reason: \"Other party didn't accept in time\",\n code: \"m.timeout\",\n });\n } else {\n await this.cancel({\n reason: \"User didn't accept in time\",\n code: \"m.timeout\",\n });\n }\n } catch (err) {\n logger.error(\"Error while cancelling verification request\", err);\n }\n };\n\n private async cancelOnError(type: string, event: MatrixEvent): Promise<boolean> {\n if (type === START_TYPE) {\n const method = event.getContent().method;\n if (!this.verificationMethods.has(method)) {\n await this.cancel(errorFromEvent(newUnknownMethodError()));\n return true;\n }\n }\n\n const isUnexpectedRequest = type === REQUEST_TYPE && this.phase !== PHASE_UNSENT;\n const isUnexpectedReady = type === READY_TYPE && this.phase !== PHASE_REQUESTED && this.phase !== PHASE_STARTED;\n // only if phase has passed from PHASE_UNSENT should we cancel, because events\n // are allowed to come in in any order (at least with InRoomChannel). So we only know\n // we're dealing with a valid request we should participate in once we've moved to PHASE_REQUESTED.\n // Before that, we could be looking at somebody else's verification request and we just\n // happen to be in the room\n if (this.phase !== PHASE_UNSENT && (isUnexpectedRequest || isUnexpectedReady)) {\n logger.warn(`Cancelling, unexpected ${type} verification ` + `event from ${event.getSender()}`);\n const reason = `Unexpected ${type} event in phase ${this.phase}`;\n await this.cancel(errorFromEvent(newUnexpectedMessageError({ reason })));\n return true;\n }\n return false;\n }\n\n private adjustObserveOnly(event: MatrixEvent, isLiveEvent = false): void {\n // don't send out events for historical requests\n if (!isLiveEvent) {\n this._observeOnly = true;\n }\n if (this.calculateEventTimeout(event) < VERIFICATION_REQUEST_MARGIN) {\n this._observeOnly = true;\n }\n }\n\n private addEvent(type: string, event: MatrixEvent, isSentByUs = false): void {\n if (isSentByUs) {\n this.eventsByUs.set(type, event);\n } else {\n this.eventsByThem.set(type, event);\n }\n\n // once we know the userId of the other party (from the .request event)\n // see if any event by anyone else crept into this.eventsByThem\n if (type === REQUEST_TYPE) {\n for (const [type, event] of this.eventsByThem.entries()) {\n if (event.getSender() !== this.otherUserId) {\n this.eventsByThem.delete(type);\n }\n }\n // also remember when we received the request event\n this.requestReceivedAt = Date.now();\n }\n }\n\n private createVerifier(\n method: VerificationMethod,\n startEvent: MatrixEvent | null = null,\n targetDevice: ITargetDevice | null = null,\n ): VerificationBase<any, any> | undefined {\n if (!targetDevice) {\n targetDevice = this.targetDevice;\n }\n const { userId, deviceId } = targetDevice;\n\n const VerifierCtor = this.verificationMethods.get(method);\n if (!VerifierCtor) {\n logger.warn(\"could not find verifier constructor for method\", method);\n return;\n }\n return new VerifierCtor(this.channel, this.client, userId!, deviceId!, startEvent, this);\n }\n\n private wasSentByOwnUser(event?: MatrixEvent): boolean {\n return event?.getSender() === this.client.getUserId();\n }\n\n // only for .request, .ready or .start\n private wasSentByOwnDevice(event?: MatrixEvent): boolean {\n if (!this.wasSentByOwnUser(event)) {\n return false;\n }\n const content = event!.getContent();\n if (!content || content.from_device !== this.client.getDeviceId()) {\n return false;\n }\n return true;\n }\n\n public onVerifierCancelled(): void {\n this._cancelled = true;\n // move to cancelled phase\n const newTransitions = this.applyPhaseTransitions();\n if (newTransitions.length) {\n this.setPhase(newTransitions[newTransitions.length - 1].phase);\n }\n }\n\n public onVerifierFinished(): void {\n this.channel.send(EventType.KeyVerificationDone, {});\n this.verifierHasFinished = true;\n // move to .done phase\n const newTransitions = this.applyPhaseTransitions();\n if (newTransitions.length) {\n this.setPhase(newTransitions[newTransitions.length - 1].phase);\n }\n }\n\n public getEventFromOtherParty(type: string): MatrixEvent | undefined {\n return this.eventsByThem.get(type);\n }\n}\n"],"mappings":";;;;;;;;AAgBA,IAAAA,OAAA,GAAAC,OAAA;AACA,IAAAC,MAAA,GAAAD,OAAA;AACA,IAAAE,OAAA,GAAAF,OAAA;AAIA,IAAAG,MAAA,GAAAH,OAAA;AAGA,IAAAI,kBAAA,GAAAJ,OAAA;AAzBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAaA;AACA,MAAMK,qBAAqB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;;AAE9C;AACA,MAAMC,0BAA0B,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;;AAElD;AACA;AACA;AACA;AACA,MAAMC,2BAA2B,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;;AAEvC,MAAMC,YAAY,GAAG,qBAAqB;AAACC,OAAA,CAAAD,YAAA,GAAAA,YAAA;AAC3C,MAAME,YAAY,GAAGF,YAAY,GAAG,SAAS;AAACC,OAAA,CAAAC,YAAA,GAAAA,YAAA;AAC9C,MAAMC,UAAU,GAAGH,YAAY,GAAG,OAAO;AAACC,OAAA,CAAAE,UAAA,GAAAA,UAAA;AAC1C,MAAMC,WAAW,GAAGJ,YAAY,GAAG,QAAQ;AAACC,OAAA,CAAAG,WAAA,GAAAA,WAAA;AAC5C,MAAMC,SAAS,GAAGL,YAAY,GAAG,MAAM;AAACC,OAAA,CAAAI,SAAA,GAAAA,SAAA;AACxC,MAAMC,UAAU,GAAGN,YAAY,GAAG,OAAO;AAACC,OAAA,CAAAK,UAAA,GAAAA,UAAA;AAAA,IAErCC,KAAK,EASjB;AAAAN,OAAA,CAAAM,KAAA,GAAAA,KAAA;AAAA,WATYA,KAAK;EAALA,KAAK,CAALA,KAAK;EAALA,KAAK,CAALA,KAAK;EAALA,KAAK,CAALA,KAAK;EAALA,KAAK,CAALA,KAAK;EAALA,KAAK,CAALA,KAAK;EAALA,KAAK,CAALA,KAAK;AAAA,GAALA,KAAK,KAAAN,OAAA,CAAAM,KAAA,GAALA,KAAK;AAUV,MAAMC,YAAY,GAAGD,KAAK,CAACE,MAAM;AAACR,OAAA,CAAAO,YAAA,GAAAA,YAAA;AAClC,MAAME,eAAe,GAAGH,KAAK,CAACI,SAAS;AAACV,OAAA,CAAAS,eAAA,GAAAA,eAAA;AACxC,MAAME,WAAW,GAAGL,KAAK,CAACM,KAAK;AAACZ,OAAA,CAAAW,WAAA,GAAAA,WAAA;AAChC,MAAME,aAAa,GAAGP,KAAK,CAACQ,OAAO;AAACd,OAAA,CAAAa,aAAA,GAAAA,aAAA;AACpC,MAAME,eAAe,GAAGT,KAAK,CAACU,SAAS;AAAChB,OAAA,CAAAe,eAAA,GAAAA,eAAA;AACxC,MAAME,UAAU,GAAGX,KAAK,CAACY,IAAI;AAAClB,OAAA,CAAAiB,UAAA,GAAAA,UAAA;AAAA,IAYzBE,wBAAwB;AAAAnB,OAAA,CAAAmB,wBAAA,GAAAA,wBAAA;AAAA,WAAxBA,wBAAwB;EAAxBA,wBAAwB;AAAA,GAAxBA,wBAAwB,KAAAnB,OAAA,CAAAmB,wBAAA,GAAxBA,wBAAwB;AAWpC;AACA;AACA;AACA;AACA;AACO,MAAMC,mBAAmB,SAAgEC,oCAAiB,CAG/G;EAUE;EACA;EACA;EACA;;EAGA;;EAKmC;;EAG5BC,WAAWA,CACEC,OAAU,EACTC,mBAAqE,EACrEC,MAAoB,EACvC;IACE,KAAK,EAAE;IAAC,KAJQF,OAAU,GAAVA,OAAU;IAAA,KACTC,mBAAqE,GAArEA,mBAAqE;IAAA,KACrEC,MAAoB,GAApBA,MAAoB;IAAA,IAAAC,gBAAA,CAAAC,OAAA,sBA1BpB,IAAIC,GAAG,EAAuB;IAAA,IAAAF,gBAAA,CAAAC,OAAA,wBAC5B,IAAIC,GAAG,EAAuB;IAAA,IAAAF,gBAAA,CAAAC,OAAA,wBAC9B,KAAK;IAAA,IAAAD,gBAAA,CAAAC,OAAA,wBACiC,IAAI;IAAA,IAAAD,gBAAA,CAAAC,OAAA,sBAC5C,KAAK;IAAA,IAAAD,gBAAA,CAAAC,OAAA,sBACL,KAAK;IAAA,IAAAD,gBAAA,CAAAC,OAAA,+BACI,KAAK;IAAA,IAAAD,gBAAA,CAAAC,OAAA,sBACd,KAAK;IAAA,IAAAD,gBAAA,CAAAC,OAAA,yBACyB,IAAI;IAAA,IAAAD,gBAAA,CAAAC,OAAA,uBAKd,IAAI;IAAA,IAAAD,gBAAA,CAAAC,OAAA,6BAGF,IAAI;IAAA,IAAAD,gBAAA,CAAAC,OAAA,yBAED,EAAE;IAAA,IAAAD,gBAAA,CAAAC,OAAA;IAAA,IAAAD,gBAAA,CAAAC,OAAA;IAAA,IAAAD,gBAAA,CAAAC,OAAA;IAAA,IAAAD,gBAAA,CAAAC,OAAA,2BA6qBtB,YAA2B;MACjD,IAAI;QACA,IAAI,IAAI,CAACE,aAAa,EAAE;UACpB,MAAM,IAAI,CAACC,MAAM,CAAC;YACdC,MAAM,EAAE,mCAAmC;YAC3CC,IAAI,EAAE;UACV,CAAC,CAAC;QACN,CAAC,MAAM;UACH,MAAM,IAAI,CAACF,MAAM,CAAC;YACdC,MAAM,EAAE,4BAA4B;YACpCC,IAAI,EAAE;UACV,CAAC,CAAC;QACN;MACJ,CAAC,CAAC,OAAOC,GAAG,EAAE;QACVC,cAAM,CAACC,KAAK,CAAC,6CAA6C,EAAEF,GAAG,CAAC;MACpE;IACJ,CAAC;IAlrBG,IAAI,CAACV,OAAO,CAACa,OAAO,GAAG,IAAI;IAC3B,IAAI,CAACC,QAAQ,CAAC9B,YAAY,EAAE,KAAK,CAAC;EACtC;;EAEA;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;EACI,OAAc+B,aAAaA,CAACC,IAAY,EAAEC,KAAkB,EAAEf,MAAoB,EAAW;IACzF,MAAMgB,OAAO,GAAGD,KAAK,CAACE,UAAU,EAAE;IAElC,IAAI,CAACH,IAAI,IAAI,CAACA,IAAI,CAACI,UAAU,CAAC5C,YAAY,CAAC,EAAE;MACzC,OAAO,KAAK;IAChB;;IAEA;IACA;IACA,IAAI,CAAC0C,OAAO,EAAE;MACVP,cAAM,CAACU,GAAG,CAAC,gDAAgD,CAAC;MAC5D,OAAO,KAAK;IAChB;IAEA,IAAIL,IAAI,KAAKtC,YAAY,IAAIsC,IAAI,KAAKlC,UAAU,EAAE;MAC9C,IAAI,CAACwC,KAAK,CAACC,OAAO,CAACL,OAAO,CAACM,OAAO,CAAC,EAAE;QACjCb,cAAM,CAACU,GAAG,CAAC,sCAAsC,GAAG,sBAAsB,CAAC;QAC3E,OAAO,KAAK;MAChB;IACJ;IAEA,IAAIL,IAAI,KAAKtC,YAAY,IAAIsC,IAAI,KAAKlC,UAAU,IAAIkC,IAAI,KAAKrC,UAAU,EAAE;MACrE,IAAI,OAAOuC,OAAO,CAACO,WAAW,KAAK,QAAQ,IAAIP,OAAO,CAACO,WAAW,CAACC,MAAM,KAAK,CAAC,EAAE;QAC7Ef,cAAM,CAACU,GAAG,CAAC,sCAAsC,GAAG,0BAA0B,CAAC;QAC/E,OAAO,KAAK;MAChB;IACJ;IAEA,OAAO,IAAI;EACf;EAEA,IAAWM,OAAOA,CAAA,EAAY;IAC1B,OAAO,IAAI,CAACC,KAAK,KAAK5C,YAAY;EACtC;;EAEA;EACA,IAAW6C,SAASA,CAAA,EAAY;IAC5B,OAAO,IAAI,CAACD,KAAK,KAAK1C,eAAe;EACzC;;EAEA;EACA,IAAW4C,SAASA,CAAA,EAAY;IAC5B,OAAO,IAAI,CAACF,KAAK,KAAKpC,eAAe;EACzC;;EAEA;EACA,IAAWuC,KAAKA,CAAA,EAAY;IACxB,OAAO,IAAI,CAACH,KAAK,KAAKxC,WAAW;EACrC;;EAEA;EACA,IAAW4C,OAAOA,CAAA,EAAY;IAC1B,OAAO,IAAI,CAACJ,KAAK,KAAKtC,aAAa;EACvC;;EAEA;EACA,IAAW2C,IAAIA,CAAA,EAAY;IACvB,OAAO,IAAI,CAACL,KAAK,KAAKlC,UAAU;EACpC;;EAEA;EACA,IAAW8B,OAAOA,CAAA,EAAyB;IACvC,OAAO,IAAI,CAACU,aAAa;EAC7B;;EAEA;EACA,IAAWC,YAAYA,CAAA,EAA8B;IACjD,OAAO,IAAI,CAACC,aAAa;EAC7B;EAEOC,qBAAqBA,CAACpB,KAAkB,EAAU;IACrD,IAAIqB,kBAAkB,GAAG,IAAI,CAACtC,OAAO,CAACuC,YAAY,CAACtB,KAAK,CAAC,GAAG5C,qBAAqB;IAEjF,IAAI,IAAI,CAACmE,iBAAiB,IAAI,CAAC,IAAI,CAAClC,aAAa,IAAI,IAAI,CAACsB,KAAK,IAAI1C,eAAe,EAAE;MAChF,MAAMuD,kBAAkB,GAAG,IAAI,CAACD,iBAAiB,GAAGlE,0BAA0B;MAC9EgE,kBAAkB,GAAGI,IAAI,CAACC,GAAG,CAACL,kBAAkB,EAAEG,kBAAkB,CAAC;IACzE;IAEA,OAAOC,IAAI,CAACE,GAAG,CAAC,CAAC,EAAEN,kBAAkB,GAAGO,IAAI,CAACC,GAAG,EAAE,CAAC;EACvD;;EAEA;EACA,IAAWC,OAAOA,CAAA,EAAW;IACzB,MAAMC,YAAY,GAAG,IAAI,CAACC,gBAAgB,CAACvE,YAAY,CAAC;IACxD,IAAIsE,YAAY,EAAE;MACd,OAAO,IAAI,CAACX,qBAAqB,CAACW,YAAY,CAAC;IACnD;IACA,OAAO,CAAC;EACZ;;EAEA;AACJ;AACA;AACA;EACI,IAAWA,YAAYA,CAAA,EAA4B;IAC/C,OAAO,IAAI,CAACC,gBAAgB,CAACvE,YAAY,CAAC;EAC9C;;EAEA;EACA,IAAWkD,KAAKA,CAAA,EAAU;IACtB,OAAO,IAAI,CAACsB,MAAM;EACtB;;EAEA;EACA,IAAWC,QAAQA,CAAA,EAA2C;IAC1D,OAAO,IAAI,CAACC,SAAS;EACzB;EAEA,IAAWC,SAASA,CAAA,EAAY;IAC5B,OAAO,IAAI,CAACzB,KAAK,GAAGxC,WAAW,IAAI,CAAC,IAAI,CAACkE,UAAU,IAAI,CAAC,IAAI,CAACC,UAAU;EAC3E;EAEA,IAAWC,SAASA,CAAA,EAAY;IAC5B,OAAO,IAAI,CAACF,UAAU;EAC1B;EAEA,IAAWG,SAASA,CAAA,EAAY;IAC5B,OAAO,IAAI,CAACF,UAAU;EAC1B;;EAEA;EACA,IAAWG,OAAOA,CAAA,EAAY;IAC1B,OAAO,CAAC,IAAI,CAACC,WAAW,IAAI,IAAI,CAACT,MAAM,KAAKxD,UAAU,IAAI,IAAI,CAACwD,MAAM,KAAK1D,eAAe;EAC7F;;EAEA;EACA,IAAWoE,UAAUA,CAAA,EAAsB;IACvC,OAAO,IAAI,CAACC,WAAW;EAC3B;;EAEA;AACJ;AACA;AACA;AACA;AACA;AACA;EACWC,wBAAwBA,CAACC,MAAc,EAAEC,KAAK,GAAG,KAAK,EAAW;IACpE,IAAI,CAACA,KAAK,IAAI,CAAC,IAAI,CAACjC,KAAK,IAAI,CAAC,IAAI,CAACC,OAAO,EAAE;MACxC,OAAO,KAAK;IAChB;IACA,MAAMiC,gBAAgB,GAAG,IAAI,CAACC,YAAY,CAACC,GAAG,CAACzF,YAAY,CAAC,IAAI,IAAI,CAACwF,YAAY,CAACC,GAAG,CAACrF,UAAU,CAAC;IACjG,IAAI,CAACmF,gBAAgB,EAAE;MACnB;MACA;MACA;MACA,IAAI,IAAI,CAACjC,OAAO,IAAI,IAAI,CAAC1B,aAAa,EAAE;QACpC,MAAM8D,YAAY,GAAG,IAAI,CAACC,UAAU,CAACF,GAAG,CAACxF,UAAU,CAAC;QACpD,MAAMuC,OAAO,GAAGkD,YAAY,IAAIA,YAAY,CAACjD,UAAU,EAAE;QACzD,MAAMmD,aAAa,GAAGpD,OAAO,IAAIA,OAAO,CAAC6C,MAAM;QAC/C,OAAOA,MAAM,IAAIO,aAAa;MAClC;MACA,OAAO,KAAK;IAChB;IACA,MAAMpD,OAAO,GAAG+C,gBAAgB,CAAC9C,UAAU,EAAE;IAC7C,IAAI,CAACD,OAAO,EAAE;MACV,OAAO,KAAK;IAChB;IACA,MAAM;MAAEM;IAAQ,CAAC,GAAGN,OAAO;IAC3B,IAAI,CAACI,KAAK,CAACC,OAAO,CAACC,OAAO,CAAC,EAAE;MACzB,OAAO,KAAK;IAChB;IAEA,OAAOA,OAAO,CAAC+C,QAAQ,CAACR,MAAM,CAAC;EACnC;;EAEA;AACJ;AACA;AACA;EACI,IAAWzD,aAAaA,CAAA,EAAY;IAChC;IACA,MAAMkE,WAAW,GAAG,IAAI,CAACH,UAAU,CAACI,IAAI,GAAG,IAAI,CAACP,YAAY,CAACO,IAAI,KAAK,CAAC;IACvE,IAAI,IAAI,CAACvB,MAAM,KAAKlE,YAAY,IAAIwF,WAAW,EAAE;MAC7C,OAAO,IAAI;IACf;IACA,MAAME,YAAY,GAAG,IAAI,CAACL,UAAU,CAACM,GAAG,CAACjG,YAAY,CAAC;IACtD,MAAMkG,eAAe,GAAG,IAAI,CAACV,YAAY,CAACS,GAAG,CAACjG,YAAY,CAAC;IAC3D,IAAIgG,YAAY,IAAI,CAACE,eAAe,EAAE;MAClC,OAAO,IAAI;IACf;IACA,IAAI,CAACF,YAAY,IAAIE,eAAe,EAAE;MAClC,OAAO,KAAK;IAChB;IACA,MAAMC,UAAU,GAAG,IAAI,CAACR,UAAU,CAACM,GAAG,CAAChG,UAAU,CAAC;IAClD,MAAMmG,aAAa,GAAG,IAAI,CAACZ,YAAY,CAACS,GAAG,CAAChG,UAAU,CAAC;IACvD,IAAIkG,UAAU,IAAI,CAACC,aAAa,EAAE;MAC9B,OAAO,IAAI;IACf;IACA,OAAO,KAAK;EAChB;;EAEA;EACA,IAAWC,gBAAgBA,CAAA,EAAW;IAClC,IAAI,IAAI,CAACzE,aAAa,EAAE;MACpB,OAAO,IAAI,CAACJ,MAAM,CAAC8E,SAAS,EAAE;IAClC,CAAC,MAAM;MACH,OAAO,IAAI,CAACC,WAAW;IAC3B;EACJ;;EAEA;EACA,IAAWC,eAAeA,CAAA,EAAW;IACjC,IAAI,IAAI,CAAC5E,aAAa,EAAE;MACpB,OAAO,IAAI,CAAC2E,WAAW;IAC3B,CAAC,MAAM;MACH,OAAO,IAAI,CAAC/E,MAAM,CAAC8E,SAAS,EAAE;IAClC;EACJ;;EAEA;EACA,IAAWC,WAAWA,CAAA,EAAW;IAC7B,OAAO,IAAI,CAACjF,OAAO,CAACmF,MAAM;EAC9B;EAEA,IAAWC,kBAAkBA,CAAA,EAAY;IACrC,OAAO,IAAI,CAAClF,MAAM,CAAC8E,SAAS,EAAE,KAAK,IAAI,CAACC,WAAW;EACvD;;EAEA;AACJ;AACA;AACA;EACI,IAAWI,gBAAgBA,CAAA,EAAuB;IAC9C,MAAMC,QAAQ,GAAG,IAAI,CAACjB,UAAU,CAACF,GAAG,CAACvF,WAAW,CAAC;IACjD,MAAM2G,WAAW,GAAG,IAAI,CAACrB,YAAY,CAACC,GAAG,CAACvF,WAAW,CAAC;IAEtD,IAAI0G,QAAQ,KAAK,CAACC,WAAW,IAAID,QAAQ,CAACE,KAAK,EAAE,GAAID,WAAW,CAACC,KAAK,EAAG,CAAC,EAAE;MACxE,OAAOF,QAAQ,CAACG,SAAS,EAAE;IAC/B;IACA,IAAIF,WAAW,EAAE;MACb,OAAOA,WAAW,CAACE,SAAS,EAAE;IAClC;IACA,OAAOC,SAAS;EACpB;;EAEA;AACJ;AACA;EACI,IAAWC,gBAAgBA,CAAA,EAAW;IAClC,MAAMC,EAAE,GAAG,IAAI,CAAC3C,gBAAgB,CAACrE,WAAW,CAAC;IAC7C,OAAOgH,EAAE,GAAGA,EAAE,CAACzE,UAAU,EAAE,CAACV,IAAI,GAAG,IAAI;EAC3C;EAEA,IAAWkD,WAAWA,CAAA,EAAY;IAC9B,OAAO,IAAI,CAACkC,YAAY;EAC5B;;EAEA;AACJ;AACA;AACA;AACA;AACA;AACA;EACI,IAAWC,YAAYA,CAAA,EAAkB;IACrC,MAAMC,eAAe,GACjB,IAAI,CAAC7B,YAAY,CAACC,GAAG,CAACzF,YAAY,CAAC,IACnC,IAAI,CAACwF,YAAY,CAACC,GAAG,CAACrF,UAAU,CAAC,IACjC,IAAI,CAACoF,YAAY,CAACC,GAAG,CAACxF,UAAU,CAAC;IACrC,MAAMqH,iBAAiB,GAAGD,eAAe,aAAfA,eAAe,uBAAfA,eAAe,CAAE5E,UAAU,EAAE;IACvD,MAAM8E,UAAU,GAAGD,iBAAiB,aAAjBA,iBAAiB,uBAAjBA,iBAAiB,CAAEvE,WAAW;IACjD,OAAO;MACH0D,MAAM,EAAE,IAAI,CAACF,WAAW;MACxBiB,QAAQ,EAAED;IACd,CAAC;EACL;;EAEA;AACJ;AACA;AACA;AACA;AACA;AACA;EACWE,oBAAoBA,CACvBpC,MAA0B,EAC1B+B,YAAkC,GAAG,IAAI,EACf;IAC1B;IACA,IAAI,CAAC,IAAI,CAACnC,WAAW,IAAI,CAAC,IAAI,CAACP,SAAS,EAAE;MACtC,MAAMgD,eAAe,GACjB,IAAI,CAACxE,KAAK,KAAK1C,eAAe,IAC9B,IAAI,CAAC0C,KAAK,KAAKxC,WAAW,IACzB,IAAI,CAACwC,KAAK,KAAK5C,YAAY,IAAI,IAAI,CAACgB,OAAO,CAACqG,gBAAgB,CAAC1H,UAAU,CAAE;MAC9E,IAAIyH,eAAe,EAAE;QACjB;QACA;QACA,IAAI,IAAI,CAAClE,aAAa,CAACR,MAAM,IAAI,CAAC,IAAI,CAACQ,aAAa,CAACqC,QAAQ,CAACR,MAAM,CAAC,EAAE;UACnE,MAAM,IAAAuC,4BAAqB,GAAE;QACjC;QACA,IAAI,CAAClD,SAAS,GAAG,IAAI,CAACmD,cAAc,CAACxC,MAAM,EAAE,IAAI,EAAE+B,YAAY,CAAC;QAChE,IAAI,CAAC,IAAI,CAAC1C,SAAS,EAAE;UACjB,MAAM,IAAAkD,4BAAqB,GAAE;QACjC;QACA,IAAI,CAAClE,aAAa,GAAG2B,MAAM;MAC/B;IACJ;IACA,OAAO,IAAI,CAACX,SAAS;EACzB;;EAEA;AACJ;AACA;AACA;EACI,MAAaoD,WAAWA,CAAA,EAAkB;IACtC,IAAI,CAAC,IAAI,CAAC7C,WAAW,IAAI,IAAI,CAACT,MAAM,KAAKlE,YAAY,EAAE;MACnD,MAAMwC,OAAO,GAAG,CAAC,GAAG,IAAI,CAACvB,mBAAmB,CAACwG,IAAI,EAAE,CAAC;MACpD,MAAM,IAAI,CAACzG,OAAO,CAAC0G,IAAI,CAAChI,YAAY,EAAE;QAAE8C;MAAQ,CAAC,CAAC;IACtD;EACJ;;EAEA;AACJ;AACA;AACA;AACA;AACA;EACI,MAAajB,MAAMA,CAAC;IAAEC,MAAM,GAAG,eAAe;IAAEC,IAAI,GAAG;EAAS,CAAC,GAAG,CAAC,CAAC,EAAiB;IACnF,IAAI,CAAC,IAAI,CAACkD,WAAW,IAAI,IAAI,CAACT,MAAM,KAAK1D,eAAe,EAAE;MACtD,IAAI,CAAC+D,UAAU,GAAG,IAAI;MACtB,IAAI,CAACoD,IAAI,CAAC/G,wBAAwB,CAACgH,MAAM,CAAC;MAC1C,IAAI,IAAI,CAACxD,SAAS,EAAE;QAChB,OAAO,IAAI,CAACA,SAAS,CAAC7C,MAAM,CAAC,IAAAsG,mBAAY,EAACpG,IAAI,EAAED,MAAM,CAAC,EAAE,CAAC;MAC9D,CAAC,MAAM;QACH,IAAI,CAACsG,iBAAiB,GAAG,IAAI,CAAC5G,MAAM,CAAC8E,SAAS,EAAG;QACjD,MAAM,IAAI,CAAChF,OAAO,CAAC0G,IAAI,CAAC9H,WAAW,EAAE;UAAE6B,IAAI;UAAED;QAAO,CAAC,CAAC;MAC1D;IACJ;EACJ;;EAEA;AACJ;AACA;AACA;EACI,MAAauG,MAAMA,CAAA,EAAkB;IACjC,IAAI,CAAC,IAAI,CAACpD,WAAW,IAAI,IAAI,CAAC/B,KAAK,KAAK1C,eAAe,IAAI,CAAC,IAAI,CAACoB,aAAa,EAAE;MAC5E,MAAMkB,OAAO,GAAG,CAAC,GAAG,IAAI,CAACvB,mBAAmB,CAACwG,IAAI,EAAE,CAAC;MACpD,IAAI,CAACnD,UAAU,GAAG,IAAI;MACtB,IAAI,CAACqD,IAAI,CAAC/G,wBAAwB,CAACgH,MAAM,CAAC;MAC1C,MAAM,IAAI,CAAC5G,OAAO,CAAC0G,IAAI,CAAC5H,UAAU,EAAE;QAAE0C;MAAQ,CAAC,CAAC;IACpD;EACJ;;EAEA;AACJ;AACA;AACA;AACA;AACA;AACA;EACWwF,OAAOA,CAACC,EAA6C,EAAgC;IACxF,OAAO,IAAIC,OAAO,CAAC,CAACC,OAAO,EAAEC,MAAM,KAAK;MACpC,MAAMC,KAAK,GAAGA,CAAA,KAAe;QACzB,IAAIC,OAAO,GAAG,KAAK;QACnB,IAAIL,EAAE,CAAC,IAAI,CAAC,EAAE;UACVE,OAAO,CAAC,IAAI,CAAC;UACbG,OAAO,GAAG,IAAI;QAClB,CAAC,MAAM,IAAI,IAAI,CAACxF,SAAS,EAAE;UACvBsF,MAAM,CAAC,IAAIG,KAAK,CAAC,WAAW,CAAC,CAAC;UAC9BD,OAAO,GAAG,IAAI;QAClB;QACA,IAAIA,OAAO,EAAE;UACT,IAAI,CAACE,GAAG,CAAC5H,wBAAwB,CAACgH,MAAM,EAAES,KAAK,CAAC;QACpD;QACA,OAAOC,OAAO;MAClB,CAAC;MACD,IAAI,CAACD,KAAK,EAAE,EAAE;QACV,IAAI,CAACI,EAAE,CAAC7H,wBAAwB,CAACgH,MAAM,EAAES,KAAK,CAAC;MACnD;IACJ,CAAC,CAAC;EACN;EAEQvG,QAAQA,CAACc,KAAY,EAAE8F,MAAM,GAAG,IAAI,EAAQ;IAChD,IAAI,CAACxE,MAAM,GAAGtB,KAAK;IACnB,IAAI8F,MAAM,EAAE;MACR,IAAI,CAACf,IAAI,CAAC/G,wBAAwB,CAACgH,MAAM,CAAC;IAC9C;EACJ;EAEQ3D,gBAAgBA,CAACjC,IAAY,EAA2B;IAC5D,OAAO,IAAI,CAACkD,YAAY,CAACC,GAAG,CAACnD,IAAI,CAAC,IAAI,IAAI,CAACqD,UAAU,CAACF,GAAG,CAACnD,IAAI,CAAC;EACnE;EAEQ2G,UAAUA,CAAC3G,IAAY,EAAE4G,MAAM,GAAG,KAAK,EAA2B;IACtE,IAAIA,MAAM,EAAE;MACR,OAAO,IAAI,CAAC1D,YAAY,CAACC,GAAG,CAACnD,IAAI,CAAC;IACtC,CAAC,MAAM;MACH,OAAO,IAAI,CAACqD,UAAU,CAACF,GAAG,CAACnD,IAAI,CAAC;IACpC;EACJ;EAEQ6G,yBAAyBA,CAAA,EAAkB;IAC/C,MAAMC,WAA0B,GAAG,CAAC;MAAElG,KAAK,EAAE5C;IAAa,CAAC,CAAC;IAC5D,MAAM4C,KAAK,GAAGA,CAAA,KAAakG,WAAW,CAACA,WAAW,CAACpG,MAAM,GAAG,CAAC,CAAC,CAACE,KAAK;;IAEpE;IACA,MAAMmG,gBAAgB,GAAG,IAAI,CAAC7D,YAAY,CAACS,GAAG,CAACjG,YAAY,CAAC;IAC5D,MAAMsE,YAAY,GAAG,IAAI,CAAC2E,UAAU,CAACjJ,YAAY,EAAEqJ,gBAAgB,CAAC;IACpE,IAAI/E,YAAY,EAAE;MACd8E,WAAW,CAACE,IAAI,CAAC;QAAEpG,KAAK,EAAE1C,eAAe;QAAE+B,KAAK,EAAE+B;MAAa,CAAC,CAAC;IACrE;IAEA,MAAMiF,UAAU,GAAGjF,YAAY,IAAI,IAAI,CAAC2E,UAAU,CAAC7I,UAAU,EAAE,CAACiJ,gBAAgB,CAAC;IACjF,IAAIE,UAAU,IAAIrG,KAAK,EAAE,KAAK1C,eAAe,EAAE;MAC3C4I,WAAW,CAACE,IAAI,CAAC;QAAEpG,KAAK,EAAExC,WAAW;QAAE6B,KAAK,EAAEgH;MAAW,CAAC,CAAC;IAC/D;IAEA,IAAIC,UAAmC;IACvC,IAAID,UAAU,IAAI,CAACjF,YAAY,EAAE;MAC7B,MAAMmF,eAAe,GAAG,IAAI,CAACjE,YAAY,CAACC,GAAG,CAACxF,UAAU,CAAC;MACzD,MAAMyJ,aAAa,GAAG,IAAI,CAAC/D,UAAU,CAACF,GAAG,CAACxF,UAAU,CAAC;MACrD;MACA,IAAIwJ,eAAe,IAAIC,aAAa,EAAE;QAClCF,UAAU,GACNC,eAAe,CAAC1C,SAAS,EAAE,GAAI2C,aAAa,CAAC3C,SAAS,EAAG,GAAG0C,eAAe,GAAGC,aAAa;MACnG,CAAC,MAAM;QACHF,UAAU,GAAGC,eAAe,GAAGA,eAAe,GAAGC,aAAa;MAClE;IACJ,CAAC,MAAM;MACHF,UAAU,GAAG,IAAI,CAACP,UAAU,CAAChJ,UAAU,EAAE,CAACoJ,gBAAgB,CAAC;IAC/D;IACA,IAAIG,UAAU,EAAE;MACZ,MAAMG,gBAAgB,GAClBzG,KAAK,EAAE,KAAK1C,eAAe,IAAI,CAAA8D,YAAY,aAAZA,YAAY,uBAAZA,YAAY,CAAEyC,SAAS,EAAE,MAAKyC,UAAU,CAACzC,SAAS,EAAE;MACvF,MAAM6C,eAAe,GAAG1G,KAAK,EAAE,KAAK5C,YAAY,IAAI,IAAI,CAACgB,OAAO,CAACqG,gBAAgB,CAAC1H,UAAU,CAAC;MAC7F,IAAI0J,gBAAgB,IAAIzG,KAAK,EAAE,KAAKxC,WAAW,IAAIkJ,eAAe,EAAE;QAChER,WAAW,CAACE,IAAI,CAAC;UAAEpG,KAAK,EAAEtC,aAAa;UAAE2B,KAAK,EAAEiH;QAAW,CAAC,CAAC;MACjE;IACJ;IAEA,MAAMK,YAAY,GAAG,IAAI,CAAClE,UAAU,CAACF,GAAG,CAACtF,SAAS,CAAC;IACnD,IAAI,IAAI,CAAC2J,mBAAmB,IAAKD,YAAY,IAAI3G,KAAK,EAAE,KAAKtC,aAAc,EAAE;MACzEwI,WAAW,CAACE,IAAI,CAAC;QAAEpG,KAAK,EAAElC;MAAW,CAAC,CAAC;IAC3C;IAEA,MAAM+I,WAAW,GAAG,IAAI,CAACxF,gBAAgB,CAACrE,WAAW,CAAC;IACtD,IAAI,CAAC,IAAI,CAAC8J,UAAU,IAAID,WAAW,KAAK7G,KAAK,EAAE,KAAKlC,UAAU,EAAE;MAC5DoI,WAAW,CAACE,IAAI,CAAC;QAAEpG,KAAK,EAAEpC,eAAe;QAAEyB,KAAK,EAAEwH;MAAY,CAAC,CAAC;MAChE,OAAOX,WAAW;IACtB;IAEA,OAAOA,WAAW;EACtB;EAEQa,iBAAiBA,CAACC,UAAuB,EAAQ;IACrD,MAAM;MAAEhH,KAAK;MAAEX;IAAM,CAAC,GAAG2H,UAAU;IACnC;IACA,IAAIhH,KAAK,KAAK1C,eAAe,IAAI0C,KAAK,KAAKxC,WAAW,EAAE;MACpD,IAAI,CAAC,IAAI,CAACyJ,kBAAkB,CAAC5H,KAAK,CAAC,EAAE;QACjC,MAAMC,OAAO,GAAGD,KAAK,CAAEE,UAAU,EAE7B;QACJ,IAAI,CAACe,aAAa,GAAGhB,OAAO,CAACM,OAAO,CAACsH,MAAM,CAAEC,CAAC,IAAK,IAAI,CAAC9I,mBAAmB,CAAC0E,GAAG,CAACoE,CAAC,CAAC,CAAC;MACvF;IACJ;IACA;IACA,IAAI,CAAC,IAAI,CAACpF,WAAW,EAAE;MACnB;MACA,IAAI/B,KAAK,KAAK1C,eAAe,IAAI0C,KAAK,KAAKtC,aAAa,IAAIsC,KAAK,KAAKxC,WAAW,EAAE;QAC/E,IACI,IAAI,CAACY,OAAO,CAACgJ,4BAA4B,IACzC,IAAI,CAACC,gBAAgB,CAAChI,KAAK,CAAC,IAC5B,CAAC,IAAI,CAAC4H,kBAAkB,CAAC5H,KAAK,CAAC,EACjC;UACE,IAAI,CAAC4E,YAAY,GAAG,IAAI;QAC5B;MACJ;IACJ;IACA;IACA,IAAIjE,KAAK,KAAKtC,aAAa,EAAE;MACzB,MAAM;QAAEyE;MAAO,CAAC,GAAG9C,KAAK,CAAEE,UAAU,EAAE;MACtC,IAAI,CAAC,IAAI,CAACiC,SAAS,IAAI,CAAC,IAAI,CAACO,WAAW,EAAE;QACtC,IAAI,CAACP,SAAS,GAAG,IAAI,CAACmD,cAAc,CAACxC,MAAM,EAAE9C,KAAK,CAAC;QACnD,IAAI,CAAC,IAAI,CAACmC,SAAS,EAAE;UACjB,IAAI,CAAC7C,MAAM,CAAC;YACRE,IAAI,EAAE,kBAAkB;YACxBD,MAAM,EAAG,mBAAkBuD,MAAO;UACtC,CAAC,CAAC;QACN,CAAC,MAAM;UACH,IAAI,CAAC3B,aAAa,GAAG2B,MAAM;QAC/B;MACJ;IACJ;EACJ;EAEQmF,qBAAqBA,CAAA,EAAkB;IAC3C,MAAMpB,WAAW,GAAG,IAAI,CAACD,yBAAyB,EAAE;IACpD,MAAMsB,WAAW,GAAGrB,WAAW,CAACsB,SAAS,CAAEC,CAAC,IAAKA,CAAC,CAACzH,KAAK,KAAK,IAAI,CAACA,KAAK,CAAC;IACxE;IACA,MAAM0H,cAAc,GAAGxB,WAAW,CAACyB,KAAK,CAACJ,WAAW,GAAG,CAAC,CAAC;IACzD;IACA,KAAK,MAAMP,UAAU,IAAIU,cAAc,EAAE;MACrC,IAAI,CAACX,iBAAiB,CAACC,UAAU,CAAC;IACtC;IACA,OAAOU,cAAc;EACzB;EAEQE,kBAAkBA,CAACC,QAAqB,EAAW;IACvD,IAAIA,QAAQ,CAACC,OAAO,EAAE,KAAK/K,UAAU,EAAE;MACnC,OAAO,KAAK;IAChB;IACA,MAAMgL,QAAQ,GAAG,IAAI,CAACvG,SAAS,CAAE8E,UAAU;IAE3C,IAAI0B,iBAAiB;IACrB,IAAI,IAAI,CAACxE,kBAAkB,EAAE;MACzB;MACA;MACA;MACA;MACA,IAAIuE,QAAQ,EAAE;QACV,MAAME,UAAU,GAAGF,QAAQ,CAACxI,UAAU,EAAE;QACxCyI,iBAAiB,GAAGC,UAAU,IAAIA,UAAU,CAACpI,WAAW;MAC5D,CAAC,MAAM;QACHmI,iBAAiB,GAAG,IAAI,CAAC1J,MAAM,CAAC4J,WAAW,EAAE;MACjD;IACJ,CAAC,MAAM;MACH,IAAIH,QAAQ,EAAE;QACVC,iBAAiB,GAAGD,QAAQ,CAAClE,SAAS,EAAE;MAC5C,CAAC,MAAM;QACHmE,iBAAiB,GAAG,IAAI,CAAC1J,MAAM,CAAC8E,SAAS,EAAE;MAC/C;IACJ;IAEA,IAAI+E,iBAAiB;IACrB,IAAI,IAAI,CAAC3E,kBAAkB,EAAE;MACzB,MAAM4E,UAAU,GAAGP,QAAQ,CAACtI,UAAU,EAAE;MACxC4I,iBAAiB,GAAGC,UAAU,IAAIA,UAAU,CAACvI,WAAW;IAC5D,CAAC,MAAM;MACHsI,iBAAiB,GAAGN,QAAQ,CAAChE,SAAS,EAAE;IAC5C;IACA,OAAOsE,iBAAiB,GAAGH,iBAAiB;EAChD;EAEOK,UAAUA,CAACC,OAAe,EAAW;IACxC,KAAK,MAAMjJ,KAAK,IAAI,IAAI,CAACoD,UAAU,CAAC8F,MAAM,EAAE,EAAE;MAC1C,IAAIlJ,KAAK,CAACuE,KAAK,EAAE,KAAK0E,OAAO,EAAE;QAC3B,OAAO,IAAI;MACf;IACJ;IACA,KAAK,MAAMjJ,KAAK,IAAI,IAAI,CAACiD,YAAY,CAACiG,MAAM,EAAE,EAAE;MAC5C,IAAIlJ,KAAK,CAACuE,KAAK,EAAE,KAAK0E,OAAO,EAAE;QAC3B,OAAO,IAAI;MACf;IACJ;IACA,OAAO,KAAK;EAChB;;EAEA;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACI,MAAaE,WAAWA,CACpBpJ,IAAY,EACZC,KAAkB,EAClBoJ,WAAoB,EACpBC,YAAqB,EACrBC,UAAmB,EACN;IACb;IACA,IAAI,IAAI,CAACtI,IAAI,IAAI,IAAI,CAACH,SAAS,EAAE;MAC7B;IACJ;IACA,MAAM0I,cAAc,GAAG,IAAI,CAAC3E,YAAY;IAExC,IAAI,CAAC4E,iBAAiB,CAACxJ,KAAK,EAAEoJ,WAAW,CAAC;IAE1C,IAAI,CAAC,IAAI,CAAC1G,WAAW,IAAI,CAAC2G,YAAY,EAAE;MACpC,IAAI,MAAM,IAAI,CAACI,aAAa,CAAC1J,IAAI,EAAEC,KAAK,CAAC,EAAE;QACvC;MACJ;IACJ;;IAEA;IACA;IACA;IACA;IACA;IACA,MAAM0J,gBAAgB,GAAGJ,UAAU,GAAG,IAAI,CAAClG,UAAU,CAACM,GAAG,CAAC3D,IAAI,CAAC,GAAG,IAAI,CAACkD,YAAY,CAACS,GAAG,CAAC3D,IAAI,CAAC;IAC7F,IAAI2J,gBAAgB,EAAE;MAClB;IACJ;IAEA,MAAMC,QAAQ,GAAG,IAAI,CAAChJ,KAAK;IAC3B,IAAI,CAACiJ,QAAQ,CAAC7J,IAAI,EAAEC,KAAK,EAAEsJ,UAAU,CAAC;;IAEtC;IACA,MAAMjB,cAAc,GAAG,IAAI,CAACJ,qBAAqB,EAAE;IACnD,IAAI;MACA;MACA;MACA,IAAI,IAAI,CAAC9F,SAAS,IAAI,CAAC,IAAI,CAACO,WAAW,EAAE;QACrC,MAAMmH,gBAAgB,GAAG,IAAI,CAACtB,kBAAkB,CAACvI,KAAK,CAAC;QACvD,IAAI,IAAI,CAACmC,SAAS,CAAC2H,mBAAmB,CAAC9J,KAAK,CAAC,IAAI6J,gBAAgB,EAAE;UAC/D,IAAI,CAAC1H,SAAS,CAAC4H,gBAAgB,CAAC/J,KAAK,CAAC;QAC1C,CAAC,MAAM,IAAI,CAACqJ,YAAY,EAAE;UAAA,IAAAW,qBAAA;UACtB,IAAIjK,IAAI,KAAKpC,WAAW,KAAAqM,qBAAA,GAAI,IAAI,CAAC7H,SAAS,CAAC8H,MAAM,cAAAD,qBAAA,eAArBA,qBAAA,CAAuB1G,QAAQ,CAACvD,IAAI,CAAC,EAAE;YAC/D,IAAI,CAACoC,SAAS,CAACgH,WAAW,CAACnJ,KAAK,CAAC;UACrC;QACJ;MACJ;MAEA,IAAIqI,cAAc,CAAC5H,MAAM,EAAE;QACvB;QACA;QACA;QACA;QACA;QACA;QACA,IAAI2I,WAAW,IAAIf,cAAc,CAAC6B,IAAI,CAAE9B,CAAC,IAAKA,CAAC,CAACzH,KAAK,KAAKxC,WAAW,CAAC,EAAE;UACpE,MAAMgM,oBAAoB,GAAG,IAAI,CAACtH,wBAAwB,CAACuH,2BAAmB,EAAE,IAAI,CAAC;UACrF,IAAID,oBAAoB,EAAE;YACtB,IAAI,CAACvH,WAAW,GAAG,MAAMyH,kBAAU,CAACC,MAAM,CAAC,IAAI,EAAE,IAAI,CAACrL,MAAM,CAAC;UACjE;QACJ;QAEA,MAAMsL,cAAc,GAAGlC,cAAc,CAACA,cAAc,CAAC5H,MAAM,GAAG,CAAC,CAAC;QAChE,MAAM;UAAEE;QAAM,CAAC,GAAG4J,cAAc;QAEhC,IAAI,CAACC,YAAY,CAAC7J,KAAK,CAAC;QACxB;QACA,IAAI,CAACd,QAAQ,CAACc,KAAK,CAAC;MACxB,CAAC,MAAM,IAAI,IAAI,CAACiE,YAAY,KAAK2E,cAAc,EAAE;QAC7C,IAAI,CAAC7D,IAAI,CAAC/G,wBAAwB,CAACgH,MAAM,CAAC;MAC9C;IACJ,CAAC,SAAS;MACN;MACAjG,cAAM,CAACU,GAAG,CACL,wBAAuB,IAAI,CAACrB,OAAO,CAAC0L,aAAc,IAAG,GACjD,GAAE1K,IAAK,kBAAiBC,KAAK,CAACuE,KAAK,EAAG,IAAG,GACzC,WAAUmG,IAAI,CAACC,SAAS,CAAC3K,KAAK,CAACE,UAAU,EAAE,CAAE,GAAE,GAC/C,YAAW,IAAI,CAACnB,OAAO,CAACkG,QAAS,IAAG,GACpC,UAASjF,KAAK,CAACwE,SAAS,EAAG,gBAAe8E,UAAW,IAAG,GACxD,eAAcF,WAAY,kBAAiBC,YAAa,IAAG,GAC3D,SAAQM,QAAS,KAAI,IAAI,CAAChJ,KAAM,IAAG,GACnC,eAAc4I,cAAe,KAAI,IAAI,CAAC3E,YAAa,EAAC,CAC5D;IACL;EACJ;EAEQ4F,YAAYA,CAAC7J,KAAY,EAAQ;IACrC,MAAMiK,aAAa,GAAG,CAAC,IAAI,CAACC,YAAY,IAAI,CAAC,IAAI,CAACnI,WAAW,IAAI/B,KAAK,KAAK1C,eAAe;IAE1F,IAAI2M,aAAa,EAAE;MACf,IAAI,CAACC,YAAY,GAAGC,UAAU,CAAC,IAAI,CAACC,eAAe,EAAE,IAAI,CAACjJ,OAAO,CAAC;IACtE;IACA,IAAI,IAAI,CAAC+I,YAAY,EAAE;MACnB,MAAMG,WAAW,GACbrK,KAAK,KAAKtC,aAAa,IAAIsC,KAAK,KAAKxC,WAAW,IAAIwC,KAAK,KAAKlC,UAAU,IAAIkC,KAAK,KAAKpC,eAAe;MACzG,IAAIyM,WAAW,EAAE;QACbC,YAAY,CAAC,IAAI,CAACJ,YAAY,CAAC;QAC/B,IAAI,CAACA,YAAY,GAAG,IAAI;MAC5B;IACJ;EACJ;EAoBA,MAAcpB,aAAaA,CAAC1J,IAAY,EAAEC,KAAkB,EAAoB;IAC5E,IAAID,IAAI,KAAKrC,UAAU,EAAE;MACrB,MAAMoF,MAAM,GAAG9C,KAAK,CAACE,UAAU,EAAE,CAAC4C,MAAM;MACxC,IAAI,CAAC,IAAI,CAAC9D,mBAAmB,CAAC0E,GAAG,CAACZ,MAAM,CAAC,EAAE;QACvC,MAAM,IAAI,CAACxD,MAAM,CAAC,IAAA4L,qBAAc,EAAC,IAAA7F,4BAAqB,GAAE,CAAC,CAAC;QAC1D,OAAO,IAAI;MACf;IACJ;IAEA,MAAM8F,mBAAmB,GAAGpL,IAAI,KAAKtC,YAAY,IAAI,IAAI,CAACkD,KAAK,KAAK5C,YAAY;IAChF,MAAMqN,iBAAiB,GAAGrL,IAAI,KAAKlC,UAAU,IAAI,IAAI,CAAC8C,KAAK,KAAK1C,eAAe,IAAI,IAAI,CAAC0C,KAAK,KAAKtC,aAAa;IAC/G;IACA;IACA;IACA;IACA;IACA,IAAI,IAAI,CAACsC,KAAK,KAAK5C,YAAY,KAAKoN,mBAAmB,IAAIC,iBAAiB,CAAC,EAAE;MAC3E1L,cAAM,CAAC2L,IAAI,CAAE,0BAAyBtL,IAAK,gBAAe,GAAI,cAAaC,KAAK,CAACwE,SAAS,EAAG,EAAC,CAAC;MAC/F,MAAMjF,MAAM,GAAI,cAAaQ,IAAK,mBAAkB,IAAI,CAACY,KAAM,EAAC;MAChE,MAAM,IAAI,CAACrB,MAAM,CAAC,IAAA4L,qBAAc,EAAC,IAAAI,gCAAyB,EAAC;QAAE/L;MAAO,CAAC,CAAC,CAAC,CAAC;MACxE,OAAO,IAAI;IACf;IACA,OAAO,KAAK;EAChB;EAEQiK,iBAAiBA,CAACxJ,KAAkB,EAAEoJ,WAAW,GAAG,KAAK,EAAQ;IACrE;IACA,IAAI,CAACA,WAAW,EAAE;MACd,IAAI,CAACxE,YAAY,GAAG,IAAI;IAC5B;IACA,IAAI,IAAI,CAACxD,qBAAqB,CAACpB,KAAK,CAAC,GAAG1C,2BAA2B,EAAE;MACjE,IAAI,CAACsH,YAAY,GAAG,IAAI;IAC5B;EACJ;EAEQgF,QAAQA,CAAC7J,IAAY,EAAEC,KAAkB,EAAEsJ,UAAU,GAAG,KAAK,EAAQ;IACzE,IAAIA,UAAU,EAAE;MACZ,IAAI,CAAClG,UAAU,CAACmI,GAAG,CAACxL,IAAI,EAAEC,KAAK,CAAC;IACpC,CAAC,MAAM;MACH,IAAI,CAACiD,YAAY,CAACsI,GAAG,CAACxL,IAAI,EAAEC,KAAK,CAAC;IACtC;;IAEA;IACA;IACA,IAAID,IAAI,KAAKtC,YAAY,EAAE;MACvB,KAAK,MAAM,CAACsC,IAAI,EAAEC,KAAK,CAAC,IAAI,IAAI,CAACiD,YAAY,CAACuI,OAAO,EAAE,EAAE;QACrD,IAAIxL,KAAK,CAACwE,SAAS,EAAE,KAAK,IAAI,CAACR,WAAW,EAAE;UACxC,IAAI,CAACf,YAAY,CAACwI,MAAM,CAAC1L,IAAI,CAAC;QAClC;MACJ;MACA;MACA,IAAI,CAACwB,iBAAiB,GAAGK,IAAI,CAACC,GAAG,EAAE;IACvC;EACJ;EAEQyD,cAAcA,CAClBxC,MAA0B,EAC1BmE,UAA8B,GAAG,IAAI,EACrCpC,YAAkC,GAAG,IAAI,EACH;IACtC,IAAI,CAACA,YAAY,EAAE;MACfA,YAAY,GAAG,IAAI,CAACA,YAAY;IACpC;IACA,MAAM;MAAEX,MAAM;MAAEe;IAAS,CAAC,GAAGJ,YAAY;IAEzC,MAAM6G,YAAY,GAAG,IAAI,CAAC1M,mBAAmB,CAACkE,GAAG,CAACJ,MAAM,CAAC;IACzD,IAAI,CAAC4I,YAAY,EAAE;MACfhM,cAAM,CAAC2L,IAAI,CAAC,gDAAgD,EAAEvI,MAAM,CAAC;MACrE;IACJ;IACA,OAAO,IAAI4I,YAAY,CAAC,IAAI,CAAC3M,OAAO,EAAE,IAAI,CAACE,MAAM,EAAEiF,MAAM,EAAGe,QAAQ,EAAGgC,UAAU,EAAE,IAAI,CAAC;EAC5F;EAEQe,gBAAgBA,CAAChI,KAAmB,EAAW;IACnD,OAAO,CAAAA,KAAK,aAALA,KAAK,uBAALA,KAAK,CAAEwE,SAAS,EAAE,MAAK,IAAI,CAACvF,MAAM,CAAC8E,SAAS,EAAE;EACzD;;EAEA;EACQ6D,kBAAkBA,CAAC5H,KAAmB,EAAW;IACrD,IAAI,CAAC,IAAI,CAACgI,gBAAgB,CAAChI,KAAK,CAAC,EAAE;MAC/B,OAAO,KAAK;IAChB;IACA,MAAMC,OAAO,GAAGD,KAAK,CAAEE,UAAU,EAAE;IACnC,IAAI,CAACD,OAAO,IAAIA,OAAO,CAACO,WAAW,KAAK,IAAI,CAACvB,MAAM,CAAC4J,WAAW,EAAE,EAAE;MAC/D,OAAO,KAAK;IAChB;IACA,OAAO,IAAI;EACf;EAEO8C,mBAAmBA,CAAA,EAAS;IAC/B,IAAI,CAAClE,UAAU,GAAG,IAAI;IACtB;IACA,MAAMY,cAAc,GAAG,IAAI,CAACJ,qBAAqB,EAAE;IACnD,IAAII,cAAc,CAAC5H,MAAM,EAAE;MACvB,IAAI,CAACZ,QAAQ,CAACwI,cAAc,CAACA,cAAc,CAAC5H,MAAM,GAAG,CAAC,CAAC,CAACE,KAAK,CAAC;IAClE;EACJ;EAEOiL,kBAAkBA,CAAA,EAAS;IAC9B,IAAI,CAAC7M,OAAO,CAAC0G,IAAI,CAACoG,gBAAS,CAACC,mBAAmB,EAAE,CAAC,CAAC,CAAC;IACpD,IAAI,CAACvE,mBAAmB,GAAG,IAAI;IAC/B;IACA,MAAMc,cAAc,GAAG,IAAI,CAACJ,qBAAqB,EAAE;IACnD,IAAII,cAAc,CAAC5H,MAAM,EAAE;MACvB,IAAI,CAACZ,QAAQ,CAACwI,cAAc,CAACA,cAAc,CAAC5H,MAAM,GAAG,CAAC,CAAC,CAACE,KAAK,CAAC;IAClE;EACJ;EAEOoL,sBAAsBA,CAAChM,IAAY,EAA2B;IACjE,OAAO,IAAI,CAACkD,YAAY,CAACC,GAAG,CAACnD,IAAI,CAAC;EACtC;AACJ;AAACvC,OAAA,CAAAoB,mBAAA,GAAAA,mBAAA"} \ No newline at end of file