init
This commit is contained in:
301
node_modules/matrix-js-sdk/lib/crypto/store/base.d.ts
generated
vendored
Normal file
301
node_modules/matrix-js-sdk/lib/crypto/store/base.d.ts
generated
vendored
Normal file
@@ -0,0 +1,301 @@
|
||||
import { type Logger } from "../../logger.ts";
|
||||
import { type CrossSigningKeyInfo } from "../../crypto-api/index.ts";
|
||||
import { type AESEncryptedSecretStoragePayload } from "../../@types/AESEncryptedSecretStoragePayload.ts";
|
||||
import { type ISignatures } from "../../@types/signed.ts";
|
||||
/**
|
||||
* Internal module. Definitions for storage for the crypto module
|
||||
*/
|
||||
export interface SecretStorePrivateKeys {
|
||||
"m.megolm_backup.v1": AESEncryptedSecretStoragePayload;
|
||||
}
|
||||
/**
|
||||
* Abstraction of things that can store data required for end-to-end encryption
|
||||
*/
|
||||
export interface CryptoStore {
|
||||
/**
|
||||
* Returns true if this CryptoStore has ever been initialised (ie, it might contain data).
|
||||
*
|
||||
* Unlike the rest of the methods in this interface, can be called before {@link CryptoStore#startup}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
containsData(): Promise<boolean>;
|
||||
/**
|
||||
* Initialise this crypto store.
|
||||
*
|
||||
* Typically, this involves provisioning storage, and migrating any existing data to the current version of the
|
||||
* storage schema where appropriate.
|
||||
*
|
||||
* Must be called before any of the rest of the methods in this interface.
|
||||
*/
|
||||
startup(): Promise<CryptoStore>;
|
||||
deleteAllData(): Promise<void>;
|
||||
/**
|
||||
* Get data on how much of the libolm to Rust Crypto migration has been done.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
getMigrationState(): Promise<MigrationState>;
|
||||
/**
|
||||
* Set data on how much of the libolm to Rust Crypto migration has been done.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
setMigrationState(migrationState: MigrationState): Promise<void>;
|
||||
getAccount(txn: unknown, func: (accountPickle: string | null) => void): void;
|
||||
storeAccount(txn: unknown, accountPickle: string): void;
|
||||
getCrossSigningKeys(txn: unknown, func: (keys: Record<string, CrossSigningKeyInfo> | null) => void): void;
|
||||
getSecretStorePrivateKey<K extends keyof SecretStorePrivateKeys>(txn: unknown, func: (key: SecretStorePrivateKeys[K] | null) => void, type: K): 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;
|
||||
storeEndToEndSession(deviceKey: string, sessionId: string, sessionInfo: ISessionInfo, txn: unknown): void;
|
||||
/**
|
||||
* Get a batch of end-to-end sessions from the database.
|
||||
*
|
||||
* @returns A batch of Olm Sessions, or `null` if no sessions are left.
|
||||
* @internal
|
||||
*/
|
||||
getEndToEndSessionsBatch(): Promise<ISessionInfo[] | null>;
|
||||
/**
|
||||
* Delete a batch of end-to-end sessions from the database.
|
||||
*
|
||||
* Any sessions in the list which are not found are silently ignored.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
deleteEndToEndSessionsBatch(sessions: {
|
||||
deviceKey?: string;
|
||||
sessionId?: string;
|
||||
}[]): Promise<void>;
|
||||
getEndToEndInboundGroupSession(senderCurve25519Key: string, sessionId: string, txn: unknown, func: (groupSession: InboundGroupSessionData | null, groupSessionWithheld: IWithheld | null) => void): void;
|
||||
storeEndToEndInboundGroupSession(senderCurve25519Key: string, sessionId: string, sessionData: InboundGroupSessionData, txn: unknown): void;
|
||||
/**
|
||||
* Count the number of Megolm sessions in the database.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
countEndToEndInboundGroupSessions(): Promise<number>;
|
||||
/**
|
||||
* Get a batch of Megolm sessions from the database.
|
||||
*
|
||||
* @returns A batch of Megolm Sessions, or `null` if no sessions are left.
|
||||
* @internal
|
||||
*/
|
||||
getEndToEndInboundGroupSessionsBatch(): Promise<SessionExtended[] | null>;
|
||||
/**
|
||||
* Delete a batch of Megolm sessions from the database.
|
||||
*
|
||||
* Any sessions in the list which are not found are silently ignored.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
deleteEndToEndInboundGroupSessionsBatch(sessions: {
|
||||
senderKey: string;
|
||||
sessionId: string;
|
||||
}[]): Promise<void>;
|
||||
getEndToEndRooms(txn: unknown, func: (rooms: Record<string, IRoomEncryption>) => void): void;
|
||||
markSessionsNeedingBackup(sessions: ISession[], txn?: unknown): Promise<void>;
|
||||
doTxn<T>(mode: Mode, stores: Iterable<string>, func: (txn: unknown) => T, log?: Logger): Promise<T>;
|
||||
}
|
||||
export type Mode = "readonly" | "readwrite";
|
||||
/** Data on a Megolm session */
|
||||
export interface ISession {
|
||||
senderKey: string;
|
||||
sessionId: string;
|
||||
sessionData?: InboundGroupSessionData;
|
||||
}
|
||||
/** Extended data on a Megolm session */
|
||||
export interface SessionExtended extends ISession {
|
||||
needsBackup: boolean;
|
||||
}
|
||||
/** Data on an Olm session */
|
||||
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 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
|
||||
*/
|
||||
state: RoomKeyRequestState;
|
||||
}
|
||||
/**
|
||||
* Keys for the `account` object store to store the migration state.
|
||||
* Values are defined in `MigrationState`.
|
||||
* @internal
|
||||
*/
|
||||
export declare const ACCOUNT_OBJECT_KEY_MIGRATION_STATE = "migrationState";
|
||||
/**
|
||||
* A record of which steps have been completed in the libolm to Rust Crypto migration.
|
||||
*
|
||||
* Used by {@link CryptoStore#getMigrationState} and {@link CryptoStore#setMigrationState}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
export declare enum MigrationState {
|
||||
/** No migration steps have yet been completed. */
|
||||
NOT_STARTED = 0,
|
||||
/** We have migrated the account data, cross-signing keys, etc. */
|
||||
INITIAL_DATA_MIGRATED = 1,
|
||||
/** INITIAL_DATA_MIGRATED, and in addition, we have migrated all the Olm sessions. */
|
||||
OLM_SESSIONS_MIGRATED = 2,
|
||||
/** OLM_SESSIONS_MIGRATED, and in addition, we have migrated all the Megolm sessions. */
|
||||
MEGOLM_SESSIONS_MIGRATED = 3,
|
||||
/** MEGOLM_SESSIONS_MIGRATED, and in addition, we have migrated all the room settings. */
|
||||
ROOM_SETTINGS_MIGRATED = 4,
|
||||
/** ROOM_SETTINGS_MIGRATED, and in addition, we have done the first own keys query in order to
|
||||
* load the public part of the keys that have been migrated */
|
||||
INITIAL_OWN_KEY_QUERY_DONE = 5
|
||||
}
|
||||
/**
|
||||
* The size of batches to be returned by {@link CryptoStore#getEndToEndSessionsBatch} and
|
||||
* {@link CryptoStore#getEndToEndInboundGroupSessionsBatch}.
|
||||
*/
|
||||
export declare const SESSION_BATCH_SIZE = 50;
|
||||
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 ICrossSigningInfo {
|
||||
keys: Record<string, CrossSigningKeyInfo>;
|
||||
firstUse: boolean;
|
||||
crossSigningVerifiedBefore: boolean;
|
||||
}
|
||||
export interface IRoomEncryption {
|
||||
algorithm: string;
|
||||
rotation_period_ms?: number;
|
||||
rotation_period_msgs?: number;
|
||||
}
|
||||
export declare enum TrackingStatus {
|
||||
NotTracked = 0,
|
||||
PendingDownload = 1,
|
||||
DownloadInProgress = 2,
|
||||
UpToDate = 3
|
||||
}
|
||||
/**
|
||||
* 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
|
||||
}
|
||||
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 IRoomKeyRequestRecipient {
|
||||
userId: string;
|
||||
deviceId: string;
|
||||
}
|
||||
interface IDevice {
|
||||
keys: Record<string, string>;
|
||||
algorithms: string[];
|
||||
verified: DeviceVerification;
|
||||
known: boolean;
|
||||
unsigned?: Record<string, any>;
|
||||
signatures?: ISignatures;
|
||||
}
|
||||
/** State of the verification of the device. */
|
||||
export declare enum DeviceVerification {
|
||||
Blocked = -1,
|
||||
Unverified = 0,
|
||||
Verified = 1
|
||||
}
|
||||
export {};
|
||||
//# sourceMappingURL=base.d.ts.map
|
||||
1
node_modules/matrix-js-sdk/lib/crypto/store/base.d.ts.map
generated
vendored
Normal file
1
node_modules/matrix-js-sdk/lib/crypto/store/base.d.ts.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
136
node_modules/matrix-js-sdk/lib/crypto/store/base.js
generated
vendored
Normal file
136
node_modules/matrix-js-sdk/lib/crypto/store/base.js
generated
vendored
Normal file
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Internal module. Definitions for storage for the crypto module
|
||||
*/
|
||||
|
||||
/**
|
||||
* Abstraction of things that can store data required for end-to-end encryption
|
||||
*/
|
||||
|
||||
/** Data on a Megolm session */
|
||||
|
||||
/** Extended data on a Megolm session */
|
||||
|
||||
/** Data on an Olm session */
|
||||
|
||||
/**
|
||||
* Represents an outgoing room key request
|
||||
*/
|
||||
|
||||
/**
|
||||
* Keys for the `account` object store to store the migration state.
|
||||
* Values are defined in `MigrationState`.
|
||||
* @internal
|
||||
*/
|
||||
export const ACCOUNT_OBJECT_KEY_MIGRATION_STATE = "migrationState";
|
||||
|
||||
/**
|
||||
* A record of which steps have been completed in the libolm to Rust Crypto migration.
|
||||
*
|
||||
* Used by {@link CryptoStore#getMigrationState} and {@link CryptoStore#setMigrationState}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
export let MigrationState = /*#__PURE__*/function (MigrationState) {
|
||||
/** No migration steps have yet been completed. */
|
||||
MigrationState[MigrationState["NOT_STARTED"] = 0] = "NOT_STARTED";
|
||||
/** We have migrated the account data, cross-signing keys, etc. */
|
||||
MigrationState[MigrationState["INITIAL_DATA_MIGRATED"] = 1] = "INITIAL_DATA_MIGRATED";
|
||||
/** INITIAL_DATA_MIGRATED, and in addition, we have migrated all the Olm sessions. */
|
||||
MigrationState[MigrationState["OLM_SESSIONS_MIGRATED"] = 2] = "OLM_SESSIONS_MIGRATED";
|
||||
/** OLM_SESSIONS_MIGRATED, and in addition, we have migrated all the Megolm sessions. */
|
||||
MigrationState[MigrationState["MEGOLM_SESSIONS_MIGRATED"] = 3] = "MEGOLM_SESSIONS_MIGRATED";
|
||||
/** MEGOLM_SESSIONS_MIGRATED, and in addition, we have migrated all the room settings. */
|
||||
MigrationState[MigrationState["ROOM_SETTINGS_MIGRATED"] = 4] = "ROOM_SETTINGS_MIGRATED";
|
||||
/** ROOM_SETTINGS_MIGRATED, and in addition, we have done the first own keys query in order to
|
||||
* load the public part of the keys that have been migrated */
|
||||
MigrationState[MigrationState["INITIAL_OWN_KEY_QUERY_DONE"] = 5] = "INITIAL_OWN_KEY_QUERY_DONE";
|
||||
return MigrationState;
|
||||
}({});
|
||||
|
||||
/**
|
||||
* The size of batches to be returned by {@link CryptoStore#getEndToEndSessionsBatch} and
|
||||
* {@link CryptoStore#getEndToEndInboundGroupSessionsBatch}.
|
||||
*/
|
||||
export const SESSION_BATCH_SIZE = 50;
|
||||
export let TrackingStatus = /*#__PURE__*/function (TrackingStatus) {
|
||||
TrackingStatus[TrackingStatus["NotTracked"] = 0] = "NotTracked";
|
||||
TrackingStatus[TrackingStatus["PendingDownload"] = 1] = "PendingDownload";
|
||||
TrackingStatus[TrackingStatus["DownloadInProgress"] = 2] = "DownloadInProgress";
|
||||
TrackingStatus[TrackingStatus["UpToDate"] = 3] = "UpToDate";
|
||||
return TrackingStatus;
|
||||
}({});
|
||||
|
||||
/**
|
||||
* 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 let RoomKeyRequestState = /*#__PURE__*/function (RoomKeyRequestState) {
|
||||
/** request not yet sent */
|
||||
RoomKeyRequestState[RoomKeyRequestState["Unsent"] = 0] = "Unsent";
|
||||
/** request sent, awaiting reply */
|
||||
RoomKeyRequestState[RoomKeyRequestState["Sent"] = 1] = "Sent";
|
||||
/** reply received, cancellation not yet sent */
|
||||
RoomKeyRequestState[RoomKeyRequestState["CancellationPending"] = 2] = "CancellationPending";
|
||||
/**
|
||||
* Cancellation not yet sent and will transition to UNSENT instead of
|
||||
* being deleted once the cancellation has been sent.
|
||||
*/
|
||||
RoomKeyRequestState[RoomKeyRequestState["CancellationPendingAndWillResend"] = 3] = "CancellationPendingAndWillResend";
|
||||
return RoomKeyRequestState;
|
||||
}({});
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/** State of the verification of the device. */
|
||||
export let DeviceVerification = /*#__PURE__*/function (DeviceVerification) {
|
||||
DeviceVerification[DeviceVerification["Blocked"] = -1] = "Blocked";
|
||||
DeviceVerification[DeviceVerification["Unverified"] = 0] = "Unverified";
|
||||
DeviceVerification[DeviceVerification["Verified"] = 1] = "Verified";
|
||||
return DeviceVerification;
|
||||
}({});
|
||||
//# sourceMappingURL=base.js.map
|
||||
1
node_modules/matrix-js-sdk/lib/crypto/store/base.js.map
generated
vendored
Normal file
1
node_modules/matrix-js-sdk/lib/crypto/store/base.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
94
node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store-backend.d.ts
generated
vendored
Normal file
94
node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store-backend.d.ts
generated
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
import { type Logger } from "../../logger.ts";
|
||||
import { type CryptoStore, type IDeviceData, type ISession, type SessionExtended, type ISessionInfo, type IWithheld, MigrationState, type Mode, type SecretStorePrivateKeys, type InboundGroupSessionData, type IRoomEncryption } from "./base.ts";
|
||||
import { type CrossSigningKeyInfo } from "../../crypto-api/index.ts";
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
export declare class Backend implements CryptoStore {
|
||||
private db;
|
||||
private nextTxnId;
|
||||
/**
|
||||
*/
|
||||
constructor(db: IDBDatabase);
|
||||
containsData(): Promise<boolean>;
|
||||
startup(): Promise<CryptoStore>;
|
||||
deleteAllData(): Promise<void>;
|
||||
/**
|
||||
* Get data on how much of the libolm to Rust Crypto migration has been done.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.getMigrationState}.
|
||||
*/
|
||||
getMigrationState(): Promise<MigrationState>;
|
||||
/**
|
||||
* Set data on how much of the libolm to Rust Crypto migration has been done.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.setMigrationState}.
|
||||
*/
|
||||
setMigrationState(migrationState: MigrationState): Promise<void>;
|
||||
getAccount(txn: IDBTransaction, func: (accountPickle: string | null) => void): void;
|
||||
storeAccount(txn: IDBTransaction, accountPickle: string): void;
|
||||
getCrossSigningKeys(txn: IDBTransaction, func: (keys: Record<string, CrossSigningKeyInfo> | null) => void): void;
|
||||
getSecretStorePrivateKey<K extends keyof SecretStorePrivateKeys>(txn: IDBTransaction, func: (key: SecretStorePrivateKeys[K] | null) => void, type: K): 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;
|
||||
storeEndToEndSession(deviceKey: string, sessionId: string, sessionInfo: ISessionInfo, txn: IDBTransaction): void;
|
||||
/**
|
||||
* Fetch a batch of Olm sessions from the database.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.getEndToEndSessionsBatch}.
|
||||
*/
|
||||
getEndToEndSessionsBatch(): Promise<null | ISessionInfo[]>;
|
||||
/**
|
||||
* Delete a batch of Olm sessions from the database.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.deleteEndToEndSessionsBatch}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
deleteEndToEndSessionsBatch(sessions: {
|
||||
deviceKey: string;
|
||||
sessionId: string;
|
||||
}[]): Promise<void>;
|
||||
getEndToEndInboundGroupSession(senderCurve25519Key: string, sessionId: string, txn: IDBTransaction, func: (groupSession: InboundGroupSessionData | null, groupSessionWithheld: IWithheld | null) => void): void;
|
||||
storeEndToEndInboundGroupSession(senderCurve25519Key: string, sessionId: string, sessionData: InboundGroupSessionData, txn: IDBTransaction): void;
|
||||
/**
|
||||
* Count the number of Megolm sessions in the database.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.countEndToEndInboundGroupSessions}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
countEndToEndInboundGroupSessions(): Promise<number>;
|
||||
/**
|
||||
* Fetch a batch of Megolm sessions from the database.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.getEndToEndInboundGroupSessionsBatch}.
|
||||
*/
|
||||
getEndToEndInboundGroupSessionsBatch(): Promise<null | SessionExtended[]>;
|
||||
/**
|
||||
* Delete a batch of Megolm sessions from the database.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.deleteEndToEndInboundGroupSessionsBatch}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
deleteEndToEndInboundGroupSessionsBatch(sessions: {
|
||||
senderKey: string;
|
||||
sessionId: string;
|
||||
}[]): Promise<void>;
|
||||
getEndToEndDeviceData(txn: IDBTransaction, func: (deviceData: IDeviceData | null) => void): void;
|
||||
getEndToEndRooms(txn: IDBTransaction, func: (rooms: Record<string, IRoomEncryption>) => void): void;
|
||||
markSessionsNeedingBackup(sessions: ISession[], txn?: IDBTransaction): Promise<void>;
|
||||
doTxn<T>(mode: Mode, stores: string | string[], func: (txn: IDBTransaction) => T, log?: Logger): Promise<T>;
|
||||
}
|
||||
export declare const VERSION: number;
|
||||
export declare function upgradeDatabase(db: IDBDatabase, oldVersion: number): void;
|
||||
//# sourceMappingURL=indexeddb-crypto-store-backend.d.ts.map
|
||||
1
node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store-backend.d.ts.map
generated
vendored
Normal file
1
node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store-backend.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"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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"}
|
||||
555
node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store-backend.js
generated
vendored
Normal file
555
node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store-backend.js
generated
vendored
Normal file
@@ -0,0 +1,555 @@
|
||||
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
import { logger } from "../../logger.js";
|
||||
import { MigrationState, SESSION_BATCH_SIZE, ACCOUNT_OBJECT_KEY_MIGRATION_STATE } from "./base.js";
|
||||
import { IndexedDBCryptoStore } from "./indexeddb-crypto-store.js";
|
||||
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.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
export class Backend {
|
||||
/**
|
||||
*/
|
||||
constructor(db) {
|
||||
_defineProperty(this, "nextTxnId", 0);
|
||||
this.db = db;
|
||||
// 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.log(`versionchange for indexeddb ${this.db.name}: closing`);
|
||||
db.close();
|
||||
};
|
||||
}
|
||||
async containsData() {
|
||||
throw Error("Not implemented for Backend");
|
||||
}
|
||||
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.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data on how much of the libolm to Rust Crypto migration has been done.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.getMigrationState}.
|
||||
*/
|
||||
async getMigrationState() {
|
||||
let migrationState = MigrationState.NOT_STARTED;
|
||||
await this.doTxn("readonly", [IndexedDBCryptoStore.STORE_ACCOUNT], txn => {
|
||||
const objectStore = txn.objectStore(IndexedDBCryptoStore.STORE_ACCOUNT);
|
||||
const getReq = objectStore.get(ACCOUNT_OBJECT_KEY_MIGRATION_STATE);
|
||||
getReq.onsuccess = () => {
|
||||
migrationState = getReq.result ?? MigrationState.NOT_STARTED;
|
||||
};
|
||||
});
|
||||
return migrationState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set data on how much of the libolm to Rust Crypto migration has been done.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.setMigrationState}.
|
||||
*/
|
||||
async setMigrationState(migrationState) {
|
||||
await this.doTxn("readwrite", [IndexedDBCryptoStore.STORE_ACCOUNT], txn => {
|
||||
const objectStore = txn.objectStore(IndexedDBCryptoStore.STORE_ACCOUNT);
|
||||
objectStore.put(migrationState, ACCOUNT_OBJECT_KEY_MIGRATION_STATE);
|
||||
});
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
};
|
||||
}
|
||||
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);
|
||||
}
|
||||
};
|
||||
}
|
||||
storeEndToEndSession(deviceKey, sessionId, sessionInfo, txn) {
|
||||
const objectStore = txn.objectStore("sessions");
|
||||
objectStore.put({
|
||||
deviceKey,
|
||||
sessionId,
|
||||
session: sessionInfo.session,
|
||||
lastReceivedMessageTs: sessionInfo.lastReceivedMessageTs
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a batch of Olm sessions from the database.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.getEndToEndSessionsBatch}.
|
||||
*/
|
||||
async getEndToEndSessionsBatch() {
|
||||
const result = [];
|
||||
await this.doTxn("readonly", [IndexedDBCryptoStore.STORE_SESSIONS], txn => {
|
||||
const objectStore = txn.objectStore(IndexedDBCryptoStore.STORE_SESSIONS);
|
||||
const getReq = objectStore.openCursor();
|
||||
getReq.onsuccess = function () {
|
||||
try {
|
||||
const cursor = getReq.result;
|
||||
if (cursor) {
|
||||
result.push(cursor.value);
|
||||
if (result.length < SESSION_BATCH_SIZE) {
|
||||
cursor.continue();
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
abortWithException(txn, e);
|
||||
}
|
||||
};
|
||||
});
|
||||
if (result.length === 0) {
|
||||
// No sessions left.
|
||||
return null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a batch of Olm sessions from the database.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.deleteEndToEndSessionsBatch}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
async deleteEndToEndSessionsBatch(sessions) {
|
||||
await this.doTxn("readwrite", [IndexedDBCryptoStore.STORE_SESSIONS], async txn => {
|
||||
try {
|
||||
const objectStore = txn.objectStore(IndexedDBCryptoStore.STORE_SESSIONS);
|
||||
for (const {
|
||||
deviceKey,
|
||||
sessionId
|
||||
} of sessions) {
|
||||
const req = objectStore.delete([deviceKey, sessionId]);
|
||||
await new Promise(resolve => {
|
||||
req.onsuccess = resolve;
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
abortWithException(txn, e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
};
|
||||
}
|
||||
storeEndToEndInboundGroupSession(senderCurve25519Key, sessionId, sessionData, txn) {
|
||||
const objectStore = txn.objectStore("inbound_group_sessions");
|
||||
objectStore.put({
|
||||
senderCurve25519Key,
|
||||
sessionId,
|
||||
session: sessionData
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Count the number of Megolm sessions in the database.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.countEndToEndInboundGroupSessions}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
async countEndToEndInboundGroupSessions() {
|
||||
let result = 0;
|
||||
await this.doTxn("readonly", [IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS], txn => {
|
||||
const sessionStore = txn.objectStore(IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS);
|
||||
const countReq = sessionStore.count();
|
||||
countReq.onsuccess = () => {
|
||||
result = countReq.result;
|
||||
};
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a batch of Megolm sessions from the database.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.getEndToEndInboundGroupSessionsBatch}.
|
||||
*/
|
||||
async getEndToEndInboundGroupSessionsBatch() {
|
||||
const result = [];
|
||||
await this.doTxn("readonly", [IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS, IndexedDBCryptoStore.STORE_BACKUP], txn => {
|
||||
const sessionStore = txn.objectStore(IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS);
|
||||
const backupStore = txn.objectStore(IndexedDBCryptoStore.STORE_BACKUP);
|
||||
const getReq = sessionStore.openCursor();
|
||||
getReq.onsuccess = function () {
|
||||
try {
|
||||
const cursor = getReq.result;
|
||||
if (cursor) {
|
||||
const backupGetReq = backupStore.get(cursor.key);
|
||||
backupGetReq.onsuccess = () => {
|
||||
result.push({
|
||||
senderKey: cursor.value.senderCurve25519Key,
|
||||
sessionId: cursor.value.sessionId,
|
||||
sessionData: cursor.value.session,
|
||||
needsBackup: backupGetReq.result !== undefined
|
||||
});
|
||||
if (result.length < SESSION_BATCH_SIZE) {
|
||||
cursor.continue();
|
||||
}
|
||||
};
|
||||
}
|
||||
} catch (e) {
|
||||
abortWithException(txn, e);
|
||||
}
|
||||
};
|
||||
});
|
||||
if (result.length === 0) {
|
||||
// No sessions left.
|
||||
return null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a batch of Megolm sessions from the database.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.deleteEndToEndInboundGroupSessionsBatch}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
async deleteEndToEndInboundGroupSessionsBatch(sessions) {
|
||||
await this.doTxn("readwrite", [IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS], async txn => {
|
||||
try {
|
||||
const objectStore = txn.objectStore(IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS);
|
||||
for (const {
|
||||
senderKey,
|
||||
sessionId
|
||||
} of sessions) {
|
||||
const req = objectStore.delete([senderKey, sessionId]);
|
||||
await new Promise(resolve => {
|
||||
req.onsuccess = resolve;
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
abortWithException(txn, e);
|
||||
}
|
||||
});
|
||||
}
|
||||
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);
|
||||
}
|
||||
};
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
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;
|
||||
});
|
||||
}));
|
||||
}
|
||||
doTxn(mode, stores, func, log = 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;
|
||||
});
|
||||
}
|
||||
}
|
||||
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.
|
||||
];
|
||||
export const VERSION = DB_MIGRATIONS.length;
|
||||
export function upgradeDatabase(db, oldVersion) {
|
||||
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 {
|
||||
// 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);
|
||||
return;
|
||||
}
|
||||
resolve(null);
|
||||
};
|
||||
txn.onerror = event => {
|
||||
if (txn._mx_abortexception !== undefined) {
|
||||
reject(txn._mx_abortexception);
|
||||
} else {
|
||||
logger.log("Error performing indexeddb txn", event);
|
||||
reject(txn.error);
|
||||
}
|
||||
};
|
||||
txn.onabort = event => {
|
||||
if (txn._mx_abortexception !== undefined) {
|
||||
reject(txn._mx_abortexception);
|
||||
} else {
|
||||
logger.log("Error performing indexeddb txn", event);
|
||||
reject(txn.error);
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
//# sourceMappingURL=indexeddb-crypto-store-backend.js.map
|
||||
1
node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store-backend.js.map
generated
vendored
Normal file
1
node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store-backend.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
251
node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store.d.ts
generated
vendored
Normal file
251
node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store.d.ts
generated
vendored
Normal file
@@ -0,0 +1,251 @@
|
||||
import { type Logger } from "../../logger.ts";
|
||||
import { type CryptoStore, type ISession, type SessionExtended, type ISessionInfo, type IWithheld, MigrationState, type Mode, type SecretStorePrivateKeys, type InboundGroupSessionData, type IRoomEncryption } from "./base.ts";
|
||||
import { type CrossSigningKeyInfo } from "../../crypto-api/index.ts";
|
||||
/**
|
||||
* 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>;
|
||||
/**
|
||||
* Utility to check if a legacy crypto store exists and has not been migrated.
|
||||
* Returns true if the store exists and has not been migrated, false otherwise.
|
||||
*/
|
||||
static existsAndIsNotMigrated(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);
|
||||
/**
|
||||
* Returns true if this CryptoStore has ever been initialised (ie, it might contain data).
|
||||
*
|
||||
* Implementation of {@link CryptoStore.containsData}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
containsData(): Promise<boolean>;
|
||||
/**
|
||||
* 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>;
|
||||
/**
|
||||
* Get data on how much of the libolm to Rust Crypto migration has been done.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.getMigrationState}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
getMigrationState(): Promise<MigrationState>;
|
||||
/**
|
||||
* Set data on how much of the libolm to Rust Crypto migration has been done.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.setMigrationState}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
setMigrationState(migrationState: MigrationState): Promise<void>;
|
||||
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, CrossSigningKeyInfo> | 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 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;
|
||||
/**
|
||||
* 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;
|
||||
/**
|
||||
* Count the number of Megolm sessions in the database.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.countEndToEndInboundGroupSessions}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
countEndToEndInboundGroupSessions(): Promise<number>;
|
||||
/**
|
||||
* Fetch a batch of Olm sessions from the database.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.getEndToEndSessionsBatch}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
getEndToEndSessionsBatch(): Promise<null | ISessionInfo[]>;
|
||||
/**
|
||||
* Delete a batch of Olm sessions from the database.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.deleteEndToEndSessionsBatch}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
deleteEndToEndSessionsBatch(sessions: {
|
||||
deviceKey: string;
|
||||
sessionId: string;
|
||||
}[]): Promise<void>;
|
||||
/**
|
||||
* 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;
|
||||
/**
|
||||
* 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;
|
||||
/**
|
||||
* Fetch a batch of Megolm sessions from the database.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.getEndToEndInboundGroupSessionsBatch}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
getEndToEndInboundGroupSessionsBatch(): Promise<SessionExtended[] | null>;
|
||||
/**
|
||||
* Delete a batch of Megolm sessions from the database.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.deleteEndToEndInboundGroupSessionsBatch}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
deleteEndToEndInboundGroupSessionsBatch(sessions: {
|
||||
senderKey: string;
|
||||
sessionId: string;
|
||||
}[]): Promise<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;
|
||||
/**
|
||||
* 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>;
|
||||
/**
|
||||
* 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?: Logger): Promise<T>;
|
||||
}
|
||||
//# sourceMappingURL=indexeddb-crypto-store.d.ts.map
|
||||
1
node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store.d.ts.map
generated
vendored
Normal file
1
node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"indexeddb-crypto-store.d.ts","sourceRoot":"","sources":["../../../src/crypto/store/indexeddb-crypto-store.ts"],"names":[],"mappings":"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"}
|
||||
472
node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store.js
generated
vendored
Normal file
472
node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store.js
generated
vendored
Normal file
@@ -0,0 +1,472 @@
|
||||
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
import { logger } from "../../logger.js";
|
||||
import { LocalStorageCryptoStore } from "./localStorage-crypto-store.js";
|
||||
import { MemoryCryptoStore } from "./memory-crypto-store.js";
|
||||
import * as IndexedDBCryptoStoreBackend from "./indexeddb-crypto-store-backend.js";
|
||||
import { InvalidCryptoStoreError, InvalidCryptoStoreState } from "../../errors.js";
|
||||
import * as IndexedDBHelpers from "../../indexeddb-helpers.js";
|
||||
import { MigrationState, ACCOUNT_OBJECT_KEY_MIGRATION_STATE } from "./base.js";
|
||||
/*
|
||||
* Internal module. indexeddb storage for e2e.
|
||||
*/
|
||||
|
||||
/**
|
||||
* An implementation of CryptoStore, which is normally backed by an indexeddb,
|
||||
* but with fallback to MemoryCryptoStore.
|
||||
*/
|
||||
export class IndexedDBCryptoStore {
|
||||
static exists(indexedDB, dbName) {
|
||||
return IndexedDBHelpers.exists(indexedDB, dbName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility to check if a legacy crypto store exists and has not been migrated.
|
||||
* Returns true if the store exists and has not been migrated, false otherwise.
|
||||
*/
|
||||
static existsAndIsNotMigrated(indexedDb, dbName) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let exists = true;
|
||||
const openDBRequest = indexedDb.open(dbName);
|
||||
openDBRequest.onupgradeneeded = () => {
|
||||
// Since we did not provide an explicit version when opening, this event
|
||||
// should only fire if the DB did not exist before at any version.
|
||||
exists = false;
|
||||
};
|
||||
openDBRequest.onblocked = () => reject(openDBRequest.error);
|
||||
openDBRequest.onsuccess = () => {
|
||||
const db = openDBRequest.result;
|
||||
if (!exists) {
|
||||
db.close();
|
||||
// The DB did not exist before, but has been created as part of this
|
||||
// existence check. Delete it now to restore previous state. Delete can
|
||||
// actually take a while to complete in some browsers, so don't wait for
|
||||
// it. This won't block future open calls that a store might issue next to
|
||||
// properly set up the DB.
|
||||
indexedDb.deleteDatabase(dbName);
|
||||
resolve(false);
|
||||
} else {
|
||||
const tx = db.transaction([IndexedDBCryptoStore.STORE_ACCOUNT], "readonly");
|
||||
const objectStore = tx.objectStore(IndexedDBCryptoStore.STORE_ACCOUNT);
|
||||
const getReq = objectStore.get(ACCOUNT_OBJECT_KEY_MIGRATION_STATE);
|
||||
getReq.onsuccess = () => {
|
||||
const migrationState = getReq.result ?? MigrationState.NOT_STARTED;
|
||||
resolve(migrationState === MigrationState.NOT_STARTED);
|
||||
};
|
||||
getReq.onerror = () => {
|
||||
reject(getReq.error);
|
||||
};
|
||||
db.close();
|
||||
}
|
||||
};
|
||||
openDBRequest.onerror = () => reject(openDBRequest.error);
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Create a new IndexedDBCryptoStore
|
||||
*
|
||||
* @param indexedDB - global indexedDB instance
|
||||
* @param dbName - name of db to connect to
|
||||
*/
|
||||
constructor(indexedDB, dbName) {
|
||||
_defineProperty(this, "backendPromise", void 0);
|
||||
_defineProperty(this, "backend", void 0);
|
||||
this.indexedDB = indexedDB;
|
||||
this.dbName = dbName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this CryptoStore has ever been initialised (ie, it might contain data).
|
||||
*
|
||||
* Implementation of {@link CryptoStore.containsData}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
async containsData() {
|
||||
return IndexedDBCryptoStore.exists(this.indexedDB, this.dbName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.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.log(`can't yet open IndexedDBCryptoStore because it is open elsewhere`);
|
||||
};
|
||||
req.onerror = ev => {
|
||||
logger.log("Error connecting to indexeddb", ev);
|
||||
reject(req.error);
|
||||
};
|
||||
req.onsuccess = () => {
|
||||
const db = req.result;
|
||||
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.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 InvalidCryptoStoreError(InvalidCryptoStoreState.TooNew);
|
||||
}
|
||||
logger.warn(`unable to connect to indexeddb ${this.dbName}: falling back to localStorage store: ${e}`);
|
||||
try {
|
||||
if (!(globalThis.localStorage instanceof Storage)) {
|
||||
throw new Error("localStorage is not available");
|
||||
}
|
||||
return new LocalStorageCryptoStore(globalThis.localStorage);
|
||||
} catch (e) {
|
||||
logger.warn(`Unable to open localStorage: falling back to in-memory store: ${e}`);
|
||||
return new 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.log(`Removing indexeddb instance: ${this.dbName}`);
|
||||
const req = this.indexedDB.deleteDatabase(this.dbName);
|
||||
req.onblocked = () => {
|
||||
logger.log(`can't yet delete IndexedDBCryptoStore because it is open elsewhere`);
|
||||
};
|
||||
req.onerror = ev => {
|
||||
logger.log("Error deleting data from indexeddb", ev);
|
||||
reject(req.error);
|
||||
};
|
||||
req.onsuccess = () => {
|
||||
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.warn(`unable to delete IndexedDBCryptoStore: ${e}`);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data on how much of the libolm to Rust Crypto migration has been done.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.getMigrationState}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
getMigrationState() {
|
||||
return this.backend.getMigrationState();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set data on how much of the libolm to Rust Crypto migration has been done.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.setMigrationState}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
setMigrationState(migrationState) {
|
||||
return this.backend.setMigrationState(migrationState);
|
||||
}
|
||||
|
||||
// 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 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Count the number of Megolm sessions in the database.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.countEndToEndInboundGroupSessions}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
countEndToEndInboundGroupSessions() {
|
||||
return this.backend.countEndToEndInboundGroupSessions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a batch of Olm sessions from the database.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.getEndToEndSessionsBatch}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
getEndToEndSessionsBatch() {
|
||||
return this.backend.getEndToEndSessionsBatch();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a batch of Olm sessions from the database.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.deleteEndToEndSessionsBatch}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
deleteEndToEndSessionsBatch(sessions) {
|
||||
return this.backend.deleteEndToEndSessionsBatch(sessions);
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a batch of Megolm sessions from the database.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.getEndToEndInboundGroupSessionsBatch}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
getEndToEndInboundGroupSessionsBatch() {
|
||||
return this.backend.getEndToEndInboundGroupSessionsBatch();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a batch of Megolm sessions from the database.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.deleteEndToEndInboundGroupSessionsBatch}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
deleteEndToEndInboundGroupSessionsBatch(sessions) {
|
||||
return this.backend.deleteEndToEndInboundGroupSessionsBatch(sessions);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
_defineProperty(IndexedDBCryptoStore, "STORE_ACCOUNT", "account");
|
||||
_defineProperty(IndexedDBCryptoStore, "STORE_SESSIONS", "sessions");
|
||||
_defineProperty(IndexedDBCryptoStore, "STORE_INBOUND_GROUP_SESSIONS", "inbound_group_sessions");
|
||||
_defineProperty(IndexedDBCryptoStore, "STORE_INBOUND_GROUP_SESSIONS_WITHHELD", "inbound_group_sessions_withheld");
|
||||
_defineProperty(IndexedDBCryptoStore, "STORE_SHARED_HISTORY_INBOUND_GROUP_SESSIONS", "shared_history_inbound_group_sessions");
|
||||
_defineProperty(IndexedDBCryptoStore, "STORE_PARKED_SHARED_HISTORY", "parked_shared_history");
|
||||
_defineProperty(IndexedDBCryptoStore, "STORE_DEVICE_DATA", "device_data");
|
||||
_defineProperty(IndexedDBCryptoStore, "STORE_ROOMS", "rooms");
|
||||
_defineProperty(IndexedDBCryptoStore, "STORE_BACKUP", "sessions_needing_backup");
|
||||
//# sourceMappingURL=indexeddb-crypto-store.js.map
|
||||
1
node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store.js.map
generated
vendored
Normal file
1
node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
102
node_modules/matrix-js-sdk/lib/crypto/store/localStorage-crypto-store.d.ts
generated
vendored
Normal file
102
node_modules/matrix-js-sdk/lib/crypto/store/localStorage-crypto-store.d.ts
generated
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
import { MemoryCryptoStore } from "./memory-crypto-store.ts";
|
||||
import { type CryptoStore, type ISession, type SessionExtended, type ISessionInfo, type IWithheld, MigrationState, type Mode, type SecretStorePrivateKeys, type InboundGroupSessionData, type IRoomEncryption } from "./base.ts";
|
||||
import { type CrossSigningKeyInfo } from "../../crypto-api/index.ts";
|
||||
export declare class LocalStorageCryptoStore extends MemoryCryptoStore implements CryptoStore {
|
||||
private readonly store;
|
||||
static exists(store: Storage): boolean;
|
||||
constructor(store: Storage);
|
||||
/**
|
||||
* Returns true if this CryptoStore has ever been initialised (ie, it might contain data).
|
||||
*
|
||||
* Implementation of {@link CryptoStore.containsData}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
containsData(): Promise<boolean>;
|
||||
/**
|
||||
* Get data on how much of the libolm to Rust Crypto migration has been done.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.getMigrationState}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
getMigrationState(): Promise<MigrationState>;
|
||||
/**
|
||||
* Set data on how much of the libolm to Rust Crypto migration has been done.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.setMigrationState}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
setMigrationState(migrationState: MigrationState): Promise<void>;
|
||||
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;
|
||||
storeEndToEndSession(deviceKey: string, sessionId: string, sessionInfo: ISessionInfo, txn: unknown): void;
|
||||
/**
|
||||
* Fetch a batch of Olm sessions from the database.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.getEndToEndSessionsBatch}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
getEndToEndSessionsBatch(): Promise<null | ISessionInfo[]>;
|
||||
/**
|
||||
* Delete a batch of Olm sessions from the database.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.deleteEndToEndSessionsBatch}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
deleteEndToEndSessionsBatch(sessions: {
|
||||
deviceKey: string;
|
||||
sessionId: string;
|
||||
}[]): Promise<void>;
|
||||
getEndToEndInboundGroupSession(senderCurve25519Key: string, sessionId: string, txn: unknown, func: (groupSession: InboundGroupSessionData | null, groupSessionWithheld: IWithheld | null) => void): void;
|
||||
storeEndToEndInboundGroupSession(senderCurve25519Key: string, sessionId: string, sessionData: InboundGroupSessionData, txn: unknown): void;
|
||||
/**
|
||||
* Count the number of Megolm sessions in the database.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.countEndToEndInboundGroupSessions}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
countEndToEndInboundGroupSessions(): Promise<number>;
|
||||
/**
|
||||
* Fetch a batch of Megolm sessions from the database.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.getEndToEndInboundGroupSessionsBatch}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
getEndToEndInboundGroupSessionsBatch(): Promise<SessionExtended[] | null>;
|
||||
/**
|
||||
* Delete a batch of Megolm sessions from the database.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.deleteEndToEndInboundGroupSessionsBatch}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
deleteEndToEndInboundGroupSessionsBatch(sessions: {
|
||||
senderKey: string;
|
||||
sessionId: string;
|
||||
}[]): Promise<void>;
|
||||
getEndToEndRooms(txn: unknown, func: (rooms: Record<string, IRoomEncryption>) => void): 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, CrossSigningKeyInfo> | null) => void): void;
|
||||
getSecretStorePrivateKey<K extends keyof SecretStorePrivateKeys>(txn: unknown, func: (key: SecretStorePrivateKeys[K] | null) => void, type: K): 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
|
||||
1
node_modules/matrix-js-sdk/lib/crypto/store/localStorage-crypto-store.d.ts.map
generated
vendored
Normal file
1
node_modules/matrix-js-sdk/lib/crypto/store/localStorage-crypto-store.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"localStorage-crypto-store.d.ts","sourceRoot":"","sources":["../../../src/crypto/store/localStorage-crypto-store.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EACH,KAAK,WAAW,EAChB,KAAK,QAAQ,EACb,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,cAAc,EACd,KAAK,IAAI,EACT,KAAK,sBAAsB,EAE3B,KAAK,uBAAuB,EAC5B,KAAK,eAAe,EACvB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAmCrE,qBAAa,uBAAwB,SAAQ,iBAAkB,YAAW,WAAW;IAW9D,OAAO,CAAC,QAAQ,CAAC,KAAK;IAVzC,OAAc,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAQ5C;IAED,YAAoC,KAAK,EAAE,OAAO,EAEjD;IAED;;;;;;OAMG;IACU,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC,CAE5C;IAED;;;;;;OAMG;IACU,iBAAiB,IAAI,OAAO,CAAC,cAAc,CAAC,CAExD;IAED;;;;;;OAMG;IACU,iBAAiB,CAAC,cAAc,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAE5E;IAIM,qBAAqB,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAU9E;IAED,OAAO,CAAC,oBAAoB;IAkBrB,kBAAkB,CACrB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,OAAO,EACZ,IAAI,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,GACtC,IAAI,CAGN;IAEM,mBAAmB,CACtB,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,OAAO,EACZ,IAAI,EAAE,CAAC,QAAQ,EAAE;QAAE,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,CAAA;KAAE,KAAK,IAAI,GAChE,IAAI,CAEN;IAEM,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,GAAG,EAAE,OAAO,GAAG,IAAI,CAI/G;IAED;;;;;;OAMG;IACU,wBAAwB,IAAI,OAAO,CAAC,IAAI,GAAG,YAAY,EAAE,CAAC,CAqBtE;IAED;;;;;;OAMG;IACU,2BAA2B,CAAC,QAAQ,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAW5G;IAIM,8BAA8B,CACjC,mBAAmB,EAAE,MAAM,EAC3B,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,OAAO,EACZ,IAAI,EAAE,CAAC,YAAY,EAAE,uBAAuB,GAAG,IAAI,EAAE,oBAAoB,EAAE,SAAS,GAAG,IAAI,KAAK,IAAI,GACrG,IAAI,CAKN;IAEM,gCAAgC,CACnC,mBAAmB,EAAE,MAAM,EAC3B,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,uBAAuB,EACpC,GAAG,EAAE,OAAO,GACb,IAAI,CAEN;IAED;;;;;;OAMG;IACU,iCAAiC,IAAI,OAAO,CAAC,MAAM,CAAC,CAShE;IAED;;;;;;OAMG;IACU,oCAAoC,IAAI,OAAO,CAAC,eAAe,EAAE,GAAG,IAAI,CAAC,CAiCrF;IAED;;;;;;OAMG;IACU,uCAAuC,CAChD,QAAQ,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,EAAE,GACrD,OAAO,CAAC,IAAI,CAAC,CAKf;IAEM,gBAAgB,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,KAAK,IAAI,GAAG,IAAI,CAYlG;IAEM,yBAAyB,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAUpE;IAED;;;;OAIG;IACI,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAGpC;IAIM,UAAU,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,GAAG,IAAI,CAGlF;IAEM,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,GAAG,IAAI,CAE7D;IAEM,mBAAmB,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,GAAG,IAAI,KAAK,IAAI,GAAG,IAAI,CAG/G;IAEM,wBAAwB,CAAC,CAAC,SAAS,MAAM,sBAAsB,EAClE,GAAG,EAAE,OAAO,EACZ,IAAI,EAAE,CAAC,GAAG,EAAE,sBAAsB,CAAC,CAAC,CAAC,GAAG,IAAI,KAAK,IAAI,EACrD,IAAI,EAAE,CAAC,GACR,IAAI,CAGN;IAEM,0BAA0B,CAAC,CAAC,SAAS,MAAM,sBAAsB,EACpE,GAAG,EAAE,OAAO,EACZ,IAAI,EAAE,CAAC,EACP,GAAG,EAAE,sBAAsB,CAAC,CAAC,CAAC,GAC/B,IAAI,CAEN;IAEM,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAE3F;CACJ"}
|
||||
342
node_modules/matrix-js-sdk/lib/crypto/store/localStorage-crypto-store.js
generated
vendored
Normal file
342
node_modules/matrix-js-sdk/lib/crypto/store/localStorage-crypto-store.js
generated
vendored
Normal file
@@ -0,0 +1,342 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
import { logger } from "../../logger.js";
|
||||
import { MemoryCryptoStore } from "./memory-crypto-store.js";
|
||||
import { MigrationState, SESSION_BATCH_SIZE } from "./base.js";
|
||||
/**
|
||||
* 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_MIGRATION_STATE = E2E_PREFIX + "migration";
|
||||
const KEY_END_TO_END_ACCOUNT = E2E_PREFIX + "account";
|
||||
const KEY_CROSS_SIGNING_KEYS = E2E_PREFIX + "cross_signing_keys";
|
||||
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 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;
|
||||
}
|
||||
export class LocalStorageCryptoStore extends MemoryCryptoStore {
|
||||
static exists(store) {
|
||||
const length = store.length;
|
||||
for (let i = 0; i < length; i++) {
|
||||
if (store.key(i)?.startsWith(E2E_PREFIX)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
constructor(store) {
|
||||
super();
|
||||
this.store = store;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this CryptoStore has ever been initialised (ie, it might contain data).
|
||||
*
|
||||
* Implementation of {@link CryptoStore.containsData}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
async containsData() {
|
||||
return LocalStorageCryptoStore.exists(this.store);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data on how much of the libolm to Rust Crypto migration has been done.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.getMigrationState}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
async getMigrationState() {
|
||||
return getJsonItem(this.store, KEY_END_TO_END_MIGRATION_STATE) ?? MigrationState.NOT_STARTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set data on how much of the libolm to Rust Crypto migration has been done.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.setMigrationState}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
async setMigrationState(migrationState) {
|
||||
setJsonItem(this.store, KEY_END_TO_END_MIGRATION_STATE, migrationState);
|
||||
}
|
||||
|
||||
// Olm Sessions
|
||||
|
||||
countEndToEndSessions(txn, func) {
|
||||
let count = 0;
|
||||
for (let i = 0; i < this.store.length; ++i) {
|
||||
const key = this.store.key(i);
|
||||
if (key?.startsWith(keyEndToEndSessions(""))) {
|
||||
const sessions = getJsonItem(this.store, key);
|
||||
count += Object.keys(sessions ?? {}).length;
|
||||
}
|
||||
}
|
||||
func(count);
|
||||
}
|
||||
_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) ?? {});
|
||||
}
|
||||
storeEndToEndSession(deviceKey, sessionId, sessionInfo, txn) {
|
||||
const sessions = this._getEndToEndSessions(deviceKey) || {};
|
||||
sessions[sessionId] = sessionInfo;
|
||||
setJsonItem(this.store, keyEndToEndSessions(deviceKey), sessions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a batch of Olm sessions from the database.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.getEndToEndSessionsBatch}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
async getEndToEndSessionsBatch() {
|
||||
const result = [];
|
||||
for (let i = 0; i < this.store.length; ++i) {
|
||||
if (this.store.key(i)?.startsWith(keyEndToEndSessions(""))) {
|
||||
const deviceKey = this.store.key(i).split("/")[1];
|
||||
for (const session of Object.values(this._getEndToEndSessions(deviceKey))) {
|
||||
result.push(session);
|
||||
if (result.length >= SESSION_BATCH_SIZE) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (result.length === 0) {
|
||||
// No sessions left.
|
||||
return null;
|
||||
}
|
||||
|
||||
// There are fewer sessions than the batch size; return the final batch of sessions.
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a batch of Olm sessions from the database.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.deleteEndToEndSessionsBatch}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
async deleteEndToEndSessionsBatch(sessions) {
|
||||
for (const {
|
||||
deviceKey,
|
||||
sessionId
|
||||
} of sessions) {
|
||||
const deviceSessions = this._getEndToEndSessions(deviceKey) || {};
|
||||
delete deviceSessions[sessionId];
|
||||
if (Object.keys(deviceSessions).length === 0) {
|
||||
// No more sessions for this device.
|
||||
this.store.removeItem(keyEndToEndSessions(deviceKey));
|
||||
} else {
|
||||
setJsonItem(this.store, keyEndToEndSessions(deviceKey), deviceSessions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Inbound Group Sessions
|
||||
|
||||
getEndToEndInboundGroupSession(senderCurve25519Key, sessionId, txn, func) {
|
||||
func(getJsonItem(this.store, keyEndToEndInboundGroupSession(senderCurve25519Key, sessionId)), getJsonItem(this.store, keyEndToEndInboundGroupSessionWithheld(senderCurve25519Key, sessionId)));
|
||||
}
|
||||
storeEndToEndInboundGroupSession(senderCurve25519Key, sessionId, sessionData, txn) {
|
||||
setJsonItem(this.store, keyEndToEndInboundGroupSession(senderCurve25519Key, sessionId), sessionData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Count the number of Megolm sessions in the database.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.countEndToEndInboundGroupSessions}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
async countEndToEndInboundGroupSessions() {
|
||||
let count = 0;
|
||||
for (let i = 0; i < this.store.length; ++i) {
|
||||
const key = this.store.key(i);
|
||||
if (key?.startsWith(KEY_INBOUND_SESSION_PREFIX)) {
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a batch of Megolm sessions from the database.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.getEndToEndInboundGroupSessionsBatch}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
async getEndToEndInboundGroupSessionsBatch() {
|
||||
const sessionsNeedingBackup = getJsonItem(this.store, KEY_SESSIONS_NEEDING_BACKUP) || {};
|
||||
const result = [];
|
||||
for (let i = 0; i < this.store.length; ++i) {
|
||||
const key = this.store.key(i);
|
||||
if (key?.startsWith(KEY_INBOUND_SESSION_PREFIX)) {
|
||||
const key2 = key.slice(KEY_INBOUND_SESSION_PREFIX.length);
|
||||
|
||||
// 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).
|
||||
|
||||
result.push({
|
||||
senderKey: key2.slice(0, 43),
|
||||
sessionId: key2.slice(44),
|
||||
sessionData: getJsonItem(this.store, key),
|
||||
needsBackup: key2 in sessionsNeedingBackup
|
||||
});
|
||||
if (result.length >= SESSION_BATCH_SIZE) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (result.length === 0) {
|
||||
// No sessions left.
|
||||
return null;
|
||||
}
|
||||
|
||||
// There are fewer sessions than the batch size; return the final batch of sessions.
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a batch of Megolm sessions from the database.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.deleteEndToEndInboundGroupSessionsBatch}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
async deleteEndToEndInboundGroupSessionsBatch(sessions) {
|
||||
for (const {
|
||||
senderKey,
|
||||
sessionId
|
||||
} of sessions) {
|
||||
const k = keyEndToEndInboundGroupSession(senderKey, sessionId);
|
||||
this.store.removeItem(k);
|
||||
}
|
||||
}
|
||||
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?.startsWith(prefix)) {
|
||||
const roomId = key.slice(prefix.length);
|
||||
result[roomId] = getJsonItem(this.store, key);
|
||||
}
|
||||
}
|
||||
func(result);
|
||||
}
|
||||
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);
|
||||
}
|
||||
storeSecretStorePrivateKey(txn, type, key) {
|
||||
setJsonItem(this.store, E2E_PREFIX + `ssss_cache.${type}`, key);
|
||||
}
|
||||
doTxn(mode, stores, func) {
|
||||
return Promise.resolve(func(null));
|
||||
}
|
||||
}
|
||||
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.log("Error: Failed to get key %s: %s", key, e.message);
|
||||
logger.log(e.stack);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
function setJsonItem(store, key, val) {
|
||||
store.setItem(key, JSON.stringify(val));
|
||||
}
|
||||
//# sourceMappingURL=localStorage-crypto-store.js.map
|
||||
1
node_modules/matrix-js-sdk/lib/crypto/store/localStorage-crypto-store.js.map
generated
vendored
Normal file
1
node_modules/matrix-js-sdk/lib/crypto/store/localStorage-crypto-store.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
117
node_modules/matrix-js-sdk/lib/crypto/store/memory-crypto-store.d.ts
generated
vendored
Normal file
117
node_modules/matrix-js-sdk/lib/crypto/store/memory-crypto-store.d.ts
generated
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
import { type CryptoStore, type ISession, type SessionExtended, type ISessionInfo, type IWithheld, MigrationState, type Mode, type SecretStorePrivateKeys, type InboundGroupSessionData, type IRoomEncryption } from "./base.ts";
|
||||
import { type CrossSigningKeyInfo } from "../../crypto-api/index.ts";
|
||||
/**
|
||||
* Internal module. in-memory storage for e2e.
|
||||
*/
|
||||
export declare class MemoryCryptoStore implements CryptoStore {
|
||||
private migrationState;
|
||||
private account;
|
||||
private crossSigningKeys;
|
||||
private privateKeys;
|
||||
private sessions;
|
||||
private inboundGroupSessions;
|
||||
private inboundGroupSessionsWithheld;
|
||||
private rooms;
|
||||
private sessionsNeedingBackup;
|
||||
/**
|
||||
* Returns true if this CryptoStore has ever been initialised (ie, it might contain data).
|
||||
*
|
||||
* Implementation of {@link CryptoStore.containsData}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
containsData(): Promise<boolean>;
|
||||
/**
|
||||
* 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>;
|
||||
/**
|
||||
* Get data on how much of the libolm to Rust Crypto migration has been done.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.getMigrationState}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
getMigrationState(): Promise<MigrationState>;
|
||||
/**
|
||||
* Set data on how much of the libolm to Rust Crypto migration has been done.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.setMigrationState}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
setMigrationState(migrationState: MigrationState): Promise<void>;
|
||||
getAccount(txn: unknown, func: (accountPickle: string | null) => void): void;
|
||||
storeAccount(txn: unknown, accountPickle: string): void;
|
||||
getCrossSigningKeys(txn: unknown, func: (keys: Record<string, CrossSigningKeyInfo> | null) => void): void;
|
||||
getSecretStorePrivateKey<K extends keyof SecretStorePrivateKeys>(txn: unknown, func: (key: SecretStorePrivateKeys[K] | null) => void, type: K): 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;
|
||||
storeEndToEndSession(deviceKey: string, sessionId: string, sessionInfo: ISessionInfo, txn: unknown): void;
|
||||
/**
|
||||
* Fetch a batch of Olm sessions from the database.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.getEndToEndSessionsBatch}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
getEndToEndSessionsBatch(): Promise<null | ISessionInfo[]>;
|
||||
/**
|
||||
* Delete a batch of Olm sessions from the database.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.deleteEndToEndSessionsBatch}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
deleteEndToEndSessionsBatch(sessions: {
|
||||
deviceKey: string;
|
||||
sessionId: string;
|
||||
}[]): Promise<void>;
|
||||
getEndToEndInboundGroupSession(senderCurve25519Key: string, sessionId: string, txn: unknown, func: (groupSession: InboundGroupSessionData | null, groupSessionWithheld: IWithheld | null) => void): void;
|
||||
storeEndToEndInboundGroupSession(senderCurve25519Key: string, sessionId: string, sessionData: InboundGroupSessionData, txn: unknown): void;
|
||||
/**
|
||||
* Count the number of Megolm sessions in the database.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.countEndToEndInboundGroupSessions}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
countEndToEndInboundGroupSessions(): Promise<number>;
|
||||
/**
|
||||
* Fetch a batch of Megolm sessions from the database.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.getEndToEndInboundGroupSessionsBatch}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
getEndToEndInboundGroupSessionsBatch(): Promise<null | SessionExtended[]>;
|
||||
/**
|
||||
* Delete a batch of Megolm sessions from the database.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.deleteEndToEndInboundGroupSessionsBatch}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
deleteEndToEndInboundGroupSessionsBatch(sessions: {
|
||||
senderKey: string;
|
||||
sessionId: string;
|
||||
}[]): Promise<void>;
|
||||
getEndToEndRooms(txn: unknown, func: (rooms: Record<string, IRoomEncryption>) => void): void;
|
||||
markSessionsNeedingBackup(sessions: ISession[]): Promise<void>;
|
||||
doTxn<T>(mode: Mode, stores: Iterable<string>, func: (txn?: unknown) => T): Promise<T>;
|
||||
}
|
||||
//# sourceMappingURL=memory-crypto-store.d.ts.map
|
||||
1
node_modules/matrix-js-sdk/lib/crypto/store/memory-crypto-store.d.ts.map
generated
vendored
Normal file
1
node_modules/matrix-js-sdk/lib/crypto/store/memory-crypto-store.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"memory-crypto-store.d.ts","sourceRoot":"","sources":["../../../src/crypto/store/memory-crypto-store.ts"],"names":[],"mappings":"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"}
|
||||
282
node_modules/matrix-js-sdk/lib/crypto/store/memory-crypto-store.js
generated
vendored
Normal file
282
node_modules/matrix-js-sdk/lib/crypto/store/memory-crypto-store.js
generated
vendored
Normal file
@@ -0,0 +1,282 @@
|
||||
import _objectSpread from "@babel/runtime/helpers/objectSpread2";
|
||||
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
import { safeSet } from "../../utils.js";
|
||||
import { MigrationState, SESSION_BATCH_SIZE } from "./base.js";
|
||||
function encodeSessionKey(senderCurve25519Key, sessionId) {
|
||||
return encodeURIComponent(senderCurve25519Key) + "/" + encodeURIComponent(sessionId);
|
||||
}
|
||||
function decodeSessionKey(key) {
|
||||
const keyParts = key.split("/");
|
||||
const senderKey = decodeURIComponent(keyParts[0]);
|
||||
const sessionId = decodeURIComponent(keyParts[1]);
|
||||
return {
|
||||
senderKey,
|
||||
sessionId
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal module. in-memory storage for e2e.
|
||||
*/
|
||||
|
||||
export class MemoryCryptoStore {
|
||||
constructor() {
|
||||
_defineProperty(this, "migrationState", MigrationState.NOT_STARTED);
|
||||
_defineProperty(this, "account", null);
|
||||
_defineProperty(this, "crossSigningKeys", null);
|
||||
_defineProperty(this, "privateKeys", {});
|
||||
_defineProperty(this, "sessions", {});
|
||||
_defineProperty(this, "inboundGroupSessions", {});
|
||||
_defineProperty(this, "inboundGroupSessionsWithheld", {});
|
||||
// Opaque device data object
|
||||
_defineProperty(this, "rooms", {});
|
||||
_defineProperty(this, "sessionsNeedingBackup", {});
|
||||
}
|
||||
/**
|
||||
* Returns true if this CryptoStore has ever been initialised (ie, it might contain data).
|
||||
*
|
||||
* Implementation of {@link CryptoStore.containsData}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
async containsData() {
|
||||
// If it contains anything, it should contain an account.
|
||||
return this.account !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data on how much of the libolm to Rust Crypto migration has been done.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.getMigrationState}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
async getMigrationState() {
|
||||
return this.migrationState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set data on how much of the libolm to Rust Crypto migration has been done.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.setMigrationState}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
async setMigrationState(migrationState) {
|
||||
this.migrationState = migrationState;
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
storeSecretStorePrivateKey(txn, type, key) {
|
||||
this.privateKeys[type] = key;
|
||||
}
|
||||
|
||||
// Olm Sessions
|
||||
|
||||
countEndToEndSessions(txn, func) {
|
||||
let count = 0;
|
||||
for (const deviceSessions of Object.values(this.sessions)) {
|
||||
count += Object.keys(deviceSessions).length;
|
||||
}
|
||||
func(count);
|
||||
}
|
||||
getEndToEndSession(deviceKey, sessionId, txn, func) {
|
||||
const deviceSessions = this.sessions[deviceKey] || {};
|
||||
func(deviceSessions[sessionId] || null);
|
||||
}
|
||||
getEndToEndSessions(deviceKey, txn, func) {
|
||||
func(this.sessions[deviceKey] || {});
|
||||
}
|
||||
storeEndToEndSession(deviceKey, sessionId, sessionInfo, txn) {
|
||||
let deviceSessions = this.sessions[deviceKey];
|
||||
if (deviceSessions === undefined) {
|
||||
deviceSessions = {};
|
||||
this.sessions[deviceKey] = deviceSessions;
|
||||
}
|
||||
safeSet(deviceSessions, sessionId, sessionInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a batch of Olm sessions from the database.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.getEndToEndSessionsBatch}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
async getEndToEndSessionsBatch() {
|
||||
const result = [];
|
||||
for (const deviceSessions of Object.values(this.sessions)) {
|
||||
for (const session of Object.values(deviceSessions)) {
|
||||
result.push(session);
|
||||
if (result.length >= SESSION_BATCH_SIZE) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (result.length === 0) {
|
||||
// No sessions left.
|
||||
return null;
|
||||
}
|
||||
|
||||
// There are fewer sessions than the batch size; return the final batch of sessions.
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a batch of Olm sessions from the database.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.deleteEndToEndSessionsBatch}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
async deleteEndToEndSessionsBatch(sessions) {
|
||||
for (const {
|
||||
deviceKey,
|
||||
sessionId
|
||||
} of sessions) {
|
||||
const deviceSessions = this.sessions[deviceKey] || {};
|
||||
delete deviceSessions[sessionId];
|
||||
if (Object.keys(deviceSessions).length === 0) {
|
||||
// No more sessions for this device.
|
||||
delete this.sessions[deviceKey];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Inbound Group Sessions
|
||||
|
||||
getEndToEndInboundGroupSession(senderCurve25519Key, sessionId, txn, func) {
|
||||
const k = encodeSessionKey(senderCurve25519Key, sessionId);
|
||||
func(this.inboundGroupSessions[k] || null, this.inboundGroupSessionsWithheld[k] || null);
|
||||
}
|
||||
storeEndToEndInboundGroupSession(senderCurve25519Key, sessionId, sessionData, txn) {
|
||||
const k = encodeSessionKey(senderCurve25519Key, sessionId);
|
||||
this.inboundGroupSessions[k] = sessionData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Count the number of Megolm sessions in the database.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.countEndToEndInboundGroupSessions}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
async countEndToEndInboundGroupSessions() {
|
||||
return Object.keys(this.inboundGroupSessions).length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a batch of Megolm sessions from the database.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.getEndToEndInboundGroupSessionsBatch}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
async getEndToEndInboundGroupSessionsBatch() {
|
||||
const result = [];
|
||||
for (const [key, session] of Object.entries(this.inboundGroupSessions)) {
|
||||
result.push(_objectSpread(_objectSpread({}, decodeSessionKey(key)), {}, {
|
||||
sessionData: session,
|
||||
needsBackup: key in this.sessionsNeedingBackup
|
||||
}));
|
||||
if (result.length >= SESSION_BATCH_SIZE) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
if (result.length === 0) {
|
||||
// No sessions left.
|
||||
return null;
|
||||
}
|
||||
|
||||
// There are fewer sessions than the batch size; return the final batch of sessions.
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a batch of Megolm sessions from the database.
|
||||
*
|
||||
* Implementation of {@link CryptoStore.deleteEndToEndInboundGroupSessionsBatch}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
async deleteEndToEndInboundGroupSessionsBatch(sessions) {
|
||||
for (const {
|
||||
senderKey,
|
||||
sessionId
|
||||
} of sessions) {
|
||||
const k = encodeSessionKey(senderKey, sessionId);
|
||||
delete this.inboundGroupSessions[k];
|
||||
}
|
||||
}
|
||||
|
||||
// E2E rooms
|
||||
|
||||
getEndToEndRooms(txn, func) {
|
||||
func(this.rooms);
|
||||
}
|
||||
markSessionsNeedingBackup(sessions) {
|
||||
for (const session of sessions) {
|
||||
const sessionKey = encodeSessionKey(session.senderKey, session.sessionId);
|
||||
this.sessionsNeedingBackup[sessionKey] = true;
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
// Session key backups
|
||||
|
||||
doTxn(mode, stores, func) {
|
||||
return Promise.resolve(func(null));
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=memory-crypto-store.js.map
|
||||
1
node_modules/matrix-js-sdk/lib/crypto/store/memory-crypto-store.js.map
generated
vendored
Normal file
1
node_modules/matrix-js-sdk/lib/crypto/store/memory-crypto-store.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user