You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-07-30 04:23:07 +03:00
Improve tsdoc types (#2940)
* Install eslint-plugin-jsdoc * Enable lint rule jsdoc/no-types * Make tsdoc more valid, add required hyphens and s/return/returns/g * Stash tsdoc work * Fix mistypes * Stash * Stash * More tsdoc work * Remove useless doc params * Fixup docs * Apply suggestions from code review Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> * Update src/crypto/verification/request/ToDeviceChannel.ts Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> * Update src/client.ts Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> * Update src/client.ts Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> * Update src/client.ts Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> * Iterate Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
a9e7a46c56
commit
c4006d752a
23
.eslintrc.js
23
.eslintrc.js
@ -2,6 +2,7 @@ module.exports = {
|
||||
plugins: [
|
||||
"matrix-org",
|
||||
"import",
|
||||
"jsdoc",
|
||||
],
|
||||
extends: [
|
||||
"plugin:matrix-org/babel",
|
||||
@ -45,7 +46,7 @@ module.exports = {
|
||||
// restrict EventEmitters to force callers to use TypedEventEmitter
|
||||
"no-restricted-imports": ["error", {
|
||||
name: "events",
|
||||
message: "Please use TypedEventEmitter instead"
|
||||
message: "Please use TypedEventEmitter instead",
|
||||
}],
|
||||
|
||||
"import/no-restricted-paths": ["error", {
|
||||
@ -61,6 +62,9 @@ module.exports = {
|
||||
files: [
|
||||
"**/*.ts",
|
||||
],
|
||||
plugins: [
|
||||
"eslint-plugin-tsdoc",
|
||||
],
|
||||
extends: [
|
||||
"plugin:matrix-org/typescript",
|
||||
],
|
||||
@ -84,6 +88,23 @@ module.exports = {
|
||||
"quotes": "off",
|
||||
// We use a `logger` intermediary module
|
||||
"no-console": "error",
|
||||
|
||||
},
|
||||
}, {
|
||||
// We don't need amazing docs in our spec files
|
||||
files: [
|
||||
"src/**/*.ts",
|
||||
],
|
||||
rules: {
|
||||
"tsdoc/syntax": "error",
|
||||
// We use some select jsdoc rules as the tsdoc linter has only one rule
|
||||
"jsdoc/no-types": "error",
|
||||
"jsdoc/empty-tags": "error",
|
||||
"jsdoc/check-property-names": "error",
|
||||
"jsdoc/check-values": "error",
|
||||
// These need a bit more work before we can enable
|
||||
// "jsdoc/check-param-names": "error",
|
||||
// "jsdoc/check-indentation": "error",
|
||||
},
|
||||
}, {
|
||||
files: [
|
||||
|
@ -88,8 +88,8 @@
|
||||
"@types/node": "18",
|
||||
"@types/sdp-transform": "^2.4.5",
|
||||
"@types/uuid": "7",
|
||||
"@typescript-eslint/eslint-plugin": "^5.6.0",
|
||||
"@typescript-eslint/parser": "^5.6.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.45.0",
|
||||
"@typescript-eslint/parser": "^5.45.0",
|
||||
"allchange": "^1.0.6",
|
||||
"babel-jest": "^29.0.0",
|
||||
"babelify": "^10.0.0",
|
||||
@ -101,7 +101,9 @@
|
||||
"eslint-config-google": "^0.14.0",
|
||||
"eslint-import-resolver-typescript": "^3.5.1",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-plugin-jsdoc": "^39.6.4",
|
||||
"eslint-plugin-matrix-org": "^0.8.0",
|
||||
"eslint-plugin-tsdoc": "^0.2.17",
|
||||
"eslint-plugin-unicorn": "^45.0.0",
|
||||
"exorcist": "^2.0.0",
|
||||
"fake-indexeddb": "^4.0.0",
|
||||
|
@ -105,7 +105,7 @@ export class TestClient {
|
||||
|
||||
/**
|
||||
* stop the client
|
||||
* @return {Promise} Resolves once the mock http backend has finished all pending flushes
|
||||
* @returns Promise which resolves once the mock http backend has finished all pending flushes
|
||||
*/
|
||||
public async stop(): Promise<void> {
|
||||
this.client.stopClient();
|
||||
@ -135,7 +135,7 @@ export class TestClient {
|
||||
* set up an expectation that the keys will be uploaded, and wait for
|
||||
* that to happen.
|
||||
*
|
||||
* @returns {Promise} for the one-time keys
|
||||
* @returns Promise for the one-time keys
|
||||
*/
|
||||
public awaitOneTimeKeyUpload(): Promise<Record<string, IOneTimeKey>> {
|
||||
if (Object.keys(this.oneTimeKeys!).length != 0) {
|
||||
@ -177,7 +177,7 @@ export class TestClient {
|
||||
*
|
||||
* We check that the query contains each of the users in `response`.
|
||||
*
|
||||
* @param {Object} response response to the query.
|
||||
* @param response - response to the query.
|
||||
*/
|
||||
public expectKeyQuery(response: IDownloadKeyResult) {
|
||||
this.httpBackend.when('POST', '/keys/query').respond<IDownloadKeyResult>(
|
||||
@ -202,7 +202,7 @@ export class TestClient {
|
||||
/**
|
||||
* get the uploaded curve25519 device key
|
||||
*
|
||||
* @return {string} base64 device key
|
||||
* @returns base64 device key
|
||||
*/
|
||||
public getDeviceKey(): string {
|
||||
const keyId = 'curve25519:' + this.deviceId;
|
||||
@ -212,7 +212,7 @@ export class TestClient {
|
||||
/**
|
||||
* get the uploaded ed25519 device key
|
||||
*
|
||||
* @return {string} base64 device key
|
||||
* @returns base64 device key
|
||||
*/
|
||||
public getSigningKey(): string {
|
||||
const keyId = 'ed25519:' + this.deviceId;
|
||||
|
@ -26,9 +26,7 @@ const ROOM_ID = "!room:id";
|
||||
* get a /sync response which contains a single e2e room (ROOM_ID), with the
|
||||
* members given
|
||||
*
|
||||
* @param {string[]} roomMembers
|
||||
*
|
||||
* @return {object} sync response
|
||||
* @returns sync response
|
||||
*/
|
||||
function getSyncResponse(roomMembers: string[]) {
|
||||
const stateEvents = [
|
||||
|
@ -60,7 +60,7 @@ async function bobUploadsDeviceKeys(): Promise<void> {
|
||||
/**
|
||||
* Set an expectation that querier will query uploader's keys; then flush the http request.
|
||||
*
|
||||
* @return {promise} resolves once the http request has completed.
|
||||
* @returns resolves once the http request has completed.
|
||||
*/
|
||||
function expectQueryKeys(querier: TestClient, uploader: TestClient): Promise<number> {
|
||||
// can't query keys before bob has uploaded them
|
||||
@ -83,7 +83,7 @@ const expectBobQueryKeys = () => expectQueryKeys(bobTestClient, aliTestClient);
|
||||
/**
|
||||
* Set an expectation that ali will claim one of bob's keys; then flush the http request.
|
||||
*
|
||||
* @return {promise} resolves once the http request has completed.
|
||||
* @returns resolves once the http request has completed.
|
||||
*/
|
||||
async function expectAliClaimKeys(): Promise<void> {
|
||||
const keys = await bobTestClient.awaitOneTimeKeyUpload();
|
||||
@ -151,7 +151,7 @@ const bobEnablesEncryption = () => clientEnablesEncryption(bobTestClient.client)
|
||||
* Ali sends a message, first claiming e2e keys. Set the expectations and
|
||||
* check the results.
|
||||
*
|
||||
* @return {promise} which resolves to the ciphertext for Bob's device.
|
||||
* @returns which resolves to the ciphertext for Bob's device.
|
||||
*/
|
||||
async function aliSendsFirstMessage(): Promise<OlmPayload> {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
@ -168,7 +168,7 @@ async function aliSendsFirstMessage(): Promise<OlmPayload> {
|
||||
* Ali sends a message without first claiming e2e keys. Set the expectations
|
||||
* and check the results.
|
||||
*
|
||||
* @return {promise} which resolves to the ciphertext for Bob's device.
|
||||
* @returns which resolves to the ciphertext for Bob's device.
|
||||
*/
|
||||
async function aliSendsMessage(): Promise<OlmPayload> {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
@ -183,7 +183,7 @@ async function aliSendsMessage(): Promise<OlmPayload> {
|
||||
* Bob sends a message, first querying (but not claiming) e2e keys. Set the
|
||||
* expectations and check the results.
|
||||
*
|
||||
* @return {promise} which resolves to the ciphertext for Ali's device.
|
||||
* @returns which resolves to the ciphertext for Ali's device.
|
||||
*/
|
||||
async function bobSendsReplyMessage(): Promise<OlmPayload> {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
@ -198,7 +198,7 @@ async function bobSendsReplyMessage(): Promise<OlmPayload> {
|
||||
/**
|
||||
* Set an expectation that Ali will send a message, and flush the request
|
||||
*
|
||||
* @return {promise} which resolves to the ciphertext for Bob's device.
|
||||
* @returns which resolves to the ciphertext for Bob's device.
|
||||
*/
|
||||
async function expectAliSendMessageRequest(): Promise<OlmPayload> {
|
||||
const content = await expectSendMessageRequest(aliTestClient.httpBackend);
|
||||
@ -212,7 +212,7 @@ async function expectAliSendMessageRequest(): Promise<OlmPayload> {
|
||||
/**
|
||||
* Set an expectation that Bob will send a message, and flush the request
|
||||
*
|
||||
* @return {promise} which resolves to the ciphertext for Bob's device.
|
||||
* @returns which resolves to the ciphertext for Bob's device.
|
||||
*/
|
||||
async function expectBobSendMessageRequest(): Promise<OlmPayload> {
|
||||
const content = await expectSendMessageRequest(bobTestClient.httpBackend);
|
||||
@ -321,8 +321,7 @@ async function recvMessage(
|
||||
* Send an initial sync response to the client (which just includes the member
|
||||
* list for our test room).
|
||||
*
|
||||
* @param {TestClient} testClient
|
||||
* @returns {Promise} which resolves when the sync has been flushed.
|
||||
* @returns which resolves when the sync has been flushed.
|
||||
*/
|
||||
function firstSync(testClient: TestClient): Promise<void> {
|
||||
// send a sync response including our test room.
|
||||
|
@ -1658,8 +1658,8 @@ describe("MatrixClient syncing", () => {
|
||||
/**
|
||||
* waits for the MatrixClient to emit one or more 'sync' events.
|
||||
*
|
||||
* @param {Number?} numSyncs number of syncs to wait for
|
||||
* @returns {Promise} promise which resolves after the sync events have happened
|
||||
* @param numSyncs - number of syncs to wait for
|
||||
* @returns promise which resolves after the sync events have happened
|
||||
*/
|
||||
function awaitSyncEvent(numSyncs?: number) {
|
||||
return utils.syncPromise(client!, numSyncs);
|
||||
|
@ -220,8 +220,8 @@ describe("megolm", () => {
|
||||
* Get the device keys for testOlmAccount in a format suitable for a
|
||||
* response to /keys/query
|
||||
*
|
||||
* @param {string} userId The user ID to query for
|
||||
* @returns {IDownloadKeyResult} The fake query response
|
||||
* @param userId - The user ID to query for
|
||||
* @returns The fake query response
|
||||
*/
|
||||
function getTestKeysQueryResponse(userId: string): IDownloadKeyResult {
|
||||
const testE2eKeys = JSON.parse(testOlmAccount.identity_keys());
|
||||
@ -248,8 +248,8 @@ describe("megolm", () => {
|
||||
* Get a one-time key for testOlmAccount in a format suitable for a
|
||||
* response to /keys/claim
|
||||
|
||||
* @param {string} userId The user ID to query for
|
||||
* @returns {IClaimOTKsResult} The fake key claim response
|
||||
* @param userId - The user ID to query for
|
||||
* @returns The fake key claim response
|
||||
*/
|
||||
function getTestKeysClaimResponse(userId: string): IClaimOTKsResult {
|
||||
testOlmAccount.generate_one_time_keys(1);
|
||||
|
@ -1446,11 +1446,11 @@ function timeout(delayMs: number, reason: string): { promise: Promise<never>, ca
|
||||
|
||||
/**
|
||||
* Listen until a callback returns data.
|
||||
* @param {EventEmitter} emitter The event emitter
|
||||
* @param {string} eventName The event to listen for
|
||||
* @param {function} callback The callback which will be invoked when events fire. Return something truthy from this to resolve the promise.
|
||||
* @param {number} timeoutMs The number of milliseconds to wait for the callback to return data. Default: 500ms.
|
||||
* @returns {Promise} A promise which will be resolved when the callback returns data. If the callback throws or the timeout is reached,
|
||||
* @param emitter - The event emitter
|
||||
* @param eventName - The event to listen for
|
||||
* @param callback - The callback which will be invoked when events fire. Return something truthy from this to resolve the promise.
|
||||
* @param timeoutMs - The number of milliseconds to wait for the callback to return data. Default: 500ms.
|
||||
* @returns A promise which will be resolved when the callback returns data. If the callback throws or the timeout is reached,
|
||||
* the promise is rejected.
|
||||
*/
|
||||
function listenUntil<T>(
|
||||
|
@ -13,9 +13,9 @@ import { eventMapperFor } from "../../src/event-mapper";
|
||||
/**
|
||||
* Return a promise that is resolved when the client next emits a
|
||||
* SYNCING event.
|
||||
* @param {Object} client The client
|
||||
* @param {Number=} count Number of syncs to wait for (default 1)
|
||||
* @return {Promise} Resolves once the client has emitted a SYNCING event
|
||||
* @param client - The client
|
||||
* @param count - Number of syncs to wait for (default 1)
|
||||
* @returns Promise which resolves once the client has emitted a SYNCING event
|
||||
*/
|
||||
export function syncPromise(client: MatrixClient, count = 1): Promise<void> {
|
||||
if (count <= 0) {
|
||||
@ -41,9 +41,9 @@ export function syncPromise(client: MatrixClient, count = 1): Promise<void> {
|
||||
|
||||
/**
|
||||
* Create a spy for an object and automatically spy its methods.
|
||||
* @param {*} constr The class constructor (used with 'new')
|
||||
* @param {string} name The name of the class
|
||||
* @return {Object} An instantiated object with spied methods/properties.
|
||||
* @param constr - The class constructor (used with 'new')
|
||||
* @param name - The name of the class
|
||||
* @returns An instantiated object with spied methods/properties.
|
||||
*/
|
||||
export function mock<T>(constr: { new(...args: any[]): T }, name: string): T {
|
||||
// Based on http://eclipsesource.com/blogs/2014/03/27/mocks-in-jasmine-tests/
|
||||
@ -84,15 +84,15 @@ interface IEventOpts {
|
||||
let testEventIndex = 1; // counter for events, easier for comparison of randomly generated events
|
||||
/**
|
||||
* Create an Event.
|
||||
* @param {Object} opts Values for the event.
|
||||
* @param {string} opts.type The event.type
|
||||
* @param {string} opts.room The event.room_id
|
||||
* @param {string} opts.sender The event.sender
|
||||
* @param {string} opts.skey Optional. The state key (auto inserts empty string)
|
||||
* @param {Object} opts.content The event.content
|
||||
* @param {boolean} opts.event True to make a MatrixEvent.
|
||||
* @param {MatrixClient} client If passed along with opts.event=true will be used to set up re-emitters.
|
||||
* @return {Object} a JSON object representing this event.
|
||||
* @param opts - Values for the event.
|
||||
* @param opts.type - The event.type
|
||||
* @param opts.room - The event.room_id
|
||||
* @param opts.sender - The event.sender
|
||||
* @param opts.skey - Optional. The state key (auto inserts empty string)
|
||||
* @param opts.content - The event.content
|
||||
* @param opts.event - True to make a MatrixEvent.
|
||||
* @param client - If passed along with opts.event=true will be used to set up re-emitters.
|
||||
* @returns a JSON object representing this event.
|
||||
*/
|
||||
export function mkEvent(opts: IEventOpts & { event: true }, client?: MatrixClient): MatrixEvent;
|
||||
export function mkEvent(opts: IEventOpts & { event?: false }, client?: MatrixClient): Partial<IEvent>;
|
||||
@ -160,8 +160,8 @@ interface IPresenceOpts {
|
||||
|
||||
/**
|
||||
* Create an m.presence event.
|
||||
* @param {Object} opts Values for the presence.
|
||||
* @return {Object|MatrixEvent} The event
|
||||
* @param opts - Values for the presence.
|
||||
* @returns The event
|
||||
*/
|
||||
export function mkPresence(opts: IPresenceOpts & { event: true }): MatrixEvent;
|
||||
export function mkPresence(opts: IPresenceOpts & { event?: false }): Partial<IEvent>;
|
||||
@ -193,16 +193,16 @@ interface IMembershipOpts {
|
||||
|
||||
/**
|
||||
* Create an m.room.member event.
|
||||
* @param {Object} opts Values for the membership.
|
||||
* @param {string} opts.room The room ID for the event.
|
||||
* @param {string} opts.mship The content.membership for the event.
|
||||
* @param {string} opts.sender The sender user ID for the event.
|
||||
* @param {string} opts.skey The target user ID for the event if applicable
|
||||
* @param opts - Values for the membership.
|
||||
* @param opts.room - The room ID for the event.
|
||||
* @param opts.mship - The content.membership for the event.
|
||||
* @param opts.sender - The sender user ID for the event.
|
||||
* @param opts.skey - The target user ID for the event if applicable
|
||||
* e.g. for invites/bans.
|
||||
* @param {string} opts.name The content.displayname for the event.
|
||||
* @param {string} opts.url The content.avatar_url for the event.
|
||||
* @param {boolean} opts.event True to make a MatrixEvent.
|
||||
* @return {Object|MatrixEvent} The event
|
||||
* @param opts.name - The content.displayname for the event.
|
||||
* @param opts.url - The content.avatar_url for the event.
|
||||
* @param opts.event - True to make a MatrixEvent.
|
||||
* @returns The event
|
||||
*/
|
||||
export function mkMembership(opts: IMembershipOpts & { event: true }): MatrixEvent;
|
||||
export function mkMembership(opts: IMembershipOpts & { event?: false }): Partial<IEvent>;
|
||||
@ -250,13 +250,13 @@ export interface IMessageOpts {
|
||||
|
||||
/**
|
||||
* Create an m.room.message event.
|
||||
* @param {Object} opts Values for the message
|
||||
* @param {string} opts.room The room ID for the event.
|
||||
* @param {string} opts.user The user ID for the event.
|
||||
* @param {string} opts.msg Optional. The content.body for the event.
|
||||
* @param {boolean} opts.event True to make a MatrixEvent.
|
||||
* @param {MatrixClient} client If passed along with opts.event=true will be used to set up re-emitters.
|
||||
* @return {Object|MatrixEvent} The event
|
||||
* @param opts - Values for the message
|
||||
* @param opts.room - The room ID for the event.
|
||||
* @param opts.user - The user ID for the event.
|
||||
* @param opts.msg - Optional. The content.body for the event.
|
||||
* @param opts.event - True to make a MatrixEvent.
|
||||
* @param client - If passed along with opts.event=true will be used to set up re-emitters.
|
||||
* @returns The event
|
||||
*/
|
||||
export function mkMessage(opts: IMessageOpts & { event: true }, client?: MatrixClient): MatrixEvent;
|
||||
export function mkMessage(opts: IMessageOpts & { event?: false }, client?: MatrixClient): Partial<IEvent>;
|
||||
@ -290,14 +290,14 @@ interface IReplyMessageOpts extends IMessageOpts {
|
||||
/**
|
||||
* Create a reply message.
|
||||
*
|
||||
* @param {Object} opts Values for the message
|
||||
* @param {string} opts.room The room ID for the event.
|
||||
* @param {string} opts.user The user ID for the event.
|
||||
* @param {string} opts.msg Optional. The content.body for the event.
|
||||
* @param {MatrixEvent} opts.replyToMessage The replied message
|
||||
* @param {boolean} opts.event True to make a MatrixEvent.
|
||||
* @param {MatrixClient} client If passed along with opts.event=true will be used to set up re-emitters.
|
||||
* @return {Object|MatrixEvent} The event
|
||||
* @param opts - Values for the message
|
||||
* @param opts.room - The room ID for the event.
|
||||
* @param opts.user - The user ID for the event.
|
||||
* @param opts.msg - Optional. The content.body for the event.
|
||||
* @param opts.replyToMessage - The replied message
|
||||
* @param opts.event - True to make a MatrixEvent.
|
||||
* @param client - If passed along with opts.event=true will be used to set up re-emitters.
|
||||
* @returns The event
|
||||
*/
|
||||
export function mkReplyMessage(opts: IReplyMessageOpts & { event: true }, client?: MatrixClient): MatrixEvent;
|
||||
export function mkReplyMessage(opts: IReplyMessageOpts & { event?: false }, client?: MatrixClient): Partial<IEvent>;
|
||||
@ -329,8 +329,6 @@ export function mkReplyMessage(
|
||||
|
||||
/**
|
||||
* A mock implementation of webstorage
|
||||
*
|
||||
* @constructor
|
||||
*/
|
||||
export class MockStorageApi implements Storage {
|
||||
private data: Record<string, any> = {};
|
||||
@ -363,8 +361,7 @@ export class MockStorageApi implements Storage {
|
||||
/**
|
||||
* If an event is being decrypted, wait for it to finish being decrypted.
|
||||
*
|
||||
* @param {MatrixEvent} event
|
||||
* @returns {Promise} promise which resolves (to `event`) when the event has been decrypted
|
||||
* @returns promise which resolves (to `event`) when the event has been decrypted
|
||||
*/
|
||||
export async function awaitDecryption(
|
||||
event: MatrixEvent, { waitOnDecryptionFailure = false } = {},
|
||||
|
@ -16,7 +16,6 @@ limitations under the License.
|
||||
|
||||
/**
|
||||
* This is an internal module. See {@link MatrixClient} for the public class.
|
||||
* @module client
|
||||
*/
|
||||
|
||||
import { mocked } from "jest-mock";
|
||||
|
@ -18,7 +18,7 @@ export interface IIdentityServerProvider {
|
||||
/**
|
||||
* Gets an access token for use against the identity server,
|
||||
* for the associated client.
|
||||
* @returns {Promise<string>} Resolves to the access token.
|
||||
* @returns Promise which resolves to the access token.
|
||||
*/
|
||||
getAccessToken(): Promise<string>;
|
||||
}
|
||||
|
@ -35,7 +35,8 @@ import { MAssetEvent, MLocationEvent, MTimestampEvent } from "./location";
|
||||
* To achieve an arbitrary number of only owner-writable state events
|
||||
* we introduce a variable suffix to the event type
|
||||
*
|
||||
* Eg
|
||||
* @example
|
||||
* ```
|
||||
* {
|
||||
* "type": "m.beacon_info.@matthew:matrix.org.1",
|
||||
* "state_key": "@matthew:matrix.org",
|
||||
@ -58,6 +59,7 @@ import { MAssetEvent, MLocationEvent, MTimestampEvent } from "./location";
|
||||
* // more content as described below
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -78,20 +80,23 @@ export type MBeaconInfoContent = {
|
||||
/**
|
||||
* m.beacon_info Event example from the spec
|
||||
* https://github.com/matrix-org/matrix-spec-proposals/pull/3672
|
||||
* @example
|
||||
* ```
|
||||
* {
|
||||
"type": "m.beacon_info",
|
||||
"state_key": "@matthew:matrix.org",
|
||||
"content": {
|
||||
"m.beacon_info": {
|
||||
"description": "The Matthew Tracker", // same as an `m.location` description
|
||||
"timeout": 86400000, // how long from the last event until we consider the beacon inactive in milliseconds
|
||||
},
|
||||
"m.ts": 1436829458432, // creation timestamp of the beacon on the client
|
||||
"m.asset": {
|
||||
"type": "m.self" // the type of asset being tracked as per MSC3488
|
||||
}
|
||||
}
|
||||
}
|
||||
* "type": "m.beacon_info",
|
||||
* "state_key": "@matthew:matrix.org",
|
||||
* "content": {
|
||||
* "m.beacon_info": {
|
||||
* "description": "The Matthew Tracker", // same as an `m.location` description
|
||||
* "timeout": 86400000, // how long from the last event until we consider the beacon inactive in milliseconds
|
||||
* },
|
||||
* "m.ts": 1436829458432, // creation timestamp of the beacon on the client
|
||||
* "m.asset": {
|
||||
* "type": "m.self" // the type of asset being tracked as per MSC3488
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -107,22 +112,24 @@ export type MBeaconInfoEventContent = &
|
||||
/**
|
||||
* m.beacon event example
|
||||
* https://github.com/matrix-org/matrix-spec-proposals/pull/3672
|
||||
*
|
||||
* @example
|
||||
* ```
|
||||
* {
|
||||
"type": "m.beacon",
|
||||
"sender": "@matthew:matrix.org",
|
||||
"content": {
|
||||
"m.relates_to": { // from MSC2674: https://github.com/matrix-org/matrix-doc/pull/2674
|
||||
"rel_type": "m.reference", // from MSC3267: https://github.com/matrix-org/matrix-doc/pull/3267
|
||||
"event_id": "$beacon_info"
|
||||
},
|
||||
"m.location": {
|
||||
"uri": "geo:51.5008,0.1247;u=35",
|
||||
"description": "Arbitrary beacon information"
|
||||
},
|
||||
"m.ts": 1636829458432,
|
||||
}
|
||||
}
|
||||
* "type": "m.beacon",
|
||||
* "sender": "@matthew:matrix.org",
|
||||
* "content": {
|
||||
* "m.relates_to": { // from MSC2674: https://github.com/matrix-org/matrix-doc/pull/2674
|
||||
* "rel_type": "m.reference", // from MSC3267: https://github.com/matrix-org/matrix-doc/pull/3267
|
||||
* "event_id": "$beacon_info"
|
||||
* },
|
||||
* "m.location": {
|
||||
* "uri": "geo:51.5008,0.1247;u=35",
|
||||
* "description": "Arbitrary beacon information"
|
||||
* },
|
||||
* "m.ts": 1636829458432,
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -171,17 +171,21 @@ export const UNSTABLE_MSC2716_MARKER = new UnstableValue("m.room.marker", "org.m
|
||||
* eventual removal.
|
||||
*
|
||||
* Schema (TypeScript):
|
||||
* ```
|
||||
* {
|
||||
* service_members?: string[]
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* Example:
|
||||
* @example
|
||||
* ```
|
||||
* {
|
||||
* "service_members": [
|
||||
* "@helperbot:localhost",
|
||||
* "@reminderbot:alice.tdl"
|
||||
* ]
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export const UNSTABLE_ELEMENT_FUNCTIONAL_USERS = new UnstableValue(
|
||||
"io.element.functional_members",
|
||||
|
@ -54,17 +54,31 @@ export interface ISendEventResponse {
|
||||
}
|
||||
|
||||
export interface IPresenceOpts {
|
||||
// One of "online", "offline" or "unavailable"
|
||||
presence: "online" | "offline" | "unavailable";
|
||||
// The status message to attach.
|
||||
status_msg?: string;
|
||||
}
|
||||
|
||||
export interface IPaginateOpts {
|
||||
// true to fill backwards, false to go forwards
|
||||
backwards?: boolean;
|
||||
// number of events to request
|
||||
limit?: number;
|
||||
}
|
||||
|
||||
export interface IGuestAccessOpts {
|
||||
/**
|
||||
* True to allow guests to join this room. This
|
||||
* implicitly gives guests write access. If false or not given, guests are
|
||||
* explicitly forbidden from joining the room.
|
||||
*/
|
||||
allowJoin: boolean;
|
||||
/**
|
||||
* True to set history visibility to
|
||||
* be world_readable. This gives guests read access *from this point forward*.
|
||||
* If false or not given, history visibility is not modified.
|
||||
*/
|
||||
allowRead: boolean;
|
||||
}
|
||||
|
||||
@ -74,7 +88,9 @@ export interface ISearchOpts {
|
||||
}
|
||||
|
||||
export interface IEventSearchOpts {
|
||||
// a JSON filter object to pass in the request
|
||||
filter?: IRoomEventFilter;
|
||||
// the term to search for
|
||||
term: string;
|
||||
}
|
||||
|
||||
@ -92,9 +108,13 @@ export interface ICreateRoomStateEvent {
|
||||
}
|
||||
|
||||
export interface ICreateRoomOpts {
|
||||
// The alias localpart to assign to this room.
|
||||
room_alias_name?: string;
|
||||
// Either 'public' or 'private'.
|
||||
visibility?: Visibility;
|
||||
// The name to give this room.
|
||||
name?: string;
|
||||
// The topic to give this room.
|
||||
topic?: string;
|
||||
preset?: Preset;
|
||||
power_level_content_override?: {
|
||||
@ -111,6 +131,7 @@ export interface ICreateRoomOpts {
|
||||
};
|
||||
creation_content?: object;
|
||||
initial_state?: ICreateRoomStateEvent[];
|
||||
// A list of user IDs to invite to this room.
|
||||
invite?: string[];
|
||||
invite_3pid?: IInvite3PID[];
|
||||
is_direct?: boolean;
|
||||
@ -121,7 +142,10 @@ export interface IRoomDirectoryOptions {
|
||||
server?: string;
|
||||
limit?: number;
|
||||
since?: string;
|
||||
|
||||
// Filter parameters
|
||||
filter?: {
|
||||
// String to search for
|
||||
generic_search_term?: string;
|
||||
room_types?: Array<RoomType | null>;
|
||||
};
|
||||
|
@ -21,10 +21,9 @@ import { UnstableValue } from "../NamespacedValue";
|
||||
/**
|
||||
* Extensible topic event type based on MSC3765
|
||||
* https://github.com/matrix-org/matrix-spec-proposals/pull/3765
|
||||
*/
|
||||
|
||||
/**
|
||||
* Eg
|
||||
*
|
||||
* @example
|
||||
* ```
|
||||
* {
|
||||
* "type": "m.room.topic,
|
||||
* "state_key": "",
|
||||
@ -39,6 +38,7 @@ import { UnstableValue } from "../NamespacedValue";
|
||||
* }],
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -15,8 +15,6 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/** @module auto-discovery */
|
||||
|
||||
import { IClientWellKnown, IWellKnownConfig } from "./client";
|
||||
import { logger } from './logger';
|
||||
import { MatrixError, Method, timeoutSignal } from "./http-api";
|
||||
@ -87,8 +85,6 @@ export class AutoDiscovery {
|
||||
/**
|
||||
* The auto discovery failed. The client is expected to communicate
|
||||
* the error to the user and refuse logging in.
|
||||
* @return {string}
|
||||
* @constructor
|
||||
*/
|
||||
public static readonly FAIL_ERROR = AutoDiscoveryAction.FAIL_ERROR;
|
||||
|
||||
@ -98,8 +94,6 @@ export class AutoDiscovery {
|
||||
* action it would for PROMPT while also warning the user about
|
||||
* what went wrong. The client may also treat this the same as
|
||||
* a FAIL_ERROR state.
|
||||
* @return {string}
|
||||
* @constructor
|
||||
*/
|
||||
public static readonly FAIL_PROMPT = AutoDiscoveryAction.FAIL_PROMPT;
|
||||
|
||||
@ -107,15 +101,11 @@ export class AutoDiscovery {
|
||||
* The auto discovery didn't fail but did not find anything of
|
||||
* interest. The client is expected to prompt the user for more
|
||||
* information, or fail if it prefers.
|
||||
* @return {string}
|
||||
* @constructor
|
||||
*/
|
||||
public static readonly PROMPT = AutoDiscoveryAction.PROMPT;
|
||||
|
||||
/**
|
||||
* The auto discovery was successful.
|
||||
* @return {string}
|
||||
* @constructor
|
||||
*/
|
||||
public static readonly SUCCESS = AutoDiscoveryAction.SUCCESS;
|
||||
|
||||
@ -125,9 +115,9 @@ export class AutoDiscovery {
|
||||
* and identity server URL the client would want. Additional details
|
||||
* may also be included, and will be transparently brought into the
|
||||
* response object unaltered.
|
||||
* @param {object} wellknown The configuration object itself, as returned
|
||||
* @param wellknown - The configuration object itself, as returned
|
||||
* by the .well-known auto-discovery endpoint.
|
||||
* @return {Promise<DiscoveredClientConfig>} Resolves to the verified
|
||||
* @returns Promise which resolves to the verified
|
||||
* configuration, which may include error states. Rejects on unexpected
|
||||
* failure, not when verification fails.
|
||||
*/
|
||||
@ -284,9 +274,9 @@ export class AutoDiscovery {
|
||||
* and identity server URL the client would want. Additional details
|
||||
* may also be discovered, and will be transparently included in the
|
||||
* response object unaltered.
|
||||
* @param {string} domain The homeserver domain to perform discovery
|
||||
* @param domain - The homeserver domain to perform discovery
|
||||
* on. For example, "matrix.org".
|
||||
* @return {Promise<DiscoveredClientConfig>} Resolves to the discovered
|
||||
* @returns Promise which resolves to the discovered
|
||||
* configuration, which may include error states. Rejects on unexpected
|
||||
* failure, not when discovery fails.
|
||||
*/
|
||||
@ -354,8 +344,8 @@ export class AutoDiscovery {
|
||||
* Gets the raw discovery client configuration for the given domain name.
|
||||
* Should only be used if there's no validation to be done on the resulting
|
||||
* object, otherwise use findClientConfig().
|
||||
* @param {string} domain The domain to get the client config for.
|
||||
* @returns {Promise<object>} Resolves to the domain's client config. Can
|
||||
* @param domain - The domain to get the client config for.
|
||||
* @returns Promise which resolves to the domain's client config. Can
|
||||
* be an empty object.
|
||||
*/
|
||||
public static async getRawClientConfig(domain?: string): Promise<IClientWellKnown> {
|
||||
@ -374,9 +364,9 @@ export class AutoDiscovery {
|
||||
* Sanitizes a given URL to ensure it is either an HTTP or HTTP URL and
|
||||
* is suitable for the requirements laid out by .well-known auto discovery.
|
||||
* If valid, the URL will also be stripped of any trailing slashes.
|
||||
* @param {string} url The potentially invalid URL to sanitize.
|
||||
* @return {string|boolean} The sanitized URL or a falsey value if the URL is invalid.
|
||||
* @private
|
||||
* @param url - The potentially invalid URL to sanitize.
|
||||
* @returns The sanitized URL or a falsey value if the URL is invalid.
|
||||
* @internal
|
||||
*/
|
||||
private static sanitizeWellKnownUrl(url?: string | null): string | false {
|
||||
if (!url) return false;
|
||||
@ -430,9 +420,9 @@ export class AutoDiscovery {
|
||||
* action: One of SUCCESS, IGNORE, or FAIL_PROMPT.
|
||||
* reason: Relatively human-readable description of what went wrong.
|
||||
* error: The actual Error, if one exists.
|
||||
* @param {string} url The URL to fetch a JSON object from.
|
||||
* @return {Promise<object>} Resolves to the returned state.
|
||||
* @private
|
||||
* @param url - The URL to fetch a JSON object from.
|
||||
* @returns Promise which resolves to the returned state.
|
||||
* @internal
|
||||
*/
|
||||
private static async fetchWellKnownObject(url: string): Promise<IWellKnownConfig> {
|
||||
let response: Response;
|
||||
|
2369
src/client.ts
2369
src/client.ts
File diff suppressed because it is too large
Load Diff
@ -14,8 +14,6 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/** @module ContentHelpers */
|
||||
|
||||
import { isProvided, REFERENCE_RELATION } from "matrix-events-sdk";
|
||||
|
||||
import { MBeaconEventContent, MBeaconInfoContent, MBeaconInfoEventContent } from "./@types/beacon";
|
||||
@ -37,9 +35,9 @@ import { IContent } from "./models/event";
|
||||
|
||||
/**
|
||||
* Generates the content for a HTML Message event
|
||||
* @param {string} body the plaintext body of the message
|
||||
* @param {string} htmlBody the HTML representation of the message
|
||||
* @returns {{msgtype: string, format: string, body: string, formatted_body: string}}
|
||||
* @param body - the plaintext body of the message
|
||||
* @param htmlBody - the HTML representation of the message
|
||||
* @returns
|
||||
*/
|
||||
export function makeHtmlMessage(body: string, htmlBody: string): IContent {
|
||||
return {
|
||||
@ -52,9 +50,9 @@ export function makeHtmlMessage(body: string, htmlBody: string): IContent {
|
||||
|
||||
/**
|
||||
* Generates the content for a HTML Notice event
|
||||
* @param {string} body the plaintext body of the notice
|
||||
* @param {string} htmlBody the HTML representation of the notice
|
||||
* @returns {{msgtype: string, format: string, body: string, formatted_body: string}}
|
||||
* @param body - the plaintext body of the notice
|
||||
* @param htmlBody - the HTML representation of the notice
|
||||
* @returns
|
||||
*/
|
||||
export function makeHtmlNotice(body: string, htmlBody: string): IContent {
|
||||
return {
|
||||
@ -67,9 +65,9 @@ export function makeHtmlNotice(body: string, htmlBody: string): IContent {
|
||||
|
||||
/**
|
||||
* Generates the content for a HTML Emote event
|
||||
* @param {string} body the plaintext body of the emote
|
||||
* @param {string} htmlBody the HTML representation of the emote
|
||||
* @returns {{msgtype: string, format: string, body: string, formatted_body: string}}
|
||||
* @param body - the plaintext body of the emote
|
||||
* @param htmlBody - the HTML representation of the emote
|
||||
* @returns
|
||||
*/
|
||||
export function makeHtmlEmote(body: string, htmlBody: string): IContent {
|
||||
return {
|
||||
@ -82,8 +80,8 @@ export function makeHtmlEmote(body: string, htmlBody: string): IContent {
|
||||
|
||||
/**
|
||||
* Generates the content for a Plaintext Message event
|
||||
* @param {string} body the plaintext body of the emote
|
||||
* @returns {{msgtype: string, body: string}}
|
||||
* @param body - the plaintext body of the emote
|
||||
* @returns
|
||||
*/
|
||||
export function makeTextMessage(body: string): IContent {
|
||||
return {
|
||||
@ -94,8 +92,8 @@ export function makeTextMessage(body: string): IContent {
|
||||
|
||||
/**
|
||||
* Generates the content for a Plaintext Notice event
|
||||
* @param {string} body the plaintext body of the notice
|
||||
* @returns {{msgtype: string, body: string}}
|
||||
* @param body - the plaintext body of the notice
|
||||
* @returns
|
||||
*/
|
||||
export function makeNotice(body: string): IContent {
|
||||
return {
|
||||
@ -106,8 +104,8 @@ export function makeNotice(body: string): IContent {
|
||||
|
||||
/**
|
||||
* Generates the content for a Plaintext Emote event
|
||||
* @param {string} body the plaintext body of the emote
|
||||
* @returns {{msgtype: string, body: string}}
|
||||
* @param body - the plaintext body of the emote
|
||||
* @returns
|
||||
*/
|
||||
export function makeEmoteMessage(body: string): IContent {
|
||||
return {
|
||||
@ -139,11 +137,11 @@ export const getTextForLocationEvent = (
|
||||
|
||||
/**
|
||||
* Generates the content for a Location event
|
||||
* @param uri a geo:// uri for the location
|
||||
* @param timestamp the timestamp when the location was correct (milliseconds since the UNIX epoch)
|
||||
* @param description the (optional) label for this location on the map
|
||||
* @param assetType the (optional) asset type of this location e.g. "m.self"
|
||||
* @param text optional. A text for the location
|
||||
* @param uri - a geo:// uri for the location
|
||||
* @param timestamp - the timestamp when the location was correct (milliseconds since the UNIX epoch)
|
||||
* @param description - the (optional) label for this location on the map
|
||||
* @param assetType - the (optional) asset type of this location e.g. "m.self"
|
||||
* @param text - optional. A text for the location
|
||||
*/
|
||||
export const makeLocationContent = (
|
||||
// this is first but optional
|
||||
|
@ -13,25 +13,22 @@ 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.
|
||||
*/
|
||||
/**
|
||||
* @module content-repo
|
||||
*/
|
||||
|
||||
import * as utils from "./utils";
|
||||
|
||||
/**
|
||||
* Get the HTTP URL for an MXC URI.
|
||||
* @param {string} baseUrl The base homeserver url which has a content repo.
|
||||
* @param {string} mxc The mxc:// URI.
|
||||
* @param {Number} width The desired width of the thumbnail.
|
||||
* @param {Number} height The desired height of the thumbnail.
|
||||
* @param {string} resizeMethod The thumbnail resize method to use, either
|
||||
* @param baseUrl - The base homeserver url which has a content repo.
|
||||
* @param mxc - The mxc:// URI.
|
||||
* @param width - The desired width of the thumbnail.
|
||||
* @param height - The desired height of the thumbnail.
|
||||
* @param resizeMethod - The thumbnail resize method to use, either
|
||||
* "crop" or "scale".
|
||||
* @param {Boolean} allowDirectLinks If true, return any non-mxc URLs
|
||||
* @param allowDirectLinks - If true, return any non-mxc URLs
|
||||
* directly. Fetching such URLs will leak information about the user to
|
||||
* anyone they share a room with. If false, will return the emptry string
|
||||
* for such URLs.
|
||||
* @return {string} The complete URL to the content.
|
||||
* @returns The complete URL to the content.
|
||||
*/
|
||||
export function getHttpUriForMxc(
|
||||
baseUrl: string,
|
||||
|
@ -16,7 +16,6 @@ limitations under the License.
|
||||
|
||||
/**
|
||||
* Cross signing methods
|
||||
* @module crypto/CrossSigning
|
||||
*/
|
||||
|
||||
import { PkSigning } from "@matrix-org/olm";
|
||||
@ -67,12 +66,10 @@ export class CrossSigningInfo {
|
||||
/**
|
||||
* Information about a user's cross-signing keys
|
||||
*
|
||||
* @class
|
||||
*
|
||||
* @param {string} userId the user that the information is about
|
||||
* @param {object} callbacks Callbacks used to interact with the app
|
||||
* @param userId - the user that the information is about
|
||||
* @param callbacks - Callbacks used to interact with the app
|
||||
* Requires getCrossSigningKey and saveCrossSigningKeys
|
||||
* @param {object} cacheCallbacks Callbacks used to interact with the cache
|
||||
* @param cacheCallbacks - Callbacks used to interact with the cache
|
||||
*/
|
||||
public constructor(
|
||||
public readonly userId: string,
|
||||
@ -102,10 +99,10 @@ export class CrossSigningInfo {
|
||||
/**
|
||||
* Calls the app callback to ask for a private key
|
||||
*
|
||||
* @param {string} type The key type ("master", "self_signing", or "user_signing")
|
||||
* @param {string} expectedPubkey The matching public key or undefined to use
|
||||
* @param type - The key type ("master", "self_signing", or "user_signing")
|
||||
* @param expectedPubkey - The matching public key or undefined to use
|
||||
* the stored public key for the given key type.
|
||||
* @returns {Array} An array with [ public key, Olm.PkSigning ]
|
||||
* @returns An array with [ public key, Olm.PkSigning ]
|
||||
*/
|
||||
public async getCrossSigningKey(type: string, expectedPubkey?: string): Promise<[string, PkSigning]> {
|
||||
const shouldCache = ["master", "self_signing", "user_signing"].indexOf(type) >= 0;
|
||||
@ -165,8 +162,8 @@ export class CrossSigningInfo {
|
||||
* XXX: This could be static, be we often seem to have an instance when we
|
||||
* want to know this anyway...
|
||||
*
|
||||
* @param {SecretStorage} secretStorage The secret store using account data
|
||||
* @returns {object} map of key name to key info the secret is encrypted
|
||||
* @param secretStorage - The secret store using account data
|
||||
* @returns map of key name to key info the secret is encrypted
|
||||
* with, or null if it is not present or not encrypted with a trusted
|
||||
* key
|
||||
*/
|
||||
@ -194,8 +191,8 @@ export class CrossSigningInfo {
|
||||
* typically called in conjunction with the creation of new cross-signing
|
||||
* keys.
|
||||
*
|
||||
* @param {Map} keys The keys to store
|
||||
* @param {SecretStorage} secretStorage The secret store using account data
|
||||
* @param keys - The keys to store
|
||||
* @param secretStorage - The secret store using account data
|
||||
*/
|
||||
public static async storeInSecretStorage(
|
||||
keys: Map<string, Uint8Array>,
|
||||
@ -211,10 +208,10 @@ export class CrossSigningInfo {
|
||||
* Get private keys from secret storage created by some other device. This
|
||||
* also passes the private keys to the app-specific callback.
|
||||
*
|
||||
* @param {string} type The type of key to get. One of "master",
|
||||
* @param type - The type of key to get. One of "master",
|
||||
* "self_signing", or "user_signing".
|
||||
* @param {SecretStorage} secretStorage The secret store using account data
|
||||
* @return {Uint8Array} The private key
|
||||
* @param secretStorage - The secret store using account data
|
||||
* @returns The private key
|
||||
*/
|
||||
public static async getFromSecretStorage(type: string, secretStorage: SecretStorage): Promise<Uint8Array | null> {
|
||||
const encodedKey = await secretStorage.get(`m.cross_signing.${type}`);
|
||||
@ -227,9 +224,9 @@ export class CrossSigningInfo {
|
||||
/**
|
||||
* Check whether the private keys exist in the local key cache.
|
||||
*
|
||||
* @param {string} [type] The type of key to get. One of "master",
|
||||
* @param type - The type of key to get. One of "master",
|
||||
* "self_signing", or "user_signing". Optional, will check all by default.
|
||||
* @returns {boolean} True if all keys are stored in the local cache.
|
||||
* @returns True if all keys are stored in the local cache.
|
||||
*/
|
||||
public async isStoredInKeyCache(type?: string): Promise<boolean> {
|
||||
const cacheCallbacks = this.cacheCallbacks;
|
||||
@ -246,7 +243,7 @@ export class CrossSigningInfo {
|
||||
/**
|
||||
* Get cross-signing private keys from the local cache.
|
||||
*
|
||||
* @returns {Map} A map from key type (string) to private key (Uint8Array)
|
||||
* @returns A map from key type (string) to private key (Uint8Array)
|
||||
*/
|
||||
public async getCrossSigningKeysFromCache(): Promise<Map<string, Uint8Array>> {
|
||||
const keys = new Map();
|
||||
@ -266,10 +263,10 @@ export class CrossSigningInfo {
|
||||
* Get the ID used to identify the user. This can also be used to test for
|
||||
* the existence of a given key type.
|
||||
*
|
||||
* @param {string} type The type of key to get the ID of. One of "master",
|
||||
* @param type - The type of key to get the ID of. One of "master",
|
||||
* "self_signing", or "user_signing". Defaults to "master".
|
||||
*
|
||||
* @return {string} the ID
|
||||
* @returns the ID
|
||||
*/
|
||||
public getId(type = "master"): string | null {
|
||||
if (!this.keys[type]) return null;
|
||||
@ -282,7 +279,7 @@ export class CrossSigningInfo {
|
||||
* will be held in this class, while the private keys are passed off to the
|
||||
* `saveCrossSigningKeys` application callback.
|
||||
*
|
||||
* @param {CrossSigningLevel} level The key types to reset
|
||||
* @param level - The key types to reset
|
||||
*/
|
||||
public async resetKeys(level?: CrossSigningLevel): Promise<void> {
|
||||
if (!this.callbacks.saveCrossSigningKeys) {
|
||||
@ -502,9 +499,9 @@ export class CrossSigningInfo {
|
||||
/**
|
||||
* Check whether a given user is trusted.
|
||||
*
|
||||
* @param {CrossSigningInfo} userCrossSigning Cross signing info for user
|
||||
* @param userCrossSigning - Cross signing info for user
|
||||
*
|
||||
* @returns {UserTrustLevel}
|
||||
* @returns
|
||||
*/
|
||||
public checkUserTrust(userCrossSigning: CrossSigningInfo): UserTrustLevel {
|
||||
// if we're checking our own key, then it's trusted if the master key
|
||||
@ -542,12 +539,12 @@ export class CrossSigningInfo {
|
||||
/**
|
||||
* Check whether a given device is trusted.
|
||||
*
|
||||
* @param {CrossSigningInfo} userCrossSigning Cross signing info for user
|
||||
* @param {module:crypto/deviceinfo} device The device to check
|
||||
* @param {boolean} localTrust Whether the device is trusted locally
|
||||
* @param {boolean} trustCrossSignedDevices Whether we trust cross signed devices
|
||||
* @param userCrossSigning - Cross signing info for user
|
||||
* @param device - The device to check
|
||||
* @param localTrust - Whether the device is trusted locally
|
||||
* @param trustCrossSignedDevices - Whether we trust cross signed devices
|
||||
*
|
||||
* @returns {DeviceTrustLevel}
|
||||
* @returns
|
||||
*/
|
||||
public checkDeviceTrust(
|
||||
userCrossSigning: CrossSigningInfo,
|
||||
@ -580,7 +577,7 @@ export class CrossSigningInfo {
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {object} Cache callbacks
|
||||
* @returns Cache callbacks
|
||||
*/
|
||||
public getCacheCallbacks(): ICacheCallbacks {
|
||||
return this.cacheCallbacks;
|
||||
@ -621,21 +618,21 @@ export class UserTrustLevel {
|
||||
) {}
|
||||
|
||||
/**
|
||||
* @returns {boolean} true if this user is verified via any means
|
||||
* @returns true if this user is verified via any means
|
||||
*/
|
||||
public isVerified(): boolean {
|
||||
return this.isCrossSigningVerified();
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {boolean} true if this user is verified via cross signing
|
||||
* @returns true if this user is verified via cross signing
|
||||
*/
|
||||
public isCrossSigningVerified(): boolean {
|
||||
return this.crossSigningVerified;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {boolean} true if we ever verified this user before (at least for
|
||||
* @returns true if we ever verified this user before (at least for
|
||||
* the history of verifications observed by this device).
|
||||
*/
|
||||
public wasCrossSigningVerified(): boolean {
|
||||
@ -643,7 +640,7 @@ export class UserTrustLevel {
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {boolean} true if this user's key is trusted on first use
|
||||
* @returns true if this user's key is trusted on first use
|
||||
*/
|
||||
public isTofu(): boolean {
|
||||
return this.tofu;
|
||||
@ -675,7 +672,7 @@ export class DeviceTrustLevel {
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {boolean} true if this device is verified via any means
|
||||
* @returns true if this device is verified via any means
|
||||
*/
|
||||
public isVerified(): boolean {
|
||||
return Boolean(this.isLocallyVerified() || (
|
||||
@ -684,21 +681,21 @@ export class DeviceTrustLevel {
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {boolean} true if this device is verified via cross signing
|
||||
* @returns true if this device is verified via cross signing
|
||||
*/
|
||||
public isCrossSigningVerified(): boolean {
|
||||
return this.crossSigningVerified;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {boolean} true if this device is verified locally
|
||||
* @returns true if this device is verified locally
|
||||
*/
|
||||
public isLocallyVerified(): boolean {
|
||||
return this.localVerified;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {boolean} true if this device is trusted from a user's key
|
||||
* @returns true if this device is trusted from a user's key
|
||||
* that is trusted on first use
|
||||
*/
|
||||
public isTofu(): boolean {
|
||||
@ -757,9 +754,9 @@ export type KeysDuringVerification = [[string, PkSigning], [string, PkSigning],
|
||||
/**
|
||||
* Request cross-signing keys from another device during verification.
|
||||
*
|
||||
* @param {MatrixClient} baseApis base Matrix API interface
|
||||
* @param {string} userId The user ID being verified
|
||||
* @param {string} deviceId The device ID being verified
|
||||
* @param baseApis - base Matrix API interface
|
||||
* @param userId - The user ID being verified
|
||||
* @param deviceId - The device ID being verified
|
||||
*/
|
||||
export async function requestKeysDuringVerification(
|
||||
baseApis: MatrixClient,
|
||||
|
@ -15,8 +15,6 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @module crypto/DeviceList
|
||||
*
|
||||
* Manages the list of other users' devices
|
||||
*/
|
||||
|
||||
@ -64,9 +62,6 @@ export type DeviceInfoMap = Record<string, Record<string, DeviceInfo>>;
|
||||
|
||||
type EmittedEvents = CryptoEvent.WillUpdateDevices | CryptoEvent.DevicesUpdated | CryptoEvent.UserCrossSigningUpdated;
|
||||
|
||||
/**
|
||||
* @alias module:crypto/DeviceList
|
||||
*/
|
||||
export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHandlerMap> {
|
||||
private devices: { [userId: string]: { [deviceId: string]: IDevice } } = {};
|
||||
|
||||
@ -163,11 +158,11 @@ export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHand
|
||||
* The actual save will be delayed by a short amount of time to
|
||||
* aggregate multiple writes to the database.
|
||||
*
|
||||
* @param {number} delay Time in ms before which the save actually happens.
|
||||
* @param delay - Time in ms before which the save actually happens.
|
||||
* By default, the save is delayed for a short period in order to batch
|
||||
* multiple writes, but this behaviour can be disabled by passing 0.
|
||||
*
|
||||
* @return {Promise<boolean>} true if the data was saved, false if
|
||||
* @returns true if the data was saved, false if
|
||||
* it was not (eg. because no changes were pending). The promise
|
||||
* will only resolve once the data is saved, so may take some time
|
||||
* to resolve.
|
||||
@ -236,7 +231,7 @@ export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHand
|
||||
/**
|
||||
* Gets the sync token last set with setSyncToken
|
||||
*
|
||||
* @return {string} The sync token
|
||||
* @returns The sync token
|
||||
*/
|
||||
public getSyncToken(): string | null {
|
||||
return this.syncToken;
|
||||
@ -250,7 +245,7 @@ export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHand
|
||||
* those changed will not be synced from the server if a new client starts
|
||||
* up with that data.
|
||||
*
|
||||
* @param {string} st The sync token
|
||||
* @param st - The sync token
|
||||
*/
|
||||
public setSyncToken(st: string | null): void {
|
||||
this.syncToken = st;
|
||||
@ -260,11 +255,10 @@ export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHand
|
||||
* Ensures up to date keys for a list of users are stored in the session store,
|
||||
* downloading and storing them if they're not (or if forceDownload is
|
||||
* true).
|
||||
* @param {Array} userIds The users to fetch.
|
||||
* @param {boolean} forceDownload Always download the keys even if cached.
|
||||
* @param userIds - The users to fetch.
|
||||
* @param forceDownload - Always download the keys even if cached.
|
||||
*
|
||||
* @return {Promise} A promise which resolves to a map userId->deviceId->{@link
|
||||
* module:crypto/deviceinfo|DeviceInfo}.
|
||||
* @returns A promise which resolves to a map userId-\>deviceId-\>{@link DeviceInfo}.
|
||||
*/
|
||||
public downloadKeys(userIds: string[], forceDownload: boolean): Promise<DeviceInfoMap> {
|
||||
const usersToDownload: string[] = [];
|
||||
@ -303,9 +297,9 @@ export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHand
|
||||
/**
|
||||
* Get the stored device keys for a list of user ids
|
||||
*
|
||||
* @param {string[]} userIds the list of users to list keys for.
|
||||
* @param userIds - the list of users to list keys for.
|
||||
*
|
||||
* @return {Object} userId->deviceId->{@link module:crypto/deviceinfo|DeviceInfo}.
|
||||
* @returns userId-\>deviceId-\>{@link DeviceInfo}.
|
||||
*/
|
||||
private getDevicesFromStore(userIds: string[]): DeviceInfoMap {
|
||||
const stored: DeviceInfoMap = {};
|
||||
@ -322,7 +316,7 @@ export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHand
|
||||
/**
|
||||
* Returns a list of all user IDs the DeviceList knows about
|
||||
*
|
||||
* @return {array} All known user IDs
|
||||
* @returns All known user IDs
|
||||
*/
|
||||
public getKnownUserIds(): string[] {
|
||||
return Object.keys(this.devices);
|
||||
@ -331,9 +325,9 @@ export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHand
|
||||
/**
|
||||
* Get the stored device keys for a user id
|
||||
*
|
||||
* @param {string} userId the user to list keys for.
|
||||
* @param userId - the user to list keys for.
|
||||
*
|
||||
* @return {module:crypto/deviceinfo[]|null} list of devices, or null if we haven't
|
||||
* @returns list of devices, or null if we haven't
|
||||
* managed to get a list of devices for this user yet.
|
||||
*/
|
||||
public getStoredDevicesForUser(userId: string): DeviceInfo[] | null {
|
||||
@ -353,9 +347,9 @@ export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHand
|
||||
/**
|
||||
* Get the stored device data for a user, in raw object form
|
||||
*
|
||||
* @param {string} userId the user to get data for
|
||||
* @param userId - the user to get data for
|
||||
*
|
||||
* @return {Object} deviceId->{object} devices, or undefined if
|
||||
* @returns `deviceId->{object}` devices, or undefined if
|
||||
* there is no data for this user.
|
||||
*/
|
||||
public getRawStoredDevicesForUser(userId: string): Record<string, IDevice> {
|
||||
@ -376,10 +370,8 @@ export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHand
|
||||
/**
|
||||
* Get the stored keys for a single device
|
||||
*
|
||||
* @param {string} userId
|
||||
* @param {string} deviceId
|
||||
*
|
||||
* @return {module:crypto/deviceinfo?} device, or undefined
|
||||
* @returns device, or undefined
|
||||
* if we don't know about this device
|
||||
*/
|
||||
public getStoredDevice(userId: string, deviceId: string): DeviceInfo | undefined {
|
||||
@ -393,10 +385,10 @@ export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHand
|
||||
/**
|
||||
* Get a user ID by one of their device's curve25519 identity key
|
||||
*
|
||||
* @param {string} algorithm encryption algorithm
|
||||
* @param {string} senderKey curve25519 key to match
|
||||
* @param algorithm - encryption algorithm
|
||||
* @param senderKey - curve25519 key to match
|
||||
*
|
||||
* @return {string} user ID
|
||||
* @returns user ID
|
||||
*/
|
||||
public getUserByIdentityKey(algorithm: string, senderKey: string): string | null {
|
||||
if (algorithm !== olmlib.OLM_ALGORITHM && algorithm !== olmlib.MEGOLM_ALGORITHM) {
|
||||
@ -410,10 +402,8 @@ export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHand
|
||||
/**
|
||||
* Find a device by curve25519 identity key
|
||||
*
|
||||
* @param {string} algorithm encryption algorithm
|
||||
* @param {string} senderKey curve25519 key to match
|
||||
*
|
||||
* @return {module:crypto/deviceinfo?}
|
||||
* @param algorithm - encryption algorithm
|
||||
* @param senderKey - curve25519 key to match
|
||||
*/
|
||||
public getDeviceByIdentityKey(algorithm: string, senderKey: string): DeviceInfo | null {
|
||||
const userId = this.getUserByIdentityKey(algorithm, senderKey);
|
||||
@ -453,8 +443,8 @@ export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHand
|
||||
/**
|
||||
* Replaces the list of devices for a user with the given device list
|
||||
*
|
||||
* @param {string} userId The user ID
|
||||
* @param {Object} devices New device info for user
|
||||
* @param userId - The user ID
|
||||
* @param devices - New device info for user
|
||||
*/
|
||||
public storeDevicesForUser(userId: string, devices: Record<string, IDevice>): void {
|
||||
this.setRawStoredDevicesForUser(userId, devices);
|
||||
@ -468,7 +458,6 @@ export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHand
|
||||
* will download the device list for the user, and that subsequent calls to
|
||||
* invalidateUserDeviceList will trigger more updates.
|
||||
*
|
||||
* @param {String} userId
|
||||
*/
|
||||
public startTrackingDeviceList(userId: string): void {
|
||||
// sanity-check the userId. This is mostly paranoia, but if synapse
|
||||
@ -497,7 +486,6 @@ export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHand
|
||||
* complete; it will just mean that we don't think that we have an up-to-date
|
||||
* list for future calls to downloadKeys.
|
||||
*
|
||||
* @param {String} userId
|
||||
*/
|
||||
public stopTrackingDeviceList(userId: string): void {
|
||||
if (this.deviceTrackingStatus[userId]) {
|
||||
@ -532,7 +520,6 @@ export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHand
|
||||
* This doesn't actually set off an update, so that several users can be
|
||||
* batched together. Call refreshOutdatedDeviceLists() for that.
|
||||
*
|
||||
* @param {String} userId
|
||||
*/
|
||||
public invalidateUserDeviceList(userId: string): void {
|
||||
if (this.deviceTrackingStatus[userId]) {
|
||||
@ -548,7 +535,7 @@ export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHand
|
||||
/**
|
||||
* If we have users who have outdated device lists, start key downloads for them
|
||||
*
|
||||
* @returns {Promise} which completes when the download completes; normally there
|
||||
* @returns which completes when the download completes; normally there
|
||||
* is no need to wait for this (it's mostly for the unit tests).
|
||||
*/
|
||||
public refreshOutdatedDeviceLists(): Promise<void> {
|
||||
@ -569,9 +556,9 @@ export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHand
|
||||
* Set the stored device data for a user, in raw object form
|
||||
* Used only by internal class DeviceListUpdateSerialiser
|
||||
*
|
||||
* @param {string} userId the user to get data for
|
||||
* @param userId - the user to get data for
|
||||
*
|
||||
* @param {Object} devices deviceId->{object} the new devices
|
||||
* @param devices - `deviceId->{object}` the new devices
|
||||
*/
|
||||
public setRawStoredDevicesForUser(userId: string, devices: Record<string, IDevice>): void {
|
||||
// remove old devices from userByIdentityKey
|
||||
@ -602,9 +589,9 @@ export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHand
|
||||
* device list tracking status for them, and the
|
||||
* keyDownloadsInProgressByUser map for them.
|
||||
*
|
||||
* @param {String[]} users list of userIds
|
||||
* @param users - list of userIds
|
||||
*
|
||||
* @return {Promise} resolves when all the users listed have
|
||||
* @returns resolves when all the users listed have
|
||||
* been updated. rejects if there was a problem updating any of the
|
||||
* users.
|
||||
*/
|
||||
@ -689,9 +676,9 @@ class DeviceListUpdateSerialiser {
|
||||
private syncToken?: string; // The sync token we send with the requests
|
||||
|
||||
/*
|
||||
* @param {object} baseApis Base API object
|
||||
* @param {object} olmDevice The Olm Device
|
||||
* @param {object} deviceList The device list object, the device list to be updated
|
||||
* @param baseApis - Base API object
|
||||
* @param olmDevice - The Olm Device
|
||||
* @param deviceList - The device list object, the device list to be updated
|
||||
*/
|
||||
public constructor(
|
||||
private readonly baseApis: MatrixClient,
|
||||
@ -702,12 +689,12 @@ class DeviceListUpdateSerialiser {
|
||||
/**
|
||||
* Make a key query request for the given users
|
||||
*
|
||||
* @param {String[]} users list of user ids
|
||||
* @param users - list of user ids
|
||||
*
|
||||
* @param {String} syncToken sync token to pass in the query request, to
|
||||
* @param syncToken - sync token to pass in the query request, to
|
||||
* help the HS give the most recent results
|
||||
*
|
||||
* @return {Promise} resolves when all the users listed have
|
||||
* @returns resolves when all the users listed have
|
||||
* been updated. rejects if there was a problem updating any of the
|
||||
* users.
|
||||
*/
|
||||
|
@ -58,8 +58,8 @@ export class EncryptionSetupBuilder {
|
||||
private sessionBackupPrivateKey?: Uint8Array;
|
||||
|
||||
/**
|
||||
* @param {Object.<String, MatrixEvent>} accountData pre-existing account data, will only be read, not written.
|
||||
* @param {CryptoCallbacks} delegateCryptoCallbacks crypto callbacks to delegate to if the key isn't in cache yet
|
||||
* @param accountData - pre-existing account data, will only be read, not written.
|
||||
* @param delegateCryptoCallbacks - crypto callbacks to delegate to if the key isn't in cache yet
|
||||
*/
|
||||
public constructor(accountData: Record<string, MatrixEvent>, delegateCryptoCallbacks?: ICryptoCallbacks) {
|
||||
this.accountDataClientAdapter = new AccountDataClientAdapter(accountData);
|
||||
@ -70,13 +70,13 @@ export class EncryptionSetupBuilder {
|
||||
/**
|
||||
* Adds new cross-signing public keys
|
||||
*
|
||||
* @param {function} authUpload Function called to await an interactive auth
|
||||
* @param authUpload - Function called to await an interactive auth
|
||||
* flow when uploading device signing keys.
|
||||
* Args:
|
||||
* {function} A function that makes the request requiring auth. Receives
|
||||
* A function that makes the request requiring auth. Receives
|
||||
* the auth data as an object. Can be called multiple times, first with
|
||||
* an empty authDict, to obtain the flows.
|
||||
* @param {Object} keys the new keys
|
||||
* @param keys - the new keys
|
||||
*/
|
||||
public addCrossSigningKeys(authUpload: ICrossSigningKeys["authUpload"], keys: ICrossSigningKeys["keys"]): void {
|
||||
this.crossSigningKeys = { authUpload, keys };
|
||||
@ -88,7 +88,7 @@ export class EncryptionSetupBuilder {
|
||||
* Used either to create a new key backup, or add signatures
|
||||
* from the new MSK.
|
||||
*
|
||||
* @param {Object} keyBackupInfo as received from/sent to the server
|
||||
* @param keyBackupInfo - as received from/sent to the server
|
||||
*/
|
||||
public addSessionBackup(keyBackupInfo: IKeyBackupInfo): void {
|
||||
this.keyBackupInfo = keyBackupInfo;
|
||||
@ -99,7 +99,6 @@ export class EncryptionSetupBuilder {
|
||||
*
|
||||
* Used after fixing the format of the key
|
||||
*
|
||||
* @param {Uint8Array} privateKey
|
||||
*/
|
||||
public addSessionBackupPrivateKeyToCache(privateKey: Uint8Array): void {
|
||||
this.sessionBackupPrivateKey = privateKey;
|
||||
@ -109,9 +108,6 @@ export class EncryptionSetupBuilder {
|
||||
* Add signatures from a given user and device/x-sign key
|
||||
* Used to sign the new cross-signing key with the device key
|
||||
*
|
||||
* @param {String} userId
|
||||
* @param {String} deviceId
|
||||
* @param {Object} signature
|
||||
*/
|
||||
public addKeySignature(userId: string, deviceId: string, signature: ISignedKey): void {
|
||||
if (!this.keySignatures) {
|
||||
@ -122,18 +118,12 @@ export class EncryptionSetupBuilder {
|
||||
userSignatures[deviceId] = signature;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {String} type
|
||||
* @param {Object} content
|
||||
* @return {Promise}
|
||||
*/
|
||||
public async setAccountData(type: string, content: object): Promise<void> {
|
||||
await this.accountDataClientAdapter.setAccountData(type, content);
|
||||
}
|
||||
|
||||
/**
|
||||
* builds the operation containing all the parts that have been added to the builder
|
||||
* @return {EncryptionSetupOperation}
|
||||
*/
|
||||
public buildOperation(): EncryptionSetupOperation {
|
||||
const accountData = this.accountDataClientAdapter.values;
|
||||
@ -150,9 +140,6 @@ export class EncryptionSetupBuilder {
|
||||
*
|
||||
* This does not yet store the operation in a way that it can be restored,
|
||||
* but that is the idea in the future.
|
||||
*
|
||||
* @param {Crypto} crypto
|
||||
* @return {Promise}
|
||||
*/
|
||||
public async persist(crypto: Crypto): Promise<void> {
|
||||
// store private keys in cache
|
||||
@ -187,10 +174,6 @@ export class EncryptionSetupBuilder {
|
||||
*/
|
||||
export class EncryptionSetupOperation {
|
||||
/**
|
||||
* @param {Map<String, Object>} accountData
|
||||
* @param {Object} crossSigningKeys
|
||||
* @param {Object} keyBackupInfo
|
||||
* @param {Object} keySignatures
|
||||
*/
|
||||
public constructor(
|
||||
private readonly accountData: Map<string, object>,
|
||||
@ -201,7 +184,6 @@ export class EncryptionSetupOperation {
|
||||
|
||||
/**
|
||||
* Runs the (remaining part of, in the future) operation by sending requests to the server.
|
||||
* @param {Crypto} crypto
|
||||
*/
|
||||
public async apply(crypto: Crypto): Promise<void> {
|
||||
const baseApis = crypto.baseApis;
|
||||
@ -270,23 +252,21 @@ class AccountDataClientAdapter
|
||||
public readonly values = new Map<string, MatrixEvent>();
|
||||
|
||||
/**
|
||||
* @param {Object.<String, MatrixEvent>} existingValues existing account data
|
||||
* @param existingValues - existing account data
|
||||
*/
|
||||
public constructor(private readonly existingValues: Record<string, MatrixEvent>) {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {String} type
|
||||
* @return {Promise<Object>} the content of the account data
|
||||
* @returns the content of the account data
|
||||
*/
|
||||
public getAccountDataFromServer<T extends {[k: string]: any}>(type: string): Promise<T> {
|
||||
return Promise.resolve(this.getAccountData(type) as T);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {String} type
|
||||
* @return {Object} the content of the account data
|
||||
* @returns the content of the account data
|
||||
*/
|
||||
public getAccountData(type: string): IContent | null {
|
||||
const modifiedValue = this.values.get(type);
|
||||
@ -300,11 +280,6 @@ class AccountDataClientAdapter
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {String} type
|
||||
* @param {Object} content
|
||||
* @return {Promise}
|
||||
*/
|
||||
public setAccountData(type: string, content: any): Promise<{}> {
|
||||
const lastEvent = this.values.get(type);
|
||||
this.values.set(type, content);
|
||||
|
@ -53,43 +53,22 @@ function checkPayloadLength(payloadString: string): void {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The type of object we use for importing and exporting megolm session data.
|
||||
*
|
||||
* @typedef {Object} module:crypto/OlmDevice.MegolmSessionData
|
||||
* @property {String} sender_key Sender's Curve25519 device key
|
||||
* @property {String[]} forwarding_curve25519_key_chain Devices which forwarded
|
||||
* this session to us (normally empty).
|
||||
* @property {Object<string, string>} sender_claimed_keys Other keys the sender claims.
|
||||
* @property {String} room_id Room this session is used in
|
||||
* @property {String} session_id Unique id for the session
|
||||
* @property {String} session_key Base64'ed key data
|
||||
*/
|
||||
|
||||
interface IInitOpts {
|
||||
fromExportedDevice?: IExportedDevice;
|
||||
pickleKey?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* data stored in the session store about an inbound group session
|
||||
*
|
||||
* @typedef {Object} InboundGroupSessionData
|
||||
* @property {string} room_id
|
||||
* @property {string} session pickled Olm.InboundGroupSession
|
||||
* @property {Object<string, string>} keysClaimed
|
||||
* @property {Array<string>} forwardingCurve25519KeyChain Devices involved in forwarding
|
||||
* this session to us (normally empty).
|
||||
* @property {boolean=} untrusted whether this session is untrusted.
|
||||
* @property {boolean=} sharedHistory whether this session exists during the room being set to shared history.
|
||||
*/
|
||||
|
||||
/** data stored in the session store about an inbound group session */
|
||||
export interface InboundGroupSessionData {
|
||||
room_id: string; // eslint-disable-line camelcase
|
||||
/** 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;
|
||||
}
|
||||
|
||||
@ -134,20 +113,13 @@ type OneTimeKeys = { curve25519: { [keyId: string]: string } };
|
||||
* OlmAccount and a number of OlmSessions.
|
||||
*
|
||||
* Accounts and sessions are kept pickled in the cryptoStore.
|
||||
*
|
||||
* @constructor
|
||||
* @alias module:crypto/OlmDevice
|
||||
*
|
||||
* @param {Object} cryptoStore A store for crypto data
|
||||
*
|
||||
* @property {string} deviceCurve25519Key Curve25519 key for the account
|
||||
* @property {string} deviceEd25519Key Ed25519 key for the account
|
||||
*/
|
||||
export class OlmDevice {
|
||||
public pickleKey = "DEFAULT_KEY"; // set by consumers
|
||||
|
||||
// don't know these until we load the account from storage in init()
|
||||
/** Curve25519 key for the account, unknown until we load the account from storage in init() */
|
||||
public deviceCurve25519Key: string | null = null;
|
||||
/** Ed25519 key for the account, unknown until we load the account from storage in init() */
|
||||
public deviceEd25519Key: string | null = null;
|
||||
private maxOneTimeKeys: number | null = null;
|
||||
|
||||
@ -184,7 +156,7 @@ export class OlmDevice {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {array} The version of Olm.
|
||||
* @returns The version of Olm.
|
||||
*/
|
||||
public static getOlmVersion(): [number, number, number] {
|
||||
return global.Olm.get_library_version();
|
||||
@ -202,12 +174,11 @@ export class OlmDevice {
|
||||
*
|
||||
* Reads the device keys from the OlmAccount object.
|
||||
*
|
||||
* @param {object} opts
|
||||
* @param {object} opts.fromExportedDevice (Optional) data from exported device
|
||||
* @param fromExportedDevice - (Optional) data from exported device
|
||||
* that must be re-created.
|
||||
* If present, opts.pickleKey is ignored
|
||||
* (exported data already provides a pickle key)
|
||||
* @param {object} opts.pickleKey (Optional) pickle key to set instead of default one
|
||||
* @param pickleKey - (Optional) pickle key to set instead of default one
|
||||
*/
|
||||
public async init({ pickleKey, fromExportedDevice }: IInitOpts = {}): Promise<void> {
|
||||
let e2eKeys;
|
||||
@ -245,9 +216,9 @@ export class OlmDevice {
|
||||
* Note that for now only the “account” and “sessions” stores are populated;
|
||||
* Other stores will be as with a new device.
|
||||
*
|
||||
* @param {IExportedDevice} exportedData Data exported from another device
|
||||
* @param exportedData - Data exported from another device
|
||||
* through the “export” method.
|
||||
* @param {Olm.Account} account an olm account to initialize
|
||||
* @param account - an olm account to initialize
|
||||
*/
|
||||
private async initialiseFromExportedDevice(exportedData: IExportedDevice, account: Account): Promise<void> {
|
||||
await this.cryptoStore.doTxn(
|
||||
@ -305,9 +276,8 @@ export class OlmDevice {
|
||||
* This function requires a live transaction object from cryptoStore.doTxn()
|
||||
* and therefore may only be called in a doTxn() callback.
|
||||
*
|
||||
* @param {*} txn Opaque transaction object from cryptoStore.doTxn()
|
||||
* @param {function} func
|
||||
* @private
|
||||
* @param txn - Opaque transaction object from cryptoStore.doTxn()
|
||||
* @internal
|
||||
*/
|
||||
private getAccount(txn: unknown, func: (account: Account) => void): void {
|
||||
this.cryptoStore.getAccount(txn, (pickledAccount: string | null) => {
|
||||
@ -326,9 +296,9 @@ export class OlmDevice {
|
||||
* This function requires a live transaction object from cryptoStore.doTxn()
|
||||
* and therefore may only be called in a doTxn() callback.
|
||||
*
|
||||
* @param {*} txn Opaque transaction object from cryptoStore.doTxn()
|
||||
* @param {object} Olm.Account object
|
||||
* @private
|
||||
* @param txn - Opaque transaction object from cryptoStore.doTxn()
|
||||
* @param Olm.Account object
|
||||
* @internal
|
||||
*/
|
||||
private storeAccount(txn: unknown, account: Account): void {
|
||||
this.cryptoStore.storeAccount(txn, account.pickle(this.pickleKey));
|
||||
@ -338,7 +308,7 @@ export class OlmDevice {
|
||||
* Export data for re-creating the Olm device later.
|
||||
* TODO export data other than just account and (P2P) sessions.
|
||||
*
|
||||
* @return {Promise<object>} The exported data
|
||||
* @returns The exported data
|
||||
*/
|
||||
public async export(): Promise<IExportedDevice> {
|
||||
const result: Partial<IExportedDevice> = {
|
||||
@ -373,11 +343,8 @@ export class OlmDevice {
|
||||
* function and will be freed as soon the callback returns. It is *not*
|
||||
* usable for the rest of the lifetime of the transaction.
|
||||
*
|
||||
* @param {string} deviceKey
|
||||
* @param {string} sessionId
|
||||
* @param {*} txn Opaque transaction object from cryptoStore.doTxn()
|
||||
* @param {function} func
|
||||
* @private
|
||||
* @param txn - Opaque transaction object from cryptoStore.doTxn()
|
||||
* @internal
|
||||
*/
|
||||
private getSession(
|
||||
deviceKey: string,
|
||||
@ -397,9 +364,7 @@ export class OlmDevice {
|
||||
* function with it. The session object is destroyed once the function
|
||||
* returns.
|
||||
*
|
||||
* @param {object} sessionInfo
|
||||
* @param {function} func
|
||||
* @private
|
||||
* @internal
|
||||
*/
|
||||
private unpickleSession(
|
||||
sessionInfo: ISessionInfo,
|
||||
@ -419,10 +384,9 @@ export class OlmDevice {
|
||||
/**
|
||||
* store our OlmSession in the session store
|
||||
*
|
||||
* @param {string} deviceKey
|
||||
* @param {object} sessionInfo {session: OlmSession, lastReceivedMessageTs: int}
|
||||
* @param {*} txn Opaque transaction object from cryptoStore.doTxn()
|
||||
* @private
|
||||
* @param sessionInfo - `{session: OlmSession, lastReceivedMessageTs: int}`
|
||||
* @param txn - Opaque transaction object from cryptoStore.doTxn()
|
||||
* @internal
|
||||
*/
|
||||
private saveSession(deviceKey: string, sessionInfo: IUnpickledSessionInfo, txn: unknown): void {
|
||||
const sessionId = sessionInfo.session.session_id();
|
||||
@ -435,9 +399,8 @@ export class OlmDevice {
|
||||
/**
|
||||
* get an OlmUtility and call the given function
|
||||
*
|
||||
* @param {function} func
|
||||
* @return {object} result of func
|
||||
* @private
|
||||
* @returns result of func
|
||||
* @internal
|
||||
*/
|
||||
private getUtility<T>(func: (utility: Utility) => T): T {
|
||||
const utility = new global.Olm.Utility();
|
||||
@ -451,8 +414,8 @@ export class OlmDevice {
|
||||
/**
|
||||
* Signs a message with the ed25519 key for this account.
|
||||
*
|
||||
* @param {string} message message to be signed
|
||||
* @return {Promise<string>} base64-encoded signature
|
||||
* @param message - message to be signed
|
||||
* @returns base64-encoded signature
|
||||
*/
|
||||
public async sign(message: string): Promise<string> {
|
||||
let result: string;
|
||||
@ -469,7 +432,7 @@ export class OlmDevice {
|
||||
/**
|
||||
* Get the current (unused, unpublished) one-time keys for this account.
|
||||
*
|
||||
* @return {object} one time keys; an object with the single property
|
||||
* @returns one time keys; an object with the single property
|
||||
* <tt>curve25519</tt>, which is itself an object mapping key id to Curve25519
|
||||
* key.
|
||||
*/
|
||||
@ -490,7 +453,7 @@ export class OlmDevice {
|
||||
/**
|
||||
* Get the maximum number of one-time keys we can store.
|
||||
*
|
||||
* @return {number} number of keys
|
||||
* @returns number of keys
|
||||
*/
|
||||
public maxNumberOfOneTimeKeys(): number {
|
||||
return this.maxOneTimeKeys ?? -1;
|
||||
@ -514,8 +477,8 @@ export class OlmDevice {
|
||||
/**
|
||||
* Generate some new one-time keys
|
||||
*
|
||||
* @param {number} numKeys number of keys to generate
|
||||
* @return {Promise} Resolved once the account is saved back having generated the keys
|
||||
* @param numKeys - number of keys to generate
|
||||
* @returns Resolved once the account is saved back having generated the keys
|
||||
*/
|
||||
public generateOneTimeKeys(numKeys: number): Promise<void> {
|
||||
return this.cryptoStore.doTxn(
|
||||
@ -532,7 +495,7 @@ export class OlmDevice {
|
||||
/**
|
||||
* Generate a new fallback keys
|
||||
*
|
||||
* @return {Promise} Resolved once the account is saved back having generated the key
|
||||
* @returns Resolved once the account is saved back having generated the key
|
||||
*/
|
||||
public async generateFallbackKey(): Promise<void> {
|
||||
await this.cryptoStore.doTxn(
|
||||
@ -576,9 +539,9 @@ export class OlmDevice {
|
||||
*
|
||||
* The new session will be stored in the cryptoStore.
|
||||
*
|
||||
* @param {string} theirIdentityKey remote user's Curve25519 identity key
|
||||
* @param {string} theirOneTimeKey remote user's one-time Curve25519 key
|
||||
* @return {string} sessionId for the outbound session.
|
||||
* @param theirIdentityKey - remote user's Curve25519 identity key
|
||||
* @param theirOneTimeKey - remote user's one-time Curve25519 key
|
||||
* @returns sessionId for the outbound session.
|
||||
*/
|
||||
public async createOutboundSession(theirIdentityKey: string, theirOneTimeKey: string): Promise<string> {
|
||||
let newSessionId: string;
|
||||
@ -615,15 +578,14 @@ export class OlmDevice {
|
||||
/**
|
||||
* Generate a new inbound session, given an incoming message
|
||||
*
|
||||
* @param {string} theirDeviceIdentityKey remote user's Curve25519 identity key
|
||||
* @param {number} messageType messageType field from the received message (must be 0)
|
||||
* @param {string} ciphertext base64-encoded body from the received message
|
||||
* @param theirDeviceIdentityKey - remote user's Curve25519 identity key
|
||||
* @param messageType - messageType field from the received message (must be 0)
|
||||
* @param ciphertext - base64-encoded body from the received message
|
||||
*
|
||||
* @return {{payload: string, session_id: string}} decrypted payload, and
|
||||
* @returns decrypted payload, and
|
||||
* session id of new session
|
||||
*
|
||||
* @raises {Error} if the received message was not valid (for instance, it
|
||||
* didn't use a valid one-time key).
|
||||
* @throws Error if the received message was not valid (for instance, it didn't use a valid one-time key).
|
||||
*/
|
||||
public async createInboundSession(
|
||||
theirDeviceIdentityKey: string,
|
||||
@ -676,9 +638,9 @@ export class OlmDevice {
|
||||
/**
|
||||
* Get a list of known session IDs for the given device
|
||||
*
|
||||
* @param {string} theirDeviceIdentityKey Curve25519 identity key for the
|
||||
* @param theirDeviceIdentityKey - Curve25519 identity key for the
|
||||
* remote device
|
||||
* @return {Promise<string[]>} a list of known session ids for the device
|
||||
* @returns a list of known session ids for the device
|
||||
*/
|
||||
public async getSessionIdsForDevice(theirDeviceIdentityKey: string): Promise<string[]> {
|
||||
const log = logger.withPrefix("[getSessionIdsForDevice]");
|
||||
@ -711,13 +673,13 @@ export class OlmDevice {
|
||||
/**
|
||||
* Get the right olm session id for encrypting messages to the given identity key
|
||||
*
|
||||
* @param {string} theirDeviceIdentityKey Curve25519 identity key for the
|
||||
* @param theirDeviceIdentityKey - Curve25519 identity key for the
|
||||
* remote device
|
||||
* @param {boolean} nowait Don't wait for an in-progress session to complete.
|
||||
* @param nowait - Don't wait for an in-progress session to complete.
|
||||
* This should only be set to true of the calling function is the function
|
||||
* that marked the session as being in-progress.
|
||||
* @param {PrefixedLogger} [log] A possibly customised log
|
||||
* @return {Promise<?string>} session id, or null if no established session
|
||||
* @param log - A possibly customised log
|
||||
* @returns session id, or null if no established session
|
||||
*/
|
||||
public async getSessionIdForDevice(
|
||||
theirDeviceIdentityKey: string,
|
||||
@ -759,12 +721,11 @@ export class OlmDevice {
|
||||
* the keys 'hasReceivedMessage' (true if the session has received an incoming
|
||||
* message and is therefore past the pre-key stage), and 'sessionId'.
|
||||
*
|
||||
* @param {string} deviceIdentityKey Curve25519 identity key for the device
|
||||
* @param {boolean} nowait Don't wait for an in-progress session to complete.
|
||||
* @param deviceIdentityKey - Curve25519 identity key for the device
|
||||
* @param nowait - Don't wait for an in-progress session to complete.
|
||||
* This should only be set to true of the calling function is the function
|
||||
* that marked the session as being in-progress.
|
||||
* @param {Logger} [log] A possibly customised log
|
||||
* @return {Array.<{sessionId: string, hasReceivedMessage: boolean}>}
|
||||
* @param log - A possibly customised log
|
||||
*/
|
||||
public async getSessionInfoForDevice(
|
||||
deviceIdentityKey: string,
|
||||
@ -813,12 +774,12 @@ export class OlmDevice {
|
||||
/**
|
||||
* Encrypt an outgoing message using an existing session
|
||||
*
|
||||
* @param {string} theirDeviceIdentityKey Curve25519 identity key for the
|
||||
* @param theirDeviceIdentityKey - Curve25519 identity key for the
|
||||
* remote device
|
||||
* @param {string} sessionId the id of the active session
|
||||
* @param {string} payloadString payload to be encrypted and sent
|
||||
* @param sessionId - the id of the active session
|
||||
* @param payloadString - payload to be encrypted and sent
|
||||
*
|
||||
* @return {Promise<string>} ciphertext
|
||||
* @returns ciphertext
|
||||
*/
|
||||
public async encryptMessage(
|
||||
theirDeviceIdentityKey: string,
|
||||
@ -849,13 +810,13 @@ export class OlmDevice {
|
||||
/**
|
||||
* Decrypt an incoming message using an existing session
|
||||
*
|
||||
* @param {string} theirDeviceIdentityKey Curve25519 identity key for the
|
||||
* @param theirDeviceIdentityKey - Curve25519 identity key for the
|
||||
* remote device
|
||||
* @param {string} sessionId the id of the active session
|
||||
* @param {number} messageType messageType field from the received message
|
||||
* @param {string} ciphertext base64-encoded body from the received message
|
||||
* @param sessionId - the id of the active session
|
||||
* @param messageType - messageType field from the received message
|
||||
* @param ciphertext - base64-encoded body from the received message
|
||||
*
|
||||
* @return {Promise<string>} decrypted payload.
|
||||
* @returns decrypted payload.
|
||||
*/
|
||||
public async decryptMessage(
|
||||
theirDeviceIdentityKey: string,
|
||||
@ -886,13 +847,13 @@ export class OlmDevice {
|
||||
/**
|
||||
* Determine if an incoming messages is a prekey message matching an existing session
|
||||
*
|
||||
* @param {string} theirDeviceIdentityKey Curve25519 identity key for the
|
||||
* @param theirDeviceIdentityKey - Curve25519 identity key for the
|
||||
* remote device
|
||||
* @param {string} sessionId the id of the active session
|
||||
* @param {number} messageType messageType field from the received message
|
||||
* @param {string} ciphertext base64-encoded body from the received message
|
||||
* @param sessionId - the id of the active session
|
||||
* @param messageType - messageType field from the received message
|
||||
* @param ciphertext - base64-encoded body from the received message
|
||||
*
|
||||
* @return {Promise<boolean>} true if the received message is a prekey message which matches
|
||||
* @returns true if the received message is a prekey message which matches
|
||||
* the given session.
|
||||
*/
|
||||
public async matchesSession(
|
||||
@ -937,8 +898,7 @@ export class OlmDevice {
|
||||
/**
|
||||
* store an OutboundGroupSession in outboundGroupSessionStore
|
||||
*
|
||||
* @param {Olm.OutboundGroupSession} session
|
||||
* @private
|
||||
* @internal
|
||||
*/
|
||||
private saveOutboundGroupSession(session: OutboundGroupSession): void {
|
||||
this.outboundGroupSessionStore[session.session_id()] = session.pickle(this.pickleKey);
|
||||
@ -948,10 +908,8 @@ export class OlmDevice {
|
||||
* extract an OutboundGroupSession from outboundGroupSessionStore and call the
|
||||
* given function
|
||||
*
|
||||
* @param {string} sessionId
|
||||
* @param {function} func
|
||||
* @return {object} result of func
|
||||
* @private
|
||||
* @returns result of func
|
||||
* @internal
|
||||
*/
|
||||
private getOutboundGroupSession<T>(sessionId: string, func: (session: OutboundGroupSession) => T): T {
|
||||
const pickled = this.outboundGroupSessionStore[sessionId];
|
||||
@ -971,7 +929,7 @@ export class OlmDevice {
|
||||
/**
|
||||
* Generate a new outbound group session
|
||||
*
|
||||
* @return {string} sessionId for the outbound session.
|
||||
* @returns sessionId for the outbound session.
|
||||
*/
|
||||
public createOutboundGroupSession(): string {
|
||||
const session = new global.Olm.OutboundGroupSession();
|
||||
@ -987,10 +945,10 @@ export class OlmDevice {
|
||||
/**
|
||||
* Encrypt an outgoing message with an outbound group session
|
||||
*
|
||||
* @param {string} sessionId the id of the outboundgroupsession
|
||||
* @param {string} payloadString payload to be encrypted and sent
|
||||
* @param sessionId - the id of the outboundgroupsession
|
||||
* @param payloadString - payload to be encrypted and sent
|
||||
*
|
||||
* @return {string} ciphertext
|
||||
* @returns ciphertext
|
||||
*/
|
||||
public encryptGroupMessage(sessionId: string, payloadString: string): string {
|
||||
logger.log(`encrypting msg with megolm session ${sessionId}`);
|
||||
@ -1007,9 +965,9 @@ export class OlmDevice {
|
||||
/**
|
||||
* Get the session keys for an outbound group session
|
||||
*
|
||||
* @param {string} sessionId the id of the outbound group session
|
||||
* @param sessionId - the id of the outbound group session
|
||||
*
|
||||
* @return {{chain_index: number, key: string}} current chain index, and
|
||||
* @returns current chain index, and
|
||||
* base64-encoded secret key.
|
||||
*/
|
||||
public getOutboundGroupSessionKey(sessionId: string): IOutboundGroupSessionKey {
|
||||
@ -1028,9 +986,9 @@ export class OlmDevice {
|
||||
* Unpickle a session from a sessionData object and invoke the given function.
|
||||
* The session is valid only until func returns.
|
||||
*
|
||||
* @param {Object} sessionData Object describing the session.
|
||||
* @param {function(Olm.InboundGroupSession)} func Invoked with the unpickled session
|
||||
* @return {*} result of func
|
||||
* @param sessionData - Object describing the session.
|
||||
* @param func - Invoked with the unpickled session
|
||||
* @returns result of func
|
||||
*/
|
||||
private unpickleInboundGroupSession<T>(
|
||||
sessionData: InboundGroupSessionData,
|
||||
@ -1048,15 +1006,12 @@ export class OlmDevice {
|
||||
/**
|
||||
* extract an InboundGroupSession from the crypto store and call the given function
|
||||
*
|
||||
* @param {string} roomId The room ID to extract the session for, or null to fetch
|
||||
* @param roomId - The room ID to extract the session for, or null to fetch
|
||||
* sessions for any room.
|
||||
* @param {string} senderKey
|
||||
* @param {string} sessionId
|
||||
* @param {*} txn Opaque transaction object from cryptoStore.doTxn()
|
||||
* @param {function(Olm.InboundGroupSession, InboundGroupSessionData)} func
|
||||
* function to call.
|
||||
* @param txn - Opaque transaction object from cryptoStore.doTxn()
|
||||
* @param func - function to call.
|
||||
*
|
||||
* @private
|
||||
* @internal
|
||||
*/
|
||||
private getInboundGroupSession(
|
||||
roomId: string,
|
||||
@ -1095,16 +1050,16 @@ export class OlmDevice {
|
||||
/**
|
||||
* Add an inbound group session to the session store
|
||||
*
|
||||
* @param {string} roomId room in which this session will be used
|
||||
* @param {string} senderKey base64-encoded curve25519 key of the sender
|
||||
* @param {Array<string>} forwardingCurve25519KeyChain Devices involved in forwarding
|
||||
* @param roomId - room in which this session will be used
|
||||
* @param senderKey - base64-encoded curve25519 key of the sender
|
||||
* @param forwardingCurve25519KeyChain - Devices involved in forwarding
|
||||
* this session to us.
|
||||
* @param {string} sessionId session identifier
|
||||
* @param {string} sessionKey base64-encoded secret key
|
||||
* @param {Object<string, string>} keysClaimed Other keys the sender claims.
|
||||
* @param {boolean} exportFormat true if the megolm keys are in export format
|
||||
* @param sessionId - session identifier
|
||||
* @param sessionKey - base64-encoded secret key
|
||||
* @param keysClaimed - Other keys the sender claims.
|
||||
* @param exportFormat - true if the megolm keys are in export format
|
||||
* (ie, they lack an ed25519 signature)
|
||||
* @param {Object} [extraSessionData={}] any other data to be include with the session
|
||||
* @param extraSessionData - any other data to be include with the session
|
||||
*/
|
||||
public async addInboundGroupSession(
|
||||
roomId: string,
|
||||
@ -1216,11 +1171,11 @@ export class OlmDevice {
|
||||
/**
|
||||
* Record in the data store why an inbound group session was withheld.
|
||||
*
|
||||
* @param {string} roomId room that the session belongs to
|
||||
* @param {string} senderKey base64-encoded curve25519 key of the sender
|
||||
* @param {string} sessionId session identifier
|
||||
* @param {string} code reason code
|
||||
* @param {string} reason human-readable version of `code`
|
||||
* @param roomId - room that the session belongs to
|
||||
* @param senderKey - base64-encoded curve25519 key of the sender
|
||||
* @param sessionId - session identifier
|
||||
* @param code - reason code
|
||||
* @param reason - human-readable version of `code`
|
||||
*/
|
||||
public async addInboundGroupSessionWithheld(
|
||||
roomId: string,
|
||||
@ -1248,18 +1203,14 @@ export class OlmDevice {
|
||||
/**
|
||||
* Decrypt a received message with an inbound group session
|
||||
*
|
||||
* @param {string} roomId room in which the message was received
|
||||
* @param {string} senderKey base64-encoded curve25519 key of the sender
|
||||
* @param {string} sessionId session identifier
|
||||
* @param {string} body base64-encoded body of the encrypted message
|
||||
* @param {string} eventId ID of the event being decrypted
|
||||
* @param {Number} timestamp timestamp of the event being decrypted
|
||||
* @param roomId - room in which the message was received
|
||||
* @param senderKey - base64-encoded curve25519 key of the sender
|
||||
* @param sessionId - session identifier
|
||||
* @param body - base64-encoded body of the encrypted message
|
||||
* @param eventId - ID of the event being decrypted
|
||||
* @param timestamp - timestamp of the event being decrypted
|
||||
*
|
||||
* @return {null} the sessionId is unknown
|
||||
*
|
||||
* @return {Promise<{result: string, senderKey: string,
|
||||
* forwardingCurve25519KeyChain: Array<string>,
|
||||
* keysClaimed: Object<string, string>}>}
|
||||
* @returns null if the sessionId is unknown
|
||||
*/
|
||||
public async decryptGroupMessage(
|
||||
roomId: string,
|
||||
@ -1375,11 +1326,11 @@ export class OlmDevice {
|
||||
/**
|
||||
* Determine if we have the keys for a given megolm session
|
||||
*
|
||||
* @param {string} roomId room in which the message was received
|
||||
* @param {string} senderKey base64-encoded curve25519 key of the sender
|
||||
* @param {string} sessionId session identifier
|
||||
* @param roomId - room in which the message was received
|
||||
* @param senderKey - base64-encoded curve25519 key of the sender
|
||||
* @param sessionId - session identifier
|
||||
*
|
||||
* @returns {Promise<boolean>} true if we have the keys to this session
|
||||
* @returns true if we have the keys to this session
|
||||
*/
|
||||
public async hasInboundSessionKeys(roomId: string, senderKey: string, sessionId: string): Promise<boolean> {
|
||||
let result: boolean;
|
||||
@ -1418,16 +1369,13 @@ export class OlmDevice {
|
||||
/**
|
||||
* Extract the keys to a given megolm session, for sharing
|
||||
*
|
||||
* @param {string} roomId room in which the message was received
|
||||
* @param {string} senderKey base64-encoded curve25519 key of the sender
|
||||
* @param {string} sessionId session identifier
|
||||
* @param {number} chainIndex The chain index at which to export the session.
|
||||
* @param roomId - room in which the message was received
|
||||
* @param senderKey - base64-encoded curve25519 key of the sender
|
||||
* @param sessionId - session identifier
|
||||
* @param chainIndex - The chain index at which to export the session.
|
||||
* If omitted, export at the first index we know about.
|
||||
*
|
||||
* @returns {Promise<{chain_index: number, key: string,
|
||||
* forwarding_curve25519_key_chain: Array<string>,
|
||||
* sender_claimed_ed25519_key: string
|
||||
* }>}
|
||||
* @returns
|
||||
* details of the session key. The key is a base64-encoded megolm key in
|
||||
* export format.
|
||||
*
|
||||
@ -1492,10 +1440,10 @@ export class OlmDevice {
|
||||
/**
|
||||
* Export an inbound group session
|
||||
*
|
||||
* @param {string} senderKey base64-encoded curve25519 key of the sender
|
||||
* @param {string} sessionId session identifier
|
||||
* @param {ISessionInfo} sessionData The session object from the store
|
||||
* @return {module:crypto/OlmDevice.MegolmSessionData} exported session data
|
||||
* @param senderKey - base64-encoded curve25519 key of the sender
|
||||
* @param sessionId - session identifier
|
||||
* @param sessionData - The session object from the store
|
||||
* @returns exported session data
|
||||
*/
|
||||
public exportInboundGroupSession(
|
||||
senderKey: string,
|
||||
@ -1539,11 +1487,11 @@ export class OlmDevice {
|
||||
/**
|
||||
* Verify an ed25519 signature.
|
||||
*
|
||||
* @param {string} key ed25519 key
|
||||
* @param {string} message message which was signed
|
||||
* @param {string} signature base64-encoded signature to be checked
|
||||
* @param key - ed25519 key
|
||||
* @param message - message which was signed
|
||||
* @param signature - base64-encoded signature to be checked
|
||||
*
|
||||
* @raises {Error} if there is a problem with the verification. If the key was
|
||||
* @throws Error if there is a problem with the verification. If the key was
|
||||
* too small then the message will be "OLM.INVALID_BASE64". If the signature
|
||||
* was invalid then the message will be "OLM.BAD_MESSAGE_MAC".
|
||||
*/
|
||||
@ -1568,11 +1516,11 @@ export const WITHHELD_MESSAGES: Record<string, string> = {
|
||||
/**
|
||||
* Calculate the message to use for the exception when a session key is withheld.
|
||||
*
|
||||
* @param {object} withheld An object that describes why the key was withheld.
|
||||
* @param withheld - An object that describes why the key was withheld.
|
||||
*
|
||||
* @return {string} the message
|
||||
* @returns the message
|
||||
*
|
||||
* @private
|
||||
* @internal
|
||||
*/
|
||||
function calculateWithheldMessage(withheld: IWithheld): string {
|
||||
if (withheld.code && withheld.code in WITHHELD_MESSAGES) {
|
||||
|
@ -27,17 +27,17 @@ import { EventType, ToDeviceMessageId } from "../@types/event";
|
||||
*
|
||||
* See https://docs.google.com/document/d/1m4gQkcnJkxNuBmb5NoFCIadIY-DyqqNAS3lloE73BlQ
|
||||
* for draft documentation on what we're supposed to be implementing here.
|
||||
*
|
||||
* @module
|
||||
*/
|
||||
|
||||
// delay between deciding we want some keys, and sending out the request, to
|
||||
// allow for (a) it turning up anyway, (b) grouping requests together
|
||||
const SEND_KEY_REQUESTS_DELAY_MS = 500;
|
||||
|
||||
/** possible states for a room key request
|
||||
/**
|
||||
* possible states for a room key request
|
||||
*
|
||||
* The state machine looks like:
|
||||
* ```
|
||||
*
|
||||
* | (cancellation sent)
|
||||
* | .-------------------------------------------------.
|
||||
@ -60,8 +60,7 @@ const SEND_KEY_REQUESTS_DELAY_MS = 500;
|
||||
* | (cancellation sent) |
|
||||
* V |
|
||||
* (deleted) <---------------------------+
|
||||
*
|
||||
* @enum {number}
|
||||
* ```
|
||||
*/
|
||||
export enum RoomKeyRequestState {
|
||||
/** request not yet sent */
|
||||
@ -134,12 +133,10 @@ export class OutgoingRoomKeyRequestManager {
|
||||
* Otherwise, a request is added to the pending list, and a job is started
|
||||
* in the background to send it.
|
||||
*
|
||||
* @param {module:crypto~RoomKeyRequestBody} requestBody
|
||||
* @param {Array<{userId: string, deviceId: string}>} recipients
|
||||
* @param {boolean} resend whether to resend the key request if there is
|
||||
* @param resend - whether to resend the key request if there is
|
||||
* already one
|
||||
*
|
||||
* @returns {Promise} resolves when the request has been added to the
|
||||
* @returns resolves when the request has been added to the
|
||||
* pending list (or we have established that a similar request already
|
||||
* exists)
|
||||
*/
|
||||
@ -239,9 +236,8 @@ export class OutgoingRoomKeyRequestManager {
|
||||
/**
|
||||
* Cancel room key requests, if any match the given requestBody
|
||||
*
|
||||
* @param {module:crypto~RoomKeyRequestBody} requestBody
|
||||
*
|
||||
* @returns {Promise} resolves when the request has been updated in our
|
||||
* @returns resolves when the request has been updated in our
|
||||
* pending list.
|
||||
*/
|
||||
public cancelRoomKeyRequest(requestBody: IRoomKeyRequestBody): Promise<unknown> {
|
||||
@ -324,11 +320,10 @@ export class OutgoingRoomKeyRequestManager {
|
||||
/**
|
||||
* Look for room key requests by target device and state
|
||||
*
|
||||
* @param {string} userId Target user ID
|
||||
* @param {string} deviceId Target device ID
|
||||
* @param userId - Target user ID
|
||||
* @param deviceId - Target device ID
|
||||
*
|
||||
* @return {Promise} resolves to a list of all the
|
||||
* {@link module:crypto/store/base~OutgoingRoomKeyRequest}
|
||||
* @returns resolves to a list of all the {@link OutgoingRoomKeyRequest}
|
||||
*/
|
||||
public getOutgoingSentRoomKeyRequest(userId: string, deviceId: string): Promise<OutgoingRoomKeyRequest[]> {
|
||||
return this.cryptoStore.getOutgoingRoomKeyRequestsByTarget(userId, deviceId, [RoomKeyRequestState.Sent]);
|
||||
@ -339,7 +334,7 @@ export class OutgoingRoomKeyRequestManager {
|
||||
* This is intended for situations where something substantial has changed, and we
|
||||
* don't really expect the other end to even care about the cancellation.
|
||||
* For example, after initialization or self-verification.
|
||||
* @return {Promise} An array of `queueRoomKeyRequest` outputs.
|
||||
* @returns An array of `queueRoomKeyRequest` outputs.
|
||||
*/
|
||||
public async cancelAndResendAllOutgoingRequests(): Promise<void[]> {
|
||||
const outgoings = await this.cryptoStore.getAllOutgoingRoomKeyRequestsByState(RoomKeyRequestState.Sent);
|
||||
|
@ -15,8 +15,6 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @module crypto/RoomList
|
||||
*
|
||||
* Manages the list of encrypted rooms
|
||||
*/
|
||||
|
||||
@ -31,9 +29,6 @@ export interface IRoomEncryption {
|
||||
}
|
||||
/* eslint-enable camelcase */
|
||||
|
||||
/**
|
||||
* @alias module:crypto/RoomList
|
||||
*/
|
||||
export class RoomList {
|
||||
// Object of roomId -> room e2e info object (body of the m.room.encryption event)
|
||||
private roomEncryption: Record<string, IRoomEncryption> = {};
|
||||
|
@ -66,7 +66,6 @@ interface ISecretInfo {
|
||||
|
||||
/**
|
||||
* Implements Secure Secret Storage and Sharing (MSC1946)
|
||||
* @module crypto/SecretStorage
|
||||
*/
|
||||
export class SecretStorage<B extends MatrixClient | undefined = MatrixClient> {
|
||||
private requests = new Map<string, ISecretRequestInternal>();
|
||||
@ -119,15 +118,15 @@ export class SecretStorage<B extends MatrixClient | undefined = MatrixClient> {
|
||||
/**
|
||||
* Add a key for encrypting secrets.
|
||||
*
|
||||
* @param {string} algorithm the algorithm used by the key.
|
||||
* @param {object} opts the options for the algorithm. The properties used
|
||||
* @param algorithm - the algorithm used by the key.
|
||||
* @param opts - the options for the algorithm. The properties used
|
||||
* depend on the algorithm given.
|
||||
* @param {string} [keyId] the ID of the key. If not given, a random
|
||||
* @param keyId - the ID of the key. If not given, a random
|
||||
* ID will be generated.
|
||||
*
|
||||
* @return {object} An object with:
|
||||
* keyId: {string} the ID of the key
|
||||
* keyInfo: {object} details about the key (iv, mac, passphrase)
|
||||
* @returns An object with:
|
||||
* keyId: the ID of the key
|
||||
* keyInfo: details about the key (iv, mac, passphrase)
|
||||
*/
|
||||
public async addKey(
|
||||
algorithm: string,
|
||||
@ -176,9 +175,9 @@ export class SecretStorage<B extends MatrixClient | undefined = MatrixClient> {
|
||||
/**
|
||||
* Get the key information for a given ID.
|
||||
*
|
||||
* @param {string} [keyId = default key's ID] The ID of the key to check
|
||||
* @param keyId - The ID of the key to check
|
||||
* for. Defaults to the default key ID if not provided.
|
||||
* @returns {Array?} If the key was found, the return value is an array of
|
||||
* @returns If the key was found, the return value is an array of
|
||||
* the form [keyId, keyInfo]. Otherwise, null is returned.
|
||||
* XXX: why is this an array when addKey returns an object?
|
||||
*/
|
||||
@ -199,9 +198,9 @@ export class SecretStorage<B extends MatrixClient | undefined = MatrixClient> {
|
||||
/**
|
||||
* Check whether we have a key with a given ID.
|
||||
*
|
||||
* @param {string} [keyId = default key's ID] The ID of the key to check
|
||||
* @param keyId - The ID of the key to check
|
||||
* for. Defaults to the default key ID if not provided.
|
||||
* @return {boolean} Whether we have the key.
|
||||
* @returns Whether we have the key.
|
||||
*/
|
||||
public async hasKey(keyId?: string): Promise<boolean> {
|
||||
return Boolean(await this.getKey(keyId));
|
||||
@ -210,10 +209,10 @@ export class SecretStorage<B extends MatrixClient | undefined = MatrixClient> {
|
||||
/**
|
||||
* Check whether a key matches what we expect based on the key info
|
||||
*
|
||||
* @param {Uint8Array} key the key to check
|
||||
* @param {object} info the key info
|
||||
* @param key - the key to check
|
||||
* @param info - the key info
|
||||
*
|
||||
* @return {boolean} whether or not the key matches
|
||||
* @returns whether or not the key matches
|
||||
*/
|
||||
public async checkKey(key: Uint8Array, info: ISecretStorageKeyInfo): Promise<boolean> {
|
||||
if (info.algorithm === SECRET_STORAGE_ALGORITHM_V1_AES) {
|
||||
@ -232,9 +231,9 @@ export class SecretStorage<B extends MatrixClient | undefined = MatrixClient> {
|
||||
/**
|
||||
* Store an encrypted secret on the server
|
||||
*
|
||||
* @param {string} name The name of the secret
|
||||
* @param {string} secret The secret contents.
|
||||
* @param {Array} keys The IDs of the keys to use to encrypt the secret
|
||||
* @param name - The name of the secret
|
||||
* @param secret - The secret contents.
|
||||
* @param keys - The IDs of the keys to use to encrypt the secret
|
||||
* or null/undefined to use the default key.
|
||||
*/
|
||||
public async store(name: string, secret: string, keys?: string[] | null): Promise<void> {
|
||||
@ -280,9 +279,9 @@ export class SecretStorage<B extends MatrixClient | undefined = MatrixClient> {
|
||||
/**
|
||||
* Get a secret from storage.
|
||||
*
|
||||
* @param {string} name the name of the secret
|
||||
* @param name - the name of the secret
|
||||
*
|
||||
* @return {string} the contents of the secret
|
||||
* @returns the contents of the secret
|
||||
*/
|
||||
public async get(name: string): Promise<string | undefined> {
|
||||
const secretInfo = await this.accountDataAdapter.getAccountDataFromServer<ISecretInfo>(name);
|
||||
@ -326,9 +325,9 @@ export class SecretStorage<B extends MatrixClient | undefined = MatrixClient> {
|
||||
/**
|
||||
* Check if a secret is stored on the server.
|
||||
*
|
||||
* @param {string} name the name of the secret
|
||||
* @param name - the name of the secret
|
||||
*
|
||||
* @return {object?} map of key name to key info the secret is encrypted
|
||||
* @returns map of key name to key info the secret is encrypted
|
||||
* with, or null if it is not present or not encrypted with a trusted
|
||||
* key
|
||||
*/
|
||||
@ -361,8 +360,8 @@ export class SecretStorage<B extends MatrixClient | undefined = MatrixClient> {
|
||||
/**
|
||||
* Request a secret from another device
|
||||
*
|
||||
* @param {string} name the name of the secret to request
|
||||
* @param {string[]} devices the devices to request the secret from
|
||||
* @param name - the name of the secret to request
|
||||
* @param devices - the devices to request the secret from
|
||||
*/
|
||||
public request(this: SecretStorage<MatrixClient>, name: string, devices: string[]): ISecretRequest {
|
||||
const requestId = this.baseApis.makeTxnId();
|
||||
|
@ -22,18 +22,21 @@ const zeroSalt = new Uint8Array(8);
|
||||
|
||||
export interface IEncryptedPayload {
|
||||
[key: string]: any; // extensible
|
||||
/** the initialization vector in base64 */
|
||||
iv: string;
|
||||
/** the ciphertext in base64 */
|
||||
ciphertext: string;
|
||||
/** the HMAC in base64 */
|
||||
mac: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* encrypt a string
|
||||
*
|
||||
* @param {string} data the plaintext to encrypt
|
||||
* @param {Uint8Array} key the encryption key to use
|
||||
* @param {string} name the name of the secret
|
||||
* @param {string} ivStr the initialization vector to use
|
||||
* @param data - the plaintext to encrypt
|
||||
* @param key - the encryption key to use
|
||||
* @param name - the name of the secret
|
||||
* @param ivStr - the initialization vector to use
|
||||
*/
|
||||
export async function encryptAES(
|
||||
data: string,
|
||||
@ -83,12 +86,9 @@ export async function encryptAES(
|
||||
/**
|
||||
* decrypt a string
|
||||
*
|
||||
* @param {object} data the encrypted data
|
||||
* @param {string} data.ciphertext the ciphertext in base64
|
||||
* @param {string} data.iv the initialization vector in base64
|
||||
* @param {string} data.mac the HMAC in base64
|
||||
* @param {Uint8Array} key the encryption key to use
|
||||
* @param {string} name the name of the secret
|
||||
* @param data - the encrypted data
|
||||
* @param key - the encryption key to use
|
||||
* @param name - the name of the secret
|
||||
*/
|
||||
export async function decryptAES(data: IEncryptedPayload, key: Uint8Array, name: string): Promise<string> {
|
||||
const [aesKey, hmacKey] = await deriveKeys(key, name);
|
||||
@ -168,10 +168,10 @@ const ZERO_STR = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0
|
||||
|
||||
/** Calculate the MAC for checking the key.
|
||||
*
|
||||
* @param {Uint8Array} key the key to use
|
||||
* @param {string} [iv] The initialization vector as a base64-encoded string.
|
||||
* @param key - the key to use
|
||||
* @param iv - The initialization vector as a base64-encoded string.
|
||||
* If omitted, a random initialization vector will be created.
|
||||
* @return {Promise<object>} An object that contains, `mac` and `iv` properties.
|
||||
* @returns An object that contains, `mac` and `iv` properties.
|
||||
*/
|
||||
export function calculateKeyCheck(key: Uint8Array, iv?: string): Promise<IEncryptedPayload> {
|
||||
return encryptAES(ZERO_STR, key, "", iv);
|
||||
|
@ -16,8 +16,6 @@ limitations under the License.
|
||||
|
||||
/**
|
||||
* Internal module. Defines the base classes of the encryption implementations
|
||||
*
|
||||
* @module
|
||||
*/
|
||||
|
||||
import { MatrixClient } from "../../client";
|
||||
@ -35,46 +33,36 @@ import { DeviceInfo } from "../deviceinfo";
|
||||
import { IRoomEncryption } from "../RoomList";
|
||||
|
||||
/**
|
||||
* map of registered encryption algorithm classes. A map from string to {@link
|
||||
* module:crypto/algorithms/base.EncryptionAlgorithm|EncryptionAlgorithm} class
|
||||
*
|
||||
* @type {Object.<string, function(new: module:crypto/algorithms/base.EncryptionAlgorithm)>}
|
||||
* Map of registered encryption algorithm classes. A map from string to {@link EncryptionAlgorithm} class
|
||||
*/
|
||||
export const ENCRYPTION_CLASSES = new Map<string, new (params: IParams) => EncryptionAlgorithm>();
|
||||
|
||||
export type DecryptionClassParams<P extends IParams = IParams> = Omit<P, "deviceId" | "config">;
|
||||
|
||||
/**
|
||||
* map of registered encryption algorithm classes. Map from string to {@link
|
||||
* module:crypto/algorithms/base.DecryptionAlgorithm|DecryptionAlgorithm} class
|
||||
*
|
||||
* @type {Object.<string, function(new: module:crypto/algorithms/base.DecryptionAlgorithm)>}
|
||||
* map of registered encryption algorithm classes. Map from string to {@link DecryptionAlgorithm} class
|
||||
*/
|
||||
export const DECRYPTION_CLASSES = new Map<string, new (params: DecryptionClassParams) => DecryptionAlgorithm>();
|
||||
|
||||
export interface IParams {
|
||||
/** The UserID for the local user */
|
||||
userId: string;
|
||||
/** The identifier for this device. */
|
||||
deviceId: string;
|
||||
/** crypto core */
|
||||
crypto: Crypto;
|
||||
/** olm.js wrapper */
|
||||
olmDevice: OlmDevice;
|
||||
/** base matrix api interface */
|
||||
baseApis: MatrixClient;
|
||||
/** The ID of the room we will be sending to */
|
||||
roomId?: string;
|
||||
/** The body of the m.room.encryption event */
|
||||
config: IRoomEncryption & object;
|
||||
}
|
||||
|
||||
/**
|
||||
* base type for encryption implementations
|
||||
*
|
||||
* @alias module:crypto/algorithms/base.EncryptionAlgorithm
|
||||
*
|
||||
* @param {object} params parameters
|
||||
* @param {string} params.userId The UserID for the local user
|
||||
* @param {string} params.deviceId The identifier for this device.
|
||||
* @param {module:crypto} params.crypto crypto core
|
||||
* @param {module:crypto/OlmDevice} params.olmDevice olm.js wrapper
|
||||
* @param {MatrixClient} baseApis base matrix api interface
|
||||
* @param {string} params.roomId The ID of the room we will be sending to
|
||||
* @param {object} params.config The body of the m.room.encryption event
|
||||
*/
|
||||
export abstract class EncryptionAlgorithm {
|
||||
protected readonly userId: string;
|
||||
@ -84,6 +72,9 @@ export abstract class EncryptionAlgorithm {
|
||||
protected readonly baseApis: MatrixClient;
|
||||
protected readonly roomId?: string;
|
||||
|
||||
/**
|
||||
* @param params - parameters
|
||||
*/
|
||||
public constructor(params: IParams) {
|
||||
this.userId = params.userId;
|
||||
this.deviceId = params.deviceId;
|
||||
@ -97,33 +88,28 @@ export abstract class EncryptionAlgorithm {
|
||||
* Perform any background tasks that can be done before a message is ready to
|
||||
* send, in order to speed up sending of the message.
|
||||
*
|
||||
* @param {module:models/room} room the room the event is in
|
||||
* @param room - the room the event is in
|
||||
*/
|
||||
public prepareToEncrypt(room: Room): void {}
|
||||
|
||||
/**
|
||||
* Encrypt a message event
|
||||
*
|
||||
* @method module:crypto/algorithms/base.EncryptionAlgorithm.encryptMessage
|
||||
* @public
|
||||
* @abstract
|
||||
*
|
||||
* @param {module:models/room} room
|
||||
* @param {string} eventType
|
||||
* @param {object} content event content
|
||||
* @param content - event content
|
||||
*
|
||||
* @return {Promise} Promise which resolves to the new event body
|
||||
* @returns Promise which resolves to the new event body
|
||||
*/
|
||||
public abstract encryptMessage(room: Room, eventType: string, content: IContent): Promise<IEncryptedContent>;
|
||||
|
||||
/**
|
||||
* Called when the membership of a member of the room changes.
|
||||
*
|
||||
* @param {module:models/event.MatrixEvent} event event causing the change
|
||||
* @param {module:models/room-member} member user whose membership changed
|
||||
* @param {string=} oldMembership previous membership
|
||||
* @param event - event causing the change
|
||||
* @param member - user whose membership changed
|
||||
* @param oldMembership - previous membership
|
||||
* @public
|
||||
* @abstract
|
||||
*/
|
||||
public onRoomMembership(event: MatrixEvent, member: RoomMember, oldMembership?: string): void {}
|
||||
|
||||
@ -139,15 +125,6 @@ export abstract class EncryptionAlgorithm {
|
||||
|
||||
/**
|
||||
* base type for decryption implementations
|
||||
*
|
||||
* @alias module:crypto/algorithms/base.DecryptionAlgorithm
|
||||
* @param {object} params parameters
|
||||
* @param {string} params.userId The UserID for the local user
|
||||
* @param {module:crypto} params.crypto crypto core
|
||||
* @param {module:crypto/OlmDevice} params.olmDevice olm.js wrapper
|
||||
* @param {MatrixClient} baseApis base matrix api interface
|
||||
* @param {string=} params.roomId The ID of the room we will be receiving
|
||||
* from. Null for to-device events.
|
||||
*/
|
||||
export abstract class DecryptionAlgorithm {
|
||||
protected readonly userId: string;
|
||||
@ -167,12 +144,9 @@ export abstract class DecryptionAlgorithm {
|
||||
/**
|
||||
* Decrypt an event
|
||||
*
|
||||
* @method module:crypto/algorithms/base.DecryptionAlgorithm#decryptEvent
|
||||
* @abstract
|
||||
* @param event - undecrypted event
|
||||
*
|
||||
* @param {MatrixEvent} event undecrypted event
|
||||
*
|
||||
* @return {Promise<module:crypto~EventDecryptionResult>} promise which
|
||||
* @returns promise which
|
||||
* resolves once we have finished decrypting. Rejects with an
|
||||
* `algorithms.DecryptionError` if there is a problem decrypting the event.
|
||||
*/
|
||||
@ -181,9 +155,7 @@ export abstract class DecryptionAlgorithm {
|
||||
/**
|
||||
* Handle a key event
|
||||
*
|
||||
* @method module:crypto/algorithms/base.DecryptionAlgorithm#onRoomKeyEvent
|
||||
*
|
||||
* @param {module:models/event.MatrixEvent} params event key event
|
||||
* @param params - event key event
|
||||
*/
|
||||
public async onRoomKeyEvent(params: MatrixEvent): Promise<void> {
|
||||
// ignore by default
|
||||
@ -192,8 +164,7 @@ export abstract class DecryptionAlgorithm {
|
||||
/**
|
||||
* Import a room key
|
||||
*
|
||||
* @param {module:crypto/OlmDevice.MegolmSessionData} session
|
||||
* @param {object} opts object
|
||||
* @param opts - object
|
||||
*/
|
||||
public async importRoomKey(session: IMegolmSessionData, opts: object): Promise<void> {
|
||||
// ignore by default
|
||||
@ -202,8 +173,7 @@ export abstract class DecryptionAlgorithm {
|
||||
/**
|
||||
* Determine if we have the keys necessary to respond to a room key request
|
||||
*
|
||||
* @param {module:crypto~IncomingRoomKeyRequest} keyRequest
|
||||
* @return {Promise<boolean>} true if we have the keys and could (theoretically) share
|
||||
* @returns true if we have the keys and could (theoretically) share
|
||||
* them; else false.
|
||||
*/
|
||||
public hasKeysForKeyRequest(keyRequest: IncomingRoomKeyRequest): Promise<boolean> {
|
||||
@ -213,7 +183,6 @@ export abstract class DecryptionAlgorithm {
|
||||
/**
|
||||
* Send the response to a room key request
|
||||
*
|
||||
* @param {module:crypto~IncomingRoomKeyRequest} keyRequest
|
||||
*/
|
||||
public shareKeysWithDevice(keyRequest: IncomingRoomKeyRequest): void {
|
||||
throw new Error("shareKeysWithDevice not supported for this DecryptionAlgorithm");
|
||||
@ -223,7 +192,7 @@ export abstract class DecryptionAlgorithm {
|
||||
* Retry decrypting all the events from a sender that haven't been
|
||||
* decrypted yet.
|
||||
*
|
||||
* @param {string} senderKey the sender's key
|
||||
* @param senderKey - the sender's key
|
||||
*/
|
||||
public async retryDecryptionFromSender(senderKey: string): Promise<boolean> {
|
||||
// ignore by default
|
||||
@ -237,13 +206,10 @@ export abstract class DecryptionAlgorithm {
|
||||
/**
|
||||
* Exception thrown when decryption fails
|
||||
*
|
||||
* @alias module:crypto/algorithms/base.DecryptionError
|
||||
* @param {string} msg user-visible message describing the problem
|
||||
* @param msg - user-visible message describing the problem
|
||||
*
|
||||
* @param {Object=} details key/value pairs reported in the logs but not shown
|
||||
* @param details - key/value pairs reported in the logs but not shown
|
||||
* to the user.
|
||||
*
|
||||
* @extends Error
|
||||
*/
|
||||
export class DecryptionError extends Error {
|
||||
public readonly detailedString: string;
|
||||
@ -268,16 +234,14 @@ function detailedStringForDecryptionError(err: DecryptionError, details?: Record
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception thrown specifically when we want to warn the user to consider
|
||||
* the security of their conversation before continuing
|
||||
*
|
||||
* @param {string} msg message describing the problem
|
||||
* @param {Object} devices userId -> {deviceId -> object}
|
||||
* set of unknown devices per user we're warning about
|
||||
* @extends Error
|
||||
*/
|
||||
export class UnknownDeviceError extends Error {
|
||||
/**
|
||||
* Exception thrown specifically when we want to warn the user to consider
|
||||
* the security of their conversation before continuing
|
||||
*
|
||||
* @param msg - message describing the problem
|
||||
* @param devices - set of unknown devices per user we're warning about
|
||||
*/
|
||||
public constructor(
|
||||
msg: string,
|
||||
public readonly devices: Record<string, Record<string, object>>,
|
||||
@ -292,15 +256,11 @@ export class UnknownDeviceError extends Error {
|
||||
/**
|
||||
* Registers an encryption/decryption class for a particular algorithm
|
||||
*
|
||||
* @param {string} algorithm algorithm tag to register for
|
||||
* @param algorithm - algorithm tag to register for
|
||||
*
|
||||
* @param {class} encryptor {@link
|
||||
* module:crypto/algorithms/base.EncryptionAlgorithm|EncryptionAlgorithm}
|
||||
* implementation
|
||||
* @param encryptor - {@link EncryptionAlgorithm} implementation
|
||||
*
|
||||
* @param {class} decryptor {@link
|
||||
* module:crypto/algorithms/base.DecryptionAlgorithm|DecryptionAlgorithm}
|
||||
* implementation
|
||||
* @param decryptor - {@link DecryptionAlgorithm} implementation
|
||||
*/
|
||||
export function registerAlgorithm<P extends IParams = IParams>(
|
||||
algorithm: string,
|
||||
|
@ -14,10 +14,6 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @module crypto/algorithms
|
||||
*/
|
||||
|
||||
import "./olm";
|
||||
import "./megolm";
|
||||
|
||||
|
@ -16,8 +16,6 @@ limitations under the License.
|
||||
|
||||
/**
|
||||
* Defines m.olm encryption/decryption
|
||||
*
|
||||
* @module crypto/algorithms/megolm
|
||||
*/
|
||||
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
@ -123,37 +121,27 @@ interface SharedWithData {
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @constructor
|
||||
*
|
||||
* @param {string} sessionId
|
||||
* @param {boolean} sharedHistory whether the session can be freely shared with
|
||||
* other group members, according to the room history visibility settings
|
||||
*
|
||||
* @property {string} sessionId
|
||||
* @property {Number} useCount number of times this session has been used
|
||||
* @property {Number} creationTime when the session was created (ms since the epoch)
|
||||
*
|
||||
* @property {object} sharedWithDevices
|
||||
* devices with which we have shared the session key
|
||||
* userId -> {deviceId -> SharedWithData}
|
||||
* @internal
|
||||
*/
|
||||
class OutboundSessionInfo {
|
||||
/** number of times this session has been used */
|
||||
public useCount = 0;
|
||||
/** when the session was created (ms since the epoch) */
|
||||
public creationTime: number;
|
||||
/** devices with which we have shared the session key `userId -> {deviceId -> SharedWithData}` */
|
||||
public sharedWithDevices: Record<string, Record<string, SharedWithData>> = {};
|
||||
public blockedDevicesNotified: Record<string, Record<string, boolean>> = {};
|
||||
|
||||
/**
|
||||
* @param sharedHistory - whether the session can be freely shared with
|
||||
* other group members, according to the room history visibility settings
|
||||
*/
|
||||
public constructor(public readonly sessionId: string, public readonly sharedHistory = false) {
|
||||
this.creationTime = new Date().getTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if it's time to rotate the session
|
||||
*
|
||||
* @param {Number} rotationPeriodMsgs
|
||||
* @param {Number} rotationPeriodMs
|
||||
* @return {Boolean}
|
||||
*/
|
||||
public needsRotation(rotationPeriodMsgs: number, rotationPeriodMs: number): boolean {
|
||||
const sessionLifetime = new Date().getTime() - this.creationTime;
|
||||
@ -189,10 +177,10 @@ class OutboundSessionInfo {
|
||||
* Determine if this session has been shared with devices which it shouldn't
|
||||
* have been.
|
||||
*
|
||||
* @param {Object} devicesInRoom userId -> {deviceId -> object}
|
||||
* @param devicesInRoom - `userId -> {deviceId -> object}`
|
||||
* devices we should shared the session with.
|
||||
*
|
||||
* @return {Boolean} true if we have shared the session with devices which aren't
|
||||
* @returns true if we have shared the session with devices which aren't
|
||||
* in devicesInRoom.
|
||||
*/
|
||||
public sharedWithTooManyDevices(devicesInRoom: Record<string, Record<string, object>>): boolean {
|
||||
@ -228,11 +216,7 @@ class OutboundSessionInfo {
|
||||
/**
|
||||
* Megolm encryption implementation
|
||||
*
|
||||
* @constructor
|
||||
* @extends {module:crypto/algorithms/EncryptionAlgorithm}
|
||||
*
|
||||
* @param {object} params parameters, as per
|
||||
* {@link module:crypto/algorithms/EncryptionAlgorithm}
|
||||
* @param params - parameters, as per {@link EncryptionAlgorithm}
|
||||
*/
|
||||
export class MegolmEncryption extends EncryptionAlgorithm {
|
||||
// the most recent attempt to set up a session. This is used to serialise
|
||||
@ -265,15 +249,14 @@ export class MegolmEncryption extends EncryptionAlgorithm {
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @internal
|
||||
*
|
||||
* @param {module:models/room} room
|
||||
* @param {Object} devicesInRoom The devices in this room, indexed by user ID
|
||||
* @param {Object} blocked The devices that are blocked, indexed by user ID
|
||||
* @param {boolean} [singleOlmCreationPhase] Only perform one round of olm
|
||||
* @param devicesInRoom - The devices in this room, indexed by user ID
|
||||
* @param blocked - The devices that are blocked, indexed by user ID
|
||||
* @param singleOlmCreationPhase - Only perform one round of olm
|
||||
* session creation
|
||||
*
|
||||
* @return {Promise} Promise which resolves to the
|
||||
* @returns Promise which resolves to the
|
||||
* OutboundSessionInfo when setup is complete.
|
||||
*/
|
||||
private async ensureOutboundSession(
|
||||
@ -488,11 +471,10 @@ export class MegolmEncryption extends EncryptionAlgorithm {
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @internal
|
||||
*
|
||||
* @param {boolean} sharedHistory
|
||||
*
|
||||
* @return {module:crypto/algorithms/megolm.OutboundSessionInfo} session
|
||||
* @returns session
|
||||
*/
|
||||
private async prepareNewSession(sharedHistory: boolean): Promise<OutboundSessionInfo> {
|
||||
const sessionId = this.olmDevice.createOutboundGroupSession();
|
||||
@ -514,15 +496,15 @@ export class MegolmEncryption extends EncryptionAlgorithm {
|
||||
* Determines what devices in devicesByUser don't have an olm session as given
|
||||
* in devicemap.
|
||||
*
|
||||
* @private
|
||||
* @internal
|
||||
*
|
||||
* @param {object} devicemap the devices that have olm sessions, as returned by
|
||||
* @param devicemap - the devices that have olm sessions, as returned by
|
||||
* olmlib.ensureOlmSessionsForDevices.
|
||||
* @param {object} devicesByUser a map of user IDs to array of deviceInfo
|
||||
* @param {array} [noOlmDevices] an array to fill with devices that don't have
|
||||
* @param devicesByUser - a map of user IDs to array of deviceInfo
|
||||
* @param noOlmDevices - an array to fill with devices that don't have
|
||||
* olm sessions
|
||||
*
|
||||
* @return {array} an array of devices that don't have olm sessions. If
|
||||
* @returns an array of devices that don't have olm sessions. If
|
||||
* noOlmDevices is specified, then noOlmDevices will be returned.
|
||||
*/
|
||||
private getDevicesWithoutSessions(
|
||||
@ -558,11 +540,11 @@ export class MegolmEncryption extends EncryptionAlgorithm {
|
||||
* Splits the user device map into multiple chunks to reduce the number of
|
||||
* devices we encrypt to per API call.
|
||||
*
|
||||
* @private
|
||||
* @internal
|
||||
*
|
||||
* @param {object} devicesByUser map from userid to list of devices
|
||||
* @param devicesByUser - map from userid to list of devices
|
||||
*
|
||||
* @return {array<array<object>>} the blocked devices, split into chunks
|
||||
* @returns the blocked devices, split into chunks
|
||||
*/
|
||||
private splitDevices<T extends DeviceInfo | IBlockedDevice>(
|
||||
devicesByUser: Record<string, Record<string, { device: T }>>,
|
||||
@ -599,18 +581,16 @@ export class MegolmEncryption extends EncryptionAlgorithm {
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @internal
|
||||
*
|
||||
* @param {module:crypto/algorithms/megolm.OutboundSessionInfo} session
|
||||
*
|
||||
* @param {number} chainIndex current chain index
|
||||
* @param chainIndex - current chain index
|
||||
*
|
||||
* @param {object<userId, deviceInfo>} userDeviceMap
|
||||
* mapping from userId to deviceInfo
|
||||
* @param userDeviceMap - mapping from userId to deviceInfo
|
||||
*
|
||||
* @param {object} payload fields to include in the encrypted payload
|
||||
* @param payload - fields to include in the encrypted payload
|
||||
*
|
||||
* @return {Promise} Promise which resolves once the key sharing
|
||||
* @returns Promise which resolves once the key sharing
|
||||
* for the given userDeviceMap is generated and has been sent.
|
||||
*/
|
||||
private encryptAndSendKeysToDevices(
|
||||
@ -639,15 +619,14 @@ export class MegolmEncryption extends EncryptionAlgorithm {
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @internal
|
||||
*
|
||||
* @param {module:crypto/algorithms/megolm.OutboundSessionInfo} session
|
||||
*
|
||||
* @param {array<object>} userDeviceMap list of blocked devices to notify
|
||||
* @param userDeviceMap - list of blocked devices to notify
|
||||
*
|
||||
* @param {object} payload fields to include in the notification payload
|
||||
* @param payload - fields to include in the notification payload
|
||||
*
|
||||
* @return {Promise} Promise which resolves once the notifications
|
||||
* @returns Promise which resolves once the notifications
|
||||
* for the given userDeviceMap is generated and has been sent.
|
||||
*/
|
||||
private async sendBlockedNotificationsToDevices(
|
||||
@ -695,10 +674,10 @@ export class MegolmEncryption extends EncryptionAlgorithm {
|
||||
* Re-shares a megolm session key with devices if the key has already been
|
||||
* sent to them.
|
||||
*
|
||||
* @param {string} senderKey The key of the originating device for the session
|
||||
* @param {string} sessionId ID of the outbound session to share
|
||||
* @param {string} userId ID of the user who owns the target device
|
||||
* @param {module:crypto/deviceinfo} device The target device
|
||||
* @param senderKey - The key of the originating device for the session
|
||||
* @param sessionId - ID of the outbound session to share
|
||||
* @param userId - ID of the user who owns the target device
|
||||
* @param device - The target device
|
||||
*/
|
||||
public async reshareKeyWithDevice(
|
||||
senderKey: string,
|
||||
@ -792,26 +771,23 @@ export class MegolmEncryption extends EncryptionAlgorithm {
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @internal
|
||||
*
|
||||
* @param {module:crypto/algorithms/megolm.OutboundSessionInfo} session
|
||||
*
|
||||
* @param {object} key the session key as returned by
|
||||
* @param key - the session key as returned by
|
||||
* OlmDevice.getOutboundGroupSessionKey
|
||||
*
|
||||
* @param {object} payload the base to-device message payload for sharing keys
|
||||
* @param payload - the base to-device message payload for sharing keys
|
||||
*
|
||||
* @param {object<string, module:crypto/deviceinfo[]>} devicesByUser
|
||||
* map from userid to list of devices
|
||||
* @param devicesByUser - map from userid to list of devices
|
||||
*
|
||||
* @param {array<object>} errorDevices
|
||||
* array that will be populated with the devices that we can't get an
|
||||
* @param errorDevices - array that will be populated with the devices that we can't get an
|
||||
* olm session for
|
||||
*
|
||||
* @param {Number} [otkTimeout] The timeout in milliseconds when requesting
|
||||
* @param otkTimeout - The timeout in milliseconds when requesting
|
||||
* one-time keys for establishing new olm sessions.
|
||||
*
|
||||
* @param {Array} [failedServers] An array to fill with remote servers that
|
||||
* @param failedServers - An array to fill with remote servers that
|
||||
* failed to respond to one-time-key requests.
|
||||
*/
|
||||
private async shareKeyWithDevices(
|
||||
@ -866,11 +842,9 @@ export class MegolmEncryption extends EncryptionAlgorithm {
|
||||
/**
|
||||
* Notify devices that we weren't able to create olm sessions.
|
||||
*
|
||||
* @param {module:crypto/algorithms/megolm.OutboundSessionInfo} session
|
||||
*
|
||||
* @param {object} key
|
||||
*
|
||||
* @param {Array<object>} failedDevices the devices that we were unable to
|
||||
* @param failedDevices - the devices that we were unable to
|
||||
* create olm sessions for, as returned by shareKeyWithDevices
|
||||
*/
|
||||
private async notifyFailedOlmDevices(
|
||||
@ -927,10 +901,8 @@ export class MegolmEncryption extends EncryptionAlgorithm {
|
||||
/**
|
||||
* Notify blocked devices that they have been blocked.
|
||||
*
|
||||
* @param {module:crypto/algorithms/megolm.OutboundSessionInfo} session
|
||||
*
|
||||
* @param {object<string, object>} devicesByUser
|
||||
* map from userid to device ID to blocked data
|
||||
* @param devicesByUser - map from userid to device ID to blocked data
|
||||
*/
|
||||
private async notifyBlockedDevices(
|
||||
session: OutboundSessionInfo,
|
||||
@ -963,7 +935,7 @@ export class MegolmEncryption extends EncryptionAlgorithm {
|
||||
* Perform any background tasks that can be done before a message is ready to
|
||||
* send, in order to speed up sending of the message.
|
||||
*
|
||||
* @param {module:models/room} room the room the event is in
|
||||
* @param room - the room the event is in
|
||||
*/
|
||||
public prepareToEncrypt(room: Room): void {
|
||||
if (this.encryptionPreparation != null) {
|
||||
@ -1008,13 +980,9 @@ export class MegolmEncryption extends EncryptionAlgorithm {
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
* @param content - plaintext event content
|
||||
*
|
||||
* @param {module:models/room} room
|
||||
* @param {string} eventType
|
||||
* @param {object} content plaintext event content
|
||||
*
|
||||
* @return {Promise} Promise which resolves to the new event body
|
||||
* @returns Promise which resolves to the new event body
|
||||
*/
|
||||
public async encryptMessage(room: Room, eventType: string, content: IContent): Promise<IMegolmEncryptedContent> {
|
||||
logger.log(`Starting to encrypt event for ${this.roomId}`);
|
||||
@ -1103,7 +1071,7 @@ export class MegolmEncryption extends EncryptionAlgorithm {
|
||||
* unknown to the user. If so, warn the user, and mark them as known to
|
||||
* give the user a chance to go verify them before re-sending this message.
|
||||
*
|
||||
* @param {Object} devicesInRoom userId -> {deviceId -> object}
|
||||
* @param devicesInRoom - `userId -> {deviceId -> object}`
|
||||
* devices we should shared the session with.
|
||||
*/
|
||||
private checkForUnknownDevices(devicesInRoom: DeviceInfoMap): void {
|
||||
@ -1133,7 +1101,7 @@ export class MegolmEncryption extends EncryptionAlgorithm {
|
||||
* Remove unknown devices from a set of devices. The devicesInRoom parameter
|
||||
* will be modified.
|
||||
*
|
||||
* @param {Object} devicesInRoom userId -> {deviceId -> object}
|
||||
* @param devicesInRoom - `userId -> {deviceId -> object}`
|
||||
* devices we should shared the session with.
|
||||
*/
|
||||
private removeUnknownDevices(devicesInRoom: DeviceInfoMap): void {
|
||||
@ -1153,11 +1121,10 @@ export class MegolmEncryption extends EncryptionAlgorithm {
|
||||
/**
|
||||
* Get the list of unblocked devices for all users in the room
|
||||
*
|
||||
* @param {module:models/room} room
|
||||
* @param forceDistributeToUnverified if set to true will include the unverified devices
|
||||
* @param forceDistributeToUnverified - if set to true will include the unverified devices
|
||||
* even if setting is set to block them (useful for verification)
|
||||
*
|
||||
* @return {Promise} Promise which resolves to an array whose
|
||||
* @returns Promise which resolves to an array whose
|
||||
* first element is a map from userId to deviceId to deviceInfo indicating
|
||||
* the devices that messages should be encrypted to, and whose second
|
||||
* element is a map from userId to deviceId to data indicating the devices
|
||||
@ -1225,11 +1192,7 @@ export class MegolmEncryption extends EncryptionAlgorithm {
|
||||
/**
|
||||
* Megolm decryption implementation
|
||||
*
|
||||
* @constructor
|
||||
* @extends {module:crypto/algorithms/DecryptionAlgorithm}
|
||||
*
|
||||
* @param {object} params parameters, as per
|
||||
* {@link module:crypto/algorithms/DecryptionAlgorithm}
|
||||
* @param params - parameters, as per {@link DecryptionAlgorithm}
|
||||
*/
|
||||
export class MegolmDecryption extends DecryptionAlgorithm {
|
||||
// events which we couldn't decrypt due to unknown sessions /
|
||||
@ -1248,12 +1211,8 @@ export class MegolmDecryption extends DecryptionAlgorithm {
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*
|
||||
* @param {MatrixEvent} event
|
||||
*
|
||||
* returns a promise which resolves to a
|
||||
* {@link module:crypto~EventDecryptionResult} once we have finished
|
||||
* {@link EventDecryptionResult} once we have finished
|
||||
* decrypting, or rejects with an `algorithms.DecryptionError` if there is a
|
||||
* problem decrypting the event.
|
||||
*/
|
||||
@ -1394,9 +1353,8 @@ export class MegolmDecryption extends DecryptionAlgorithm {
|
||||
/**
|
||||
* Add an event to the list of those awaiting their session keys.
|
||||
*
|
||||
* @private
|
||||
* @internal
|
||||
*
|
||||
* @param {module:models/event.MatrixEvent} event
|
||||
*/
|
||||
private addEventToPendingList(event: MatrixEvent): void {
|
||||
const content = event.getWireContent();
|
||||
@ -1415,9 +1373,8 @@ export class MegolmDecryption extends DecryptionAlgorithm {
|
||||
/**
|
||||
* Remove an event from the list of those awaiting their session keys.
|
||||
*
|
||||
* @private
|
||||
* @internal
|
||||
*
|
||||
* @param {module:models/event.MatrixEvent} event
|
||||
*/
|
||||
private removeEventFromPendingList(event: MatrixEvent): void {
|
||||
const content = event.getWireContent();
|
||||
@ -1438,11 +1395,6 @@ export class MegolmDecryption extends DecryptionAlgorithm {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*
|
||||
* @param {module:models/event.MatrixEvent} event key event
|
||||
*/
|
||||
public async onRoomKeyEvent(event: MatrixEvent): Promise<void> {
|
||||
const content = event.getContent<Partial<IMessage["content"]>>();
|
||||
let senderKey = event.getSenderKey()!;
|
||||
@ -1619,9 +1571,7 @@ export class MegolmDecryption extends DecryptionAlgorithm {
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*
|
||||
* @param {module:models/event.MatrixEvent} event key event
|
||||
* @param event - key event
|
||||
*/
|
||||
public async onRoomKeyWithheldEvent(event: MatrixEvent): Promise<void> {
|
||||
const content = event.getContent();
|
||||
@ -1706,9 +1656,6 @@ export class MegolmDecryption extends DecryptionAlgorithm {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public hasKeysForKeyRequest(keyRequest: IncomingRoomKeyRequest): Promise<boolean> {
|
||||
const body = keyRequest.requestBody;
|
||||
|
||||
@ -1720,9 +1667,6 @@ export class MegolmDecryption extends DecryptionAlgorithm {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public shareKeysWithDevice(keyRequest: IncomingRoomKeyRequest): void {
|
||||
const userId = keyRequest.userId;
|
||||
const deviceId = keyRequest.deviceId;
|
||||
@ -1808,19 +1752,15 @@ export class MegolmDecryption extends DecryptionAlgorithm {
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*
|
||||
* @param {module:crypto/OlmDevice.MegolmSessionData} session
|
||||
* @param {object} [opts={}] options for the import
|
||||
* @param {boolean} [opts.untrusted] whether the key should be considered as untrusted
|
||||
* @param {string} [opts.source] where the key came from
|
||||
* @param untrusted - whether the key should be considered as untrusted
|
||||
* @param source - where the key came from
|
||||
*/
|
||||
public importRoomKey(
|
||||
session: IMegolmSessionData,
|
||||
opts: { untrusted?: boolean, source?: string } = {},
|
||||
{ untrusted, source }: { untrusted?: boolean, source?: string } = {},
|
||||
): Promise<void> {
|
||||
const extraSessionData: OlmGroupSessionExtraData = {};
|
||||
if (opts.untrusted || session.untrusted) {
|
||||
if (untrusted || session.untrusted) {
|
||||
extraSessionData.untrusted = true;
|
||||
}
|
||||
if (session["org.matrix.msc3061.shared_history"]) {
|
||||
@ -1836,7 +1776,7 @@ export class MegolmDecryption extends DecryptionAlgorithm {
|
||||
true,
|
||||
extraSessionData,
|
||||
).then(() => {
|
||||
if (opts.source !== "backup") {
|
||||
if (source !== "backup") {
|
||||
// don't wait for it to complete
|
||||
this.crypto.backupManager.backupGroupSession(
|
||||
session.sender_key, session.session_id,
|
||||
@ -1855,13 +1795,11 @@ export class MegolmDecryption extends DecryptionAlgorithm {
|
||||
* Have another go at decrypting events after we receive a key. Resolves once
|
||||
* decryption has been re-attempted on all events.
|
||||
*
|
||||
* @private
|
||||
* @param {String} senderKey
|
||||
* @param {String} sessionId
|
||||
* @param {Boolean} forceRedecryptIfUntrusted whether messages that were already
|
||||
* @internal
|
||||
* @param forceRedecryptIfUntrusted - whether messages that were already
|
||||
* successfully decrypted using untrusted keys should be re-decrypted
|
||||
*
|
||||
* @return {Boolean} whether all messages were successfully
|
||||
* @returns whether all messages were successfully
|
||||
* decrypted with trusted keys
|
||||
*/
|
||||
private async retryDecryption(
|
||||
|
@ -16,8 +16,6 @@ limitations under the License.
|
||||
|
||||
/**
|
||||
* Defines m.olm encryption/decryption
|
||||
*
|
||||
* @module crypto/algorithms/olm
|
||||
*/
|
||||
|
||||
import { logger } from '../../logger';
|
||||
@ -44,21 +42,17 @@ export interface IMessage {
|
||||
/**
|
||||
* Olm encryption implementation
|
||||
*
|
||||
* @constructor
|
||||
* @extends {module:crypto/algorithms/EncryptionAlgorithm}
|
||||
*
|
||||
* @param {object} params parameters, as per
|
||||
* {@link module:crypto/algorithms/EncryptionAlgorithm}
|
||||
* @param params - parameters, as per {@link EncryptionAlgorithm}
|
||||
*/
|
||||
class OlmEncryption extends EncryptionAlgorithm {
|
||||
private sessionPrepared = false;
|
||||
private prepPromise: Promise<void> | null = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @internal
|
||||
|
||||
* @param {string[]} roomMembers list of currently-joined users in the room
|
||||
* @return {Promise} Promise which resolves when setup is complete
|
||||
* @param roomMembers - list of currently-joined users in the room
|
||||
* @returns Promise which resolves when setup is complete
|
||||
*/
|
||||
private ensureSession(roomMembers: string[]): Promise<void> {
|
||||
if (this.prepPromise) {
|
||||
@ -83,13 +77,9 @@ class OlmEncryption extends EncryptionAlgorithm {
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
* @param content - plaintext event content
|
||||
*
|
||||
* @param {module:models/room} room
|
||||
* @param {string} eventType
|
||||
* @param {object} content plaintext event content
|
||||
*
|
||||
* @return {Promise} Promise which resolves to the new event body
|
||||
* @returns Promise which resolves to the new event body
|
||||
*/
|
||||
public async encryptMessage(room: Room, eventType: string, content: IContent): Promise<IOlmEncryptedContent> {
|
||||
// pick the list of recipients based on the membership list.
|
||||
@ -150,19 +140,12 @@ class OlmEncryption extends EncryptionAlgorithm {
|
||||
/**
|
||||
* Olm decryption implementation
|
||||
*
|
||||
* @constructor
|
||||
* @extends {module:crypto/algorithms/DecryptionAlgorithm}
|
||||
* @param {object} params parameters, as per
|
||||
* {@link module:crypto/algorithms/DecryptionAlgorithm}
|
||||
* @param params - parameters, as per {@link DecryptionAlgorithm}
|
||||
*/
|
||||
class OlmDecryption extends DecryptionAlgorithm {
|
||||
/**
|
||||
* @inheritdoc
|
||||
*
|
||||
* @param {MatrixEvent} event
|
||||
*
|
||||
* returns a promise which resolves to a
|
||||
* {@link module:crypto~EventDecryptionResult} once we have finished
|
||||
* {@link EventDecryptionResult} once we have finished
|
||||
* decrypting. Rejects with an `algorithms.DecryptionError` if there is a
|
||||
* problem decrypting the event.
|
||||
*/
|
||||
@ -275,10 +258,10 @@ class OlmDecryption extends DecryptionAlgorithm {
|
||||
/**
|
||||
* Attempt to decrypt an Olm message
|
||||
*
|
||||
* @param {string} theirDeviceIdentityKey Curve25519 identity key of the sender
|
||||
* @param {object} message message object, with 'type' and 'body' fields
|
||||
* @param theirDeviceIdentityKey - Curve25519 identity key of the sender
|
||||
* @param message - message object, with 'type' and 'body' fields
|
||||
*
|
||||
* @return {string} payload, if decrypted successfully.
|
||||
* @returns payload, if decrypted successfully.
|
||||
*/
|
||||
private decryptMessage(theirDeviceIdentityKey: string, message: IMessage): Promise<string> {
|
||||
// This is a wrapper that serialises decryptions of prekey messages, because
|
||||
|
@ -66,8 +66,7 @@ export interface IRecoveryKey {
|
||||
export interface ICreateSecretStorageOpts {
|
||||
/**
|
||||
* Function called to await a secret storage key creation flow.
|
||||
* Returns:
|
||||
* {Promise<Object>} Object with public key metadata, encoded private
|
||||
* @returns Promise resolving to an object with public key metadata, encoded private
|
||||
* recovery key which should be disposed of after displaying to the user,
|
||||
* and raw private key to avoid round tripping if needed.
|
||||
*/
|
||||
@ -131,6 +130,7 @@ export interface IImportOpts {
|
||||
}
|
||||
|
||||
export interface IImportRoomKeysOpts {
|
||||
/** called with an object that has a "stage" param */
|
||||
progressCallback?: (stage: IImportOpts) => void;
|
||||
untrusted?: boolean;
|
||||
source?: string; // TODO: Enum
|
||||
|
@ -15,8 +15,6 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @module crypto/backup
|
||||
*
|
||||
* Classes for dealing with key backup.
|
||||
*/
|
||||
|
||||
@ -134,7 +132,7 @@ export class BackupManager {
|
||||
*
|
||||
* Throws an error if a problem is detected.
|
||||
*
|
||||
* @param {IKeyBackupInfo} info the key backup info
|
||||
* @param info - the key backup info
|
||||
*/
|
||||
public static checkBackupVersion(info: IKeyBackupInfo): void {
|
||||
const Algorithm = algorithmsByName[info.algorithm];
|
||||
@ -276,7 +274,7 @@ export class BackupManager {
|
||||
* Forces a re-check of the key backup and enables/disables it
|
||||
* as appropriate.
|
||||
*
|
||||
* @return {Object} Object with backup info (as returned by
|
||||
* @returns Object with backup info (as returned by
|
||||
* getKeyBackupVersion) in backupInfo and
|
||||
* trust information (as returned by isKeyBackupTrusted)
|
||||
* in trustInfo.
|
||||
@ -309,15 +307,7 @@ export class BackupManager {
|
||||
/**
|
||||
* Check if the given backup info is trusted.
|
||||
*
|
||||
* @param {IKeyBackupInfo} backupInfo key backup info dict from /room_keys/version
|
||||
* @return {object} {
|
||||
* usable: [bool], // is the backup trusted, true iff there is a sig that is valid & from a trusted device
|
||||
* sigs: [
|
||||
* valid: [bool || null], // true: valid, false: invalid, null: cannot attempt validation
|
||||
* deviceId: [string],
|
||||
* device: [DeviceInfo || null],
|
||||
* ]
|
||||
* }
|
||||
* @param backupInfo - key backup info dict from /room_keys/version
|
||||
*/
|
||||
public async isKeyBackupTrusted(backupInfo?: IKeyBackupInfo): Promise<TrustInfo> {
|
||||
const ret = {
|
||||
@ -432,7 +422,7 @@ export class BackupManager {
|
||||
* Schedules sending all keys waiting to be sent to the backup, if not already
|
||||
* scheduled. Retries if necessary.
|
||||
*
|
||||
* @param maxDelay Maximum delay to wait in ms. 0 means no delay.
|
||||
* @param maxDelay - Maximum delay to wait in ms. 0 means no delay.
|
||||
*/
|
||||
public async scheduleKeyBackupSend(maxDelay = 10000): Promise<void> {
|
||||
if (this.sendingBackups) return;
|
||||
@ -490,8 +480,8 @@ export class BackupManager {
|
||||
* Take some e2e keys waiting to be backed up and send them
|
||||
* to the backup.
|
||||
*
|
||||
* @param {number} limit Maximum number of keys to back up
|
||||
* @returns {number} Number of sessions backed up
|
||||
* @param limit - Maximum number of keys to back up
|
||||
* @returns Number of sessions backed up
|
||||
*/
|
||||
public async backupPendingKeys(limit: number): Promise<number> {
|
||||
const sessions = await this.baseApis.crypto!.cryptoStore.getSessionsNeedingBackup(limit);
|
||||
@ -573,7 +563,7 @@ export class BackupManager {
|
||||
/**
|
||||
* Marks all group sessions as needing to be backed up without scheduling
|
||||
* them to upload in the background.
|
||||
* @returns {Promise<int>} Resolves to the number of sessions now requiring a backup
|
||||
* @returns Promise which resolves to the number of sessions now requiring a backup
|
||||
* (which will be equal to the number of sessions in the store).
|
||||
*/
|
||||
public async flagAllGroupSessionsForBackup(): Promise<number> {
|
||||
@ -599,7 +589,7 @@ export class BackupManager {
|
||||
|
||||
/**
|
||||
* Counts the number of end to end session keys that are waiting to be backed up
|
||||
* @returns {Promise<int>} Resolves to the number of sessions requiring backup
|
||||
* @returns Promise which resolves to the number of sessions requiring backup
|
||||
*/
|
||||
public countSessionsNeedingBackup(): Promise<number> {
|
||||
return this.baseApis.crypto!.cryptoStore.countSessionsNeedingBackup();
|
||||
|
@ -16,10 +16,6 @@ limitations under the License.
|
||||
|
||||
import { ISignatures } from "../@types/signed";
|
||||
|
||||
/**
|
||||
* @module crypto/deviceinfo
|
||||
*/
|
||||
|
||||
export interface IDevice {
|
||||
keys: Record<string, string>;
|
||||
algorithms: string[];
|
||||
@ -37,36 +33,15 @@ enum DeviceVerification {
|
||||
|
||||
/**
|
||||
* Information about a user's device
|
||||
*
|
||||
* @constructor
|
||||
* @alias module:crypto/deviceinfo
|
||||
*
|
||||
* @property {string} deviceId the ID of this device
|
||||
*
|
||||
* @property {string[]} algorithms list of algorithms supported by this device
|
||||
*
|
||||
* @property {Object.<string,string>} keys a map from
|
||||
* <key type>:<id> -> <base64-encoded key>>
|
||||
*
|
||||
* @property {module:crypto/deviceinfo.DeviceVerification} verified
|
||||
* whether the device has been verified/blocked by the user
|
||||
*
|
||||
* @property {boolean} known
|
||||
* whether the user knows of this device's existence (useful when warning
|
||||
* the user that a user has added new devices)
|
||||
*
|
||||
* @property {Object} unsigned additional data from the homeserver
|
||||
*
|
||||
* @param {string} deviceId id of the device
|
||||
*/
|
||||
export class DeviceInfo {
|
||||
/**
|
||||
* rehydrate a DeviceInfo from the session store
|
||||
*
|
||||
* @param {object} obj raw object from session store
|
||||
* @param {string} deviceId id of the device
|
||||
* @param obj - raw object from session store
|
||||
* @param deviceId - id of the device
|
||||
*
|
||||
* @return {module:crypto~DeviceInfo} new DeviceInfo
|
||||
* @returns new DeviceInfo
|
||||
*/
|
||||
public static fromStorage(obj: Partial<IDevice>, deviceId: string): DeviceInfo {
|
||||
const res = new DeviceInfo(deviceId);
|
||||
@ -79,28 +54,36 @@ export class DeviceInfo {
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @enum
|
||||
*/
|
||||
public static DeviceVerification = {
|
||||
VERIFIED: DeviceVerification.Verified,
|
||||
UNVERIFIED: DeviceVerification.Unverified,
|
||||
BLOCKED: DeviceVerification.Blocked,
|
||||
};
|
||||
|
||||
/** list of algorithms supported by this device */
|
||||
public algorithms: string[] = [];
|
||||
/** a map from `<key type>:<id> -> <base64-encoded key>` */
|
||||
public keys: Record<string, string> = {};
|
||||
/** whether the device has been verified/blocked by the user */
|
||||
public verified = DeviceVerification.Unverified;
|
||||
/**
|
||||
* whether the user knows of this device's existence
|
||||
* (useful when warning the user that a user has added new devices)
|
||||
*/
|
||||
public known = false;
|
||||
/** additional data from the homeserver */
|
||||
public unsigned: Record<string, any> = {};
|
||||
public signatures: ISignatures = {};
|
||||
|
||||
/**
|
||||
* @param deviceId - id of the device
|
||||
*/
|
||||
public constructor(public readonly deviceId: string) {}
|
||||
|
||||
/**
|
||||
* Prepare a DeviceInfo for JSON serialisation in the session store
|
||||
*
|
||||
* @return {object} deviceinfo with non-serialised members removed
|
||||
* @returns deviceinfo with non-serialised members removed
|
||||
*/
|
||||
public toStorage(): IDevice {
|
||||
return {
|
||||
@ -116,7 +99,7 @@ export class DeviceInfo {
|
||||
/**
|
||||
* Get the fingerprint for this device (ie, the Ed25519 key)
|
||||
*
|
||||
* @return {string} base64-encoded fingerprint of this device
|
||||
* @returns base64-encoded fingerprint of this device
|
||||
*/
|
||||
public getFingerprint(): string {
|
||||
return this.keys["ed25519:" + this.deviceId];
|
||||
@ -125,7 +108,7 @@ export class DeviceInfo {
|
||||
/**
|
||||
* Get the identity key for this device (ie, the Curve25519 key)
|
||||
*
|
||||
* @return {string} base64-encoded identity key of this device
|
||||
* @returns base64-encoded identity key of this device
|
||||
*/
|
||||
public getIdentityKey(): string {
|
||||
return this.keys["curve25519:" + this.deviceId];
|
||||
@ -134,7 +117,7 @@ export class DeviceInfo {
|
||||
/**
|
||||
* Get the configured display name for this device, if any
|
||||
*
|
||||
* @return {string?} displayname
|
||||
* @returns displayname
|
||||
*/
|
||||
public getDisplayName(): string | null {
|
||||
return this.unsigned.device_display_name || null;
|
||||
@ -143,7 +126,7 @@ export class DeviceInfo {
|
||||
/**
|
||||
* Returns true if this device is blocked
|
||||
*
|
||||
* @return {Boolean} true if blocked
|
||||
* @returns true if blocked
|
||||
*/
|
||||
public isBlocked(): boolean {
|
||||
return this.verified == DeviceVerification.Blocked;
|
||||
@ -152,7 +135,7 @@ export class DeviceInfo {
|
||||
/**
|
||||
* Returns true if this device is verified
|
||||
*
|
||||
* @return {Boolean} true if verified
|
||||
* @returns true if verified
|
||||
*/
|
||||
public isVerified(): boolean {
|
||||
return this.verified == DeviceVerification.Verified;
|
||||
@ -161,7 +144,7 @@ export class DeviceInfo {
|
||||
/**
|
||||
* Returns true if this device is unverified
|
||||
*
|
||||
* @return {Boolean} true if unverified
|
||||
* @returns true if unverified
|
||||
*/
|
||||
public isUnverified(): boolean {
|
||||
return this.verified == DeviceVerification.Unverified;
|
||||
@ -170,7 +153,7 @@ export class DeviceInfo {
|
||||
/**
|
||||
* Returns true if the user knows about this device's existence
|
||||
*
|
||||
* @return {Boolean} true if known
|
||||
* @returns true if known
|
||||
*/
|
||||
public isKnown(): boolean {
|
||||
return this.known === true;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -59,6 +59,10 @@ export interface IKeyBackupInfo {
|
||||
/* eslint-enable camelcase */
|
||||
|
||||
export interface IKeyBackupPrepareOpts {
|
||||
/**
|
||||
* Whether to use Secure Secret Storage to store the key encrypting key backups.
|
||||
* Optional, defaults to false.
|
||||
*/
|
||||
secureSecretStorage: boolean;
|
||||
}
|
||||
|
||||
|
@ -15,8 +15,6 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @module olmlib
|
||||
*
|
||||
* Utilities common to olm encryption algorithms
|
||||
*/
|
||||
|
||||
@ -55,22 +53,20 @@ export const MEGOLM_ALGORITHM = Algorithm.Megolm;
|
||||
export const MEGOLM_BACKUP_ALGORITHM = Algorithm.MegolmBackup;
|
||||
|
||||
export interface IOlmSessionResult {
|
||||
/** device info */
|
||||
device: DeviceInfo;
|
||||
/** base64 olm session id; null if no session could be established */
|
||||
sessionId: string | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypt an event payload for an Olm device
|
||||
*
|
||||
* @param {Object<string, string>} resultsObject The `ciphertext` property
|
||||
* @param resultsObject - The `ciphertext` property
|
||||
* of the m.room.encrypted event to which to add our result
|
||||
*
|
||||
* @param {string} ourUserId
|
||||
* @param {string} ourDeviceId
|
||||
* @param {module:crypto/OlmDevice} olmDevice olm.js wrapper
|
||||
* @param {string} recipientUserId
|
||||
* @param {module:crypto/deviceinfo} recipientDevice
|
||||
* @param {object} payloadFields fields to include in the encrypted payload
|
||||
* @param olmDevice - olm.js wrapper
|
||||
* @param payloadFields - fields to include in the encrypted payload
|
||||
*
|
||||
* Returns a promise which resolves (to undefined) when the payload
|
||||
* has been encrypted into `resultsObject`
|
||||
@ -145,17 +141,14 @@ interface IExistingOlmSession {
|
||||
* Get the existing olm sessions for the given devices, and the devices that
|
||||
* don't have olm sessions.
|
||||
*
|
||||
* @param {module:crypto/OlmDevice} olmDevice
|
||||
*
|
||||
* @param {MatrixClient} baseApis
|
||||
*
|
||||
* @param {object<string, module:crypto/deviceinfo[]>} devicesByUser
|
||||
* map from userid to list of devices to ensure sessions for
|
||||
* @param devicesByUser - map from userid to list of devices to ensure sessions for
|
||||
*
|
||||
* @return {Promise} resolves to an array. The first element of the array is a
|
||||
* @returns resolves to an array. The first element of the array is a
|
||||
* a map of user IDs to arrays of deviceInfo, representing the devices that
|
||||
* don't have established olm sessions. The second element of the array is
|
||||
* a map from userId to deviceId to {@link module:crypto~OlmSessionResult}
|
||||
* a map from userId to deviceId to {@link OlmSessionResult}
|
||||
*/
|
||||
export async function getExistingOlmSessions(
|
||||
olmDevice: OlmDevice,
|
||||
@ -197,27 +190,22 @@ export async function getExistingOlmSessions(
|
||||
/**
|
||||
* Try to make sure we have established olm sessions for the given devices.
|
||||
*
|
||||
* @param {module:crypto/OlmDevice} olmDevice
|
||||
* @param devicesByUser - map from userid to list of devices to ensure sessions for
|
||||
*
|
||||
* @param {MatrixClient} baseApis
|
||||
*
|
||||
* @param {object<string, module:crypto/deviceinfo[]>} devicesByUser
|
||||
* map from userid to list of devices to ensure sessions for
|
||||
*
|
||||
* @param {boolean} [force=false] If true, establish a new session even if one
|
||||
* @param force - If true, establish a new session even if one
|
||||
* already exists.
|
||||
*
|
||||
* @param {Number} [otkTimeout] The timeout in milliseconds when requesting
|
||||
* @param otkTimeout - The timeout in milliseconds when requesting
|
||||
* one-time keys for establishing new olm sessions.
|
||||
*
|
||||
* @param {Array} [failedServers] An array to fill with remote servers that
|
||||
* @param failedServers - An array to fill with remote servers that
|
||||
* failed to respond to one-time-key requests.
|
||||
*
|
||||
* @param {Logger} [log] A possibly customised log
|
||||
* @param log - A possibly customised log
|
||||
*
|
||||
* @return {Promise} resolves once the sessions are complete, to
|
||||
* @returns resolves once the sessions are complete, to
|
||||
* an Object mapping from userId to deviceId to
|
||||
* {@link module:crypto~OlmSessionResult}
|
||||
* {@link OlmSessionResult}
|
||||
*/
|
||||
export async function ensureOlmSessionsForDevices(
|
||||
olmDevice: OlmDevice,
|
||||
@ -442,15 +430,15 @@ export interface IObject {
|
||||
/**
|
||||
* Verify the signature on an object
|
||||
*
|
||||
* @param {module:crypto/OlmDevice} olmDevice olm wrapper to use for verify op
|
||||
* @param olmDevice - olm wrapper to use for verify op
|
||||
*
|
||||
* @param {Object} obj object to check signature on.
|
||||
* @param obj - object to check signature on.
|
||||
*
|
||||
* @param {string} signingUserId ID of the user whose signature should be checked
|
||||
* @param signingUserId - ID of the user whose signature should be checked
|
||||
*
|
||||
* @param {string} signingDeviceId ID of the device whose signature should be checked
|
||||
* @param signingDeviceId - ID of the device whose signature should be checked
|
||||
*
|
||||
* @param {string} signingKey base64-ed ed25519 public key
|
||||
* @param signingKey - base64-ed ed25519 public key
|
||||
*
|
||||
* Returns a promise which resolves (to undefined) if the the signature is good,
|
||||
* or rejects with an Error if it is bad.
|
||||
@ -485,13 +473,13 @@ export async function verifySignature(
|
||||
|
||||
/**
|
||||
* Sign a JSON object using public key cryptography
|
||||
* @param {Object} obj Object to sign. The object will be modified to include
|
||||
* @param obj - Object to sign. The object will be modified to include
|
||||
* the new signature
|
||||
* @param {Olm.PkSigning|Uint8Array} key the signing object or the private key
|
||||
* @param key - the signing object or the private key
|
||||
* seed
|
||||
* @param {string} userId The user ID who owns the signing key
|
||||
* @param {string} pubKey The public key (ignored if key is a seed)
|
||||
* @returns {string} the signature for the object
|
||||
* @param userId - The user ID who owns the signing key
|
||||
* @param pubKey - The public key (ignored if key is a seed)
|
||||
* @returns the signature for the object
|
||||
*/
|
||||
export function pkSign(obj: object & IObject, key: Uint8Array | PkSigning, userId: string, pubKey: string): string {
|
||||
let createdKey = false;
|
||||
@ -521,9 +509,9 @@ export function pkSign(obj: object & IObject, key: Uint8Array | PkSigning, userI
|
||||
|
||||
/**
|
||||
* Verify a signed JSON object
|
||||
* @param {Object} obj Object to verify
|
||||
* @param {string} pubKey The public key to use to verify
|
||||
* @param {string} userId The user ID who signed the object
|
||||
* @param obj - Object to verify
|
||||
* @param pubKey - The public key to use to verify
|
||||
* @param userId - The user ID who signed the object
|
||||
*/
|
||||
export function pkVerify(obj: IObject, pubKey: string, userId: string): void {
|
||||
const keyId = "ed25519:" + pubKey;
|
||||
@ -563,8 +551,8 @@ export function isOlmEncrypted(event: MatrixEvent): boolean {
|
||||
|
||||
/**
|
||||
* Encode a typed array of uint8 as base64.
|
||||
* @param {Uint8Array} uint8Array The data to encode.
|
||||
* @return {string} The base64.
|
||||
* @param uint8Array - The data to encode.
|
||||
* @returns The base64.
|
||||
*/
|
||||
export function encodeBase64(uint8Array: ArrayBuffer | Uint8Array): string {
|
||||
return Buffer.from(uint8Array).toString("base64");
|
||||
@ -572,8 +560,8 @@ export function encodeBase64(uint8Array: ArrayBuffer | Uint8Array): string {
|
||||
|
||||
/**
|
||||
* Encode a typed array of uint8 as unpadded base64.
|
||||
* @param {Uint8Array} uint8Array The data to encode.
|
||||
* @return {string} The unpadded base64.
|
||||
* @param uint8Array - The data to encode.
|
||||
* @returns The unpadded base64.
|
||||
*/
|
||||
export function encodeUnpaddedBase64(uint8Array: ArrayBuffer | Uint8Array): string {
|
||||
return encodeBase64(uint8Array).replace(/=+$/g, '');
|
||||
@ -581,8 +569,8 @@ export function encodeUnpaddedBase64(uint8Array: ArrayBuffer | Uint8Array): stri
|
||||
|
||||
/**
|
||||
* Decode a base64 string to a typed array of uint8.
|
||||
* @param {string} base64 The base64 to decode.
|
||||
* @return {Uint8Array} The decoded data.
|
||||
* @param base64 - The base64 to decode.
|
||||
* @returns The decoded data.
|
||||
*/
|
||||
export function decodeBase64(base64: string): Uint8Array {
|
||||
return Buffer.from(base64, "base64");
|
||||
|
@ -30,8 +30,6 @@ import { IEncryptedPayload } from "../aes";
|
||||
|
||||
/**
|
||||
* Internal module. Definitions for storage for the crypto module
|
||||
*
|
||||
* @module
|
||||
*/
|
||||
|
||||
export interface SecretStorePrivateKeys {
|
||||
@ -46,8 +44,6 @@ export interface SecretStorePrivateKeys {
|
||||
|
||||
/**
|
||||
* Abstraction of things that can store data required for end-to-end encryption
|
||||
*
|
||||
* @interface CryptoStore
|
||||
*/
|
||||
export interface CryptoStore {
|
||||
startup(): Promise<CryptoStore>;
|
||||
@ -197,32 +193,29 @@ export interface IWithheld {
|
||||
|
||||
/**
|
||||
* Represents an outgoing room key request
|
||||
*
|
||||
* @typedef {Object} OutgoingRoomKeyRequest
|
||||
*
|
||||
* @property {string} requestId 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.
|
||||
*
|
||||
* @property {string?} cancellationTxnId
|
||||
* transaction id for the cancellation, if any
|
||||
*
|
||||
* @property {Array<{userId: string, deviceId: string}>} recipients
|
||||
* list of recipients for the request
|
||||
*
|
||||
* @property {module:crypto~RoomKeyRequestBody} requestBody
|
||||
* parameters for the request.
|
||||
*
|
||||
* @property {Number} state current state of this request (states are defined
|
||||
* in {@link module:crypto/OutgoingRoomKeyRequestManager~ROOM_KEY_REQUEST_STATES})
|
||||
*/
|
||||
export interface OutgoingRoomKeyRequest {
|
||||
/**
|
||||
* Unique id for this request. Used for both an id within the request for later pairing with a cancellation,
|
||||
* and for the transaction id when sending the to_device messages to our local server.
|
||||
*/
|
||||
requestId: string;
|
||||
requestTxnId?: string;
|
||||
/**
|
||||
* Transaction id for the cancellation, if any
|
||||
*/
|
||||
cancellationTxnId?: string;
|
||||
/**
|
||||
* List of recipients for the request
|
||||
*/
|
||||
recipients: IRoomKeyRequestRecipient[];
|
||||
/**
|
||||
* Parameters for the request
|
||||
*/
|
||||
requestBody: IRoomKeyRequestBody;
|
||||
/**
|
||||
* current state of this request (states are defined in {@link OutgoingRoomKeyRequestManager})
|
||||
*/
|
||||
state: RoomKeyRequestState;
|
||||
}
|
||||
|
||||
|
@ -39,14 +39,11 @@ 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.
|
||||
*
|
||||
* @implements {module:crypto/store/base~CryptoStore}
|
||||
*/
|
||||
export class Backend implements CryptoStore {
|
||||
private nextTxnId = 0;
|
||||
|
||||
/**
|
||||
* @param {IDBDatabase} db
|
||||
*/
|
||||
public constructor(private db: IDBDatabase) {
|
||||
// make sure we close the db on `onversionchange` - otherwise
|
||||
@ -71,10 +68,9 @@ export class Backend implements CryptoStore {
|
||||
* Look for an existing outgoing room key request, and if none is found,
|
||||
* add a new one
|
||||
*
|
||||
* @param {module:crypto/store/base~OutgoingRoomKeyRequest} request
|
||||
*
|
||||
* @returns {Promise} resolves to
|
||||
* {@link module:crypto/store/base~OutgoingRoomKeyRequest}: either the
|
||||
* @returns resolves to
|
||||
* {@link OutgoingRoomKeyRequest}: either the
|
||||
* same instance as passed in, or the existing one.
|
||||
*/
|
||||
public getOrAddOutgoingRoomKeyRequest(request: OutgoingRoomKeyRequest): Promise<OutgoingRoomKeyRequest> {
|
||||
@ -113,11 +109,10 @@ export class Backend implements CryptoStore {
|
||||
/**
|
||||
* Look for an existing room key request
|
||||
*
|
||||
* @param {module:crypto~RoomKeyRequestBody} requestBody
|
||||
* existing request to look for
|
||||
* @param requestBody - existing request to look for
|
||||
*
|
||||
* @return {Promise} resolves to the matching
|
||||
* {@link module:crypto/store/base~OutgoingRoomKeyRequest}, or null if
|
||||
* @returns resolves to the matching
|
||||
* {@link OutgoingRoomKeyRequest}, or null if
|
||||
* not found
|
||||
*/
|
||||
public getOutgoingRoomKeyRequest(requestBody: IRoomKeyRequestBody): Promise<OutgoingRoomKeyRequest | null> {
|
||||
@ -134,13 +129,12 @@ export class Backend implements CryptoStore {
|
||||
/**
|
||||
* look for an existing room key request in the db
|
||||
*
|
||||
* @private
|
||||
* @param {IDBTransaction} txn database transaction
|
||||
* @param {module:crypto~RoomKeyRequestBody} requestBody
|
||||
* existing request to look for
|
||||
* @param {Function} callback function to call with the results of the
|
||||
* @internal
|
||||
* @param txn - database transaction
|
||||
* @param requestBody - existing request to look for
|
||||
* @param callback - function to call with the results of the
|
||||
* search. Either passed a matching
|
||||
* {@link module:crypto/store/base~OutgoingRoomKeyRequest}, or null if
|
||||
* {@link OutgoingRoomKeyRequest}, or null if
|
||||
* not found.
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
@ -181,10 +175,10 @@ export class Backend implements CryptoStore {
|
||||
/**
|
||||
* Look for room key requests by state
|
||||
*
|
||||
* @param {Array<Number>} wantedStates list of acceptable states
|
||||
* @param wantedStates - list of acceptable states
|
||||
*
|
||||
* @return {Promise} resolves to the a
|
||||
* {@link module:crypto/store/base~OutgoingRoomKeyRequest}, or null if
|
||||
* @returns resolves to the a
|
||||
* {@link OutgoingRoomKeyRequest}, or null if
|
||||
* there are no pending requests in those states. If there are multiple
|
||||
* requests in those states, an arbitrary one is chosen.
|
||||
*/
|
||||
@ -233,8 +227,7 @@ export class Backend implements CryptoStore {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Number} wantedState
|
||||
* @return {Promise<Array<*>>} All elements in a given state
|
||||
* @returns All elements in a given state
|
||||
*/
|
||||
public getAllOutgoingRoomKeyRequestsByState(wantedState: number): Promise<OutgoingRoomKeyRequest[]> {
|
||||
return new Promise((resolve, reject) => {
|
||||
@ -294,12 +287,12 @@ export class Backend implements CryptoStore {
|
||||
* Look for an existing room key request by id and state, and update it if
|
||||
* found
|
||||
*
|
||||
* @param {string} requestId ID of request to update
|
||||
* @param {number} expectedState state we expect to find the request in
|
||||
* @param {Object} updates name/value map of updates to apply
|
||||
* @param requestId - ID of request to update
|
||||
* @param expectedState - state we expect to find the request in
|
||||
* @param updates - name/value map of updates to apply
|
||||
*
|
||||
* @returns {Promise} resolves to
|
||||
* {@link module:crypto/store/base~OutgoingRoomKeyRequest}
|
||||
* @returns resolves to
|
||||
* {@link OutgoingRoomKeyRequest}
|
||||
* updated request, or null if no matching row was found
|
||||
*/
|
||||
public updateOutgoingRoomKeyRequest(
|
||||
@ -337,10 +330,10 @@ export class Backend implements CryptoStore {
|
||||
* Look for an existing room key request by id and state, and delete it if
|
||||
* found
|
||||
*
|
||||
* @param {string} requestId ID of request to update
|
||||
* @param {number} expectedState state we expect to find the request in
|
||||
* @param requestId - ID of request to update
|
||||
* @param expectedState - state we expect to find the request in
|
||||
*
|
||||
* @returns {Promise} resolves once the operation is completed
|
||||
* @returns resolves once the operation is completed
|
||||
*/
|
||||
public deleteOutgoingRoomKeyRequest(
|
||||
requestId: string,
|
||||
|
@ -39,15 +39,11 @@ import { InboundGroupSessionData } from "../OlmDevice";
|
||||
|
||||
/**
|
||||
* Internal module. indexeddb storage for e2e.
|
||||
*
|
||||
* @module
|
||||
*/
|
||||
|
||||
/**
|
||||
* An implementation of CryptoStore, which is normally backed by an indexeddb,
|
||||
* but with fallback to MemoryCryptoStore.
|
||||
*
|
||||
* @implements {module:crypto/store/base~CryptoStore}
|
||||
*/
|
||||
export class IndexedDBCryptoStore implements CryptoStore {
|
||||
public static STORE_ACCOUNT = 'account';
|
||||
@ -70,8 +66,8 @@ export class IndexedDBCryptoStore implements CryptoStore {
|
||||
/**
|
||||
* Create a new IndexedDBCryptoStore
|
||||
*
|
||||
* @param {IDBFactory} indexedDB global indexedDB instance
|
||||
* @param {string} dbName name of db to connect to
|
||||
* @param indexedDB - global indexedDB instance
|
||||
* @param dbName - name of db to connect to
|
||||
*/
|
||||
public constructor(private readonly indexedDB: IDBFactory, private readonly dbName: string) {}
|
||||
|
||||
@ -81,7 +77,7 @@ export class IndexedDBCryptoStore implements CryptoStore {
|
||||
*
|
||||
* This must be called before the store can be used.
|
||||
*
|
||||
* @return {Promise} resolves to either an IndexedDBCryptoStoreBackend.Backend,
|
||||
* @returns resolves to either an IndexedDBCryptoStoreBackend.Backend,
|
||||
* or a MemoryCryptoStore
|
||||
*/
|
||||
public startup(): Promise<CryptoStore> {
|
||||
@ -167,7 +163,7 @@ export class IndexedDBCryptoStore implements CryptoStore {
|
||||
/**
|
||||
* Delete all data from this store.
|
||||
*
|
||||
* @returns {Promise} resolves when the store has been cleared.
|
||||
* @returns resolves when the store has been cleared.
|
||||
*/
|
||||
public deleteAllData(): Promise<void> {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
@ -206,10 +202,9 @@ export class IndexedDBCryptoStore implements CryptoStore {
|
||||
* Look for an existing outgoing room key request, and if none is found,
|
||||
* add a new one
|
||||
*
|
||||
* @param {module:crypto/store/base~OutgoingRoomKeyRequest} request
|
||||
*
|
||||
* @returns {Promise} resolves to
|
||||
* {@link module:crypto/store/base~OutgoingRoomKeyRequest}: either the
|
||||
* @returns resolves to
|
||||
* {@link OutgoingRoomKeyRequest}: either the
|
||||
* same instance as passed in, or the existing one.
|
||||
*/
|
||||
public getOrAddOutgoingRoomKeyRequest(request: OutgoingRoomKeyRequest): Promise<OutgoingRoomKeyRequest> {
|
||||
@ -219,11 +214,10 @@ export class IndexedDBCryptoStore implements CryptoStore {
|
||||
/**
|
||||
* Look for an existing room key request
|
||||
*
|
||||
* @param {module:crypto~RoomKeyRequestBody} requestBody
|
||||
* existing request to look for
|
||||
* @param requestBody - existing request to look for
|
||||
*
|
||||
* @return {Promise} resolves to the matching
|
||||
* {@link module:crypto/store/base~OutgoingRoomKeyRequest}, or null if
|
||||
* @returns resolves to the matching
|
||||
* {@link OutgoingRoomKeyRequest}, or null if
|
||||
* not found
|
||||
*/
|
||||
public getOutgoingRoomKeyRequest(requestBody: IRoomKeyRequestBody): Promise<OutgoingRoomKeyRequest | null> {
|
||||
@ -233,10 +227,10 @@ export class IndexedDBCryptoStore implements CryptoStore {
|
||||
/**
|
||||
* Look for room key requests by state
|
||||
*
|
||||
* @param {Array<Number>} wantedStates list of acceptable states
|
||||
* @param wantedStates - list of acceptable states
|
||||
*
|
||||
* @return {Promise} resolves to the a
|
||||
* {@link module:crypto/store/base~OutgoingRoomKeyRequest}, or null if
|
||||
* @returns resolves to the a
|
||||
* {@link OutgoingRoomKeyRequest}, or null if
|
||||
* there are no pending requests in those states. If there are multiple
|
||||
* requests in those states, an arbitrary one is chosen.
|
||||
*/
|
||||
@ -248,8 +242,7 @@ export class IndexedDBCryptoStore implements CryptoStore {
|
||||
* Look for room key requests by state –
|
||||
* unlike above, return a list of all entries in one state.
|
||||
*
|
||||
* @param {Number} wantedState
|
||||
* @return {Promise<Array<*>>} Returns an array of requests in the given state
|
||||
* @returns Returns an array of requests in the given state
|
||||
*/
|
||||
public getAllOutgoingRoomKeyRequestsByState(wantedState: number): Promise<OutgoingRoomKeyRequest[]> {
|
||||
return this.backend!.getAllOutgoingRoomKeyRequestsByState(wantedState);
|
||||
@ -258,12 +251,12 @@ export class IndexedDBCryptoStore implements CryptoStore {
|
||||
/**
|
||||
* Look for room key requests by target device and state
|
||||
*
|
||||
* @param {string} userId Target user ID
|
||||
* @param {string} deviceId Target device ID
|
||||
* @param {Array<Number>} wantedStates list of acceptable states
|
||||
* @param userId - Target user ID
|
||||
* @param deviceId - Target device ID
|
||||
* @param wantedStates - list of acceptable states
|
||||
*
|
||||
* @return {Promise} resolves to a list of all the
|
||||
* {@link module:crypto/store/base~OutgoingRoomKeyRequest}
|
||||
* @returns resolves to a list of all the
|
||||
* {@link OutgoingRoomKeyRequest}
|
||||
*/
|
||||
public getOutgoingRoomKeyRequestsByTarget(
|
||||
userId: string,
|
||||
@ -279,12 +272,12 @@ export class IndexedDBCryptoStore implements CryptoStore {
|
||||
* Look for an existing room key request by id and state, and update it if
|
||||
* found
|
||||
*
|
||||
* @param {string} requestId ID of request to update
|
||||
* @param {number} expectedState state we expect to find the request in
|
||||
* @param {Object} updates name/value map of updates to apply
|
||||
* @param requestId - ID of request to update
|
||||
* @param expectedState - state we expect to find the request in
|
||||
* @param updates - name/value map of updates to apply
|
||||
*
|
||||
* @returns {Promise} resolves to
|
||||
* {@link module:crypto/store/base~OutgoingRoomKeyRequest}
|
||||
* @returns resolves to
|
||||
* {@link OutgoingRoomKeyRequest}
|
||||
* updated request, or null if no matching row was found
|
||||
*/
|
||||
public updateOutgoingRoomKeyRequest(
|
||||
@ -301,10 +294,10 @@ export class IndexedDBCryptoStore implements CryptoStore {
|
||||
* Look for an existing room key request by id and state, and delete it if
|
||||
* found
|
||||
*
|
||||
* @param {string} requestId ID of request to update
|
||||
* @param {number} expectedState state we expect to find the request in
|
||||
* @param requestId - ID of request to update
|
||||
* @param expectedState - state we expect to find the request in
|
||||
*
|
||||
* @returns {Promise} resolves once the operation is completed
|
||||
* @returns resolves once the operation is completed
|
||||
*/
|
||||
public deleteOutgoingRoomKeyRequest(
|
||||
requestId: string,
|
||||
@ -319,8 +312,8 @@ export class IndexedDBCryptoStore implements CryptoStore {
|
||||
* Get the account pickle from the store.
|
||||
* This requires an active transaction. See doTxn().
|
||||
*
|
||||
* @param {*} txn An active transaction. See doTxn().
|
||||
* @param {function(string)} func Called with the account pickle
|
||||
* @param txn - An active transaction. See doTxn().
|
||||
* @param func - Called with the account pickle
|
||||
*/
|
||||
public getAccount(txn: IDBTransaction, func: (accountPickle: string | null) => void): void {
|
||||
this.backend!.getAccount(txn, func);
|
||||
@ -330,8 +323,8 @@ export class IndexedDBCryptoStore implements CryptoStore {
|
||||
* Write the account pickle to the store.
|
||||
* This requires an active transaction. See doTxn().
|
||||
*
|
||||
* @param {*} txn An active transaction. See doTxn().
|
||||
* @param {string} accountPickle The new account pickle to store.
|
||||
* @param txn - An active transaction. See doTxn().
|
||||
* @param accountPickle - The new account pickle to store.
|
||||
*/
|
||||
public storeAccount(txn: IDBTransaction, accountPickle: string): void {
|
||||
this.backend!.storeAccount(txn, accountPickle);
|
||||
@ -341,9 +334,9 @@ export class IndexedDBCryptoStore implements CryptoStore {
|
||||
* Get the public part of the cross-signing keys (eg. self-signing key,
|
||||
* user signing key).
|
||||
*
|
||||
* @param {*} txn An active transaction. See doTxn().
|
||||
* @param {function(string)} func Called with the account keys object:
|
||||
* { key_type: base64 encoded seed } where key type = user_signing_key_seed or self_signing_key_seed
|
||||
* @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
|
||||
*/
|
||||
public getCrossSigningKeys(
|
||||
txn: IDBTransaction,
|
||||
@ -353,9 +346,9 @@ export class IndexedDBCryptoStore implements CryptoStore {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {*} txn An active transaction. See doTxn().
|
||||
* @param {function(string)} func Called with the private key
|
||||
* @param {string} type A key type
|
||||
* @param txn - An active transaction. See doTxn().
|
||||
* @param func - Called with the private key
|
||||
* @param type - A key type
|
||||
*/
|
||||
public getSecretStorePrivateKey<K extends keyof SecretStorePrivateKeys>(
|
||||
txn: IDBTransaction,
|
||||
@ -368,8 +361,8 @@ export class IndexedDBCryptoStore implements CryptoStore {
|
||||
/**
|
||||
* Write the cross-signing keys back to the store
|
||||
*
|
||||
* @param {*} txn An active transaction. See doTxn().
|
||||
* @param {string} keys keys object as getCrossSigningKeys()
|
||||
* @param txn - An active transaction. See doTxn().
|
||||
* @param keys - keys object as getCrossSigningKeys()
|
||||
*/
|
||||
public storeCrossSigningKeys(txn: IDBTransaction, keys: Record<string, ICrossSigningKey>): void {
|
||||
this.backend!.storeCrossSigningKeys(txn, keys);
|
||||
@ -378,9 +371,9 @@ export class IndexedDBCryptoStore implements CryptoStore {
|
||||
/**
|
||||
* Write the cross-signing private keys back to the store
|
||||
*
|
||||
* @param {*} txn An active transaction. See doTxn().
|
||||
* @param {string} type The type of cross-signing private key to store
|
||||
* @param {string} key keys object as getCrossSigningKeys()
|
||||
* @param txn - An active transaction. See doTxn().
|
||||
* @param type - The type of cross-signing private key to store
|
||||
* @param key - keys object as getCrossSigningKeys()
|
||||
*/
|
||||
public storeSecretStorePrivateKey<K extends keyof SecretStorePrivateKeys>(
|
||||
txn: IDBTransaction,
|
||||
@ -394,8 +387,8 @@ export class IndexedDBCryptoStore implements CryptoStore {
|
||||
|
||||
/**
|
||||
* Returns the number of end-to-end sessions in the store
|
||||
* @param {*} txn An active transaction. See doTxn().
|
||||
* @param {function(int)} func Called with the count of sessions
|
||||
* @param txn - An active transaction. See doTxn().
|
||||
* @param func - Called with the count of sessions
|
||||
*/
|
||||
public countEndToEndSessions(txn: IDBTransaction, func: (count: number) => void): void {
|
||||
this.backend!.countEndToEndSessions(txn, func);
|
||||
@ -404,10 +397,10 @@ export class IndexedDBCryptoStore implements CryptoStore {
|
||||
/**
|
||||
* Retrieve a specific end-to-end session between the logged-in user
|
||||
* and another device.
|
||||
* @param {string} deviceKey The public key of the other device.
|
||||
* @param {string} sessionId The ID of the session to retrieve
|
||||
* @param {*} txn An active transaction. See doTxn().
|
||||
* @param {function(object)} func Called with A map from sessionId
|
||||
* @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
|
||||
@ -425,9 +418,9 @@ export class IndexedDBCryptoStore implements CryptoStore {
|
||||
/**
|
||||
* Retrieve the end-to-end sessions between the logged-in user and another
|
||||
* device.
|
||||
* @param {string} deviceKey The public key of the other device.
|
||||
* @param {*} txn An active transaction. See doTxn().
|
||||
* @param {function(object)} func Called with A map from sessionId
|
||||
* @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
|
||||
@ -443,8 +436,8 @@ export class IndexedDBCryptoStore implements CryptoStore {
|
||||
|
||||
/**
|
||||
* Retrieve all end-to-end sessions
|
||||
* @param {*} txn An active transaction. See doTxn().
|
||||
* @param {function(object)} func Called one for each session with
|
||||
* @param txn - An active transaction. See doTxn().
|
||||
* @param func - Called one for each session with
|
||||
* an object with, deviceKey, lastReceivedMessageTs, sessionId
|
||||
* and session keys.
|
||||
*/
|
||||
@ -454,10 +447,10 @@ export class IndexedDBCryptoStore implements CryptoStore {
|
||||
|
||||
/**
|
||||
* Store a session between the logged-in user and another device
|
||||
* @param {string} deviceKey The public key of the other device.
|
||||
* @param {string} sessionId The ID for this end-to-end session.
|
||||
* @param {string} sessionInfo Session information object
|
||||
* @param {*} txn An active transaction. See doTxn().
|
||||
* @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().
|
||||
*/
|
||||
public storeEndToEndSession(
|
||||
deviceKey: string,
|
||||
@ -485,10 +478,10 @@ export class IndexedDBCryptoStore implements CryptoStore {
|
||||
/**
|
||||
* Retrieve the end-to-end inbound group session for a given
|
||||
* server key and session ID
|
||||
* @param {string} senderCurve25519Key The sender's curve 25519 key
|
||||
* @param {string} sessionId The ID of the session
|
||||
* @param {*} txn An active transaction. See doTxn().
|
||||
* @param {function(object)} func Called with A map from sessionId
|
||||
* @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.
|
||||
*/
|
||||
public getEndToEndInboundGroupSession(
|
||||
@ -502,10 +495,10 @@ export class IndexedDBCryptoStore implements CryptoStore {
|
||||
|
||||
/**
|
||||
* Fetches all inbound group sessions in the store
|
||||
* @param {*} txn An active transaction. See doTxn().
|
||||
* @param {function(object)} func Called once for each group session
|
||||
* in the store with an object having keys {senderKey, sessionId,
|
||||
* sessionData}, then once with null to indicate the end of the list.
|
||||
* @param txn - An active transaction. See doTxn().
|
||||
* @param func - Called once for each group session
|
||||
* in the store with an object having keys `{senderKey, sessionId, sessionData}`,
|
||||
* then once with null to indicate the end of the list.
|
||||
*/
|
||||
public getAllEndToEndInboundGroupSessions(
|
||||
txn: IDBTransaction,
|
||||
@ -518,10 +511,10 @@ export class IndexedDBCryptoStore implements CryptoStore {
|
||||
* Adds an end-to-end inbound group session to the store.
|
||||
* If there already exists an inbound group session with the same
|
||||
* senderCurve25519Key and sessionID, the session will not be added.
|
||||
* @param {string} senderCurve25519Key The sender's curve 25519 key
|
||||
* @param {string} sessionId The ID of the session
|
||||
* @param {object} sessionData The session data structure
|
||||
* @param {*} txn An active transaction. See doTxn().
|
||||
* @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().
|
||||
*/
|
||||
public addEndToEndInboundGroupSession(
|
||||
senderCurve25519Key: string,
|
||||
@ -536,10 +529,10 @@ export class IndexedDBCryptoStore implements CryptoStore {
|
||||
* 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 {string} senderCurve25519Key The sender's curve 25519 key
|
||||
* @param {string} sessionId The ID of the session
|
||||
* @param {object} sessionData The session data structure
|
||||
* @param {*} txn An active transaction. See doTxn().
|
||||
* @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().
|
||||
*/
|
||||
public storeEndToEndInboundGroupSession(
|
||||
senderCurve25519Key: string,
|
||||
@ -568,8 +561,7 @@ export class IndexedDBCryptoStore implements CryptoStore {
|
||||
* These all need to be written out in full each time such that the snapshot
|
||||
* is always consistent, so they are stored in one object.
|
||||
*
|
||||
* @param {Object} deviceData
|
||||
* @param {*} txn An active transaction. See doTxn().
|
||||
* @param txn - An active transaction. See doTxn().
|
||||
*/
|
||||
public storeEndToEndDeviceData(deviceData: IDeviceData, txn: IDBTransaction): void {
|
||||
this.backend!.storeEndToEndDeviceData(deviceData, txn);
|
||||
@ -578,8 +570,8 @@ export class IndexedDBCryptoStore implements CryptoStore {
|
||||
/**
|
||||
* Get the state of all tracked devices
|
||||
*
|
||||
* @param {*} txn An active transaction. See doTxn().
|
||||
* @param {function(Object)} func Function called with the
|
||||
* @param txn - An active transaction. See doTxn().
|
||||
* @param func - Function called with the
|
||||
* device data
|
||||
*/
|
||||
public getEndToEndDeviceData(txn: IDBTransaction, func: (deviceData: IDeviceData | null) => void): void {
|
||||
@ -590,18 +582,18 @@ export class IndexedDBCryptoStore implements CryptoStore {
|
||||
|
||||
/**
|
||||
* Store the end-to-end state for a room.
|
||||
* @param {string} roomId The room's ID.
|
||||
* @param {object} roomInfo The end-to-end info for the room.
|
||||
* @param {*} txn An active transaction. See doTxn().
|
||||
* @param roomId - The room's ID.
|
||||
* @param roomInfo - The end-to-end info for the room.
|
||||
* @param txn - An active transaction. See doTxn().
|
||||
*/
|
||||
public storeEndToEndRoom(roomId: string, roomInfo: IRoomEncryption, txn: IDBTransaction): void {
|
||||
this.backend!.storeEndToEndRoom(roomId, roomInfo, txn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an object of roomId->roomInfo for all e2e rooms in the store
|
||||
* @param {*} txn An active transaction. See doTxn().
|
||||
* @param {function(Object)} func Function called with the end to end encrypted rooms
|
||||
* 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
|
||||
*/
|
||||
public getEndToEndRooms(txn: IDBTransaction, func: (rooms: Record<string, IRoomEncryption>) => void): void {
|
||||
this.backend!.getEndToEndRooms(txn, func);
|
||||
@ -611,9 +603,9 @@ export class IndexedDBCryptoStore implements CryptoStore {
|
||||
|
||||
/**
|
||||
* Get the inbound group sessions that need to be backed up.
|
||||
* @param {number} limit The maximum number of sessions to retrieve. 0
|
||||
* @param limit - The maximum number of sessions to retrieve. 0
|
||||
* for no limit.
|
||||
* @returns {Promise} resolves to an array of inbound group sessions
|
||||
* @returns resolves to an array of inbound group sessions
|
||||
*/
|
||||
public getSessionsNeedingBackup(limit: number): Promise<ISession[]> {
|
||||
return this.backend!.getSessionsNeedingBackup(limit);
|
||||
@ -621,8 +613,8 @@ export class IndexedDBCryptoStore implements CryptoStore {
|
||||
|
||||
/**
|
||||
* Count the inbound group sessions that need to be backed up.
|
||||
* @param {*} txn An active transaction. See doTxn(). (optional)
|
||||
* @returns {Promise} resolves to the number of sessions
|
||||
* @param txn - An active transaction. See doTxn(). (optional)
|
||||
* @returns resolves to the number of sessions
|
||||
*/
|
||||
public countSessionsNeedingBackup(txn?: IDBTransaction): Promise<number> {
|
||||
return this.backend!.countSessionsNeedingBackup(txn);
|
||||
@ -630,9 +622,9 @@ export class IndexedDBCryptoStore implements CryptoStore {
|
||||
|
||||
/**
|
||||
* Unmark sessions as needing to be backed up.
|
||||
* @param {Array<object>} sessions The sessions that need to be backed up.
|
||||
* @param {*} txn An active transaction. See doTxn(). (optional)
|
||||
* @returns {Promise} resolves when the sessions are unmarked
|
||||
* @param sessions - The sessions that need to be backed up.
|
||||
* @param txn - An active transaction. See doTxn(). (optional)
|
||||
* @returns resolves when the sessions are unmarked
|
||||
*/
|
||||
public unmarkSessionsNeedingBackup(sessions: ISession[], txn?: IDBTransaction): Promise<void> {
|
||||
return this.backend!.unmarkSessionsNeedingBackup(sessions, txn);
|
||||
@ -640,9 +632,9 @@ export class IndexedDBCryptoStore implements CryptoStore {
|
||||
|
||||
/**
|
||||
* Mark sessions as needing to be backed up.
|
||||
* @param {Array<object>} sessions The sessions that need to be backed up.
|
||||
* @param {*} txn An active transaction. See doTxn(). (optional)
|
||||
* @returns {Promise} resolves when the sessions are marked
|
||||
* @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
|
||||
*/
|
||||
public markSessionsNeedingBackup(sessions: ISession[], txn?: IDBTransaction): Promise<void> {
|
||||
return this.backend!.markSessionsNeedingBackup(sessions, txn);
|
||||
@ -650,10 +642,10 @@ export class IndexedDBCryptoStore implements CryptoStore {
|
||||
|
||||
/**
|
||||
* Add a shared-history group session for a room.
|
||||
* @param {string} roomId The room that the key belongs to
|
||||
* @param {string} senderKey The sender's curve 25519 key
|
||||
* @param {string} sessionId The ID of the session
|
||||
* @param {*} txn An active transaction. See doTxn(). (optional)
|
||||
* @param roomId - The room that the key belongs to
|
||||
* @param senderKey - The sender's curve 25519 key
|
||||
* @param sessionId - The ID of the session
|
||||
* @param txn - An active transaction. See doTxn(). (optional)
|
||||
*/
|
||||
public addSharedHistoryInboundGroupSession(
|
||||
roomId: string,
|
||||
@ -666,9 +658,9 @@ export class IndexedDBCryptoStore implements CryptoStore {
|
||||
|
||||
/**
|
||||
* Get the shared-history group session for a room.
|
||||
* @param {string} roomId The room that the key belongs to
|
||||
* @param {*} txn An active transaction. See doTxn(). (optional)
|
||||
* @returns {Promise} Resolves to an array of [senderKey, sessionId]
|
||||
* @param roomId - The room that the key belongs to
|
||||
* @param txn - An active transaction. See doTxn(). (optional)
|
||||
* @returns Promise which resolves to an array of [senderKey, sessionId]
|
||||
*/
|
||||
public getSharedHistoryInboundGroupSessions(
|
||||
roomId: string,
|
||||
@ -704,16 +696,16 @@ export class IndexedDBCryptoStore implements CryptoStore {
|
||||
* only be called within a callback of either this function or
|
||||
* one of the store functions operating on the same transaction.
|
||||
*
|
||||
* @param {string} mode 'readwrite' if you need to call setter
|
||||
* @param mode - 'readwrite' if you need to call setter
|
||||
* functions with this transaction. Otherwise, 'readonly'.
|
||||
* @param {string[]} stores List IndexedDBCryptoStore.STORE_*
|
||||
* @param stores - List IndexedDBCryptoStore.STORE_*
|
||||
* options representing all types of object that will be
|
||||
* accessed or written to with this transaction.
|
||||
* @param {function(*)} func Function called with the
|
||||
* @param func - Function called with the
|
||||
* transaction object: an opaque object that should be passed
|
||||
* to store functions.
|
||||
* @param {Logger} [log] A possibly customised log
|
||||
* @return {Promise} Promise that resolves with the result of the `func`
|
||||
* @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
|
||||
|
@ -28,8 +28,6 @@ import { InboundGroupSessionData } from "../OlmDevice";
|
||||
* some things backed by localStorage. It exists because indexedDB
|
||||
* is broken in Firefox private mode or set to, "will not remember
|
||||
* history".
|
||||
*
|
||||
* @module
|
||||
*/
|
||||
|
||||
const E2E_PREFIX = "crypto.";
|
||||
@ -62,9 +60,6 @@ function keyEndToEndRoomsPrefix(roomId: string): string {
|
||||
return KEY_ROOMS_PREFIX + roomId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @implements {module:crypto/store/base~CryptoStore}
|
||||
*/
|
||||
export class LocalStorageCryptoStore extends MemoryCryptoStore {
|
||||
public static exists(store: Storage): boolean {
|
||||
const length = store.length;
|
||||
@ -364,7 +359,7 @@ export class LocalStorageCryptoStore extends MemoryCryptoStore {
|
||||
/**
|
||||
* Delete all data from this store.
|
||||
*
|
||||
* @returns {Promise} Promise which resolves when the store has been cleared.
|
||||
* @returns Promise which resolves when the store has been cleared.
|
||||
*/
|
||||
public deleteAllData(): Promise<void> {
|
||||
this.store.removeItem(KEY_END_TO_END_ACCOUNT);
|
||||
|
@ -35,13 +35,8 @@ import { InboundGroupSessionData } from "../OlmDevice";
|
||||
|
||||
/**
|
||||
* Internal module. in-memory storage for e2e.
|
||||
*
|
||||
* @module
|
||||
*/
|
||||
|
||||
/**
|
||||
* @implements {module:crypto/store/base~CryptoStore}
|
||||
*/
|
||||
export class MemoryCryptoStore implements CryptoStore {
|
||||
private outgoingRoomKeyRequests: OutgoingRoomKeyRequest[] = [];
|
||||
private account: string | null = null;
|
||||
@ -65,7 +60,7 @@ export class MemoryCryptoStore implements CryptoStore {
|
||||
*
|
||||
* This must be called before the store can be used.
|
||||
*
|
||||
* @return {Promise} resolves to the store.
|
||||
* @returns resolves to the store.
|
||||
*/
|
||||
public async startup(): Promise<CryptoStore> {
|
||||
// No startup work to do for the memory store.
|
||||
@ -75,7 +70,7 @@ export class MemoryCryptoStore implements CryptoStore {
|
||||
/**
|
||||
* Delete all data from this store.
|
||||
*
|
||||
* @returns {Promise} Promise which resolves when the store has been cleared.
|
||||
* @returns Promise which resolves when the store has been cleared.
|
||||
*/
|
||||
public deleteAllData(): Promise<void> {
|
||||
return Promise.resolve();
|
||||
@ -85,10 +80,9 @@ export class MemoryCryptoStore implements CryptoStore {
|
||||
* Look for an existing outgoing room key request, and if none is found,
|
||||
* add a new one
|
||||
*
|
||||
* @param {module:crypto/store/base~OutgoingRoomKeyRequest} request
|
||||
*
|
||||
* @returns {Promise} resolves to
|
||||
* {@link module:crypto/store/base~OutgoingRoomKeyRequest}: either the
|
||||
* @returns resolves to
|
||||
* {@link OutgoingRoomKeyRequest}: either the
|
||||
* same instance as passed in, or the existing one.
|
||||
*/
|
||||
public getOrAddOutgoingRoomKeyRequest(request: OutgoingRoomKeyRequest): Promise<OutgoingRoomKeyRequest> {
|
||||
@ -122,11 +116,10 @@ export class MemoryCryptoStore implements CryptoStore {
|
||||
/**
|
||||
* Look for an existing room key request
|
||||
*
|
||||
* @param {module:crypto~RoomKeyRequestBody} requestBody
|
||||
* existing request to look for
|
||||
* @param requestBody - existing request to look for
|
||||
*
|
||||
* @return {Promise} resolves to the matching
|
||||
* {@link module:crypto/store/base~OutgoingRoomKeyRequest}, or null if
|
||||
* @returns resolves to the matching
|
||||
* {@link OutgoingRoomKeyRequest}, or null if
|
||||
* not found
|
||||
*/
|
||||
public getOutgoingRoomKeyRequest(requestBody: IRoomKeyRequestBody): Promise<OutgoingRoomKeyRequest | null> {
|
||||
@ -138,10 +131,9 @@ export class MemoryCryptoStore implements CryptoStore {
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @param {module:crypto~RoomKeyRequestBody} requestBody
|
||||
* existing request to look for
|
||||
* @param requestBody - existing request to look for
|
||||
*
|
||||
* @return {module:crypto/store/base~OutgoingRoomKeyRequest?}
|
||||
* @returns
|
||||
* the matching request, or null if not found
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
@ -157,10 +149,10 @@ export class MemoryCryptoStore implements CryptoStore {
|
||||
/**
|
||||
* Look for room key requests by state
|
||||
*
|
||||
* @param {Array<Number>} wantedStates list of acceptable states
|
||||
* @param wantedStates - list of acceptable states
|
||||
*
|
||||
* @return {Promise} resolves to the a
|
||||
* {@link module:crypto/store/base~OutgoingRoomKeyRequest}, or null if
|
||||
* @returns resolves to the a
|
||||
* {@link OutgoingRoomKeyRequest}, or null if
|
||||
* there are no pending requests in those states
|
||||
*/
|
||||
public getOutgoingRoomKeyRequestByState(wantedStates: number[]): Promise<OutgoingRoomKeyRequest | null> {
|
||||
@ -176,8 +168,7 @@ export class MemoryCryptoStore implements CryptoStore {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Number} wantedState
|
||||
* @return {Promise<Array<*>>} All OutgoingRoomKeyRequests in state
|
||||
* @returns All OutgoingRoomKeyRequests in state
|
||||
*/
|
||||
public getAllOutgoingRoomKeyRequestsByState(wantedState: number): Promise<OutgoingRoomKeyRequest[]> {
|
||||
return Promise.resolve(
|
||||
@ -210,12 +201,12 @@ export class MemoryCryptoStore implements CryptoStore {
|
||||
* Look for an existing room key request by id and state, and update it if
|
||||
* found
|
||||
*
|
||||
* @param {string} requestId ID of request to update
|
||||
* @param {number} expectedState state we expect to find the request in
|
||||
* @param {Object} updates name/value map of updates to apply
|
||||
* @param requestId - ID of request to update
|
||||
* @param expectedState - state we expect to find the request in
|
||||
* @param updates - name/value map of updates to apply
|
||||
*
|
||||
* @returns {Promise} resolves to
|
||||
* {@link module:crypto/store/base~OutgoingRoomKeyRequest}
|
||||
* @returns resolves to
|
||||
* {@link OutgoingRoomKeyRequest}
|
||||
* updated request, or null if no matching row was found
|
||||
*/
|
||||
public updateOutgoingRoomKeyRequest(
|
||||
@ -246,10 +237,10 @@ export class MemoryCryptoStore implements CryptoStore {
|
||||
* Look for an existing room key request by id and state, and delete it if
|
||||
* found
|
||||
*
|
||||
* @param {string} requestId ID of request to update
|
||||
* @param {number} expectedState state we expect to find the request in
|
||||
* @param requestId - ID of request to update
|
||||
* @param expectedState - state we expect to find the request in
|
||||
*
|
||||
* @returns {Promise} resolves once the operation is completed
|
||||
* @returns resolves once the operation is completed
|
||||
*/
|
||||
public deleteOutgoingRoomKeyRequest(
|
||||
requestId: string,
|
||||
|
@ -17,7 +17,6 @@ limitations under the License.
|
||||
|
||||
/**
|
||||
* Base class for verification methods.
|
||||
* @module crypto/verification/Base
|
||||
*/
|
||||
|
||||
import { MatrixEvent } from '../../models/event';
|
||||
@ -74,21 +73,19 @@ export class VerificationBase<
|
||||
*
|
||||
* <p>Subclasses must have a NAME class property.</p>
|
||||
*
|
||||
* @class
|
||||
*
|
||||
* @param {Object} channel the verification channel to send verification messages over.
|
||||
* @param channel - the verification channel to send verification messages over.
|
||||
* TODO: Channel types
|
||||
*
|
||||
* @param {MatrixClient} baseApis base matrix api interface
|
||||
* @param baseApis - base matrix api interface
|
||||
*
|
||||
* @param {string} userId the user ID that is being verified
|
||||
* @param userId - the user ID that is being verified
|
||||
*
|
||||
* @param {string} deviceId the device ID that is being verified
|
||||
* @param deviceId - the device ID that is being verified
|
||||
*
|
||||
* @param {object} [startEvent] the m.key.verification.start event that
|
||||
* @param startEvent - the m.key.verification.start event that
|
||||
* initiated this verification, if any
|
||||
*
|
||||
* @param {object} [request] the key verification request object related to
|
||||
* @param request - the key verification request object related to
|
||||
* this verification, if any
|
||||
*/
|
||||
public constructor(
|
||||
@ -279,7 +276,7 @@ export class VerificationBase<
|
||||
/**
|
||||
* Begin the key verification
|
||||
*
|
||||
* @returns {Promise} Promise which resolves when the verification has
|
||||
* @returns Promise which resolves when the verification has
|
||||
* completed.
|
||||
*/
|
||||
public verify(): Promise<void> {
|
||||
|
@ -16,8 +16,6 @@ limitations under the License.
|
||||
|
||||
/**
|
||||
* Error messages.
|
||||
*
|
||||
* @module crypto/verification/Error
|
||||
*/
|
||||
|
||||
import { MatrixEvent } from "../../models/event";
|
||||
|
@ -17,7 +17,6 @@ limitations under the License.
|
||||
/**
|
||||
* Verification method that is illegal to have (cannot possibly
|
||||
* do verification with this method).
|
||||
* @module crypto/verification/IllegalMethod
|
||||
*/
|
||||
|
||||
import { VerificationBase as Base, VerificationEvent, VerificationEventHandlerMap } from "./Base";
|
||||
@ -26,10 +25,6 @@ import { MatrixClient } from "../../client";
|
||||
import { MatrixEvent } from "../../models/event";
|
||||
import { VerificationRequest } from "./request/VerificationRequest";
|
||||
|
||||
/**
|
||||
* @class crypto/verification/IllegalMethod/IllegalMethod
|
||||
* @extends {module:crypto/verification/Base}
|
||||
*/
|
||||
export class IllegalMethod extends Base<VerificationEvent, VerificationEventHandlerMap> {
|
||||
public static factory(
|
||||
channel: IVerificationChannel,
|
||||
|
@ -16,7 +16,6 @@ limitations under the License.
|
||||
|
||||
/**
|
||||
* QR code key verification.
|
||||
* @module crypto/verification/QRCode
|
||||
*/
|
||||
|
||||
import { VerificationBase as Base, VerificationEventHandlerMap } from "./Base";
|
||||
@ -44,10 +43,6 @@ type EventHandlerMap = {
|
||||
[QrCodeEvent.ShowReciprocateQr]: (qr: IReciprocateQr) => void;
|
||||
} & VerificationEventHandlerMap;
|
||||
|
||||
/**
|
||||
* @class crypto/verification/QRCode/ReciprocateQRCode
|
||||
* @extends {module:crypto/verification/Base}
|
||||
*/
|
||||
export class ReciprocateQRCode extends Base<QrCodeEvent, EventHandlerMap> {
|
||||
public reciprocateQREvent?: IReciprocateQr;
|
||||
|
||||
|
@ -16,7 +16,6 @@ limitations under the License.
|
||||
|
||||
/**
|
||||
* Short Authentication String (SAS) verification.
|
||||
* @module crypto/verification/SAS
|
||||
*/
|
||||
|
||||
import anotherjson from 'another-json';
|
||||
@ -232,10 +231,6 @@ type EventHandlerMap = {
|
||||
[SasEvent.ShowSas]: (sas: ISasEvent) => void;
|
||||
} & VerificationEventHandlerMap;
|
||||
|
||||
/**
|
||||
* @alias module:crypto/verification/SAS
|
||||
* @extends {module:crypto/verification/Base}
|
||||
*/
|
||||
export class SAS extends Base<SasEvent, EventHandlerMap> {
|
||||
private waitingForAccept?: boolean;
|
||||
public ourSASPubKey?: string;
|
||||
|
@ -17,11 +17,11 @@ limitations under the License.
|
||||
/**
|
||||
* Implementation of decimal encoding of SAS as per:
|
||||
* https://spec.matrix.org/v1.4/client-server-api/#sas-method-decimal
|
||||
* @param sasBytes the five bytes generated by HKDF
|
||||
* @param sasBytes - the five bytes generated by HKDF
|
||||
* @returns the derived three numbers between 1000 and 9191 inclusive
|
||||
*/
|
||||
export function generateDecimalSas(sasBytes: number[]): [number, number, number] {
|
||||
/**
|
||||
/*
|
||||
* +--------+--------+--------+--------+--------+
|
||||
* | Byte 0 | Byte 1 | Byte 2 | Byte 3 | Byte 4 |
|
||||
* +--------+--------+--------+--------+--------+
|
||||
|
@ -40,9 +40,9 @@ export class InRoomChannel implements IVerificationChannel {
|
||||
private requestEventId?: string;
|
||||
|
||||
/**
|
||||
* @param {MatrixClient} client the matrix client, to send messages with and get current user & device from.
|
||||
* @param {string} roomId id of the room where verification events should be posted in, should be a DM with the given user.
|
||||
* @param {string} userId id of user that the verification request is directed at, should be present in the room.
|
||||
* @param client - the matrix client, to send messages with and get current user & device from.
|
||||
* @param roomId - id of the room where verification events should be posted in, should be a DM with the given user.
|
||||
* @param userId - id of user that the verification request is directed at, should be present in the room.
|
||||
*/
|
||||
public constructor(
|
||||
private readonly client: MatrixClient,
|
||||
@ -78,8 +78,8 @@ export class InRoomChannel implements IVerificationChannel {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {MatrixEvent} event the event to get the timestamp of
|
||||
* @return {number} the timestamp when the event was sent
|
||||
* @param event - the event to get the timestamp of
|
||||
* @returns the timestamp when the event was sent
|
||||
*/
|
||||
public getTimestamp(event: MatrixEvent): number {
|
||||
return event.getTs();
|
||||
@ -87,8 +87,8 @@ export class InRoomChannel implements IVerificationChannel {
|
||||
|
||||
/**
|
||||
* Checks whether the given event type should be allowed to initiate a new VerificationRequest over this channel
|
||||
* @param {string} type the event type to check
|
||||
* @returns {boolean} boolean flag
|
||||
* @param type - the event type to check
|
||||
* @returns boolean flag
|
||||
*/
|
||||
public static canCreateRequest(type: string): boolean {
|
||||
return type === REQUEST_TYPE;
|
||||
@ -100,8 +100,8 @@ export class InRoomChannel implements IVerificationChannel {
|
||||
|
||||
/**
|
||||
* Extract the transaction id used by a given key verification event, if any
|
||||
* @param {MatrixEvent} event the event
|
||||
* @returns {string} the transaction id
|
||||
* @param event - the event
|
||||
* @returns the transaction id
|
||||
*/
|
||||
public static getTransactionId(event: MatrixEvent): string | undefined {
|
||||
if (InRoomChannel.getEventType(event) === REQUEST_TYPE) {
|
||||
@ -119,9 +119,9 @@ export class InRoomChannel implements IVerificationChannel {
|
||||
* This only does checks that don't rely on the current state of a potentially already channel
|
||||
* so we can prevent channels being created by invalid events.
|
||||
* `handleEvent` can do more checks and choose to ignore invalid events.
|
||||
* @param {MatrixEvent} event the event to validate
|
||||
* @param {MatrixClient} client the client to get the current user and device id from
|
||||
* @returns {boolean} whether the event is valid and should be passed to handleEvent
|
||||
* @param event - the event to validate
|
||||
* @param client - the client to get the current user and device id from
|
||||
* @returns whether the event is valid and should be passed to handleEvent
|
||||
*/
|
||||
public static validateEvent(event: MatrixEvent, client: MatrixClient): boolean {
|
||||
const txnId = InRoomChannel.getTransactionId(event);
|
||||
@ -156,8 +156,8 @@ export class InRoomChannel implements IVerificationChannel {
|
||||
* As m.key.verification.request events are as m.room.message events with the InRoomChannel
|
||||
* to have a fallback message in non-supporting clients, we map the real event type
|
||||
* to the symbolic one to keep things in unison with ToDeviceChannel
|
||||
* @param {MatrixEvent} event the event to get the type of
|
||||
* @returns {string} the "symbolic" event type
|
||||
* @param event - the event to get the type of
|
||||
* @returns the "symbolic" event type
|
||||
*/
|
||||
public static getEventType(event: MatrixEvent): string {
|
||||
const type = event.getType();
|
||||
@ -179,10 +179,10 @@ export class InRoomChannel implements IVerificationChannel {
|
||||
|
||||
/**
|
||||
* Changes the state of the channel, request, and verifier in response to a key verification event.
|
||||
* @param {MatrixEvent} event to handle
|
||||
* @param {VerificationRequest} request the request to forward handling to
|
||||
* @param {boolean} isLiveEvent whether this is an even received through sync or not
|
||||
* @returns {Promise} a promise that resolves when any requests as an answer to the passed-in event are sent.
|
||||
* @param event - to handle
|
||||
* @param request - the request to forward handling to
|
||||
* @param isLiveEvent - whether this is an even received through sync or not
|
||||
* @returns a promise that resolves when any requests as an answer to the passed-in event are sent.
|
||||
*/
|
||||
public async handleEvent(event: MatrixEvent, request: VerificationRequest, isLiveEvent = false): Promise<void> {
|
||||
// prevent processing the same event multiple times, as under
|
||||
@ -228,8 +228,8 @@ export class InRoomChannel implements IVerificationChannel {
|
||||
* so it has the same format as returned by `completeContent` before sending.
|
||||
* The relation can not appear on the event content because of encryption,
|
||||
* relations are excluded from encryption.
|
||||
* @param {MatrixEvent} event the received event
|
||||
* @returns {Object} the content object with the relation added again
|
||||
* @param event - the received event
|
||||
* @returns the content object with the relation added again
|
||||
*/
|
||||
public completedContentFromEvent(event: MatrixEvent): Record<string, any> {
|
||||
// ensure m.related_to is included in e2ee rooms
|
||||
@ -244,9 +244,9 @@ export class InRoomChannel implements IVerificationChannel {
|
||||
* This is public so verification methods (SAS uses this) can get the exact
|
||||
* content that will be sent independent of the used channel,
|
||||
* as they need to calculate the hash of it.
|
||||
* @param {string} type the event type
|
||||
* @param {object} content the (incomplete) content
|
||||
* @returns {object} the complete content, as it will be sent.
|
||||
* @param type - the event type
|
||||
* @param content - the (incomplete) content
|
||||
* @returns the complete content, as it will be sent.
|
||||
*/
|
||||
public completeContent(type: string, content: Record<string, any>): Record<string, any> {
|
||||
content = Object.assign({}, content);
|
||||
@ -276,9 +276,9 @@ export class InRoomChannel implements IVerificationChannel {
|
||||
|
||||
/**
|
||||
* Send an event over the channel with the content not having gone through `completeContent`.
|
||||
* @param {string} type the event type
|
||||
* @param {object} uncompletedContent the (incomplete) content
|
||||
* @returns {Promise} the promise of the request
|
||||
* @param type - the event type
|
||||
* @param uncompletedContent - the (incomplete) content
|
||||
* @returns the promise of the request
|
||||
*/
|
||||
public send(type: string, uncompletedContent: Record<string, any>): Promise<void> {
|
||||
const content = this.completeContent(type, uncompletedContent);
|
||||
@ -287,9 +287,8 @@ export class InRoomChannel implements IVerificationChannel {
|
||||
|
||||
/**
|
||||
* Send an event over the channel with the content having gone through `completeContent` already.
|
||||
* @param {string} type the event type
|
||||
* @param {object} content
|
||||
* @returns {Promise} the promise of the request
|
||||
* @param type - the event type
|
||||
* @returns the promise of the request
|
||||
*/
|
||||
public async sendCompleted(type: string, content: Record<string, any>): Promise<void> {
|
||||
let sendType = type;
|
||||
|
@ -69,8 +69,8 @@ export class ToDeviceChannel implements IVerificationChannel {
|
||||
|
||||
/**
|
||||
* Extract the transaction id used by a given key verification event, if any
|
||||
* @param {MatrixEvent} event the event
|
||||
* @returns {string} the transaction id
|
||||
* @param event - the event
|
||||
* @returns the transaction id
|
||||
*/
|
||||
public static getTransactionId(event: MatrixEvent): string {
|
||||
const content = event.getContent();
|
||||
@ -79,8 +79,8 @@ export class ToDeviceChannel implements IVerificationChannel {
|
||||
|
||||
/**
|
||||
* Checks whether the given event type should be allowed to initiate a new VerificationRequest over this channel
|
||||
* @param {string} type the event type to check
|
||||
* @returns {boolean} boolean flag
|
||||
* @param type - the event type to check
|
||||
* @returns boolean flag
|
||||
*/
|
||||
public static canCreateRequest(type: string): boolean {
|
||||
return type === REQUEST_TYPE || type === START_TYPE;
|
||||
@ -95,9 +95,9 @@ export class ToDeviceChannel implements IVerificationChannel {
|
||||
* This only does checks that don't rely on the current state of a potentially already channel
|
||||
* so we can prevent channels being created by invalid events.
|
||||
* `handleEvent` can do more checks and choose to ignore invalid events.
|
||||
* @param {MatrixEvent} event the event to validate
|
||||
* @param {MatrixClient} client the client to get the current user and device id from
|
||||
* @returns {boolean} whether the event is valid and should be passed to handleEvent
|
||||
* @param event - the event to validate
|
||||
* @param client - the client to get the current user and device id from
|
||||
* @returns whether the event is valid and should be passed to handleEvent
|
||||
*/
|
||||
public static validateEvent(event: MatrixEvent, client: MatrixClient): boolean {
|
||||
if (event.isCancelled()) {
|
||||
@ -137,8 +137,8 @@ export class ToDeviceChannel implements IVerificationChannel {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {MatrixEvent} event the event to get the timestamp of
|
||||
* @return {number} the timestamp when the event was sent
|
||||
* @param event - the event to get the timestamp of
|
||||
* @returns the timestamp when the event was sent
|
||||
*/
|
||||
public getTimestamp(event: MatrixEvent): number {
|
||||
const content = event.getContent();
|
||||
@ -147,10 +147,10 @@ export class ToDeviceChannel implements IVerificationChannel {
|
||||
|
||||
/**
|
||||
* Changes the state of the channel, request, and verifier in response to a key verification event.
|
||||
* @param {MatrixEvent} event to handle
|
||||
* @param {VerificationRequest} request the request to forward handling to
|
||||
* @param {boolean} isLiveEvent whether this is an even received through sync or not
|
||||
* @returns {Promise} a promise that resolves when any requests as an answer to the passed-in event are sent.
|
||||
* @param event - to handle
|
||||
* @param request - the request to forward handling to
|
||||
* @param isLiveEvent - whether this is an even received through sync or not
|
||||
* @returns a promise that resolves when any requests as an answer to the passed-in event are sent.
|
||||
*/
|
||||
public async handleEvent(event: MatrixEvent, request: Request, isLiveEvent = false): Promise<void> {
|
||||
const type = event.getType();
|
||||
@ -196,9 +196,9 @@ export class ToDeviceChannel implements IVerificationChannel {
|
||||
}
|
||||
|
||||
/**
|
||||
* See {InRoomChannel.completedContentFromEvent} why this is needed.
|
||||
* @param {MatrixEvent} event the received event
|
||||
* @returns {Object} the content object
|
||||
* See {@link InRoomChannel#completedContentFromEvent} for why this is needed.
|
||||
* @param event - the received event
|
||||
* @returns the content object
|
||||
*/
|
||||
public completedContentFromEvent(event: MatrixEvent): Record<string, any> {
|
||||
return event.getContent();
|
||||
@ -209,9 +209,9 @@ export class ToDeviceChannel implements IVerificationChannel {
|
||||
* This is public so verification methods (SAS uses this) can get the exact
|
||||
* content that will be sent independent of the used channel,
|
||||
* as they need to calculate the hash of it.
|
||||
* @param {string} type the event type
|
||||
* @param {object} content the (incomplete) content
|
||||
* @returns {object} the complete content, as it will be sent.
|
||||
* @param type - the event type
|
||||
* @param content - the (incomplete) content
|
||||
* @returns the complete content, as it will be sent.
|
||||
*/
|
||||
public completeContent(type: string, content: Record<string, any>): Record<string, any> {
|
||||
// make a copy
|
||||
@ -230,9 +230,9 @@ export class ToDeviceChannel implements IVerificationChannel {
|
||||
|
||||
/**
|
||||
* Send an event over the channel with the content not having gone through `completeContent`.
|
||||
* @param {string} type the event type
|
||||
* @param {object} uncompletedContent the (incomplete) content
|
||||
* @returns {Promise} the promise of the request
|
||||
* @param type - the event type
|
||||
* @param uncompletedContent - the (incomplete) content
|
||||
* @returns the promise of the request
|
||||
*/
|
||||
public send(type: string, uncompletedContent: Record<string, any> = {}): Promise<void> {
|
||||
// create transaction id when sending request
|
||||
@ -245,9 +245,8 @@ export class ToDeviceChannel implements IVerificationChannel {
|
||||
|
||||
/**
|
||||
* Send an event over the channel with the content having gone through `completeContent` already.
|
||||
* @param {string} type the event type
|
||||
* @param {object} content
|
||||
* @returns {Promise} the promise of the request
|
||||
* @param type - the event type
|
||||
* @returns the promise of the request
|
||||
*/
|
||||
public async sendCompleted(type: string, content: Record<string, any>): Promise<void> {
|
||||
let result;
|
||||
@ -286,7 +285,7 @@ export class ToDeviceChannel implements IVerificationChannel {
|
||||
|
||||
/**
|
||||
* Allow Crypto module to create and know the transaction id before the .start event gets sent.
|
||||
* @returns {string} the transaction id
|
||||
* @returns the transaction id
|
||||
*/
|
||||
public static makeTransactionId(): string {
|
||||
return randomString(32);
|
||||
|
@ -81,6 +81,9 @@ export enum VerificationRequestEvent {
|
||||
}
|
||||
|
||||
type EventHandlerMap = {
|
||||
/**
|
||||
* Fires whenever the state of the request object has changed.
|
||||
*/
|
||||
[VerificationRequestEvent.Change]: () => void;
|
||||
};
|
||||
|
||||
@ -88,7 +91,6 @@ type EventHandlerMap = {
|
||||
* State machine for verification requests.
|
||||
* Things that differ based on what channel is used to
|
||||
* send and receive verification events are put in `InRoomChannel` or `ToDeviceChannel`.
|
||||
* @event "change" whenever the state of the request object has changed.
|
||||
*/
|
||||
export class VerificationRequest<
|
||||
C extends IVerificationChannel = IVerificationChannel,
|
||||
@ -129,10 +131,10 @@ export class VerificationRequest<
|
||||
/**
|
||||
* Stateless validation logic not specific to the channel.
|
||||
* Invoked by the same static method in either channel.
|
||||
* @param {string} type the "symbolic" event type, as returned by the `getEventType` function on the channel.
|
||||
* @param {MatrixEvent} event the event to validate. Don't call getType() on it but use the `type` parameter instead.
|
||||
* @param {MatrixClient} client the client to get the current user and device id from
|
||||
* @returns {boolean} whether the event is valid and should be passed to handleEvent
|
||||
* @param type - the "symbolic" event type, as returned by the `getEventType` function on the channel.
|
||||
* @param event - the event to validate. Don't call getType() on it but use the `type` parameter instead.
|
||||
* @param client - the client to get the current user and device id from
|
||||
* @returns whether the event is valid and should be passed to handleEvent
|
||||
*/
|
||||
public static validateEvent(type: string, event: MatrixEvent, client: MatrixClient): boolean {
|
||||
const content = event.getContent();
|
||||
@ -234,7 +236,7 @@ export class VerificationRequest<
|
||||
|
||||
/**
|
||||
* The key verification request event.
|
||||
* @returns {MatrixEvent} The request event, or falsey if not found.
|
||||
* @returns The request event, or falsey if not found.
|
||||
*/
|
||||
public get requestEvent(): MatrixEvent | undefined {
|
||||
return this.getEventByEither(REQUEST_TYPE);
|
||||
@ -278,9 +280,9 @@ export class VerificationRequest<
|
||||
* This is useful when setting up the QR code UI, as it is somewhat asymmetrical:
|
||||
* if the other party supports SCAN_QR, we should show a QR code in the UI, and vice versa.
|
||||
* For methods that need to be supported by both ends, use the `methods` property.
|
||||
* @param {string} method the method to check
|
||||
* @param {boolean} force to check even if the phase is not ready or started yet, internal usage
|
||||
* @return {boolean} whether or not the other party said the supported the method */
|
||||
* @param method - the method to check
|
||||
* @param force - to check even if the phase is not ready or started yet, internal usage
|
||||
* @returns whether or not the other party said the supported the method */
|
||||
public otherPartySupportsMethod(method: string, force = false): boolean {
|
||||
if (!force && !this.ready && !this.started) {
|
||||
return false;
|
||||
@ -398,7 +400,7 @@ export class VerificationRequest<
|
||||
* given the events sent so far in the verification. This is the
|
||||
* same algorithm used to determine which device to send the
|
||||
* verification to when no specific device is specified.
|
||||
* @returns {{userId: *, deviceId: *}} The device information
|
||||
* @returns The device information
|
||||
*/
|
||||
public get targetDevice(): ITargetDevice {
|
||||
const theirFirstEvent =
|
||||
@ -415,10 +417,10 @@ export class VerificationRequest<
|
||||
|
||||
/* Start the key verification, creating a verifier and sending a .start event.
|
||||
* If no previous events have been sent, pass in `targetDevice` to set who to direct this request to.
|
||||
* @param {string} method the name of the verification method to use.
|
||||
* @param {string?} targetDevice.userId the id of the user to direct this request to
|
||||
* @param {string?} targetDevice.deviceId the id of the device to direct this request to
|
||||
* @returns {VerifierBase} the verifier of the given method
|
||||
* @param method - the name of the verification method to use.
|
||||
* @param targetDevice.userId the id of the user to direct this request to
|
||||
* @param targetDevice.deviceId the id of the device to direct this request to
|
||||
* @returns the verifier of the given method
|
||||
*/
|
||||
public beginKeyVerification(
|
||||
method: VerificationMethod,
|
||||
@ -448,7 +450,7 @@ export class VerificationRequest<
|
||||
|
||||
/**
|
||||
* sends the initial .request event.
|
||||
* @returns {Promise} resolves when the event has been sent.
|
||||
* @returns resolves when the event has been sent.
|
||||
*/
|
||||
public async sendRequest(): Promise<void> {
|
||||
if (!this.observeOnly && this._phase === PHASE_UNSENT) {
|
||||
@ -459,9 +461,9 @@ export class VerificationRequest<
|
||||
|
||||
/**
|
||||
* Cancels the request, sending a cancellation to the other party
|
||||
* @param {string?} error.reason the error reason to send the cancellation with
|
||||
* @param {string?} error.code the error code to send the cancellation with
|
||||
* @returns {Promise} resolves when the event has been sent.
|
||||
* @param reason - the error reason to send the cancellation with
|
||||
* @param code - the error code to send the cancellation with
|
||||
* @returns resolves when the event has been sent.
|
||||
*/
|
||||
public async cancel({ reason = "User declined", code = "m.user" } = {}): Promise<void> {
|
||||
if (!this.observeOnly && this._phase !== PHASE_CANCELLED) {
|
||||
@ -478,7 +480,7 @@ export class VerificationRequest<
|
||||
|
||||
/**
|
||||
* Accepts the request, sending a .ready event to the other party
|
||||
* @returns {Promise} resolves when the event has been sent.
|
||||
* @returns resolves when the event has been sent.
|
||||
*/
|
||||
public async accept(): Promise<void> {
|
||||
if (!this.observeOnly && this.phase === PHASE_REQUESTED && !this.initiatedByMe) {
|
||||
@ -491,10 +493,10 @@ export class VerificationRequest<
|
||||
|
||||
/**
|
||||
* Can be used to listen for state changes until the callback returns true.
|
||||
* @param {Function} fn callback to evaluate whether the request is in the desired state.
|
||||
* @param fn - callback to evaluate whether the request is in the desired state.
|
||||
* Takes the request as an argument.
|
||||
* @returns {Promise} that resolves once the callback returns true
|
||||
* @throws {Error} when the request is cancelled
|
||||
* @returns that resolves once the callback returns true
|
||||
* @throws Error when the request is cancelled
|
||||
*/
|
||||
public waitFor(fn: (request: VerificationRequest) => boolean): Promise<VerificationRequest> {
|
||||
return new Promise((resolve, reject) => {
|
||||
@ -701,13 +703,13 @@ export class VerificationRequest<
|
||||
|
||||
/**
|
||||
* Changes the state of the request and verifier in response to a key verification event.
|
||||
* @param {string} type the "symbolic" event type, as returned by the `getEventType` function on the channel.
|
||||
* @param {MatrixEvent} event the event to handle. Don't call getType() on it but use the `type` parameter instead.
|
||||
* @param {boolean} isLiveEvent whether this is an even received through sync or not
|
||||
* @param {boolean} isRemoteEcho whether this is the remote echo of an event sent by the same device
|
||||
* @param {boolean} isSentByUs whether this event is sent by a party that can accept and/or observe the request like one of our peers.
|
||||
* @param type - the "symbolic" event type, as returned by the `getEventType` function on the channel.
|
||||
* @param event - the event to handle. Don't call getType() on it but use the `type` parameter instead.
|
||||
* @param isLiveEvent - whether this is an even received through sync or not
|
||||
* @param isRemoteEcho - whether this is the remote echo of an event sent by the same device
|
||||
* @param isSentByUs - whether this event is sent by a party that can accept and/or observe the request like one of our peers.
|
||||
* For InRoomChannel this means any device for the syncing user. For ToDeviceChannel, just the syncing device.
|
||||
* @returns {Promise} a promise that resolves when any requests as an answer to the passed-in event are sent.
|
||||
* @returns a promise that resolves when any requests as an answer to the passed-in event are sent.
|
||||
*/
|
||||
public async handleEvent(
|
||||
type: string,
|
||||
|
@ -85,7 +85,7 @@ export interface ICapabilities {
|
||||
|
||||
/**
|
||||
* Whether this client needs access to TURN servers.
|
||||
* @default false
|
||||
* @defaultValue false
|
||||
*/
|
||||
turnServers?: boolean;
|
||||
}
|
||||
|
@ -20,8 +20,11 @@ import { IEvent, MatrixEvent, MatrixEventEvent } from "./models/event";
|
||||
export type EventMapper = (obj: Partial<IEvent>) => MatrixEvent;
|
||||
|
||||
export interface MapperOpts {
|
||||
// don't re-emit events emitted on an event mapped by this mapper on the client
|
||||
preventReEmit?: boolean;
|
||||
// decrypt event proactively
|
||||
decrypt?: boolean;
|
||||
// the event is a to_device event
|
||||
toDevice?: boolean;
|
||||
}
|
||||
|
||||
|
@ -22,16 +22,12 @@ import {
|
||||
THREAD_RELATION_TYPE,
|
||||
} from "./models/thread";
|
||||
|
||||
/**
|
||||
* @module filter-component
|
||||
*/
|
||||
|
||||
/**
|
||||
* Checks if a value matches a given field value, which may be a * terminated
|
||||
* wildcard pattern.
|
||||
* @param {String} actualValue The value to be compared
|
||||
* @param {String} filterValue The filter pattern to be compared
|
||||
* @return {boolean} true if the actualValue matches the filterValue
|
||||
* @param actualValue - The value to be compared
|
||||
* @param filterValue - The filter pattern to be compared
|
||||
* @returns true if the actualValue matches the filterValue
|
||||
*/
|
||||
function matchesWildcard(actualValue: string, filterValue: string): boolean {
|
||||
if (filterValue.endsWith("*")) {
|
||||
@ -68,17 +64,14 @@ export interface IFilterComponent {
|
||||
*
|
||||
* N.B. that synapse refers to these as 'Filters', and what js-sdk refers to as
|
||||
* 'Filters' are referred to as 'FilterCollections'.
|
||||
*
|
||||
* @constructor
|
||||
* @param {Object} filterJson the definition of this filter JSON, e.g. { 'contains_url': true }
|
||||
*/
|
||||
export class FilterComponent {
|
||||
public constructor(private filterJson: IFilterComponent, public readonly userId?: string | undefined | null) {}
|
||||
|
||||
/**
|
||||
* Checks with the filter component matches the given event
|
||||
* @param {MatrixEvent} event event to be checked against the filter
|
||||
* @return {boolean} true if the event matches the filter
|
||||
* @param event - event to be checked against the filter
|
||||
* @returns true if the event matches the filter
|
||||
*/
|
||||
public check(event: MatrixEvent): boolean {
|
||||
const bundledRelationships = event.getUnsigned()?.["m.relations"] || {};
|
||||
@ -122,13 +115,13 @@ export class FilterComponent {
|
||||
|
||||
/**
|
||||
* Checks whether the filter component matches the given event fields.
|
||||
* @param {String} roomId the roomId for the event being checked
|
||||
* @param {String} sender the sender of the event being checked
|
||||
* @param {String} eventType the type of the event being checked
|
||||
* @param {boolean} containsUrl whether the event contains a content.url field
|
||||
* @param {boolean} relationTypes whether has aggregated relation of the given type
|
||||
* @param {boolean} relationSenders whether one of the relation is sent by the user listed
|
||||
* @return {boolean} true if the event fields match the filter
|
||||
* @param roomId - the roomId for the event being checked
|
||||
* @param sender - the sender of the event being checked
|
||||
* @param eventType - the type of the event being checked
|
||||
* @param containsUrl - whether the event contains a content.url field
|
||||
* @param relationTypes - whether has aggregated relation of the given type
|
||||
* @param relationSenders - whether one of the relation is sent by the user listed
|
||||
* @returns true if the event fields match the filter
|
||||
*/
|
||||
private checkFields(
|
||||
roomId: string | undefined,
|
||||
@ -194,8 +187,8 @@ export class FilterComponent {
|
||||
|
||||
/**
|
||||
* Filters a list of events down to those which match this filter component
|
||||
* @param {MatrixEvent[]} events Events to be checked against the filter component
|
||||
* @return {MatrixEvent[]} events which matched the filter component
|
||||
* @param events - Events to be checked against the filter component
|
||||
* @returns events which matched the filter component
|
||||
*/
|
||||
public filter(events: MatrixEvent[]): MatrixEvent[] {
|
||||
return events.filter(this.check, this);
|
||||
@ -204,7 +197,7 @@ export class FilterComponent {
|
||||
/**
|
||||
* Returns the limit field for a given filter component, providing a default of
|
||||
* 10 if none is otherwise specified. Cargo-culted from Synapse.
|
||||
* @return {Number} the limit for this filter component.
|
||||
* @returns the limit for this filter component.
|
||||
*/
|
||||
public limit(): number {
|
||||
return this.filterJson.limit !== undefined ? this.filterJson.limit : 10;
|
||||
|
@ -14,10 +14,6 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @module filter
|
||||
*/
|
||||
|
||||
import {
|
||||
EventType,
|
||||
RelationType,
|
||||
@ -27,9 +23,6 @@ import { FilterComponent, IFilterComponent } from "./filter-component";
|
||||
import { MatrixEvent } from "./models/event";
|
||||
|
||||
/**
|
||||
* @param {Object} obj
|
||||
* @param {string} keyNesting
|
||||
* @param {*} val
|
||||
*/
|
||||
function setProp(obj: Record<string, any>, keyNesting: string, val: any): void {
|
||||
const nestedKeys = keyNesting.split(".") as [keyof typeof obj];
|
||||
@ -78,14 +71,6 @@ interface IRoomFilter {
|
||||
}
|
||||
/* eslint-enable camelcase */
|
||||
|
||||
/**
|
||||
* Construct a new Filter.
|
||||
* @constructor
|
||||
* @param {string} userId The user ID for this filter.
|
||||
* @param {string=} filterId The filter ID if known.
|
||||
* @prop {string} userId The user ID of the filter
|
||||
* @prop {?string} filterId The filter ID
|
||||
*/
|
||||
export class Filter {
|
||||
public static LAZY_LOADING_MESSAGES_FILTER = {
|
||||
lazy_load_members: true,
|
||||
@ -93,11 +78,6 @@ export class Filter {
|
||||
|
||||
/**
|
||||
* Create a filter from existing data.
|
||||
* @static
|
||||
* @param {string} userId
|
||||
* @param {string} filterId
|
||||
* @param {Object} jsonObj
|
||||
* @return {Filter}
|
||||
*/
|
||||
public static fromJson(userId: string | undefined | null, filterId: string, jsonObj: IFilterDefinition): Filter {
|
||||
const filter = new Filter(userId, filterId);
|
||||
@ -109,11 +89,16 @@ export class Filter {
|
||||
private roomFilter?: FilterComponent;
|
||||
private roomTimelineFilter?: FilterComponent;
|
||||
|
||||
/**
|
||||
* Construct a new Filter.
|
||||
* @param userId - The user ID for this filter.
|
||||
* @param filterId - The filter ID if known.
|
||||
*/
|
||||
public constructor(public readonly userId: string | undefined | null, public filterId?: string) {}
|
||||
|
||||
/**
|
||||
* Get the ID of this filter on your homeserver (if known)
|
||||
* @return {?string} The filter ID
|
||||
* @returns The filter ID
|
||||
*/
|
||||
public getFilterId(): string | undefined {
|
||||
return this.filterId;
|
||||
@ -121,7 +106,7 @@ export class Filter {
|
||||
|
||||
/**
|
||||
* Get the JSON body of the filter.
|
||||
* @return {Object} The filter definition
|
||||
* @returns The filter definition
|
||||
*/
|
||||
public getDefinition(): IFilterDefinition {
|
||||
return this.definition;
|
||||
@ -129,7 +114,7 @@ export class Filter {
|
||||
|
||||
/**
|
||||
* Set the JSON body of the filter
|
||||
* @param {Object} definition The filter definition
|
||||
* @param definition - The filter definition
|
||||
*/
|
||||
public setDefinition(definition: IFilterDefinition): void {
|
||||
this.definition = definition;
|
||||
@ -198,7 +183,7 @@ export class Filter {
|
||||
|
||||
/**
|
||||
* Get the room.timeline filter component of the filter
|
||||
* @return {FilterComponent} room timeline filter component
|
||||
* @returns room timeline filter component
|
||||
*/
|
||||
public getRoomTimelineFilterComponent(): FilterComponent | undefined {
|
||||
return this.roomTimelineFilter;
|
||||
@ -207,8 +192,8 @@ export class Filter {
|
||||
/**
|
||||
* Filter the list of events based on whether they are allowed in a timeline
|
||||
* based on this filter
|
||||
* @param {MatrixEvent[]} events the list of events being filtered
|
||||
* @return {MatrixEvent[]} the list of events which match the filter
|
||||
* @param events - the list of events being filtered
|
||||
* @returns the list of events which match the filter
|
||||
*/
|
||||
public filterRoomTimeline(events: MatrixEvent[]): MatrixEvent[] {
|
||||
if (this.roomFilter) {
|
||||
@ -222,7 +207,7 @@ export class Filter {
|
||||
|
||||
/**
|
||||
* Set the max number of events to return for each room's timeline.
|
||||
* @param {Number} limit The max number of events to return for each room.
|
||||
* @param limit - The max number of events to return for each room.
|
||||
*/
|
||||
public setTimelineLimit(limit: number): void {
|
||||
setProp(this.definition, "room.timeline.limit", limit);
|
||||
@ -230,7 +215,6 @@ export class Filter {
|
||||
|
||||
/**
|
||||
* Enable threads unread notification
|
||||
* @param {boolean} enabled
|
||||
*/
|
||||
public setUnreadThreadNotifications(enabled: boolean): void {
|
||||
this.definition = {
|
||||
@ -251,7 +235,7 @@ export class Filter {
|
||||
|
||||
/**
|
||||
* Control whether left rooms should be included in responses.
|
||||
* @param {boolean} includeLeave True to make rooms the user has left appear
|
||||
* @param includeLeave - True to make rooms the user has left appear
|
||||
* in responses.
|
||||
*/
|
||||
public setIncludeLeaveRooms(includeLeave: boolean): void {
|
||||
|
@ -26,9 +26,8 @@ interface IErrorJson extends Partial<IUsageLimit> {
|
||||
/**
|
||||
* Construct a generic HTTP error. This is a JavaScript Error with additional information
|
||||
* specific to HTTP responses.
|
||||
* @constructor
|
||||
* @param {string} msg The error message to include.
|
||||
* @param {number} httpStatus The HTTP response status code.
|
||||
* @param msg - The error message to include.
|
||||
* @param httpStatus - The HTTP response status code.
|
||||
*/
|
||||
export class HTTPError extends Error {
|
||||
public constructor(msg: string, public readonly httpStatus?: number) {
|
||||
@ -36,21 +35,18 @@ export class HTTPError extends Error {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a Matrix error. This is a JavaScript Error with additional
|
||||
* information specific to the standard Matrix error response.
|
||||
* @constructor
|
||||
* @param {Object} errorJson The Matrix error JSON returned from the homeserver.
|
||||
* @prop {string} errcode The Matrix 'errcode' value, e.g. "M_FORBIDDEN".
|
||||
* @prop {string} name Same as MatrixError.errcode but with a default unknown string.
|
||||
* @prop {string} message The Matrix 'error' value, e.g. "Missing token."
|
||||
* @prop {Object} data The raw Matrix error JSON used to construct this object.
|
||||
* @prop {number} httpStatus The numeric HTTP status code given
|
||||
*/
|
||||
export class MatrixError extends HTTPError {
|
||||
// The Matrix 'errcode' value, e.g. "M_FORBIDDEN".
|
||||
public readonly errcode?: string;
|
||||
// The raw Matrix error JSON used to construct this object.
|
||||
public data: IErrorJson;
|
||||
|
||||
/**
|
||||
* Construct a Matrix error. This is a JavaScript Error with additional
|
||||
* information specific to the standard Matrix error response.
|
||||
* @param errorJson - The Matrix error JSON returned from the homeserver.
|
||||
* @param httpStatus - The numeric HTTP status code given
|
||||
*/
|
||||
public constructor(
|
||||
errorJson: IErrorJson = {},
|
||||
public readonly httpStatus?: number,
|
||||
@ -76,7 +72,6 @@ export class MatrixError extends HTTPError {
|
||||
* that a request failed because of some error with the connection, either
|
||||
* CORS was not correctly configured on the server, the server didn't response,
|
||||
* the request timed out, or the internet connection on the client side went down.
|
||||
* @constructor
|
||||
*/
|
||||
export class ConnectionError extends Error {
|
||||
public constructor(message: string, cause?: Error) {
|
||||
|
@ -16,7 +16,6 @@ limitations under the License.
|
||||
|
||||
/**
|
||||
* This is an internal module. See {@link MatrixHttpApi} for the public class.
|
||||
* @module http-api
|
||||
*/
|
||||
|
||||
import * as utils from "../utils";
|
||||
@ -64,13 +63,13 @@ export class FetchHttpApi<O extends IHttpOpts> {
|
||||
|
||||
/**
|
||||
* Sets the base URL for the identity server
|
||||
* @param {string} url The new base url
|
||||
* @param url - The new base url
|
||||
*/
|
||||
public setIdBaseUrl(url: string): void {
|
||||
this.opts.idBaseUrl = url;
|
||||
}
|
||||
|
||||
public idServerRequest<T extends {}>(
|
||||
public idServerRequest<T extends Record<string, unknown>>(
|
||||
method: Method,
|
||||
path: string,
|
||||
params: Record<string, string | string[]> | undefined,
|
||||
@ -104,35 +103,29 @@ export class FetchHttpApi<O extends IHttpOpts> {
|
||||
|
||||
/**
|
||||
* Perform an authorised request to the homeserver.
|
||||
* @param {string} method The HTTP method e.g. "GET".
|
||||
* @param {string} path The HTTP path <b>after</b> the supplied prefix e.g.
|
||||
* @param method - The HTTP method e.g. "GET".
|
||||
* @param path - The HTTP path <b>after</b> the supplied prefix e.g.
|
||||
* "/createRoom".
|
||||
*
|
||||
* @param {Object=} queryParams A dict of query params (these will NOT be
|
||||
* @param queryParams - A dict of query params (these will NOT be
|
||||
* urlencoded). If unspecified, there will be no query params.
|
||||
*
|
||||
* @param {Object} [body] The HTTP JSON body.
|
||||
* @param body - The HTTP JSON body.
|
||||
*
|
||||
* @param {Object|Number=} opts additional options. If a number is specified,
|
||||
* @param opts - additional options. If a number is specified,
|
||||
* this is treated as `opts.localTimeoutMs`.
|
||||
*
|
||||
* @param {Number=} opts.localTimeoutMs The maximum amount of time to wait before
|
||||
* timing out the request. If not specified, there is no timeout.
|
||||
*
|
||||
* @param {string=} opts.prefix The full prefix to use e.g.
|
||||
* "/_matrix/client/v2_alpha". If not specified, uses this.opts.prefix.
|
||||
*
|
||||
* @param {string=} opts.baseUrl The alternative base url to use.
|
||||
* If not specified, uses this.opts.baseUrl
|
||||
*
|
||||
* @param {Object=} opts.headers map of additional request headers
|
||||
*
|
||||
* @return {Promise} Resolves to <code>{data: {Object},
|
||||
* headers: {Object}, code: {Number}}</code>.
|
||||
* If <code>onlyData</code> is set, this will resolve to the <code>data</code>
|
||||
* object only.
|
||||
* @return {module:http-api.MatrixError} Rejects with an error if a problem
|
||||
* occurred. This includes network problems and Matrix-specific error JSON.
|
||||
* @returns Promise which resolves to
|
||||
* ```
|
||||
* {
|
||||
* data: {Object},
|
||||
* headers: {Object},
|
||||
* code: {Number},
|
||||
* }
|
||||
* ```
|
||||
* If `onlyData` is set, this will resolve to the `data` object only.
|
||||
* @returns Rejects with an error if a problem occurred.
|
||||
* This includes network problems and Matrix-specific error JSON.
|
||||
*/
|
||||
public authedRequest<T>(
|
||||
method: Method,
|
||||
@ -176,30 +169,28 @@ export class FetchHttpApi<O extends IHttpOpts> {
|
||||
|
||||
/**
|
||||
* Perform a request to the homeserver without any credentials.
|
||||
* @param {string} method The HTTP method e.g. "GET".
|
||||
* @param {string} path The HTTP path <b>after</b> the supplied prefix e.g.
|
||||
* @param method - The HTTP method e.g. "GET".
|
||||
* @param path - The HTTP path <b>after</b> the supplied prefix e.g.
|
||||
* "/createRoom".
|
||||
*
|
||||
* @param {Object=} queryParams A dict of query params (these will NOT be
|
||||
* @param queryParams - A dict of query params (these will NOT be
|
||||
* urlencoded). If unspecified, there will be no query params.
|
||||
*
|
||||
* @param {Object} [body] The HTTP JSON body.
|
||||
* @param body - The HTTP JSON body.
|
||||
*
|
||||
* @param {Object=} opts additional options
|
||||
* @param opts - additional options
|
||||
*
|
||||
* @param {Number=} opts.localTimeoutMs The maximum amount of time to wait before
|
||||
* timing out the request. If not specified, there is no timeout.
|
||||
*
|
||||
* @param {string=} opts.prefix The full prefix to use e.g.
|
||||
* "/_matrix/client/v2_alpha". If not specified, uses this.opts.prefix.
|
||||
*
|
||||
* @param {Object=} opts.headers map of additional request headers
|
||||
*
|
||||
* @return {Promise} Resolves to <code>{data: {Object},
|
||||
* headers: {Object}, code: {Number}}</code>.
|
||||
* If <code>onlyData</code> is set, this will resolve to the <code>data</code>
|
||||
* @returns Promise which resolves to
|
||||
* ```
|
||||
* {
|
||||
* data: {Object},
|
||||
* headers: {Object},
|
||||
* code: {Number},
|
||||
* }
|
||||
* ```
|
||||
* If `onlyData</code> is set, this will resolve to the <code>data`
|
||||
* object only.
|
||||
* @return {module:http-api.MatrixError} Rejects with an error if a problem
|
||||
* @returns Rejects with an error if a problem
|
||||
* occurred. This includes network problems and Matrix-specific error JSON.
|
||||
*/
|
||||
public request<T>(
|
||||
@ -215,21 +206,16 @@ export class FetchHttpApi<O extends IHttpOpts> {
|
||||
|
||||
/**
|
||||
* Perform a request to an arbitrary URL.
|
||||
* @param {string} method The HTTP method e.g. "GET".
|
||||
* @param {string} url The HTTP URL object.
|
||||
* @param method - The HTTP method e.g. "GET".
|
||||
* @param url - The HTTP URL object.
|
||||
*
|
||||
* @param {Object} [body] The HTTP JSON body.
|
||||
* @param body - The HTTP JSON body.
|
||||
*
|
||||
* @param {Object=} opts additional options
|
||||
* @param opts - additional options
|
||||
*
|
||||
* @param {Number=} opts.localTimeoutMs The maximum amount of time to wait before
|
||||
* timing out the request. If not specified, there is no timeout.
|
||||
*
|
||||
* @param {Object=} opts.headers map of additional request headers
|
||||
*
|
||||
* @return {Promise} Resolves to data unless `onlyData` is specified as false,
|
||||
* @returns Promise which resolves to data unless `onlyData` is specified as false,
|
||||
* where the resolved value will be a fetch Response object.
|
||||
* @return {module:http-api.MatrixError} Rejects with an error if a problem
|
||||
* @returns Rejects with an error if a problem
|
||||
* occurred. This includes network problems and Matrix-specific error JSON.
|
||||
*/
|
||||
public async requestOtherUrl<T>(
|
||||
@ -310,11 +296,11 @@ export class FetchHttpApi<O extends IHttpOpts> {
|
||||
|
||||
/**
|
||||
* Form and return a homeserver request URL based on the given path params and prefix.
|
||||
* @param {string} path The HTTP path <b>after</b> the supplied prefix e.g. "/createRoom".
|
||||
* @param {Object} queryParams A dict of query params (these will NOT be urlencoded).
|
||||
* @param {string} prefix The full prefix to use e.g. "/_matrix/client/v2_alpha", defaulting to this.opts.prefix.
|
||||
* @param {string} baseUrl The baseUrl to use e.g. "https://matrix.org/", defaulting to this.opts.baseUrl.
|
||||
* @return {string} URL
|
||||
* @param path - The HTTP path <b>after</b> the supplied prefix e.g. "/createRoom".
|
||||
* @param queryParams - A dict of query params (these will NOT be urlencoded).
|
||||
* @param prefix - The full prefix to use e.g. "/_matrix/client/v2_alpha", defaulting to this.opts.prefix.
|
||||
* @param baseUrl - The baseUrl to use e.g. "https://matrix.org/", defaulting to this.opts.baseUrl.
|
||||
* @returns URL
|
||||
*/
|
||||
public getUrl(
|
||||
path: string,
|
||||
|
@ -35,27 +35,13 @@ export class MatrixHttpApi<O extends IHttpOpts> extends FetchHttpApi<O> {
|
||||
/**
|
||||
* Upload content to the homeserver
|
||||
*
|
||||
* @param {object} file The object to upload. On a browser, something that
|
||||
* @param file - The object to upload. On a browser, something that
|
||||
* can be sent to XMLHttpRequest.send (typically a File). Under node.js,
|
||||
* a Buffer, String or ReadStream.
|
||||
*
|
||||
* @param {object} opts options object
|
||||
* @param opts - options object
|
||||
*
|
||||
* @param {string=} opts.name Name to give the file on the server. Defaults
|
||||
* to <tt>file.name</tt>.
|
||||
*
|
||||
* @param {boolean=} opts.includeFilename if false will not send the filename,
|
||||
* e.g for encrypted file uploads where filename leaks are undesirable.
|
||||
* Defaults to true.
|
||||
*
|
||||
* @param {string=} opts.type Content-type for the upload. Defaults to
|
||||
* <tt>file.type</tt>, or <tt>application/octet-stream</tt>.
|
||||
*
|
||||
* @param {Function=} opts.progressHandler Optional. Called when a chunk of
|
||||
* data has been uploaded, with an object containing the fields `loaded`
|
||||
* (number of bytes transferred) and `total` (total size, if known).
|
||||
*
|
||||
* @return {Promise} Resolves to response object, as
|
||||
* @returns Promise which resolves to response object, as
|
||||
* determined by this.opts.onlyData, opts.rawResponse, and
|
||||
* opts.onlyContentUri. Rejects with an error (usually a MatrixError).
|
||||
*/
|
||||
@ -190,7 +176,7 @@ export class MatrixHttpApi<O extends IHttpOpts> extends FetchHttpApi<O> {
|
||||
|
||||
/**
|
||||
* Get the content repository url with query parameters.
|
||||
* @return {Object} An object with a 'base', 'path' and 'params' for base URL,
|
||||
* @returns An object with a 'base', 'path' and 'params' for base URL,
|
||||
* path and query parameters respectively.
|
||||
*/
|
||||
public getContentUri(): IContentUri {
|
||||
|
@ -32,11 +32,25 @@ export interface IHttpOpts {
|
||||
}
|
||||
|
||||
export interface IRequestOpts {
|
||||
/**
|
||||
* The alternative base url to use.
|
||||
* If not specified, uses this.opts.baseUrl
|
||||
*/
|
||||
baseUrl?: string;
|
||||
/**
|
||||
* The full prefix to use e.g.
|
||||
* "/_matrix/client/v2_alpha". If not specified, uses this.opts.prefix.
|
||||
*/
|
||||
prefix?: string;
|
||||
|
||||
/**
|
||||
* map of additional request headers
|
||||
*/
|
||||
headers?: Record<string, string>;
|
||||
abortSignal?: AbortSignal;
|
||||
/**
|
||||
* The maximum amount of time to wait before
|
||||
* timing out the request. If not specified, there is no timeout.
|
||||
*/
|
||||
localTimeoutMs?: number;
|
||||
keepAlive?: boolean; // defaults to false
|
||||
json?: boolean; // defaults to true
|
||||
@ -62,7 +76,29 @@ export enum HttpApiEvent {
|
||||
}
|
||||
|
||||
export type HttpApiEventHandlerMap = {
|
||||
/**
|
||||
* Fires whenever the login session the JS SDK is using is no
|
||||
* longer valid and the user must log in again.
|
||||
* NB. This only fires when action is required from the user, not
|
||||
* when then login session can be renewed by using a refresh token.
|
||||
* @example
|
||||
* ```
|
||||
* matrixClient.on("Session.logged_out", function(errorObj){
|
||||
* // show the login screen
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
[HttpApiEvent.SessionLoggedOut]: (err: MatrixError) => void;
|
||||
/**
|
||||
* Fires when the JS SDK receives a M_CONSENT_NOT_GIVEN error in response
|
||||
* to a HTTP request.
|
||||
* @example
|
||||
* ```
|
||||
* matrixClient.on("no_consent", function(message, contentUri) {
|
||||
* console.info(message + ' Go to ' + contentUri);
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
[HttpApiEvent.NoConsent]: (message: string, consentUri: string) => void;
|
||||
};
|
||||
|
||||
@ -72,9 +108,26 @@ export interface UploadProgress {
|
||||
}
|
||||
|
||||
export interface UploadOpts {
|
||||
/**
|
||||
* Name to give the file on the server. Defaults to <tt>file.name</tt>.
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* Content-type for the upload. Defaults to
|
||||
* <tt>file.type</tt>, or <tt>applicaton/octet-stream</tt>.
|
||||
*/
|
||||
type?: string;
|
||||
/**
|
||||
* if false will not send the filename,
|
||||
* e.g for encrypted file uploads where filename leaks are undesirable.
|
||||
* Defaults to true.
|
||||
*/
|
||||
includeFilename?: boolean;
|
||||
/**
|
||||
* Optional. Called when a chunk of
|
||||
* data has been uploaded, with an object containing the fields `loaded`
|
||||
* (number of bytes transferred) and `total` (total size, if known).
|
||||
*/
|
||||
progressHandler?(progress: UploadProgress): void;
|
||||
abortController?: AbortController;
|
||||
}
|
||||
|
@ -67,9 +67,9 @@ export function anySignal(signals: AbortSignal[]): {
|
||||
* If it is a JSON response, we will parse it into a MatrixError. Otherwise
|
||||
* we return a generic Error.
|
||||
*
|
||||
* @param {XMLHttpRequest|Response} response response object
|
||||
* @param {String} body raw body of the response
|
||||
* @returns {Error}
|
||||
* @param response - response object
|
||||
* @param body - raw body of the response
|
||||
* @returns
|
||||
*/
|
||||
export function parseErrorResponse(response: XMLHttpRequest | Response, body?: string): Error {
|
||||
let contentType: ParsedMediaType | null;
|
||||
@ -102,8 +102,8 @@ function isXhr(response: XMLHttpRequest | Response): response is XMLHttpRequest
|
||||
*
|
||||
* returns null if no content-type header could be found.
|
||||
*
|
||||
* @param {XMLHttpRequest|Response} response response object
|
||||
* @returns {{type: String, parameters: Object}?} parsed content-type header, or null if not found
|
||||
* @param response - response object
|
||||
* @returns parsed content-type header, or null if not found
|
||||
*/
|
||||
function getResponseContentType(response: XMLHttpRequest | Response): ParsedMediaType | null {
|
||||
let contentType: string | null;
|
||||
@ -124,10 +124,10 @@ function getResponseContentType(response: XMLHttpRequest | Response): ParsedMedi
|
||||
|
||||
/**
|
||||
* Retries a network operation run in a callback.
|
||||
* @param {number} maxAttempts maximum attempts to try
|
||||
* @param {Function} callback callback that returns a promise of the network operation. If rejected with ConnectionError, it will be retried by calling the callback again.
|
||||
* @return {any} the result of the network operation
|
||||
* @throws {ConnectionError} If after maxAttempts the callback still throws ConnectionError
|
||||
* @param maxAttempts - maximum attempts to try
|
||||
* @param callback - callback that returns a promise of the network operation. If rejected with ConnectionError, it will be retried by calling the callback again.
|
||||
* @returns the result of the network operation
|
||||
* @throws {@link ConnectionError} If after maxAttempts the callback still throws ConnectionError
|
||||
*/
|
||||
export async function retryNetworkOperation<T>(maxAttempts: number, callback: () => Promise<T>): Promise<T> {
|
||||
let attempts = 0;
|
||||
|
@ -18,9 +18,9 @@ limitations under the License.
|
||||
* Check if an IndexedDB database exists. The only way to do so is to try opening it, so
|
||||
* we do that and then delete it did not exist before.
|
||||
*
|
||||
* @param {Object} indexedDB The `indexedDB` interface
|
||||
* @param {string} dbName The database name to test for
|
||||
* @returns {boolean} Whether the database exists
|
||||
* @param indexedDB - The `indexedDB` interface
|
||||
* @param dbName - The database name to test for
|
||||
* @returns Whether the database exists
|
||||
*/
|
||||
export function exists(indexedDB: IDBFactory, dbName: string): Promise<boolean> {
|
||||
return new Promise<boolean>((resolve, reject) => {
|
||||
|
@ -20,6 +20,6 @@ limitations under the License.
|
||||
* to be used separately
|
||||
*/
|
||||
|
||||
/** The {@link module:indexeddb-store-worker~IndexedDBStoreWorker} class. */
|
||||
/** The {@link IndexedDBStoreWorker} class. */
|
||||
export { IndexedDBStoreWorker } from "./store/indexeddb-store-worker";
|
||||
|
||||
|
@ -16,8 +16,6 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/** @module interactive-auth */
|
||||
|
||||
import { logger } from './logger';
|
||||
import { MatrixClient } from "./client";
|
||||
import { defer, IDeferred } from "./utils";
|
||||
@ -31,8 +29,11 @@ interface IFlow {
|
||||
}
|
||||
|
||||
export interface IInputs {
|
||||
// An email address. If supplied, a flow using email verification will be chosen.
|
||||
emailAddress?: string;
|
||||
// An ISO two letter country code. Gives the country that opts.phoneNumber should be resolved relative to.
|
||||
phoneCountry?: string;
|
||||
// A phone number. If supplied, a flow using phone number validation will be chosen.
|
||||
phoneNumber?: string;
|
||||
registrationToken?: string;
|
||||
}
|
||||
@ -106,15 +107,66 @@ class NoAuthFlowFoundError extends Error {
|
||||
}
|
||||
|
||||
interface IOpts {
|
||||
/**
|
||||
* A matrix client to use for the auth process
|
||||
*/
|
||||
matrixClient: MatrixClient;
|
||||
/**
|
||||
* Error response from the last request. If null, a request will be made with no auth before starting.
|
||||
*/
|
||||
authData?: IAuthData;
|
||||
/**
|
||||
* Inputs provided by the user and used by different stages of the auto process.
|
||||
* The inputs provided will affect what flow is chosen.
|
||||
*/
|
||||
inputs?: IInputs;
|
||||
/**
|
||||
* If resuming an existing interactive auth session, the sessionId of that session.
|
||||
*/
|
||||
sessionId?: string;
|
||||
/**
|
||||
* If resuming an existing interactive auth session, the client secret for that session
|
||||
*/
|
||||
clientSecret?: string;
|
||||
/**
|
||||
* If returning from having completed m.login.email.identity auth, the sid for the email verification session.
|
||||
*/
|
||||
emailSid?: string;
|
||||
|
||||
/**
|
||||
* Called with the new auth dict to submit the request.
|
||||
* Also passes a second deprecated arg which is a flag set to true if this request is a background request.
|
||||
* The busyChanged callback should be used instead of the background flag.
|
||||
* Should return a promise which resolves to the successful response or rejects with a MatrixError.
|
||||
*/
|
||||
doRequest(auth: IAuthData | null, background: boolean): Promise<IAuthData>;
|
||||
/**
|
||||
* Called when the status of the UI auth changes,
|
||||
* ie. when the state of an auth stage changes of when the auth flow moves to a new stage.
|
||||
* The arguments are: the login type (eg m.login.password); and an object which is either an error or an
|
||||
* informational object specific to the login type.
|
||||
* If the 'errcode' key is defined, the object is an error, and has keys:
|
||||
* errcode: string, the textual error code, eg. M_UNKNOWN
|
||||
* error: string, human readable string describing the error
|
||||
*
|
||||
* The login type specific objects are as follows:
|
||||
* m.login.email.identity:
|
||||
* * emailSid: string, the sid of the active email auth session
|
||||
*/
|
||||
stateUpdated(nextStage: AuthType, status: IStageStatus): void;
|
||||
|
||||
/**
|
||||
* A function that takes the email address (string), clientSecret (string), attempt number (int) and
|
||||
* sessionId (string) and calls the relevant requestToken function and returns the promise returned by that
|
||||
* function.
|
||||
* If the resulting promise rejects, the rejection will propagate through to the attemptAuth promise.
|
||||
*/
|
||||
requestEmailToken(email: string, secret: string, attempt: number, session: string): Promise<{ sid: string }>;
|
||||
/**
|
||||
* Called whenever the interactive auth logic becomes busy submitting information provided by the user or finishes.
|
||||
* After this has been called with true the UI should indicate that a request is in progress
|
||||
* until it is called again with false.
|
||||
*/
|
||||
busyChanged?(busy: boolean): void;
|
||||
startAuthStage?(nextStage: string): Promise<void>; // LEGACY
|
||||
}
|
||||
@ -131,70 +183,7 @@ interface IOpts {
|
||||
* callbacks, and information gathered from the user can be submitted with
|
||||
* submitAuthDict.
|
||||
*
|
||||
* @constructor
|
||||
* @alias module:interactive-auth
|
||||
*
|
||||
* @param {object} opts options object
|
||||
*
|
||||
* @param {object} opts.matrixClient A matrix client to use for the auth process
|
||||
*
|
||||
* @param {object?} opts.authData error response from the last request. If
|
||||
* null, a request will be made with no auth before starting.
|
||||
*
|
||||
* @param {function(object?): Promise} opts.doRequest
|
||||
* called with the new auth dict to submit the request. Also passes a
|
||||
* second deprecated arg which is a flag set to true if this request
|
||||
* is a background request. The busyChanged callback should be used
|
||||
* instead of the background flag. Should return a promise which resolves
|
||||
* to the successful response or rejects with a MatrixError.
|
||||
*
|
||||
* @param {function(boolean): Promise} opts.busyChanged
|
||||
* called whenever the interactive auth logic becomes busy submitting
|
||||
* information provided by the user or finishes. After this has been
|
||||
* called with true the UI should indicate that a request is in progress
|
||||
* until it is called again with false.
|
||||
*
|
||||
* @param {function(string, object?)} opts.stateUpdated
|
||||
* called when the status of the UI auth changes, ie. when the state of
|
||||
* an auth stage changes of when the auth flow moves to a new stage.
|
||||
* The arguments are: the login type (eg m.login.password); and an object
|
||||
* which is either an error or an informational object specific to the
|
||||
* login type. If the 'errcode' key is defined, the object is an error,
|
||||
* and has keys:
|
||||
* errcode: string, the textual error code, eg. M_UNKNOWN
|
||||
* error: string, human readable string describing the error
|
||||
*
|
||||
* The login type specific objects are as follows:
|
||||
* m.login.email.identity:
|
||||
* * emailSid: string, the sid of the active email auth session
|
||||
*
|
||||
* @param {object?} opts.inputs Inputs provided by the user and used by different
|
||||
* stages of the auto process. The inputs provided will affect what flow is chosen.
|
||||
*
|
||||
* @param {string?} opts.inputs.emailAddress An email address. If supplied, a flow
|
||||
* using email verification will be chosen.
|
||||
*
|
||||
* @param {string?} opts.inputs.phoneCountry An ISO two letter country code. Gives
|
||||
* the country that opts.phoneNumber should be resolved relative to.
|
||||
*
|
||||
* @param {string?} opts.inputs.phoneNumber A phone number. If supplied, a flow
|
||||
* using phone number validation will be chosen.
|
||||
*
|
||||
* @param {string?} opts.sessionId If resuming an existing interactive auth session,
|
||||
* the sessionId of that session.
|
||||
*
|
||||
* @param {string?} opts.clientSecret If resuming an existing interactive auth session,
|
||||
* the client secret for that session
|
||||
*
|
||||
* @param {string?} opts.emailSid If returning from having completed m.login.email.identity
|
||||
* auth, the sid for the email verification session.
|
||||
*
|
||||
* @param {function?} opts.requestEmailToken A function that takes the email address (string),
|
||||
* clientSecret (string), attempt number (int) and sessionId (string) and calls the
|
||||
* relevant requestToken function and returns the promise returned by that function.
|
||||
* If the resulting promise rejects, the rejection will propagate through to the
|
||||
* attemptAuth promise.
|
||||
*
|
||||
* @param opts - options object
|
||||
*/
|
||||
export class InteractiveAuth {
|
||||
private readonly matrixClient: MatrixClient;
|
||||
@ -236,7 +225,7 @@ export class InteractiveAuth {
|
||||
/**
|
||||
* begin the authentication process.
|
||||
*
|
||||
* @return {Promise} which resolves to the response on success,
|
||||
* @returns which resolves to the response on success,
|
||||
* or rejects with the error on failure. Rejects with NoAuthFlowFoundError if
|
||||
* no suitable authentication flow can be found
|
||||
*/
|
||||
@ -307,7 +296,7 @@ export class InteractiveAuth {
|
||||
/**
|
||||
* get the auth session ID
|
||||
*
|
||||
* @return {string} session id
|
||||
* @returns session id
|
||||
*/
|
||||
public getSessionId(): string | undefined {
|
||||
return this.data?.session;
|
||||
@ -317,7 +306,7 @@ export class InteractiveAuth {
|
||||
* get the client secret used for validation sessions
|
||||
* with the identity server.
|
||||
*
|
||||
* @return {string} client secret
|
||||
* @returns client secret
|
||||
*/
|
||||
public getClientSecret(): string {
|
||||
return this.clientSecret;
|
||||
@ -326,8 +315,8 @@ export class InteractiveAuth {
|
||||
/**
|
||||
* get the server params for a given stage
|
||||
*
|
||||
* @param {string} loginType login type for the stage
|
||||
* @return {object?} any parameters from the server for this stage
|
||||
* @param loginType - login type for the stage
|
||||
* @returns any parameters from the server for this stage
|
||||
*/
|
||||
public getStageParams(loginType: string): Record<string, any> | undefined {
|
||||
return this.data.params?.[loginType];
|
||||
@ -342,10 +331,10 @@ export class InteractiveAuth {
|
||||
* make attemptAuth resolve/reject, or cause the startAuthStage callback
|
||||
* to be called for a new stage.
|
||||
*
|
||||
* @param {object} authData new auth dict to send to the server. Should
|
||||
* @param authData - new auth dict to send to the server. Should
|
||||
* include a `type` property denoting the login type, as well as any
|
||||
* other params for that stage.
|
||||
* @param {boolean} background If true, this request failing will not result
|
||||
* @param background - If true, this request failing will not result
|
||||
* in the attemptAuth promise being rejected. This can be set to true
|
||||
* for requests that just poll to see if auth has been completed elsewhere.
|
||||
*/
|
||||
@ -398,7 +387,7 @@ export class InteractiveAuth {
|
||||
* Gets the sid for the email validation session
|
||||
* Specific to m.login.email.identity
|
||||
*
|
||||
* @returns {string} The sid of the email auth session
|
||||
* @returns The sid of the email auth session
|
||||
*/
|
||||
public getEmailSid(): string | undefined {
|
||||
return this.emailSid;
|
||||
@ -410,7 +399,7 @@ export class InteractiveAuth {
|
||||
* of the email validation.
|
||||
* Specific to m.login.email.identity
|
||||
*
|
||||
* @param {string} sid The sid for the email validation session
|
||||
* @param sid - The sid for the email validation session
|
||||
*/
|
||||
public setEmailSid(sid: string): void {
|
||||
this.emailSid = sid;
|
||||
@ -448,9 +437,9 @@ export class InteractiveAuth {
|
||||
* Fire off a request, and either resolve the promise, or call
|
||||
* startAuthStage.
|
||||
*
|
||||
* @private
|
||||
* @param {object?} auth new auth dict, including session id
|
||||
* @param {boolean?} background If true, this request is a background poll, so it
|
||||
* @internal
|
||||
* @param auth - new auth dict, including session id
|
||||
* @param background - If true, this request is a background poll, so it
|
||||
* failing will not result in the attemptAuth promise being rejected.
|
||||
* This can be set to true for requests that just poll to see if auth has
|
||||
* been completed elsewhere.
|
||||
@ -526,8 +515,8 @@ export class InteractiveAuth {
|
||||
/**
|
||||
* Pick the next stage and call the callback
|
||||
*
|
||||
* @private
|
||||
* @throws {NoAuthFlowFoundError} If no suitable authentication flow can be found
|
||||
* @internal
|
||||
* @throws {@link NoAuthFlowFoundError} If no suitable authentication flow can be found
|
||||
*/
|
||||
private startNextAuthStage(): void {
|
||||
const nextStage = this.chooseStage();
|
||||
@ -559,9 +548,9 @@ export class InteractiveAuth {
|
||||
/**
|
||||
* Pick the next auth stage
|
||||
*
|
||||
* @private
|
||||
* @return {string?} login type
|
||||
* @throws {NoAuthFlowFoundError} If no suitable authentication flow can be found
|
||||
* @internal
|
||||
* @returns login type
|
||||
* @throws {@link NoAuthFlowFoundError} If no suitable authentication flow can be found
|
||||
*/
|
||||
private chooseStage(): AuthType | undefined {
|
||||
if (this.chosenFlow === null) {
|
||||
@ -584,9 +573,9 @@ export class InteractiveAuth {
|
||||
* this could result in the email not being used which would leave
|
||||
* the account with no means to reset a password.
|
||||
*
|
||||
* @private
|
||||
* @return {object} flow
|
||||
* @throws {NoAuthFlowFoundError} If no suitable authentication flow can be found
|
||||
* @internal
|
||||
* @returns flow
|
||||
* @throws {@link NoAuthFlowFoundError} If no suitable authentication flow can be found
|
||||
*/
|
||||
private chooseFlow(): IFlow {
|
||||
const flows = this.data.flows || [];
|
||||
@ -625,9 +614,8 @@ export class InteractiveAuth {
|
||||
/**
|
||||
* Get the first uncompleted stage in the given flow
|
||||
*
|
||||
* @private
|
||||
* @param {object} flow
|
||||
* @return {string} login type
|
||||
* @internal
|
||||
* @returns login type
|
||||
*/
|
||||
private firstUncompletedStage(flow: IFlow): AuthType | undefined {
|
||||
const completed = this.data.completed || [];
|
||||
|
@ -15,10 +15,6 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @module logger
|
||||
*/
|
||||
|
||||
import log, { Logger } from "loglevel";
|
||||
|
||||
// This is to demonstrate, that you can use any namespace you want.
|
||||
@ -56,7 +52,7 @@ log.methodFactory = function(methodName, logLevel, loggerName) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Drop-in replacement for <code>console</code> using {@link https://www.npmjs.com/package/loglevel|loglevel}.
|
||||
* Drop-in replacement for `console` using {@link https://www.npmjs.com/package/loglevel|loglevel}.
|
||||
* Can be tailored down to specific use cases if needed.
|
||||
*/
|
||||
export const logger = log.getLogger(DEFAULT_NAMESPACE) as PrefixedLogger;
|
||||
|
@ -70,8 +70,7 @@ let cryptoStoreFactory = (): CryptoStore => new MemoryCryptoStore;
|
||||
/**
|
||||
* Configure a different factory to be used for creating crypto stores
|
||||
*
|
||||
* @param {Function} fac a function which will return a new
|
||||
* {@link module:crypto.store.base~CryptoStore}.
|
||||
* @param fac - a function which will return a new {@link CryptoStore}
|
||||
*/
|
||||
export function setCryptoStoreFactory(fac: () => CryptoStore): void {
|
||||
cryptoStoreFactory = fac;
|
||||
@ -88,24 +87,14 @@ function amendClientOpts(opts: ICreateClientOpts): ICreateClientOpts {
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a Matrix Client. Similar to {@link module:client.MatrixClient}
|
||||
* Construct a Matrix Client. Similar to {@link MatrixClient}
|
||||
* except that the 'request', 'store' and 'scheduler' dependencies are satisfied.
|
||||
* @param {Object} opts The configuration options for this client. These configuration
|
||||
* options will be passed directly to {@link module:client.MatrixClient}.
|
||||
* @param {Object} opts.store If not set, defaults to
|
||||
* {@link module:store/memory.MemoryStore}.
|
||||
* @param {Object} opts.scheduler If not set, defaults to
|
||||
* {@link module:scheduler~MatrixScheduler}.
|
||||
* @param opts - The configuration options for this client. These configuration
|
||||
* options will be passed directly to {@link MatrixClient}.
|
||||
*
|
||||
* @param {module:crypto.store.base~CryptoStore=} opts.cryptoStore
|
||||
* crypto store implementation. Calls the factory supplied to
|
||||
* {@link setCryptoStoreFactory} if unspecified; or if no factory has been
|
||||
* specified, uses a default implementation (indexeddb in the browser,
|
||||
* in-memory otherwise).
|
||||
*
|
||||
* @return {MatrixClient} A new matrix client.
|
||||
* @see {@link module:client.MatrixClient} for the full list of options for
|
||||
* <code>opts</code>.
|
||||
* @returns A new matrix client.
|
||||
* @see {@link MatrixClient} for the full list of options for
|
||||
* `opts`.
|
||||
*/
|
||||
export function createClient(opts: ICreateClientOpts): MatrixClient {
|
||||
return new MatrixClient(amendClientOpts(opts));
|
||||
|
@ -67,7 +67,7 @@ export class MSC3089Branch {
|
||||
|
||||
/**
|
||||
* Deletes the file from the tree, including all prior edits/versions.
|
||||
* @returns {Promise<void>} Resolves when complete.
|
||||
* @returns Promise which resolves when complete.
|
||||
*/
|
||||
public async delete(): Promise<void> {
|
||||
await this.client.sendStateEvent(this.roomId, UNSTABLE_MSC3089_BRANCH.name, {}, this.id);
|
||||
@ -79,7 +79,7 @@ export class MSC3089Branch {
|
||||
|
||||
/**
|
||||
* Gets the name for this file.
|
||||
* @returns {string} The name, or "Unnamed File" if unknown.
|
||||
* @returns The name, or "Unnamed File" if unknown.
|
||||
*/
|
||||
public getName(): string {
|
||||
return this.indexEvent.getContent()['name'] || "Unnamed File";
|
||||
@ -87,8 +87,8 @@ export class MSC3089Branch {
|
||||
|
||||
/**
|
||||
* Sets the name for this file.
|
||||
* @param {string} name The new name for this file.
|
||||
* @returns {Promise<void>} Resolves when complete.
|
||||
* @param name - The new name for this file.
|
||||
* @returns Promise which resolves when complete.
|
||||
*/
|
||||
public async setName(name: string): Promise<void> {
|
||||
await this.client.sendStateEvent(this.roomId, UNSTABLE_MSC3089_BRANCH.name, {
|
||||
@ -99,7 +99,7 @@ export class MSC3089Branch {
|
||||
|
||||
/**
|
||||
* Gets whether or not a file is locked.
|
||||
* @returns {boolean} True if locked, false otherwise.
|
||||
* @returns True if locked, false otherwise.
|
||||
*/
|
||||
public isLocked(): boolean {
|
||||
return this.indexEvent.getContent()['locked'] || false;
|
||||
@ -107,8 +107,8 @@ export class MSC3089Branch {
|
||||
|
||||
/**
|
||||
* Sets a file as locked or unlocked.
|
||||
* @param {boolean} locked True to lock the file, false otherwise.
|
||||
* @returns {Promise<void>} Resolves when complete.
|
||||
* @param locked - True to lock the file, false otherwise.
|
||||
* @returns Promise which resolves when complete.
|
||||
*/
|
||||
public async setLocked(locked: boolean): Promise<void> {
|
||||
await this.client.sendStateEvent(this.roomId, UNSTABLE_MSC3089_BRANCH.name, {
|
||||
@ -119,7 +119,7 @@ export class MSC3089Branch {
|
||||
|
||||
/**
|
||||
* Gets information about the file needed to download it.
|
||||
* @returns {Promise<{info: IEncryptedFile, httpUrl: string}>} Information about the file.
|
||||
* @returns Information about the file.
|
||||
*/
|
||||
public async getFileInfo(): Promise<{ info: IEncryptedFile, httpUrl: string }> {
|
||||
const event = await this.getFileEvent();
|
||||
@ -136,7 +136,7 @@ export class MSC3089Branch {
|
||||
|
||||
/**
|
||||
* Gets the event the file points to.
|
||||
* @returns {Promise<MatrixEvent>} Resolves to the file's event.
|
||||
* @returns Promise which resolves to the file's event.
|
||||
*/
|
||||
public async getFileEvent(): Promise<MatrixEvent> {
|
||||
const room = this.client.getRoom(this.roomId);
|
||||
@ -161,11 +161,11 @@ export class MSC3089Branch {
|
||||
|
||||
/**
|
||||
* Creates a new version of this file with contents in a type that is compatible with MatrixClient.uploadContent().
|
||||
* @param {string} name The name of the file.
|
||||
* @param {File | String | Buffer | ReadStream | Blob} encryptedContents The encrypted contents.
|
||||
* @param {Partial<IEncryptedFile>} info The encrypted file information.
|
||||
* @param {IContent} additionalContent Optional event content fields to include in the message.
|
||||
* @returns {Promise<ISendEventResponse>} Resolves to the file event's sent response.
|
||||
* @param name - The name of the file.
|
||||
* @param encryptedContents - The encrypted contents.
|
||||
* @param info - The encrypted file information.
|
||||
* @param additionalContent - Optional event content fields to include in the message.
|
||||
* @returns Promise which resolves to the file event's sent response.
|
||||
*/
|
||||
public async createNewVersion(
|
||||
name: string,
|
||||
@ -200,7 +200,7 @@ export class MSC3089Branch {
|
||||
|
||||
/**
|
||||
* Gets the file's version history, starting at this file.
|
||||
* @returns {Promise<MSC3089Branch[]>} Resolves to the file's version history, with the
|
||||
* @returns Promise which resolves to the file's version history, with the
|
||||
* first element being the current version and the last element being the first version.
|
||||
*/
|
||||
public async getVersionHistory(): Promise<MSC3089Branch[]> {
|
||||
|
@ -111,8 +111,8 @@ export class MSC3089TreeSpace {
|
||||
|
||||
/**
|
||||
* Sets the name of the tree space.
|
||||
* @param {string} name The new name for the space.
|
||||
* @returns {Promise<void>} Resolves when complete.
|
||||
* @param name - The new name for the space.
|
||||
* @returns Promise which resolves when complete.
|
||||
*/
|
||||
public async setName(name: string): Promise<void> {
|
||||
await this.client.sendStateEvent(this.roomId, EventType.RoomName, { name }, "");
|
||||
@ -121,15 +121,15 @@ export class MSC3089TreeSpace {
|
||||
/**
|
||||
* Invites a user to the tree space. They will be given the default Viewer
|
||||
* permission level unless specified elsewhere.
|
||||
* @param {string} userId The user ID to invite.
|
||||
* @param {boolean} andSubspaces True (default) to invite the user to all
|
||||
* @param userId - The user ID to invite.
|
||||
* @param andSubspaces - True (default) to invite the user to all
|
||||
* directories/subspaces too, recursively.
|
||||
* @param {boolean} shareHistoryKeys True (default) to share encryption keys
|
||||
* @param shareHistoryKeys - True (default) to share encryption keys
|
||||
* with the invited user. This will allow them to decrypt the events (files)
|
||||
* in the tree. Keys will not be shared if the room is lacking appropriate
|
||||
* history visibility (by default, history visibility is "shared" in trees,
|
||||
* which is an appropriate visibility for these purposes).
|
||||
* @returns {Promise<void>} Resolves when complete.
|
||||
* @returns Promise which resolves when complete.
|
||||
*/
|
||||
public async invite(userId: string, andSubspaces = true, shareHistoryKeys = true): Promise<void> {
|
||||
const promises: Promise<void>[] = [this.retryInvite(userId)];
|
||||
@ -164,9 +164,9 @@ export class MSC3089TreeSpace {
|
||||
* Sets the permissions of a user to the given role. Note that if setting a user
|
||||
* to Owner then they will NOT be able to be demoted. If the user does not have
|
||||
* permission to change the power level of the target, an error will be thrown.
|
||||
* @param {string} userId The user ID to change the role of.
|
||||
* @param {TreePermissions} role The role to assign.
|
||||
* @returns {Promise<void>} Resolves when complete.
|
||||
* @param userId - The user ID to change the role of.
|
||||
* @param role - The role to assign.
|
||||
* @returns Promise which resolves when complete.
|
||||
*/
|
||||
public async setPermissions(userId: string, role: TreePermissions): Promise<void> {
|
||||
const currentPls = this.room.currentState.getStateEvents(EventType.RoomPowerLevels, "");
|
||||
@ -200,8 +200,8 @@ export class MSC3089TreeSpace {
|
||||
* Gets the current permissions of a user. Note that any users missing explicit permissions (or not
|
||||
* in the space) will be considered Viewers. Appropriate membership checks need to be performed
|
||||
* elsewhere.
|
||||
* @param {string} userId The user ID to check permissions of.
|
||||
* @returns {TreePermissions} The permissions for the user, defaulting to Viewer.
|
||||
* @param userId - The user ID to check permissions of.
|
||||
* @returns The permissions for the user, defaulting to Viewer.
|
||||
*/
|
||||
public getPermissions(userId: string): TreePermissions {
|
||||
const currentPls = this.room.currentState.getStateEvents(EventType.RoomPowerLevels, "");
|
||||
@ -220,8 +220,8 @@ export class MSC3089TreeSpace {
|
||||
|
||||
/**
|
||||
* Creates a directory under this tree space, represented as another tree space.
|
||||
* @param {string} name The name for the directory.
|
||||
* @returns {Promise<MSC3089TreeSpace>} Resolves to the created directory.
|
||||
* @param name - The name for the directory.
|
||||
* @returns Promise which resolves to the created directory.
|
||||
*/
|
||||
public async createDirectory(name: string): Promise<MSC3089TreeSpace> {
|
||||
const directory = await this.client.unstableCreateFileTree(name);
|
||||
@ -239,7 +239,7 @@ export class MSC3089TreeSpace {
|
||||
|
||||
/**
|
||||
* Gets a list of all known immediate subdirectories to this tree space.
|
||||
* @returns {MSC3089TreeSpace[]} The tree spaces (directories). May be empty, but not null.
|
||||
* @returns The tree spaces (directories). May be empty, but not null.
|
||||
*/
|
||||
public getDirectories(): MSC3089TreeSpace[] {
|
||||
const trees: MSC3089TreeSpace[] = [];
|
||||
@ -261,8 +261,8 @@ export class MSC3089TreeSpace {
|
||||
/**
|
||||
* Gets a subdirectory of a given ID under this tree space. Note that this will not recurse
|
||||
* into children and instead only look one level deep.
|
||||
* @param {string} roomId The room ID (directory ID) to find.
|
||||
* @returns {MSC3089TreeSpace | undefined} The directory, or undefined if not found.
|
||||
* @param roomId - The room ID (directory ID) to find.
|
||||
* @returns The directory, or undefined if not found.
|
||||
*/
|
||||
public getDirectory(roomId: string): MSC3089TreeSpace | undefined {
|
||||
return this.getDirectories().find(r => r.roomId === roomId);
|
||||
@ -270,7 +270,7 @@ export class MSC3089TreeSpace {
|
||||
|
||||
/**
|
||||
* Deletes the tree, kicking all members and deleting **all subdirectories**.
|
||||
* @returns {Promise<void>} Resolves when complete.
|
||||
* @returns Promise which resolves when complete.
|
||||
*/
|
||||
public async delete(): Promise<void> {
|
||||
const subdirectories = this.getDirectories();
|
||||
@ -341,7 +341,7 @@ export class MSC3089TreeSpace {
|
||||
/**
|
||||
* Gets the current order index for this directory. Note that if this is the top level space
|
||||
* then -1 will be returned.
|
||||
* @returns {number} The order index of this space.
|
||||
* @returns The order index of this space.
|
||||
*/
|
||||
public getOrder(): number {
|
||||
if (this.isTopLevel) return -1;
|
||||
@ -357,8 +357,8 @@ export class MSC3089TreeSpace {
|
||||
* Sets the order index for this directory within its parent. Note that if this is a top level
|
||||
* space then an error will be thrown. -1 can be used to move the child to the start, and numbers
|
||||
* larger than the number of children can be used to move the child to the end.
|
||||
* @param {number} index The new order index for this space.
|
||||
* @returns {Promise<void>} Resolves when complete.
|
||||
* @param index - The new order index for this space.
|
||||
* @returns Promise which resolves when complete.
|
||||
* @throws Throws if this is a top level space.
|
||||
*/
|
||||
public async setOrder(index: number): Promise<void> {
|
||||
@ -464,11 +464,11 @@ export class MSC3089TreeSpace {
|
||||
/**
|
||||
* Creates (uploads) a new file to this tree. The file must have already been encrypted for the room.
|
||||
* The file contents are in a type that is compatible with MatrixClient.uploadContent().
|
||||
* @param {string} name The name of the file.
|
||||
* @param {File | String | Buffer | ReadStream | Blob} encryptedContents The encrypted contents.
|
||||
* @param {Partial<IEncryptedFile>} info The encrypted file information.
|
||||
* @param {IContent} additionalContent Optional event content fields to include in the message.
|
||||
* @returns {Promise<ISendEventResponse>} Resolves to the file event's sent response.
|
||||
* @param name - The name of the file.
|
||||
* @param encryptedContents - The encrypted contents.
|
||||
* @param info - The encrypted file information.
|
||||
* @param additionalContent - Optional event content fields to include in the message.
|
||||
* @returns Promise which resolves to the file event's sent response.
|
||||
*/
|
||||
public async createFile(
|
||||
name: string,
|
||||
@ -512,8 +512,8 @@ export class MSC3089TreeSpace {
|
||||
|
||||
/**
|
||||
* Retrieves a file from the tree.
|
||||
* @param {string} fileEventId The event ID of the file.
|
||||
* @returns {MSC3089Branch | null} The file, or null if not found.
|
||||
* @param fileEventId - The event ID of the file.
|
||||
* @returns The file, or null if not found.
|
||||
*/
|
||||
public getFile(fileEventId: string): MSC3089Branch | null {
|
||||
const branch = this.room.currentState.getStateEvents(UNSTABLE_MSC3089_BRANCH.name, fileEventId);
|
||||
@ -522,7 +522,7 @@ export class MSC3089TreeSpace {
|
||||
|
||||
/**
|
||||
* Gets an array of all known files for the tree.
|
||||
* @returns {MSC3089Branch[]} The known files. May be empty, but not null.
|
||||
* @returns The known files. May be empty, but not null.
|
||||
*/
|
||||
public listFiles(): MSC3089Branch[] {
|
||||
return this.listAllFiles().filter(b => b.isActive);
|
||||
@ -530,7 +530,7 @@ export class MSC3089TreeSpace {
|
||||
|
||||
/**
|
||||
* Gets an array of all known files for the tree, including inactive/invalid ones.
|
||||
* @returns {MSC3089Branch[]} The known files. May be empty, but not null.
|
||||
* @returns The known files. May be empty, but not null.
|
||||
*/
|
||||
public listAllFiles(): MSC3089Branch[] {
|
||||
const branches = this.room.currentState.getStateEvents(UNSTABLE_MSC3089_BRANCH.name) ?? [];
|
||||
|
@ -17,9 +17,6 @@ limitations under the License.
|
||||
import { MatrixEvent } from "./event";
|
||||
import { Direction } from "./event-timeline";
|
||||
|
||||
/**
|
||||
* @module models/event-context
|
||||
*/
|
||||
export class EventContext {
|
||||
private timeline: MatrixEvent[];
|
||||
private ourEventIndex = 0;
|
||||
@ -38,9 +35,7 @@ export class EventContext {
|
||||
* It also stores pagination tokens for going backwards and forwards in the
|
||||
* timeline.
|
||||
*
|
||||
* @param {MatrixEvent} ourEvent the event at the centre of this context
|
||||
*
|
||||
* @constructor
|
||||
* @param ourEvent - the event at the centre of this context
|
||||
*/
|
||||
public constructor(public readonly ourEvent: MatrixEvent) {
|
||||
this.timeline = [ourEvent];
|
||||
@ -51,7 +46,7 @@ export class EventContext {
|
||||
*
|
||||
* This is a convenience function for getTimeline()[getOurEventIndex()].
|
||||
*
|
||||
* @return {MatrixEvent} The event at the centre of this context.
|
||||
* @returns The event at the centre of this context.
|
||||
*/
|
||||
public getEvent(): MatrixEvent {
|
||||
return this.timeline[this.ourEventIndex];
|
||||
@ -60,7 +55,7 @@ export class EventContext {
|
||||
/**
|
||||
* Get the list of events in this context
|
||||
*
|
||||
* @return {Array} An array of MatrixEvents
|
||||
* @returns An array of MatrixEvents
|
||||
*/
|
||||
public getTimeline(): MatrixEvent[] {
|
||||
return this.timeline;
|
||||
@ -68,8 +63,6 @@ export class EventContext {
|
||||
|
||||
/**
|
||||
* Get the index in the timeline of our event
|
||||
*
|
||||
* @return {Number}
|
||||
*/
|
||||
public getOurEventIndex(): number {
|
||||
return this.ourEventIndex;
|
||||
@ -78,9 +71,7 @@ export class EventContext {
|
||||
/**
|
||||
* Get a pagination token.
|
||||
*
|
||||
* @param {boolean} backwards true to get the pagination token for going
|
||||
* backwards in time
|
||||
* @return {string}
|
||||
* @param backwards - true to get the pagination token for going
|
||||
*/
|
||||
public getPaginateToken(backwards = false): string | null {
|
||||
return this.paginateTokens[backwards ? Direction.Backward : Direction.Forward];
|
||||
@ -91,8 +82,8 @@ export class EventContext {
|
||||
*
|
||||
* Generally this will be used only by the matrix js sdk.
|
||||
*
|
||||
* @param {string} token pagination token
|
||||
* @param {boolean} backwards true to set the pagination token for going
|
||||
* @param token - pagination token
|
||||
* @param backwards - true to set the pagination token for going
|
||||
* backwards in time
|
||||
*/
|
||||
public setPaginateToken(token?: string, backwards = false): void {
|
||||
@ -102,8 +93,8 @@ export class EventContext {
|
||||
/**
|
||||
* Add more events to the timeline
|
||||
*
|
||||
* @param {Array} events new events, in timeline order
|
||||
* @param {boolean} atStart true to insert new events at the start
|
||||
* @param events - new events, in timeline order
|
||||
* @param atStart - true to insert new events at the start
|
||||
*/
|
||||
public addEvents(events: MatrixEvent[], atStart = false): void {
|
||||
// TODO: should we share logic with Room.addEventsToTimeline?
|
||||
|
@ -17,7 +17,6 @@ limitations under the License.
|
||||
/**
|
||||
* Enum for event statuses.
|
||||
* @readonly
|
||||
* @enum {string}
|
||||
*/
|
||||
export enum EventStatus {
|
||||
/** The event was not sent and will no longer be retried. */
|
||||
|
@ -14,10 +14,6 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @module models/event-timeline-set
|
||||
*/
|
||||
|
||||
import { EventTimeline, IAddEventOptions } from "./event-timeline";
|
||||
import { MatrixEvent } from "./event";
|
||||
import { logger } from '../logger';
|
||||
@ -31,16 +27,20 @@ import { Thread, ThreadFilterType } from "./thread";
|
||||
|
||||
const DEBUG = true;
|
||||
|
||||
/* istanbul ignore next */
|
||||
let debuglog: (...args: any[]) => void;
|
||||
if (DEBUG) {
|
||||
// using bind means that we get to keep useful line numbers in the console
|
||||
debuglog = logger.log.bind(logger);
|
||||
} else {
|
||||
/* istanbul ignore next */
|
||||
debuglog = function(): void {};
|
||||
}
|
||||
|
||||
interface IOpts {
|
||||
// Set to true to enable improved timeline support.
|
||||
timelineSupport?: boolean;
|
||||
// The filter object, if any, for this timelineSet.
|
||||
filter?: Filter;
|
||||
pendingEvents?: boolean;
|
||||
}
|
||||
@ -51,7 +51,9 @@ export enum DuplicateStrategy {
|
||||
}
|
||||
|
||||
export interface IRoomTimelineData {
|
||||
// the timeline the event was added to/removed from
|
||||
timeline: EventTimeline;
|
||||
// true if the event was a real-time event added to the end of the live timeline
|
||||
liveEvent?: boolean;
|
||||
}
|
||||
|
||||
@ -75,6 +77,26 @@ export interface IAddLiveEventOptions
|
||||
type EmittedEvents = RoomEvent.Timeline | RoomEvent.TimelineReset;
|
||||
|
||||
export type EventTimelineSetHandlerMap = {
|
||||
/**
|
||||
* Fires whenever the timeline in a room is updated.
|
||||
* @param event - The matrix event which caused this event to fire.
|
||||
* @param room - The room, if any, whose timeline was updated.
|
||||
* @param toStartOfTimeline - True if this event was added to the start
|
||||
* @param removed - True if this event has just been removed from the timeline
|
||||
* (beginning; oldest) of the timeline e.g. due to pagination.
|
||||
*
|
||||
* @param data - more data about the event
|
||||
*
|
||||
* @example
|
||||
* ```
|
||||
* matrixClient.on("Room.timeline",
|
||||
* function(event, room, toStartOfTimeline, removed, data) {
|
||||
* if (!toStartOfTimeline && data.liveEvent) {
|
||||
* var messageToAppend = room.timeline.[room.timeline.length - 1];
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
[RoomEvent.Timeline]: (
|
||||
event: MatrixEvent,
|
||||
room: Room | undefined,
|
||||
@ -82,6 +104,18 @@ export type EventTimelineSetHandlerMap = {
|
||||
removed: boolean,
|
||||
data: IRoomTimelineData,
|
||||
) => void;
|
||||
/**
|
||||
* Fires whenever the live timeline in a room is reset.
|
||||
*
|
||||
* When we get a 'limited' sync (for example, after a network outage), we reset
|
||||
* the live timeline to be empty before adding the recent events to the new
|
||||
* timeline. This event is fired after the timeline is reset, and before the
|
||||
* new events are added.
|
||||
*
|
||||
* @param room - The room whose live timeline was reset, if any
|
||||
* @param timelineSet - timelineSet room whose live timeline was reset
|
||||
* @param resetAllTimelines - True if all timelines were reset.
|
||||
*/
|
||||
[RoomEvent.TimelineReset]: (
|
||||
room: Room | undefined,
|
||||
eventTimelineSet: EventTimelineSet,
|
||||
@ -119,20 +153,13 @@ export class EventTimelineSet extends TypedEventEmitter<EmittedEvents, EventTime
|
||||
* <p>In order that we can find events from their ids later, we also maintain a
|
||||
* map from event_id to timeline and index.
|
||||
*
|
||||
* @constructor
|
||||
* @param {Room=} room
|
||||
* Room for this timelineSet. May be null for non-room cases, such as the
|
||||
* @param room - Room for this timelineSet. May be null for non-room cases, such as the
|
||||
* notification timeline.
|
||||
* @param {Object} opts Options inherited from Room.
|
||||
*
|
||||
* @param {boolean} [opts.timelineSupport = false]
|
||||
* Set to true to enable improved timeline support.
|
||||
* @param {Object} [opts.filter = null]
|
||||
* The filter object, if any, for this timelineSet.
|
||||
* @param {MatrixClient=} client the Matrix client which owns this EventTimelineSet,
|
||||
* @param opts - Options inherited from Room.
|
||||
* @param client - the Matrix client which owns this EventTimelineSet,
|
||||
* can be omitted if room is specified.
|
||||
* @param {Thread=} thread the thread to which this timeline set relates.
|
||||
* @param {boolean} isThreadTimeline Whether this timeline set relates to a thread list timeline
|
||||
* @param thread - the thread to which this timeline set relates.
|
||||
* @param isThreadTimeline - Whether this timeline set relates to a thread list timeline
|
||||
* (e.g., All threads or My threads)
|
||||
*/
|
||||
public constructor(
|
||||
@ -159,7 +186,7 @@ export class EventTimelineSet extends TypedEventEmitter<EmittedEvents, EventTime
|
||||
|
||||
/**
|
||||
* Get all the timelines in this set
|
||||
* @return {module:models/event-timeline~EventTimeline[]} the timelines in this set
|
||||
* @returns the timelines in this set
|
||||
*/
|
||||
public getTimelines(): EventTimeline[] {
|
||||
return this.timelines;
|
||||
@ -167,7 +194,7 @@ export class EventTimelineSet extends TypedEventEmitter<EmittedEvents, EventTime
|
||||
|
||||
/**
|
||||
* Get the filter object this timeline set is filtered on, if any
|
||||
* @return {?Filter} the optional filter for this timelineSet
|
||||
* @returns the optional filter for this timelineSet
|
||||
*/
|
||||
public getFilter(): Filter | undefined {
|
||||
return this.filter;
|
||||
@ -176,7 +203,7 @@ export class EventTimelineSet extends TypedEventEmitter<EmittedEvents, EventTime
|
||||
/**
|
||||
* Set the filter object this timeline set is filtered on
|
||||
* (passed to the server when paginating via /messages).
|
||||
* @param {Filter} filter the filter for this timelineSet
|
||||
* @param filter - the filter for this timelineSet
|
||||
*/
|
||||
public setFilter(filter?: Filter): void {
|
||||
this.filter = filter;
|
||||
@ -186,10 +213,10 @@ export class EventTimelineSet extends TypedEventEmitter<EmittedEvents, EventTime
|
||||
* Get the list of pending sent events for this timelineSet's room, filtered
|
||||
* by the timelineSet's filter if appropriate.
|
||||
*
|
||||
* @return {module:models/event.MatrixEvent[]} A list of the sent events
|
||||
* @returns A list of the sent events
|
||||
* waiting for remote echo.
|
||||
*
|
||||
* @throws If <code>opts.pendingEventOrdering</code> was not 'detached'
|
||||
* @throws If `opts.pendingEventOrdering` was not 'detached'
|
||||
*/
|
||||
public getPendingEvents(): MatrixEvent[] {
|
||||
if (!this.room || !this.displayPendingEvents) {
|
||||
@ -201,7 +228,7 @@ export class EventTimelineSet extends TypedEventEmitter<EmittedEvents, EventTime
|
||||
/**
|
||||
* Get the live timeline for this room.
|
||||
*
|
||||
* @return {module:models/event-timeline~EventTimeline} live timeline
|
||||
* @returns live timeline
|
||||
*/
|
||||
public getLiveTimeline(): EventTimeline {
|
||||
return this.liveTimeline;
|
||||
@ -210,7 +237,7 @@ export class EventTimelineSet extends TypedEventEmitter<EmittedEvents, EventTime
|
||||
/**
|
||||
* Set the live timeline for this room.
|
||||
*
|
||||
* @return {module:models/event-timeline~EventTimeline} live timeline
|
||||
* @returns live timeline
|
||||
*/
|
||||
public setLiveTimeline(timeline: EventTimeline): void {
|
||||
this.liveTimeline = timeline;
|
||||
@ -218,8 +245,8 @@ export class EventTimelineSet extends TypedEventEmitter<EmittedEvents, EventTime
|
||||
|
||||
/**
|
||||
* Return the timeline (if any) this event is in.
|
||||
* @param {String} eventId the eventId being sought
|
||||
* @return {module:models/event-timeline~EventTimeline} timeline
|
||||
* @param eventId - the eventId being sought
|
||||
* @returns timeline
|
||||
*/
|
||||
public eventIdToTimeline(eventId: string): EventTimeline | undefined {
|
||||
return this._eventIdToTimeline.get(eventId);
|
||||
@ -228,8 +255,8 @@ export class EventTimelineSet extends TypedEventEmitter<EmittedEvents, EventTime
|
||||
/**
|
||||
* Track a new event as if it were in the same timeline as an old event,
|
||||
* replacing it.
|
||||
* @param {String} oldEventId event ID of the original event
|
||||
* @param {String} newEventId event ID of the replacement event
|
||||
* @param oldEventId - event ID of the original event
|
||||
* @param newEventId - event ID of the replacement event
|
||||
*/
|
||||
public replaceEventId(oldEventId: string, newEventId: string): void {
|
||||
const existingTimeline = this._eventIdToTimeline.get(oldEventId);
|
||||
@ -244,11 +271,12 @@ export class EventTimelineSet extends TypedEventEmitter<EmittedEvents, EventTime
|
||||
*
|
||||
* <p>This is used when /sync returns a 'limited' timeline.
|
||||
*
|
||||
* @param {string=} backPaginationToken token for back-paginating the new timeline
|
||||
* @param {string=} forwardPaginationToken token for forward-paginating the old live timeline,
|
||||
* @param backPaginationToken - token for back-paginating the new timeline
|
||||
* @param forwardPaginationToken - token for forward-paginating the old live timeline,
|
||||
* if absent or null, all timelines are reset.
|
||||
*
|
||||
* @fires module:client~MatrixClient#event:"Room.timelineReset"
|
||||
* @remarks
|
||||
* Fires {@link RoomEvent.TimelineReset}
|
||||
*/
|
||||
public resetLiveTimeline(backPaginationToken?: string, forwardPaginationToken?: string): void {
|
||||
// Each EventTimeline has RoomState objects tracking the state at the start
|
||||
@ -293,8 +321,8 @@ export class EventTimelineSet extends TypedEventEmitter<EmittedEvents, EventTime
|
||||
/**
|
||||
* Get the timeline which contains the given event, if any
|
||||
*
|
||||
* @param {string} eventId event ID to look for
|
||||
* @return {?module:models/event-timeline~EventTimeline} timeline containing
|
||||
* @param eventId - event ID to look for
|
||||
* @returns timeline containing
|
||||
* the given event, or null if unknown
|
||||
*/
|
||||
public getTimelineForEvent(eventId?: string): EventTimeline | null {
|
||||
@ -306,8 +334,8 @@ export class EventTimelineSet extends TypedEventEmitter<EmittedEvents, EventTime
|
||||
/**
|
||||
* Get an event which is stored in our timelines
|
||||
*
|
||||
* @param {string} eventId event ID to look for
|
||||
* @return {?module:models/event~MatrixEvent} the given event, or undefined if unknown
|
||||
* @param eventId - event ID to look for
|
||||
* @returns the given event, or undefined if unknown
|
||||
*/
|
||||
public findEventById(eventId: string): MatrixEvent | undefined {
|
||||
const tl = this.getTimelineForEvent(eventId);
|
||||
@ -322,7 +350,7 @@ export class EventTimelineSet extends TypedEventEmitter<EmittedEvents, EventTime
|
||||
/**
|
||||
* Add a new timeline to this timeline list
|
||||
*
|
||||
* @return {module:models/event-timeline~EventTimeline} newly-created timeline
|
||||
* @returns newly-created timeline
|
||||
*/
|
||||
public addTimeline(): EventTimeline {
|
||||
if (!this.timelineSupport) {
|
||||
@ -341,18 +369,19 @@ export class EventTimelineSet extends TypedEventEmitter<EmittedEvents, EventTime
|
||||
*
|
||||
* <p>Will fire "Room.timeline" for each event added.
|
||||
*
|
||||
* @param {MatrixEvent[]} events A list of events to add.
|
||||
* @param events - A list of events to add.
|
||||
*
|
||||
* @param {boolean} toStartOfTimeline True to add these events to the start
|
||||
* @param toStartOfTimeline - True to add these events to the start
|
||||
* (oldest) instead of the end (newest) of the timeline. If true, the oldest
|
||||
* event will be the <b>last</b> element of 'events'.
|
||||
*
|
||||
* @param {module:models/event-timeline~EventTimeline} timeline timeline to
|
||||
* @param timeline - timeline to
|
||||
* add events to.
|
||||
*
|
||||
* @param {string=} paginationToken token for the next batch of events
|
||||
* @param paginationToken - token for the next batch of events
|
||||
*
|
||||
* @fires module:client~MatrixClient#event:"Room.timeline"
|
||||
* @remarks
|
||||
* Fires {@link RoomEvent.Timeline}
|
||||
*
|
||||
*/
|
||||
public addEventsToTimeline(
|
||||
@ -557,8 +586,8 @@ export class EventTimelineSet extends TypedEventEmitter<EmittedEvents, EventTime
|
||||
/**
|
||||
* Add an event to the end of this live timeline.
|
||||
*
|
||||
* @param {MatrixEvent} event Event to be added
|
||||
* @param {IAddLiveEventOptions} options addLiveEvent options
|
||||
* @param event - Event to be added
|
||||
* @param options - addLiveEvent options
|
||||
*/
|
||||
public addLiveEvent(
|
||||
event: MatrixEvent,
|
||||
@ -653,11 +682,10 @@ export class EventTimelineSet extends TypedEventEmitter<EmittedEvents, EventTime
|
||||
*
|
||||
* Will fire "Room.timeline" for each event added.
|
||||
*
|
||||
* @param {MatrixEvent} event
|
||||
* @param {EventTimeline} timeline
|
||||
* @param {IAddEventToTimelineOptions} options addEventToTimeline options
|
||||
* @param options - addEventToTimeline options
|
||||
*
|
||||
* @fires module:client~MatrixClient#event:"Room.timeline"
|
||||
* @remarks
|
||||
* Fires {@link RoomEvent.Timeline}
|
||||
*/
|
||||
public addEventToTimeline(
|
||||
event: MatrixEvent,
|
||||
@ -745,11 +773,12 @@ export class EventTimelineSet extends TypedEventEmitter<EmittedEvents, EventTime
|
||||
* Replaces event with ID oldEventId with one with newEventId, if oldEventId is
|
||||
* recognised. Otherwise, add to the live timeline. Used to handle remote echos.
|
||||
*
|
||||
* @param {MatrixEvent} localEvent the new event to be added to the timeline
|
||||
* @param {String} oldEventId the ID of the original event
|
||||
* @param {boolean} newEventId the ID of the replacement event
|
||||
* @param localEvent - the new event to be added to the timeline
|
||||
* @param oldEventId - the ID of the original event
|
||||
* @param newEventId - the ID of the replacement event
|
||||
*
|
||||
* @fires module:client~MatrixClient#event:"Room.timeline"
|
||||
* @remarks
|
||||
* Fires {@link RoomEvent.Timeline}
|
||||
*/
|
||||
public handleRemoteEcho(
|
||||
localEvent: MatrixEvent,
|
||||
@ -771,9 +800,9 @@ export class EventTimelineSet extends TypedEventEmitter<EmittedEvents, EventTime
|
||||
/**
|
||||
* Removes a single event from this room.
|
||||
*
|
||||
* @param {String} eventId The id of the event to remove
|
||||
* @param eventId - The id of the event to remove
|
||||
*
|
||||
* @return {?MatrixEvent} the removed event, or null if the event was not found
|
||||
* @returns the removed event, or null if the event was not found
|
||||
* in this room.
|
||||
*/
|
||||
public removeEvent(eventId: string): MatrixEvent | null {
|
||||
@ -796,10 +825,10 @@ export class EventTimelineSet extends TypedEventEmitter<EmittedEvents, EventTime
|
||||
/**
|
||||
* Determine where two events appear in the timeline relative to one another
|
||||
*
|
||||
* @param {string} eventId1 The id of the first event
|
||||
* @param {string} eventId2 The id of the second event
|
||||
* @param eventId1 - The id of the first event
|
||||
* @param eventId2 - The id of the second event
|
||||
|
||||
* @return {?number} a number less than zero if eventId1 precedes eventId2, and
|
||||
* @returns a number less than zero if eventId1 precedes eventId2, and
|
||||
* greater than zero if eventId1 succeeds eventId2. zero if they are the
|
||||
* same event; null if we can't tell (either because we don't know about one
|
||||
* of the events, or because they are in separate timelines which don't join
|
||||
@ -873,9 +902,9 @@ export class EventTimelineSet extends TypedEventEmitter<EmittedEvents, EventTime
|
||||
* for events which should be shown in the main room timeline.
|
||||
* Requires the `room` property to have been set at EventTimelineSet construction time.
|
||||
*
|
||||
* @param event {MatrixEvent} the event to check whether it belongs to this timeline set.
|
||||
* @throws {Error} if `room` was not set when constructing this timeline set.
|
||||
* @return {boolean} whether the event belongs to this timeline set.
|
||||
* @param event - the event to check whether it belongs to this timeline set.
|
||||
* @throws Error if `room` was not set when constructing this timeline set.
|
||||
* @returns whether the event belongs to this timeline set.
|
||||
*/
|
||||
public canContain(event: MatrixEvent): boolean {
|
||||
if (!this.room) {
|
||||
@ -891,43 +920,3 @@ export class EventTimelineSet extends TypedEventEmitter<EmittedEvents, EventTime
|
||||
return shouldLiveInRoom;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires whenever the timeline in a room is updated.
|
||||
* @event module:client~MatrixClient#"Room.timeline"
|
||||
* @param {MatrixEvent} event The matrix event which caused this event to fire.
|
||||
* @param {?Room} room The room, if any, whose timeline was updated.
|
||||
* @param {boolean} toStartOfTimeline True if this event was added to the start
|
||||
* @param {boolean} removed True if this event has just been removed from the timeline
|
||||
* (beginning; oldest) of the timeline e.g. due to pagination.
|
||||
*
|
||||
* @param {object} data more data about the event
|
||||
*
|
||||
* @param {module:models/event-timeline.EventTimeline} data.timeline the timeline the
|
||||
* event was added to/removed from
|
||||
*
|
||||
* @param {boolean} data.liveEvent true if the event was a real-time event
|
||||
* added to the end of the live timeline
|
||||
*
|
||||
* @example
|
||||
* matrixClient.on("Room.timeline",
|
||||
* function(event, room, toStartOfTimeline, removed, data) {
|
||||
* if (!toStartOfTimeline && data.liveEvent) {
|
||||
* var messageToAppend = room.timeline.[room.timeline.length - 1];
|
||||
* }
|
||||
* });
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fires whenever the live timeline in a room is reset.
|
||||
*
|
||||
* When we get a 'limited' sync (for example, after a network outage), we reset
|
||||
* the live timeline to be empty before adding the recent events to the new
|
||||
* timeline. This event is fired after the timeline is reset, and before the
|
||||
* new events are added.
|
||||
*
|
||||
* @event module:client~MatrixClient#"Room.timelineReset"
|
||||
* @param {Room} room The room whose live timeline was reset, if any
|
||||
* @param {EventTimelineSet} timelineSet timelineSet room whose live timeline was reset
|
||||
* @param {boolean} resetAllTimelines True if all timelines were reset.
|
||||
*/
|
||||
|
@ -14,10 +14,6 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @module models/event-timeline
|
||||
*/
|
||||
|
||||
import { logger } from '../logger';
|
||||
import { IMarkerFoundOptions, RoomState } from "./room-state";
|
||||
import { EventTimelineSet } from "./event-timeline-set";
|
||||
@ -63,9 +59,9 @@ export class EventTimeline {
|
||||
/**
|
||||
* Static helper method to set sender and target properties
|
||||
*
|
||||
* @param {MatrixEvent} event the event whose metadata is to be set
|
||||
* @param {RoomState} stateContext the room state to be queried
|
||||
* @param {boolean} toStartOfTimeline if true the event's forwardLooking flag is set false
|
||||
* @param event - the event whose metadata is to be set
|
||||
* @param stateContext - the room state to be queried
|
||||
* @param toStartOfTimeline - if true the event's forwardLooking flag is set false
|
||||
*/
|
||||
public static setEventMetadata(event: MatrixEvent, stateContext: RoomState, toStartOfTimeline: boolean): void {
|
||||
// When we try to generate a sentinel member before we have that member
|
||||
@ -127,8 +123,7 @@ export class EventTimeline {
|
||||
* <p>Once a timeline joins up with its neighbour, they are linked together into a
|
||||
* doubly-linked list.
|
||||
*
|
||||
* @param {EventTimelineSet} eventTimelineSet the set of timelines this is part of
|
||||
* @constructor
|
||||
* @param eventTimelineSet - the set of timelines this is part of
|
||||
*/
|
||||
public constructor(private readonly eventTimelineSet: EventTimelineSet) {
|
||||
this.roomId = eventTimelineSet.room?.roomId ?? null;
|
||||
@ -148,9 +143,9 @@ export class EventTimeline {
|
||||
*
|
||||
* <p>This can only be called before any events are added.
|
||||
*
|
||||
* @param {MatrixEvent[]} stateEvents list of state events to initialise the
|
||||
* @param stateEvents - list of state events to initialise the
|
||||
* state with.
|
||||
* @throws {Error} if an attempt is made to call this after addEvent is called.
|
||||
* @throws Error if an attempt is made to call this after addEvent is called.
|
||||
*/
|
||||
public initialiseState(stateEvents: MatrixEvent[], { timelineWasEmpty }: IInitialiseStateOptions = {}): void {
|
||||
if (this.events.length > 0) {
|
||||
@ -167,11 +162,11 @@ export class EventTimeline {
|
||||
* The end state of this timeline gets replaced with an independent copy of the current RoomState,
|
||||
* and will need a new pagination token if it ever needs to paginate forwards.
|
||||
|
||||
* @param {string} direction EventTimeline.BACKWARDS to get the state at the
|
||||
* @param direction - EventTimeline.BACKWARDS to get the state at the
|
||||
* start of the timeline; EventTimeline.FORWARDS to get the state at the end
|
||||
* of the timeline.
|
||||
*
|
||||
* @return {EventTimeline} the new timeline
|
||||
* @returns the new timeline
|
||||
*/
|
||||
public forkLive(direction: Direction): EventTimeline {
|
||||
const forkState = this.getState(direction);
|
||||
@ -191,11 +186,11 @@ export class EventTimeline {
|
||||
/**
|
||||
* Creates an independent timeline, inheriting the directional state from this timeline.
|
||||
*
|
||||
* @param {string} direction EventTimeline.BACKWARDS to get the state at the
|
||||
* @param direction - EventTimeline.BACKWARDS to get the state at the
|
||||
* start of the timeline; EventTimeline.FORWARDS to get the state at the end
|
||||
* of the timeline.
|
||||
*
|
||||
* @return {EventTimeline} the new timeline
|
||||
* @returns the new timeline
|
||||
*/
|
||||
public fork(direction: Direction): EventTimeline {
|
||||
const forkState = this.getState(direction);
|
||||
@ -207,7 +202,7 @@ export class EventTimeline {
|
||||
|
||||
/**
|
||||
* Get the ID of the room for this timeline
|
||||
* @return {string} room ID
|
||||
* @returns room ID
|
||||
*/
|
||||
public getRoomId(): string | null {
|
||||
return this.roomId;
|
||||
@ -215,7 +210,7 @@ export class EventTimeline {
|
||||
|
||||
/**
|
||||
* Get the filter for this timeline's timelineSet (if any)
|
||||
* @return {Filter} filter
|
||||
* @returns filter
|
||||
*/
|
||||
public getFilter(): Filter | undefined {
|
||||
return this.eventTimelineSet.getFilter();
|
||||
@ -223,7 +218,7 @@ export class EventTimeline {
|
||||
|
||||
/**
|
||||
* Get the timelineSet for this timeline
|
||||
* @return {EventTimelineSet} timelineSet
|
||||
* @returns timelineSet
|
||||
*/
|
||||
public getTimelineSet(): EventTimelineSet {
|
||||
return this.eventTimelineSet;
|
||||
@ -237,8 +232,6 @@ export class EventTimeline {
|
||||
* relative to the base index (although note that a given event's index may
|
||||
* well be less than the base index, thus giving that event a negative relative
|
||||
* index).
|
||||
*
|
||||
* @return {number}
|
||||
*/
|
||||
public getBaseIndex(): number {
|
||||
return this.baseIndex;
|
||||
@ -247,7 +240,7 @@ export class EventTimeline {
|
||||
/**
|
||||
* Get the list of events in this context
|
||||
*
|
||||
* @return {MatrixEvent[]} An array of MatrixEvents
|
||||
* @returns An array of MatrixEvents
|
||||
*/
|
||||
public getEvents(): MatrixEvent[] {
|
||||
return this.events;
|
||||
@ -256,11 +249,11 @@ export class EventTimeline {
|
||||
/**
|
||||
* Get the room state at the start/end of the timeline
|
||||
*
|
||||
* @param {string} direction EventTimeline.BACKWARDS to get the state at the
|
||||
* @param direction - EventTimeline.BACKWARDS to get the state at the
|
||||
* start of the timeline; EventTimeline.FORWARDS to get the state at the end
|
||||
* of the timeline.
|
||||
*
|
||||
* @return {RoomState} state at the start/end of the timeline
|
||||
* @returns state at the start/end of the timeline
|
||||
*/
|
||||
public getState(direction: Direction): RoomState | undefined {
|
||||
if (direction == EventTimeline.BACKWARDS) {
|
||||
@ -275,11 +268,11 @@ export class EventTimeline {
|
||||
/**
|
||||
* Get a pagination token
|
||||
*
|
||||
* @param {string} direction EventTimeline.BACKWARDS to get the pagination
|
||||
* @param direction - EventTimeline.BACKWARDS to get the pagination
|
||||
* token for going backwards in time; EventTimeline.FORWARDS to get the
|
||||
* pagination token for going forwards in time.
|
||||
*
|
||||
* @return {?string} pagination token
|
||||
* @returns pagination token
|
||||
*/
|
||||
public getPaginationToken(direction: Direction): string | null {
|
||||
if (this.roomId) {
|
||||
@ -294,9 +287,9 @@ export class EventTimeline {
|
||||
/**
|
||||
* Set a pagination token
|
||||
*
|
||||
* @param {?string} token pagination token
|
||||
* @param token - pagination token
|
||||
*
|
||||
* @param {string} direction EventTimeline.BACKWARDS to set the pagination
|
||||
* @param direction - EventTimeline.BACKWARDS to set the pagination
|
||||
* token for going backwards in time; EventTimeline.FORWARDS to set the
|
||||
* pagination token for going forwards in time.
|
||||
*/
|
||||
@ -313,10 +306,10 @@ export class EventTimeline {
|
||||
/**
|
||||
* Get the next timeline in the series
|
||||
*
|
||||
* @param {string} direction EventTimeline.BACKWARDS to get the previous
|
||||
* @param direction - EventTimeline.BACKWARDS to get the previous
|
||||
* timeline; EventTimeline.FORWARDS to get the next timeline.
|
||||
*
|
||||
* @return {?EventTimeline} previous or following timeline, if they have been
|
||||
* @returns previous or following timeline, if they have been
|
||||
* joined up.
|
||||
*/
|
||||
public getNeighbouringTimeline(direction: Direction): EventTimeline | null {
|
||||
@ -332,12 +325,12 @@ export class EventTimeline {
|
||||
/**
|
||||
* Set the next timeline in the series
|
||||
*
|
||||
* @param {EventTimeline} neighbour previous/following timeline
|
||||
* @param neighbour - previous/following timeline
|
||||
*
|
||||
* @param {string} direction EventTimeline.BACKWARDS to set the previous
|
||||
* @param direction - EventTimeline.BACKWARDS to set the previous
|
||||
* timeline; EventTimeline.FORWARDS to set the next timeline.
|
||||
*
|
||||
* @throws {Error} if an attempt is made to set the neighbouring timeline when
|
||||
* @throws Error if an attempt is made to set the neighbouring timeline when
|
||||
* it is already set.
|
||||
*/
|
||||
public setNeighbouringTimeline(neighbour: EventTimeline, direction: Direction): void {
|
||||
@ -361,8 +354,8 @@ export class EventTimeline {
|
||||
/**
|
||||
* Add a new event to the timeline, and update the state
|
||||
*
|
||||
* @param {MatrixEvent} event new event
|
||||
* @param {IAddEventOptions} options addEvent options
|
||||
* @param event - new event
|
||||
* @param options - addEvent options
|
||||
*/
|
||||
public addEvent(
|
||||
event: MatrixEvent,
|
||||
@ -447,8 +440,8 @@ export class EventTimeline {
|
||||
/**
|
||||
* Remove an event from the timeline
|
||||
*
|
||||
* @param {string} eventId ID of event to be removed
|
||||
* @return {?MatrixEvent} removed event, or null if not found
|
||||
* @param eventId - ID of event to be removed
|
||||
* @returns removed event, or null if not found
|
||||
*/
|
||||
public removeEvent(eventId: string): MatrixEvent | null {
|
||||
for (let i = this.events.length - 1; i >= 0; i--) {
|
||||
@ -467,7 +460,7 @@ export class EventTimeline {
|
||||
/**
|
||||
* Return a string to identify this timeline, for debugging
|
||||
*
|
||||
* @return {string} name for this timeline
|
||||
* @returns name for this timeline
|
||||
*/
|
||||
public toString(): string {
|
||||
return this.name;
|
||||
|
@ -17,7 +17,6 @@ limitations under the License.
|
||||
/**
|
||||
* This is an internal module. See {@link MatrixEvent} and {@link RoomEvent} for
|
||||
* the public classes.
|
||||
* @module models/event
|
||||
*/
|
||||
|
||||
import { ExtensibleEvent, ExtensibleEvents, Optional } from "matrix-events-sdk";
|
||||
@ -80,15 +79,15 @@ export interface IEvent {
|
||||
redacts?: string;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @deprecated in favour of `sender`
|
||||
*/
|
||||
user_id?: string;
|
||||
/**
|
||||
* @deprecated
|
||||
* @deprecated in favour of `unsigned.prev_content`
|
||||
*/
|
||||
prev_content?: IContent;
|
||||
/**
|
||||
* @deprecated
|
||||
* @deprecated in favour of `origin_server_ts`
|
||||
*/
|
||||
age?: number;
|
||||
}
|
||||
@ -150,8 +149,11 @@ interface IKeyRequestRecipient {
|
||||
}
|
||||
|
||||
export interface IDecryptOptions {
|
||||
// Emits "event.decrypted" if set to true
|
||||
emit?: boolean;
|
||||
// True if this is a retry (enables more logging)
|
||||
isRetry?: boolean;
|
||||
// whether the message should be re-decrypted if it was previously successfully decrypted with an untrusted key
|
||||
forceRedecryptIfUntrusted?: boolean;
|
||||
}
|
||||
|
||||
@ -192,6 +194,12 @@ export enum MatrixEventEvent {
|
||||
export type MatrixEventEmittedEvents = MatrixEventEvent | ThreadEvent.Update;
|
||||
|
||||
export type MatrixEventHandlerMap = {
|
||||
/**
|
||||
* Fires when an event is decrypted
|
||||
*
|
||||
* @param event - The matrix event which has been decrypted
|
||||
* @param err - The error that occurred during decryption, or `undefined` if no error occurred.
|
||||
*/
|
||||
[MatrixEventEvent.Decrypted]: (event: MatrixEvent, err?: Error) => void;
|
||||
[MatrixEventEvent.BeforeRedaction]: (event: MatrixEvent, redactionEvent: MatrixEvent) => void;
|
||||
[MatrixEventEvent.VisibilityChange]: (event: MatrixEvent, visible: boolean) => void;
|
||||
@ -271,12 +279,43 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
*/
|
||||
public localTimestamp: number;
|
||||
|
||||
// XXX: these should be read-only
|
||||
/**
|
||||
* The room member who sent this event, or null e.g.
|
||||
* this is a presence event. This is only guaranteed to be set for events that
|
||||
* appear in a timeline, ie. do not guarantee that it will be set on state
|
||||
* events.
|
||||
* @privateRemarks
|
||||
* Should be read-only
|
||||
*/
|
||||
public sender: RoomMember | null = null;
|
||||
/**
|
||||
* The room member who is the target of this event, e.g.
|
||||
* the invitee, the person being banned, etc.
|
||||
* @privateRemarks
|
||||
* Should be read-only
|
||||
*/
|
||||
public target: RoomMember | null = null;
|
||||
/**
|
||||
* The sending status of the event.
|
||||
* @privateRemarks
|
||||
* Should be read-only
|
||||
*/
|
||||
public status: EventStatus | null = null;
|
||||
/**
|
||||
* most recent error associated with sending the event, if any
|
||||
* @privateRemarks
|
||||
* Should be read-only
|
||||
*/
|
||||
public error: MatrixError | null = null;
|
||||
public forwardLooking = true; // only state events may be backwards looking
|
||||
/**
|
||||
* True if this event is 'forward looking', meaning
|
||||
* that getDirectionalContent() will return event.content and not event.prev_content.
|
||||
* Only state events may be backwards looking
|
||||
* Default: true. <strong>This property is experimental and may change.</strong>
|
||||
* @privateRemarks
|
||||
* Should be read-only
|
||||
*/
|
||||
public forwardLooking = true;
|
||||
|
||||
/* If the event is a `m.key.verification.request` (or to_device `m.key.verification.start`) event,
|
||||
* `Crypto` will set this the `VerificationRequest` for the event
|
||||
@ -288,26 +327,11 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
|
||||
/**
|
||||
* Construct a Matrix Event object
|
||||
* @constructor
|
||||
*
|
||||
* @param {Object} event The raw event to be wrapped in this DAO
|
||||
*
|
||||
* @prop {Object} event The raw (possibly encrypted) event. <b>Do not access
|
||||
* @param event - The raw (possibly encrypted) event. <b>Do not access
|
||||
* this property</b> directly unless you absolutely have to. Prefer the getter
|
||||
* methods defined on this class. Using the getter methods shields your app
|
||||
* from changes to event JSON between Matrix versions.
|
||||
*
|
||||
* @prop {RoomMember} sender The room member who sent this event, or null e.g.
|
||||
* this is a presence event. This is only guaranteed to be set for events that
|
||||
* appear in a timeline, ie. do not guarantee that it will be set on state
|
||||
* events.
|
||||
* @prop {RoomMember} target The room member who is the target of this event, e.g.
|
||||
* the invitee, the person being banned, etc.
|
||||
* @prop {EventStatus} status The sending status of the event.
|
||||
* @prop {Error} error most recent error associated with sending the event, if any
|
||||
* @prop {boolean} forwardLooking True if this event is 'forward looking', meaning
|
||||
* that getDirectionalContent() will return event.content and not event.prev_content.
|
||||
* Default: true. <strong>This property is experimental and may change.</strong>
|
||||
*/
|
||||
public constructor(public event: Partial<IEvent> = {}) {
|
||||
super();
|
||||
@ -360,7 +384,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
/**
|
||||
* Gets the event as though it would appear unencrypted. If the event is already not
|
||||
* encrypted, it is simply returned as-is.
|
||||
* @returns {IEvent} The event in wire format.
|
||||
* @returns The event in wire format.
|
||||
*/
|
||||
public getEffectiveEvent(): IEvent {
|
||||
const content = Object.assign({}, this.getContent()); // clone for mutation
|
||||
@ -389,7 +413,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
|
||||
/**
|
||||
* Get the event_id for this event.
|
||||
* @return {string} The event ID, e.g. <code>$143350589368169JsLZx:localhost
|
||||
* @returns The event ID, e.g. <code>$143350589368169JsLZx:localhost
|
||||
* </code>
|
||||
*/
|
||||
public getId(): string | undefined {
|
||||
@ -398,7 +422,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
|
||||
/**
|
||||
* Get the user_id for this event.
|
||||
* @return {string} The user ID, e.g. <code>@alice:matrix.org</code>
|
||||
* @returns The user ID, e.g. `@alice:matrix.org`
|
||||
*/
|
||||
public getSender(): string | undefined {
|
||||
return this.event.sender || this.event.user_id; // v2 / v1
|
||||
@ -407,7 +431,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
/**
|
||||
* Get the (decrypted, if necessary) type of event.
|
||||
*
|
||||
* @return {string} The event type, e.g. <code>m.room.message</code>
|
||||
* @returns The event type, e.g. `m.room.message`
|
||||
*/
|
||||
public getType(): EventType | string {
|
||||
if (this.clearEvent) {
|
||||
@ -420,16 +444,16 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
* Get the (possibly encrypted) type of the event that will be sent to the
|
||||
* homeserver.
|
||||
*
|
||||
* @return {string} The event type.
|
||||
* @returns The event type.
|
||||
*/
|
||||
public getWireType(): EventType | string {
|
||||
return this.event.type!;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the room_id for this event. This will return <code>undefined</code>
|
||||
* for <code>m.presence</code> events.
|
||||
* @return {string?} The room ID, e.g. <code>!cURbafjkfsMDVwdRDQ:matrix.org
|
||||
* Get the room_id for this event. This will return `undefined`
|
||||
* for `m.presence` events.
|
||||
* @returns The room ID, e.g. <code>!cURbafjkfsMDVwdRDQ:matrix.org
|
||||
* </code>
|
||||
*/
|
||||
public getRoomId(): string | undefined {
|
||||
@ -438,7 +462,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
|
||||
/**
|
||||
* Get the timestamp of this event.
|
||||
* @return {Number} The event timestamp, e.g. <code>1433502692297</code>
|
||||
* @returns The event timestamp, e.g. `1433502692297`
|
||||
*/
|
||||
public getTs(): number {
|
||||
return this.event.origin_server_ts!;
|
||||
@ -446,7 +470,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
|
||||
/**
|
||||
* Get the timestamp of this event, as a Date object.
|
||||
* @return {Date} The event date, e.g. <code>new Date(1433502692297)</code>
|
||||
* @returns The event date, e.g. `new Date(1433502692297)`
|
||||
*/
|
||||
public getDate(): Date | null {
|
||||
return this.event.origin_server_ts ? new Date(this.event.origin_server_ts) : null;
|
||||
@ -457,7 +481,11 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
*
|
||||
* This is intended for logging, to help trace errors. Example output:
|
||||
*
|
||||
* id=$HjnOHV646n0SjLDAqFrgIjim7RCpB7cdMXFrekWYAn type=m.room.encrypted sender=@user:example.com room=!room:example.com ts=2022-10-25T17:30:28.404Z
|
||||
* @example
|
||||
* ```
|
||||
* id=$HjnOHV646n0SjLDAqFrgIjim7RCpB7cdMXFrekWYAn type=m.room.encrypted
|
||||
* sender=@user:example.com room=!room:example.com ts=2022-10-25T17:30:28.404Z
|
||||
* ```
|
||||
*/
|
||||
public getDetails(): string {
|
||||
let details = `id=${this.getId()} type=${this.getWireType()} sender=${this.getSender()}`;
|
||||
@ -476,7 +504,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
* Get the (decrypted, if necessary) event content JSON, even if the event
|
||||
* was replaced by another event.
|
||||
*
|
||||
* @return {Object} The event content JSON, or an empty object.
|
||||
* @returns The event content JSON, or an empty object.
|
||||
*/
|
||||
public getOriginalContent<T = IContent>(): T {
|
||||
if (this._localRedactionEvent) {
|
||||
@ -493,7 +521,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
* or the content from the replacing event, if any.
|
||||
* See `makeReplaced`.
|
||||
*
|
||||
* @return {Object} The event content JSON, or an empty object.
|
||||
* @returns The event content JSON, or an empty object.
|
||||
*/
|
||||
public getContent<T extends IContent = IContent>(): T {
|
||||
if (this._localRedactionEvent) {
|
||||
@ -509,7 +537,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
* Get the (possibly encrypted) event content JSON that will be sent to the
|
||||
* homeserver.
|
||||
*
|
||||
* @return {Object} The event content JSON, or an empty object.
|
||||
* @returns The event content JSON, or an empty object.
|
||||
*/
|
||||
public getWireContent(): IContent {
|
||||
return this.event.content || {};
|
||||
@ -560,7 +588,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
/**
|
||||
* Get the previous event content JSON. This will only return something for
|
||||
* state events which exist in the timeline.
|
||||
* @return {Object} The previous event content JSON, or an empty object.
|
||||
* @returns The previous event content JSON, or an empty object.
|
||||
*/
|
||||
public getPrevContent(): IContent {
|
||||
// v2 then v1 then default
|
||||
@ -573,7 +601,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
* In practice, this means we get the chronologically earlier content value
|
||||
* for this event (this method should surely be called getEarlierContent)
|
||||
* <strong>This method is experimental and may change.</strong>
|
||||
* @return {Object} event.content if this event is forward-looking, else
|
||||
* @returns event.content if this event is forward-looking, else
|
||||
* event.prev_content.
|
||||
*/
|
||||
public getDirectionalContent(): IContent {
|
||||
@ -585,7 +613,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
* event arrived at the device, and not the age of the event when this
|
||||
* function was called.
|
||||
* Can only be returned once the server has echo'ed back
|
||||
* @return {Number|undefined} The age of this event in milliseconds.
|
||||
* @returns The age of this event in milliseconds.
|
||||
*/
|
||||
public getAge(): number | undefined {
|
||||
return this.getUnsigned().age || this.event.age; // v2 / v1
|
||||
@ -595,7 +623,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
* Get the age of the event when this function was called.
|
||||
* This is the 'age' field adjusted according to how long this client has
|
||||
* had the event.
|
||||
* @return {Number} The age of this event in milliseconds.
|
||||
* @returns The age of this event in milliseconds.
|
||||
*/
|
||||
public getLocalAge(): number {
|
||||
return Date.now() - this.localTimestamp;
|
||||
@ -604,7 +632,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
/**
|
||||
* Get the event state_key if it has one. This will return <code>undefined
|
||||
* </code> for message events.
|
||||
* @return {string} The event's <code>state_key</code>.
|
||||
* @returns The event's `state_key`.
|
||||
*/
|
||||
public getStateKey(): string | undefined {
|
||||
return this.event.state_key;
|
||||
@ -612,7 +640,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
|
||||
/**
|
||||
* Check if this event is a state event.
|
||||
* @return {boolean} True if this is a state event.
|
||||
* @returns True if this is a state event.
|
||||
*/
|
||||
public isState(): boolean {
|
||||
return this.event.state_key !== undefined;
|
||||
@ -624,18 +652,18 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @param {string} cryptoType type of the encrypted event - typically
|
||||
* @param cryptoType - type of the encrypted event - typically
|
||||
* <tt>"m.room.encrypted"</tt>
|
||||
*
|
||||
* @param {object} cryptoContent raw 'content' for the encrypted event.
|
||||
* @param cryptoContent - raw 'content' for the encrypted event.
|
||||
*
|
||||
* @param {string} senderCurve25519Key curve25519 key to record for the
|
||||
* @param senderCurve25519Key - curve25519 key to record for the
|
||||
* sender of this event.
|
||||
* See {@link module:models/event.MatrixEvent#getSenderKey}.
|
||||
* See {@link MatrixEvent#getSenderKey}.
|
||||
*
|
||||
* @param {string} claimedEd25519Key claimed ed25519 key to record for the
|
||||
* @param claimedEd25519Key - claimed ed25519 key to record for the
|
||||
* sender if this event.
|
||||
* See {@link module:models/event.MatrixEvent#getClaimedEd25519Key}
|
||||
* See {@link MatrixEvent#getClaimedEd25519Key}
|
||||
*/
|
||||
public makeEncrypted(
|
||||
cryptoType: string,
|
||||
@ -657,7 +685,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
/**
|
||||
* Check if this event is currently being decrypted.
|
||||
*
|
||||
* @return {boolean} True if this event is currently being decrypted, else false.
|
||||
* @returns True if this event is currently being decrypted, else false.
|
||||
*/
|
||||
public isBeingDecrypted(): boolean {
|
||||
return this.decryptionPromise != null;
|
||||
@ -672,7 +700,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
*
|
||||
* (This implies that we might retry decryption at some point in the future)
|
||||
*
|
||||
* @return {boolean} True if this event is an encrypted event which we
|
||||
* @returns True if this event is an encrypted event which we
|
||||
* couldn't decrypt.
|
||||
*/
|
||||
public isDecryptionFailure(): boolean {
|
||||
@ -695,14 +723,9 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @param {module:crypto} crypto crypto module
|
||||
* @param {object} options
|
||||
* @param {boolean} options.isRetry True if this is a retry (enables more logging)
|
||||
* @param {boolean} options.emit Emits "event.decrypted" if set to true
|
||||
* @param {boolean} options.forceRedecryptIfUntrusted whether the message should be
|
||||
* re-decrypted if it was previously successfully decrypted with an untrusted key
|
||||
* @param crypto - crypto module
|
||||
*
|
||||
* @returns {Promise} promise which resolves (to undefined) when the decryption
|
||||
* @returns promise which resolves (to undefined) when the decryption
|
||||
* attempt is completed.
|
||||
*/
|
||||
public async attemptDecryption(crypto: Crypto, options: IDecryptOptions = {}): Promise<void> {
|
||||
@ -741,10 +764,10 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
/**
|
||||
* Cancel any room key request for this event and resend another.
|
||||
*
|
||||
* @param {module:crypto} crypto crypto module
|
||||
* @param {string} userId the user who received this event
|
||||
* @param crypto - crypto module
|
||||
* @param userId - the user who received this event
|
||||
*
|
||||
* @returns {Promise} a promise that resolves when the request is queued
|
||||
* @returns a promise that resolves when the request is queued
|
||||
*/
|
||||
public cancelAndResendKeyRequest(crypto: Crypto, userId: string): Promise<void> {
|
||||
const wireContent = this.getWireContent();
|
||||
@ -759,9 +782,9 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
/**
|
||||
* Calculate the recipients for keyshare requests.
|
||||
*
|
||||
* @param {string} userId the user who received this event.
|
||||
* @param userId - the user who received this event.
|
||||
*
|
||||
* @returns {Array} array of recipients
|
||||
* @returns array of recipients
|
||||
*/
|
||||
public getKeyRequestRecipients(userId: string): IKeyRequestRecipient[] {
|
||||
// send the request to all of our own devices, and the
|
||||
@ -903,10 +926,10 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @fires module:models/event.MatrixEvent#"Event.decrypted"
|
||||
* @param decryptionResult - the decryption result, including the plaintext and some key info
|
||||
*
|
||||
* @param {module:crypto~EventDecryptionResult} decryptionResult
|
||||
* the decryption result, including the plaintext and some key info
|
||||
* @remarks
|
||||
* Fires {@link MatrixEventEvent.Decrypted}
|
||||
*/
|
||||
private setClearData(decryptionResult: IEventDecryptionResult): void {
|
||||
this.clearEvent = decryptionResult.clearEvent;
|
||||
@ -922,7 +945,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
* Gets the cleartext content for this event. If the event is not encrypted,
|
||||
* or encryption has not been completed, this will return null.
|
||||
*
|
||||
* @returns {Object} The cleartext (decrypted) content for the event
|
||||
* @returns The cleartext (decrypted) content for the event
|
||||
*/
|
||||
public getClearContent(): IContent | null {
|
||||
return this.clearEvent ? this.clearEvent.content : null;
|
||||
@ -930,7 +953,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
|
||||
/**
|
||||
* Check if the event is encrypted.
|
||||
* @return {boolean} True if this event is encrypted.
|
||||
* @returns True if this event is encrypted.
|
||||
*/
|
||||
public isEncrypted(): boolean {
|
||||
return !this.isState() && this.event.type === EventType.RoomMessageEncrypted;
|
||||
@ -946,8 +969,6 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
*
|
||||
* For a megolm-encrypted event, it is inferred from the Olm message which
|
||||
* established the megolm session
|
||||
*
|
||||
* @return {string}
|
||||
*/
|
||||
public getSenderKey(): string | null {
|
||||
return this.senderCurve25519Key;
|
||||
@ -957,8 +978,6 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
* The additional keys the sender of this encrypted event claims to possess.
|
||||
*
|
||||
* Just a wrapper for #getClaimedEd25519Key (q.v.)
|
||||
*
|
||||
* @return {Object<string, string>}
|
||||
*/
|
||||
public getKeysClaimed(): Partial<Record<"ed25519", string>> {
|
||||
if (!this.claimedEd25519Key) return {};
|
||||
@ -982,8 +1001,6 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
*
|
||||
* In general, applications should not use this method directly, but should
|
||||
* instead use MatrixClient.getEventSenderDeviceInfo.
|
||||
*
|
||||
* @return {string}
|
||||
*/
|
||||
public getClaimedEd25519Key(): string | null {
|
||||
return this.claimedEd25519Key;
|
||||
@ -1001,7 +1018,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
* If the device that sent us the key (A) got it from another device which
|
||||
* it wasn't prepared to vouch for (B), the result will be [A, B]. And so on.
|
||||
*
|
||||
* @return {string[]} base64-encoded curve25519 keys, from oldest to newest.
|
||||
* @returns base64-encoded curve25519 keys, from oldest to newest.
|
||||
*/
|
||||
public getForwardingCurve25519KeyChain(): string[] {
|
||||
return this.forwardingCurve25519KeyChain;
|
||||
@ -1010,8 +1027,6 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
/**
|
||||
* Whether the decryption key was obtained from an untrusted source. If so,
|
||||
* we cannot verify the authenticity of the message.
|
||||
*
|
||||
* @return {boolean}
|
||||
*/
|
||||
public isKeySourceUntrusted(): boolean | undefined {
|
||||
return !!this.untrusted;
|
||||
@ -1047,13 +1062,15 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
/**
|
||||
* Change the visibility of an event, as per https://github.com/matrix-org/matrix-doc/pull/3531 .
|
||||
*
|
||||
* @fires module:models/event.MatrixEvent#"Event.visibilityChange" if `visibilityEvent`
|
||||
* @param visibilityChange - event holding a hide/unhide payload, or nothing
|
||||
* if the event is being reset to its original visibility (presumably
|
||||
* by a visibility event being redacted).
|
||||
*
|
||||
* @remarks
|
||||
* Fires {@link MatrixEventEvent.VisibilityChange} if `visibilityEvent`
|
||||
* caused a change in the actual visibility of this event, either by making it
|
||||
* visible (if it was hidden), by making it hidden (if it was visible) or by
|
||||
* changing the reason (if it was hidden).
|
||||
* @param visibilityChange event holding a hide/unhide payload, or nothing
|
||||
* if the event is being reset to its original visibility (presumably
|
||||
* by a visibility event being redacted).
|
||||
*/
|
||||
public applyVisibilityEvent(visibilityChange?: IVisibilityChange): void {
|
||||
const visible = visibilityChange?.visible ?? true;
|
||||
@ -1093,8 +1110,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
* Update the content of an event in the same way it would be by the server
|
||||
* if it were redacted before it was sent to us
|
||||
*
|
||||
* @param {module:models/event.MatrixEvent} redactionEvent
|
||||
* event causing the redaction
|
||||
* @param redactionEvent - event causing the redaction
|
||||
*/
|
||||
public makeRedacted(redactionEvent: MatrixEvent): void {
|
||||
// quick sanity-check
|
||||
@ -1145,7 +1161,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
/**
|
||||
* Check if this event has been redacted
|
||||
*
|
||||
* @return {boolean} True if this event has been redacted
|
||||
* @returns True if this event has been redacted
|
||||
*/
|
||||
public isRedacted(): boolean {
|
||||
return Boolean(this.getUnsigned().redacted_because);
|
||||
@ -1154,7 +1170,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
/**
|
||||
* Check if this event is a redaction of another event
|
||||
*
|
||||
* @return {boolean} True if this event is a redaction
|
||||
* @returns True if this event is a redaction
|
||||
*/
|
||||
public isRedaction(): boolean {
|
||||
return this.getType() === EventType.RoomRedaction;
|
||||
@ -1201,7 +1217,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
* Check if this event alters the visibility of another event,
|
||||
* as per https://github.com/matrix-org/matrix-doc/pull/3531.
|
||||
*
|
||||
* @returns {boolean} True if this event alters the visibility
|
||||
* @returns True if this event alters the visibility
|
||||
* of another event.
|
||||
*/
|
||||
public isVisibilityEvent(): boolean {
|
||||
@ -1212,7 +1228,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
* Get the (decrypted, if necessary) redaction event JSON
|
||||
* if event was redacted
|
||||
*
|
||||
* @returns {object} The redaction event JSON, or an empty object
|
||||
* @returns The redaction event JSON, or an empty object
|
||||
*/
|
||||
public getRedactionEvent(): IEvent | {} | null {
|
||||
if (!this.isRedacted()) return null;
|
||||
@ -1229,7 +1245,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
/**
|
||||
* Get the push actions, if known, for this event
|
||||
*
|
||||
* @return {?Object} push actions
|
||||
* @returns push actions
|
||||
*/
|
||||
public getPushActions(): IActionsObject | null {
|
||||
return this.pushActions;
|
||||
@ -1238,7 +1254,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
/**
|
||||
* Set the push actions for this event.
|
||||
*
|
||||
* @param {Object} pushActions push actions
|
||||
* @param pushActions - push actions
|
||||
*/
|
||||
public setPushActions(pushActions: IActionsObject | null): void {
|
||||
this.pushActions = pushActions;
|
||||
@ -1246,7 +1262,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
|
||||
/**
|
||||
* Replace the `event` property and recalculate any properties based on it.
|
||||
* @param {Object} event the object to assign to the `event` property
|
||||
* @param event - the object to assign to the `event` property
|
||||
*/
|
||||
public handleRemoteEcho(event: object): void {
|
||||
const oldUnsigned = this.getUnsigned();
|
||||
@ -1276,8 +1292,6 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
/**
|
||||
* Whether the event is in any phase of sending, send failure, waiting for
|
||||
* remote echo, etc.
|
||||
*
|
||||
* @return {boolean}
|
||||
*/
|
||||
public isSending(): boolean {
|
||||
return !!this.status;
|
||||
@ -1286,7 +1300,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
/**
|
||||
* Update the event's sending status and emit an event as well.
|
||||
*
|
||||
* @param {String} status The new status
|
||||
* @param status - The new status
|
||||
*/
|
||||
public setStatus(status: EventStatus | null): void {
|
||||
this.status = status;
|
||||
@ -1302,9 +1316,8 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
* Get whether the event is a relation event, and of a given type if
|
||||
* `relType` is passed in. State events cannot be relation events
|
||||
*
|
||||
* @param {string?} relType if given, checks that the relation is of the
|
||||
* @param relType - if given, checks that the relation is of the
|
||||
* given type
|
||||
* @return {boolean}
|
||||
*/
|
||||
public isRelation(relType?: string): boolean {
|
||||
// Relation info is lifted out of the encrypted content when sent to
|
||||
@ -1319,8 +1332,6 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
|
||||
/**
|
||||
* Get relation info for the event, if any.
|
||||
*
|
||||
* @return {Object}
|
||||
*/
|
||||
public getRelation(): IEventRelation | null {
|
||||
if (!this.isRelation()) {
|
||||
@ -1332,9 +1343,10 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
/**
|
||||
* Set an event that replaces the content of this event, through an m.replace relation.
|
||||
*
|
||||
* @fires module:models/event.MatrixEvent#"Event.replaced"
|
||||
* @param newEvent - the event with the replacing content, if any.
|
||||
*
|
||||
* @param {MatrixEvent?} newEvent the event with the replacing content, if any.
|
||||
* @remarks
|
||||
* Fires {@link MatrixEventEvent.Replaced}
|
||||
*/
|
||||
public makeReplaced(newEvent?: MatrixEvent): void {
|
||||
// don't allow redacted events to be replaced.
|
||||
@ -1359,8 +1371,6 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
* Returns the status of any associated edit or redaction
|
||||
* (not for reactions/annotations as their local echo doesn't affect the original event),
|
||||
* or else the status of the event.
|
||||
*
|
||||
* @return {EventStatus}
|
||||
*/
|
||||
public getAssociatedStatus(): EventStatus | null {
|
||||
if (this._replacingEvent) {
|
||||
@ -1377,8 +1387,6 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
|
||||
/**
|
||||
* Returns the event ID of the event replacing the content of this event, if any.
|
||||
*
|
||||
* @return {string?}
|
||||
*/
|
||||
public replacingEventId(): string | undefined {
|
||||
const replaceRelation = this.getServerAggregatedRelation<IAggregatedRelation>(RelationType.Replace);
|
||||
@ -1393,8 +1401,6 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
* Returns the event replacing the content of this event, if any.
|
||||
* Replacements are aggregated on the server, so this would only
|
||||
* return an event in case it came down the sync, or for local echo of edits.
|
||||
*
|
||||
* @return {MatrixEvent?}
|
||||
*/
|
||||
public replacingEvent(): MatrixEvent | null {
|
||||
return this._replacingEvent;
|
||||
@ -1402,8 +1408,6 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
|
||||
/**
|
||||
* Returns the origin_server_ts of the event replacing the content of this event, if any.
|
||||
*
|
||||
* @return {Date?}
|
||||
*/
|
||||
public replacingEventDate(): Date | undefined {
|
||||
const replaceRelation = this.getServerAggregatedRelation<IAggregatedRelation>(RelationType.Replace);
|
||||
@ -1419,7 +1423,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
|
||||
/**
|
||||
* Returns the event that wants to redact this event, but hasn't been sent yet.
|
||||
* @return {MatrixEvent} the event
|
||||
* @returns the event
|
||||
*/
|
||||
public localRedactionEvent(): MatrixEvent | null {
|
||||
return this._localRedactionEvent;
|
||||
@ -1427,8 +1431,6 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
|
||||
/**
|
||||
* For relations and redactions, returns the event_id this event is referring to.
|
||||
*
|
||||
* @return {string?}
|
||||
*/
|
||||
public getAssociatedId(): string | undefined {
|
||||
const relation = this.getRelation();
|
||||
@ -1443,8 +1445,6 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
|
||||
/**
|
||||
* Checks if this event is associated with another event. See `getAssociatedId`.
|
||||
*
|
||||
* @return {boolean}
|
||||
* @deprecated use hasAssociation instead.
|
||||
*/
|
||||
public hasAssocation(): boolean {
|
||||
@ -1453,8 +1453,6 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
|
||||
/**
|
||||
* Checks if this event is associated with another event. See `getAssociatedId`.
|
||||
*
|
||||
* @return {boolean}
|
||||
*/
|
||||
public hasAssociation(): boolean {
|
||||
return !!this.getAssociatedId();
|
||||
@ -1466,7 +1464,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
* Used to replace a local id with remote one before sending
|
||||
* an event with a related id.
|
||||
*
|
||||
* @param {string} eventId the new event id
|
||||
* @param eventId - the new event id
|
||||
*/
|
||||
public updateAssociatedId(eventId: string): void {
|
||||
const relation = this.getRelation();
|
||||
@ -1481,7 +1479,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
* Flags an event as cancelled due to future conditions. For example, a verification
|
||||
* request event in the same sync transaction may be flagged as cancelled to warn
|
||||
* listeners that a cancellation event is coming down the same pipe shortly.
|
||||
* @param {boolean} cancelled Whether the event is to be cancelled or not.
|
||||
* @param cancelled - Whether the event is to be cancelled or not.
|
||||
*/
|
||||
public flagCancelled(cancelled = true): void {
|
||||
this._isCancelled = cancelled;
|
||||
@ -1490,7 +1488,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
/**
|
||||
* Gets whether or not the event is flagged as cancelled. See flagCancelled() for
|
||||
* more information.
|
||||
* @returns {boolean} True if the event is cancelled, false otherwise.
|
||||
* @returns True if the event is cancelled, false otherwise.
|
||||
*/
|
||||
public isCancelled(): boolean {
|
||||
return this._isCancelled;
|
||||
@ -1508,7 +1506,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
*
|
||||
* This is meant to be used to snapshot the event details themselves, not the
|
||||
* features (such as sender) surrounding the event.
|
||||
* @returns {MatrixEvent} A snapshot of this event.
|
||||
* @returns A snapshot of this event.
|
||||
*/
|
||||
public toSnapshot(): MatrixEvent {
|
||||
const ev = new MatrixEvent(JSON.parse(JSON.stringify(this.event)));
|
||||
@ -1525,8 +1523,8 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
* Determines if this event is equivalent to the given event. This only checks
|
||||
* the event object itself, not the other properties of the event. Intended for
|
||||
* use with toSnapshot() to identify events changing.
|
||||
* @param {MatrixEvent} otherEvent The other event to check against.
|
||||
* @returns {boolean} True if the events are the same, false otherwise.
|
||||
* @param otherEvent - The other event to check against.
|
||||
* @returns True if the events are the same, false otherwise.
|
||||
*/
|
||||
public isEquivalentTo(otherEvent: MatrixEvent): boolean {
|
||||
if (!otherEvent) return false;
|
||||
@ -1546,8 +1544,6 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
* This is named `toJSON` for use with `JSON.stringify` which checks objects
|
||||
* for functions named `toJSON` and will call them to customise the output
|
||||
* if they are defined.
|
||||
*
|
||||
* @return {Object}
|
||||
*/
|
||||
public toJSON(): object {
|
||||
const event = this.getEffectiveEvent();
|
||||
@ -1625,15 +1621,3 @@ const REDACT_KEEP_CONTENT_MAP: Record<string, Record<string, 1>> = {
|
||||
'users': 1, 'users_default': 1,
|
||||
},
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* Fires when an event is decrypted
|
||||
*
|
||||
* @event module:models/event.MatrixEvent#"Event.decrypted"
|
||||
*
|
||||
* @param {module:models/event.MatrixEvent} event
|
||||
* The matrix event which has been decrypted
|
||||
* @param {module:crypto/algorithms/base.DecryptionError?} err
|
||||
* The error that occurred during decryption, or `undefined` if no
|
||||
* error occurred.
|
||||
*/
|
||||
|
@ -81,10 +81,10 @@ export class IgnoredInvites {
|
||||
/**
|
||||
* Add a new rule.
|
||||
*
|
||||
* @param scope The scope for this rule.
|
||||
* @param entity The entity covered by this rule. Globs are supported.
|
||||
* @param reason A human-readable reason for introducing this new rule.
|
||||
* @return The event id for the new rule.
|
||||
* @param scope - The scope for this rule.
|
||||
* @param entity - The entity covered by this rule. Globs are supported.
|
||||
* @param reason - A human-readable reason for introducing this new rule.
|
||||
* @returns The event id for the new rule.
|
||||
*/
|
||||
public async addRule(scope: PolicyScope, entity: string, reason: string): Promise<string> {
|
||||
const target = await this.getOrCreateTargetRoom();
|
||||
@ -107,9 +107,9 @@ export class IgnoredInvites {
|
||||
* Add a new room to the list of sources. If the user isn't a member of the
|
||||
* room, attempt to join it.
|
||||
*
|
||||
* @param roomId A valid room id. If this room is already in the list
|
||||
* @param roomId - A valid room id. If this room is already in the list
|
||||
* of sources, it will not be duplicated.
|
||||
* @return `true` if the source was added, `false` if it was already present.
|
||||
* @returns `true` if the source was added, `false` if it was already present.
|
||||
* @throws If `roomId` isn't the id of a room that the current user is already
|
||||
* member of or can join.
|
||||
*
|
||||
@ -142,8 +142,8 @@ export class IgnoredInvites {
|
||||
/**
|
||||
* Find out whether an invite should be ignored.
|
||||
*
|
||||
* @param sender The user id for the user who issued the invite.
|
||||
* @param roomId The room to which the user is invited.
|
||||
* @param sender - The user id for the user who issued the invite.
|
||||
* @param roomId - The room to which the user is invited.
|
||||
* @returns A rule matching the entity, if any was found, `null` otherwise.
|
||||
*/
|
||||
public async getRuleForInvite({ sender, roomId }: {
|
||||
|
@ -63,9 +63,9 @@ export abstract class ReadReceipt<
|
||||
|
||||
/**
|
||||
* Gets the latest receipt for a given user in the room
|
||||
* @param userId The id of the user for which we want the receipt
|
||||
* @param ignoreSynthesized Whether to ignore synthesized receipts or not
|
||||
* @param receiptType Optional. The type of the receipt we want to get
|
||||
* @param userId - The id of the user for which we want the receipt
|
||||
* @param ignoreSynthesized - Whether to ignore synthesized receipts or not
|
||||
* @param receiptType - Optional. The type of the receipt we want to get
|
||||
* @returns the latest receipts of the chosen type for the chosen user
|
||||
*/
|
||||
public getReadReceiptForUserId(
|
||||
@ -82,11 +82,11 @@ export abstract class ReadReceipt<
|
||||
/**
|
||||
* Get the ID of the event that a given user has read up to, or null if we
|
||||
* have received no read receipts from them.
|
||||
* @param {String} userId The user ID to get read receipt event ID for
|
||||
* @param {Boolean} ignoreSynthesized If true, return only receipts that have been
|
||||
* @param userId - The user ID to get read receipt event ID for
|
||||
* @param ignoreSynthesized - If true, return only receipts that have been
|
||||
* sent by the server, not implicit ones generated
|
||||
* by the JS SDK.
|
||||
* @return {String} ID of the latest event that the given user has read, or null.
|
||||
* @returns ID of the latest event that the given user has read, or null.
|
||||
*/
|
||||
public getEventReadUpTo(userId: string, ignoreSynthesized = false): string | null {
|
||||
// XXX: This is very very ugly and I hope I won't have to ever add a new
|
||||
@ -212,8 +212,8 @@ export abstract class ReadReceipt<
|
||||
|
||||
/**
|
||||
* Get a list of receipts for the given event.
|
||||
* @param {MatrixEvent} event the event to get receipts for
|
||||
* @return {Object[]} A list of receipts with a userId, type and data keys or
|
||||
* @param event - the event to get receipts for
|
||||
* @returns A list of receipts with a userId, type and data keys or
|
||||
* an empty list.
|
||||
*/
|
||||
public getReceiptsForEvent(event: MatrixEvent): CachedReceipt[] {
|
||||
@ -225,9 +225,9 @@ export abstract class ReadReceipt<
|
||||
/**
|
||||
* Add a temporary local-echo receipt to the room to reflect in the
|
||||
* client the fact that we've sent one.
|
||||
* @param {string} userId The user ID if the receipt sender
|
||||
* @param {MatrixEvent} e The event that is to be acknowledged
|
||||
* @param {ReceiptType} receiptType The type of receipt
|
||||
* @param userId - The user ID if the receipt sender
|
||||
* @param e - The event that is to be acknowledged
|
||||
* @param receiptType - The type of receipt
|
||||
*/
|
||||
public addLocalEchoReceipt(userId: string, e: MatrixEvent, receiptType: ReceiptType): void {
|
||||
this.addReceipt(synthesizeReceipt(userId, e, receiptType), true);
|
||||
@ -235,8 +235,8 @@ export abstract class ReadReceipt<
|
||||
|
||||
/**
|
||||
* Get a list of user IDs who have <b>read up to</b> the given event.
|
||||
* @param {MatrixEvent} event the event to get read receipts for.
|
||||
* @return {String[]} A list of user IDs.
|
||||
* @param event - the event to get read receipts for.
|
||||
* @returns A list of user IDs.
|
||||
*/
|
||||
public getUsersReadUpTo(event: MatrixEvent): string[] {
|
||||
return this.getReceiptsForEvent(event).filter(function(receipt) {
|
||||
@ -250,9 +250,9 @@ export abstract class ReadReceipt<
|
||||
* Determines if the given user has read a particular event ID with the known
|
||||
* history of the room. This is not a definitive check as it relies only on
|
||||
* what is available to the room at the time of execution.
|
||||
* @param {String} userId The user ID to check the read state of.
|
||||
* @param {String} eventId The event ID to check if the user read.
|
||||
* @returns {Boolean} True if the user has read the event, false otherwise.
|
||||
* @param userId - The user ID to check the read state of.
|
||||
* @param eventId - The event ID to check if the user read.
|
||||
* @returns True if the user has read the event, false otherwise.
|
||||
*/
|
||||
public hasUserReadEvent(userId: string, eventId: string): boolean {
|
||||
const readUpToId = this.getEventReadUpTo(userId, false);
|
||||
|
@ -32,17 +32,14 @@ export class RelationsContainer {
|
||||
/**
|
||||
* Get a collection of child events to a given event in this timeline set.
|
||||
*
|
||||
* @param {String} eventId
|
||||
* The ID of the event that you'd like to access child events for.
|
||||
* @param eventId - The ID of the event that you'd like to access child events for.
|
||||
* For example, with annotations, this would be the ID of the event being annotated.
|
||||
* @param {String} relationType
|
||||
* The type of relationship involved, such as "m.annotation", "m.reference", "m.replace", etc.
|
||||
* @param {String} eventType
|
||||
* The relation event's type, such as "m.reaction", etc.
|
||||
* @throws If <code>eventId</code>, <code>relationType</code> or <code>eventType</code>
|
||||
* @param relationType - The type of relationship involved, such as "m.annotation", "m.reference", "m.replace", etc.
|
||||
* @param eventType - The relation event's type, such as "m.reaction", etc.
|
||||
* @throws If `eventId</code>, <code>relationType</code> or <code>eventType`
|
||||
* are not valid.
|
||||
*
|
||||
* @returns {?Relations}
|
||||
* @returns
|
||||
* A container for relation events or undefined if there are no relation events for
|
||||
* the relationType.
|
||||
*/
|
||||
@ -71,7 +68,7 @@ export class RelationsContainer {
|
||||
* Child events can point to other child events as their parent, so this method may be
|
||||
* called for events which are also logically child events.
|
||||
*
|
||||
* @param {MatrixEvent} event The event to check as relation target.
|
||||
* @param event - The event to check as relation target.
|
||||
*/
|
||||
public aggregateParentEvent(event: MatrixEvent): void {
|
||||
const relationsForEvent = this.relations.get(event.getId()!);
|
||||
@ -87,8 +84,8 @@ export class RelationsContainer {
|
||||
/**
|
||||
* Add relation events to the relevant relation collection.
|
||||
*
|
||||
* @param {MatrixEvent} event The new child event to be aggregated.
|
||||
* @param {EventTimelineSet} timelineSet The event timeline set within which to search for the related event if any.
|
||||
* @param event - The new child event to be aggregated.
|
||||
* @param timelineSet - The event timeline set within which to search for the related event if any.
|
||||
*/
|
||||
public aggregateChildEvent(event: MatrixEvent, timelineSet?: EventTimelineSet): void {
|
||||
if (event.isRedacted() || event.status === EventStatus.CANCELLED) {
|
||||
|
@ -52,13 +52,9 @@ export class Relations extends TypedEventEmitter<RelationsEvent, EventHandlerMap
|
||||
private readonly client: MatrixClient;
|
||||
|
||||
/**
|
||||
* @param {RelationType} relationType
|
||||
* The type of relation involved, such as "m.annotation", "m.reference",
|
||||
* "m.replace", etc.
|
||||
* @param {String} eventType
|
||||
* The relation event's type, such as "m.reaction", etc.
|
||||
* @param {MatrixClient|Room} client
|
||||
* The client which created this instance. For backwards compatibility also accepts a Room.
|
||||
* @param relationType - The type of relation involved, such as "m.annotation", "m.reference", "m.replace", etc.
|
||||
* @param eventType - The relation event's type, such as "m.reaction", etc.
|
||||
* @param client - The client which created this instance. For backwards compatibility also accepts a Room.
|
||||
*/
|
||||
public constructor(
|
||||
public readonly relationType: RelationType | string,
|
||||
@ -72,8 +68,7 @@ export class Relations extends TypedEventEmitter<RelationsEvent, EventHandlerMap
|
||||
/**
|
||||
* Add relation events to this collection.
|
||||
*
|
||||
* @param {MatrixEvent} event
|
||||
* The new relation event to be added.
|
||||
* @param event - The new relation event to be added.
|
||||
*/
|
||||
public async addEvent(event: MatrixEvent): Promise<void> {
|
||||
if (this.relationEventIds.has(event.getId()!)) {
|
||||
@ -120,8 +115,7 @@ export class Relations extends TypedEventEmitter<RelationsEvent, EventHandlerMap
|
||||
/**
|
||||
* Remove relation event from this collection.
|
||||
*
|
||||
* @param {MatrixEvent} event
|
||||
* The relation event to remove.
|
||||
* @param event - The relation event to remove.
|
||||
*/
|
||||
private async removeEvent(event: MatrixEvent): Promise<void> {
|
||||
if (!this.relations.has(event)) {
|
||||
@ -157,8 +151,8 @@ export class Relations extends TypedEventEmitter<RelationsEvent, EventHandlerMap
|
||||
/**
|
||||
* Listens for event status changes to remove cancelled events.
|
||||
*
|
||||
* @param {MatrixEvent} event The event whose status has changed
|
||||
* @param {EventStatus} status The new status
|
||||
* @param event - The event whose status has changed
|
||||
* @param status - The new status
|
||||
*/
|
||||
private onEventStatus = (event: MatrixEvent, status: EventStatus | null): void => {
|
||||
if (!event.isSending()) {
|
||||
@ -181,7 +175,6 @@ export class Relations extends TypedEventEmitter<RelationsEvent, EventHandlerMap
|
||||
* won't match timeline order in the case of scrollback.
|
||||
* TODO: Tweak `addEvent` to insert correctly for scrollback.
|
||||
*
|
||||
* @return {Array}
|
||||
* Relation events in insertion order.
|
||||
*/
|
||||
public getRelations(): MatrixEvent[] {
|
||||
@ -246,8 +239,7 @@ export class Relations extends TypedEventEmitter<RelationsEvent, EventHandlerMap
|
||||
* - after the server accepted the redaction and remote echoed back to us
|
||||
* - before the original event has been marked redacted in the client
|
||||
*
|
||||
* @param {MatrixEvent} redactedEvent
|
||||
* The original relation event that is about to be redacted.
|
||||
* @param redactedEvent - The original relation event that is about to be redacted.
|
||||
*/
|
||||
private onBeforeRedaction = async (redactedEvent: MatrixEvent): Promise<void> => {
|
||||
if (!this.relations.has(redactedEvent)) {
|
||||
@ -275,7 +267,6 @@ export class Relations extends TypedEventEmitter<RelationsEvent, EventHandlerMap
|
||||
*
|
||||
* This is currently only supported for the annotation relation type.
|
||||
*
|
||||
* @return {Array}
|
||||
* An array of [key, events] pairs sorted by descending event count.
|
||||
* The events are stored in a Set (which preserves insertion order).
|
||||
*/
|
||||
@ -293,7 +284,6 @@ export class Relations extends TypedEventEmitter<RelationsEvent, EventHandlerMap
|
||||
*
|
||||
* This is currently only supported for the annotation relation type.
|
||||
*
|
||||
* @return {Object}
|
||||
* An object with each relation sender as a key and the matching Set of
|
||||
* events for that sender as a value.
|
||||
*/
|
||||
@ -311,8 +301,6 @@ export class Relations extends TypedEventEmitter<RelationsEvent, EventHandlerMap
|
||||
*
|
||||
* This is currently only supported for the m.replace relation type,
|
||||
* once the target event is known, see `addEvent`.
|
||||
*
|
||||
* @return {MatrixEvent?}
|
||||
*/
|
||||
public async getLastReplacement(): Promise<MatrixEvent | null> {
|
||||
if (this.relationType !== RelationType.Replace) {
|
||||
@ -354,7 +342,7 @@ export class Relations extends TypedEventEmitter<RelationsEvent, EventHandlerMap
|
||||
}
|
||||
|
||||
/*
|
||||
* @param {MatrixEvent} targetEvent the event the relations are related to.
|
||||
* @param targetEvent - the event the relations are related to.
|
||||
*/
|
||||
public async setTargetEvent(event: MatrixEvent): Promise<void> {
|
||||
if (this.targetEvent) {
|
||||
|
@ -14,10 +14,6 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @module models/room-member
|
||||
*/
|
||||
|
||||
import { getHttpUriForMxc } from "../content-repo";
|
||||
import * as utils from "../utils";
|
||||
import { User } from "./user";
|
||||
@ -35,9 +31,56 @@ export enum RoomMemberEvent {
|
||||
}
|
||||
|
||||
export type RoomMemberEventHandlerMap = {
|
||||
/**
|
||||
* Fires whenever any room member's membership state changes.
|
||||
* @param event - The matrix event which caused this event to fire.
|
||||
* @param member - The member whose RoomMember.membership changed.
|
||||
* @param oldMembership - The previous membership state. Null if it's a new member.
|
||||
* @example
|
||||
* ```
|
||||
* matrixClient.on("RoomMember.membership", function(event, member, oldMembership){
|
||||
* var newState = member.membership;
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
[RoomMemberEvent.Membership]: (event: MatrixEvent, member: RoomMember, oldMembership?: string) => void;
|
||||
/**
|
||||
* Fires whenever any room member's name changes.
|
||||
* @param event - The matrix event which caused this event to fire.
|
||||
* @param member - The member whose RoomMember.name changed.
|
||||
* @param oldName - The previous name. Null if the member didn't have a name previously.
|
||||
* @example
|
||||
* ```
|
||||
* matrixClient.on("RoomMember.name", function(event, member){
|
||||
* var newName = member.name;
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
[RoomMemberEvent.Name]: (event: MatrixEvent, member: RoomMember, oldName: string | null) => void;
|
||||
/**
|
||||
* Fires whenever any room member's power level changes.
|
||||
* @param event - The matrix event which caused this event to fire.
|
||||
* @param member - The member whose RoomMember.powerLevel changed.
|
||||
* @example
|
||||
* ```
|
||||
* matrixClient.on("RoomMember.powerLevel", function(event, member){
|
||||
* var newPowerLevel = member.powerLevel;
|
||||
* var newNormPowerLevel = member.powerLevelNorm;
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
[RoomMemberEvent.PowerLevel]: (event: MatrixEvent, member: RoomMember) => void;
|
||||
/**
|
||||
* Fires whenever any room member's typing state changes.
|
||||
* @param event - The matrix event which caused this event to fire.
|
||||
* @param member - The member whose RoomMember.typing changed.
|
||||
* @example
|
||||
* ```
|
||||
* matrixClient.on("RoomMember.typing", function(event, member){
|
||||
* var isTyping = member.typing;
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
[RoomMemberEvent.Typing]: (event: MatrixEvent, member: RoomMember) => void;
|
||||
};
|
||||
|
||||
@ -47,41 +90,55 @@ export class RoomMember extends TypedEventEmitter<RoomMemberEvent, RoomMemberEve
|
||||
public requestedProfileInfo = false; // used by sync.ts
|
||||
|
||||
// XXX these should be read-only
|
||||
/**
|
||||
* True if the room member is currently typing.
|
||||
*/
|
||||
public typing = false;
|
||||
/**
|
||||
* The human-readable name for this room member. This will be
|
||||
* disambiguated with a suffix of " (\@user_id:matrix.org)" if another member shares the
|
||||
* same displayname.
|
||||
*/
|
||||
public name: string;
|
||||
/**
|
||||
* The ambiguous displayname of this room member.
|
||||
*/
|
||||
public rawDisplayName: string;
|
||||
/**
|
||||
* The power level for this room member.
|
||||
*/
|
||||
public powerLevel = 0;
|
||||
/**
|
||||
* The normalised power level (0-100) for this room member.
|
||||
*/
|
||||
public powerLevelNorm = 0;
|
||||
/**
|
||||
* The User object for this room member, if one exists.
|
||||
*/
|
||||
public user?: User;
|
||||
/**
|
||||
* The membership state for this room member e.g. 'join'.
|
||||
*/
|
||||
public membership?: string;
|
||||
/**
|
||||
* True if the member's name is disambiguated.
|
||||
*/
|
||||
public disambiguate = false;
|
||||
/**
|
||||
* The events describing this RoomMember.
|
||||
*/
|
||||
public events: {
|
||||
/**
|
||||
* The m.room.member event for this RoomMember.
|
||||
*/
|
||||
member?: MatrixEvent;
|
||||
} = {};
|
||||
|
||||
/**
|
||||
* Construct a new room member.
|
||||
*
|
||||
* @constructor
|
||||
* @alias module:models/room-member
|
||||
*
|
||||
* @param {string} roomId The room ID of the member.
|
||||
* @param {string} userId The user ID of the member.
|
||||
* @prop {string} roomId The room ID for this member.
|
||||
* @prop {string} userId The user ID of this member.
|
||||
* @prop {boolean} typing True if the room member is currently typing.
|
||||
* @prop {string} name The human-readable name for this room member. This will be
|
||||
* disambiguated with a suffix of " (@user_id:matrix.org)" if another member shares the
|
||||
* same displayname.
|
||||
* @prop {string} rawDisplayName The ambiguous displayname of this room member.
|
||||
* @prop {Number} powerLevel The power level for this room member.
|
||||
* @prop {Number} powerLevelNorm The normalised power level (0-100) for this
|
||||
* room member.
|
||||
* @prop {User} user The User object for this room member, if one exists.
|
||||
* @prop {string} membership The membership state for this room member e.g. 'join'.
|
||||
* @prop {Object} events The events describing this RoomMember.
|
||||
* @prop {MatrixEvent} events.member The m.room.member event for this RoomMember.
|
||||
* @prop {boolean} disambiguate True if the member's name is disambiguated.
|
||||
* @param roomId - The room ID of the member.
|
||||
* @param userId - The user ID of the member.
|
||||
*/
|
||||
public constructor(public readonly roomId: string, public readonly userId: string) {
|
||||
super();
|
||||
@ -99,7 +156,7 @@ export class RoomMember extends TypedEventEmitter<RoomMemberEvent, RoomMemberEve
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {boolean} does the member come from a channel that is not sync?
|
||||
* @returns does the member come from a channel that is not sync?
|
||||
* This is used to store the member seperately
|
||||
* from the sync state so it available across browser sessions.
|
||||
*/
|
||||
@ -110,11 +167,13 @@ export class RoomMember extends TypedEventEmitter<RoomMemberEvent, RoomMemberEve
|
||||
/**
|
||||
* Update this room member's membership event. May fire "RoomMember.name" if
|
||||
* this event updates this member's name.
|
||||
* @param {MatrixEvent} event The <code>m.room.member</code> event
|
||||
* @param {RoomState} roomState Optional. The room state to take into account
|
||||
* @param event - The `m.room.member` event
|
||||
* @param roomState - Optional. The room state to take into account
|
||||
* when calculating (e.g. for disambiguating users with the same name).
|
||||
* @fires module:client~MatrixClient#event:"RoomMember.name"
|
||||
* @fires module:client~MatrixClient#event:"RoomMember.membership"
|
||||
*
|
||||
* @remarks
|
||||
* Fires {@link RoomMemberEvent.Name}
|
||||
* Fires {@link RoomMemberEvent.Membership}
|
||||
*/
|
||||
public setMembershipEvent(event: MatrixEvent, roomState?: RoomState): void {
|
||||
const displayName = event.getDirectionalContent().displayname ?? "";
|
||||
@ -164,9 +223,10 @@ export class RoomMember extends TypedEventEmitter<RoomMemberEvent, RoomMemberEve
|
||||
/**
|
||||
* Update this room member's power level event. May fire
|
||||
* "RoomMember.powerLevel" if this event updates this member's power levels.
|
||||
* @param {MatrixEvent} powerLevelEvent The <code>m.room.power_levels</code>
|
||||
* event
|
||||
* @fires module:client~MatrixClient#event:"RoomMember.powerLevel"
|
||||
* @param powerLevelEvent - The `m.room.power_levels` event
|
||||
*
|
||||
* @remarks
|
||||
* Fires {@link RoomMemberEvent.PowerLevel}
|
||||
*/
|
||||
public setPowerLevelEvent(powerLevelEvent: MatrixEvent): void {
|
||||
if (powerLevelEvent.getType() !== EventType.RoomPowerLevels || powerLevelEvent.getStateKey() !== "") {
|
||||
@ -206,8 +266,10 @@ export class RoomMember extends TypedEventEmitter<RoomMemberEvent, RoomMemberEve
|
||||
/**
|
||||
* Update this room member's typing event. May fire "RoomMember.typing" if
|
||||
* this event changes this member's typing state.
|
||||
* @param {MatrixEvent} event The typing event
|
||||
* @fires module:client~MatrixClient#event:"RoomMember.typing"
|
||||
* @param event - The typing event
|
||||
*
|
||||
* @remarks
|
||||
* Fires {@link RoomMemberEvent.Typing}
|
||||
*/
|
||||
public setTypingEvent(event: MatrixEvent): void {
|
||||
if (event.getType() !== "m.typing") {
|
||||
@ -240,7 +302,7 @@ export class RoomMember extends TypedEventEmitter<RoomMemberEvent, RoomMemberEve
|
||||
* Get the timestamp when this RoomMember was last updated. This timestamp is
|
||||
* updated when properties on this RoomMember are updated.
|
||||
* It is updated <i>before</i> firing events.
|
||||
* @return {number} The timestamp
|
||||
* @returns The timestamp
|
||||
*/
|
||||
public getLastModifiedTime(): number {
|
||||
return this.modified;
|
||||
@ -255,7 +317,7 @@ export class RoomMember extends TypedEventEmitter<RoomMemberEvent, RoomMemberEve
|
||||
/**
|
||||
* If this member was invited with the is_direct flag set, return
|
||||
* the user that invited this member
|
||||
* @return {string} user id of the inviter
|
||||
* @returns user id of the inviter
|
||||
*/
|
||||
public getDMInviter(): string | undefined {
|
||||
// when not available because that room state hasn't been loaded in,
|
||||
@ -285,21 +347,21 @@ export class RoomMember extends TypedEventEmitter<RoomMemberEvent, RoomMemberEve
|
||||
|
||||
/**
|
||||
* Get the avatar URL for a room member.
|
||||
* @param {string} baseUrl The base homeserver URL See
|
||||
* {@link module:client~MatrixClient#getHomeserverUrl}.
|
||||
* @param {Number} width The desired width of the thumbnail.
|
||||
* @param {Number} height The desired height of the thumbnail.
|
||||
* @param {string} resizeMethod The thumbnail resize method to use, either
|
||||
* @param baseUrl - The base homeserver URL See
|
||||
* {@link MatrixClient#getHomeserverUrl}.
|
||||
* @param width - The desired width of the thumbnail.
|
||||
* @param height - The desired height of the thumbnail.
|
||||
* @param resizeMethod - The thumbnail resize method to use, either
|
||||
* "crop" or "scale".
|
||||
* @param {Boolean} allowDefault (optional) Passing false causes this method to
|
||||
* @param allowDefault - (optional) Passing false causes this method to
|
||||
* return null if the user has no avatar image. Otherwise, a default image URL
|
||||
* will be returned. Default: true. (Deprecated)
|
||||
* @param {Boolean} allowDirectLinks (optional) If true, the avatar URL will be
|
||||
* @param allowDirectLinks - (optional) If true, the avatar URL will be
|
||||
* returned even if it is a direct hyperlink rather than a matrix content URL.
|
||||
* If false, any non-matrix content URLs will be ignored. Setting this option to
|
||||
* true will expose URLs that, if fetched, will leak information about the user
|
||||
* to anyone who they share a room with.
|
||||
* @return {?string} the avatar URL or null.
|
||||
* @returns the avatar URL or null.
|
||||
*/
|
||||
public getAvatarUrl(
|
||||
baseUrl: string,
|
||||
@ -323,7 +385,7 @@ export class RoomMember extends TypedEventEmitter<RoomMemberEvent, RoomMemberEve
|
||||
|
||||
/**
|
||||
* get the mxc avatar url, either from a state event, or from a lazily loaded member
|
||||
* @return {string} the mxc avatar url
|
||||
* @returns the mxc avatar url
|
||||
*/
|
||||
public getMxcAvatarUrl(): string | undefined {
|
||||
if (this.events.member) {
|
||||
@ -390,52 +452,3 @@ function calculateDisplayName(
|
||||
// with the embed chars or marker chars.
|
||||
return utils.removeDirectionOverrideChars(displayName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires whenever any room member's name changes.
|
||||
* @event module:client~MatrixClient#"RoomMember.name"
|
||||
* @param {MatrixEvent} event The matrix event which caused this event to fire.
|
||||
* @param {RoomMember} member The member whose RoomMember.name changed.
|
||||
* @param {string?} oldName The previous name. Null if the member didn't have a
|
||||
* name previously.
|
||||
* @example
|
||||
* matrixClient.on("RoomMember.name", function(event, member){
|
||||
* var newName = member.name;
|
||||
* });
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fires whenever any room member's membership state changes.
|
||||
* @event module:client~MatrixClient#"RoomMember.membership"
|
||||
* @param {MatrixEvent} event The matrix event which caused this event to fire.
|
||||
* @param {RoomMember} member The member whose RoomMember.membership changed.
|
||||
* @param {string?} oldMembership The previous membership state. Null if it's a
|
||||
* new member.
|
||||
* @example
|
||||
* matrixClient.on("RoomMember.membership", function(event, member, oldMembership){
|
||||
* var newState = member.membership;
|
||||
* });
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fires whenever any room member's typing state changes.
|
||||
* @event module:client~MatrixClient#"RoomMember.typing"
|
||||
* @param {MatrixEvent} event The matrix event which caused this event to fire.
|
||||
* @param {RoomMember} member The member whose RoomMember.typing changed.
|
||||
* @example
|
||||
* matrixClient.on("RoomMember.typing", function(event, member){
|
||||
* var isTyping = member.typing;
|
||||
* });
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fires whenever any room member's power level changes.
|
||||
* @event module:client~MatrixClient#"RoomMember.powerLevel"
|
||||
* @param {MatrixEvent} event The matrix event which caused this event to fire.
|
||||
* @param {RoomMember} member The member whose RoomMember.powerLevel changed.
|
||||
* @example
|
||||
* matrixClient.on("RoomMember.powerLevel", function(event, member){
|
||||
* var newPowerLevel = member.powerLevel;
|
||||
* var newNormPowerLevel = member.powerLevelNorm;
|
||||
* });
|
||||
*/
|
||||
|
@ -14,10 +14,6 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @module models/room-state
|
||||
*/
|
||||
|
||||
import { RoomMember } from "./room-member";
|
||||
import { logger } from '../logger';
|
||||
import * as utils from "../utils";
|
||||
@ -77,8 +73,52 @@ export enum RoomStateEvent {
|
||||
}
|
||||
|
||||
export type RoomStateEventHandlerMap = {
|
||||
/**
|
||||
* Fires whenever the event dictionary in room state is updated.
|
||||
* @param event - The matrix event which caused this event to fire.
|
||||
* @param state - The room state whose RoomState.events dictionary
|
||||
* was updated.
|
||||
* @param prevEvent - The event being replaced by the new state, if
|
||||
* known. Note that this can differ from `getPrevContent()` on the new state event
|
||||
* as this is the store's view of the last state, not the previous state provided
|
||||
* by the server.
|
||||
* @example
|
||||
* ```
|
||||
* matrixClient.on("RoomState.events", function(event, state, prevEvent){
|
||||
* var newStateEvent = event;
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
[RoomStateEvent.Events]: (event: MatrixEvent, state: RoomState, lastStateEvent: MatrixEvent | null) => void;
|
||||
/**
|
||||
* Fires whenever a member in the members dictionary is updated in any way.
|
||||
* @param event - The matrix event which caused this event to fire.
|
||||
* @param state - The room state whose RoomState.members dictionary
|
||||
* was updated.
|
||||
* @param member - The room member that was updated.
|
||||
* @example
|
||||
* ```
|
||||
* matrixClient.on("RoomState.members", function(event, state, member){
|
||||
* var newMembershipState = member.membership;
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
[RoomStateEvent.Members]: (event: MatrixEvent, state: RoomState, member: RoomMember) => void;
|
||||
/**
|
||||
* Fires whenever a member is added to the members dictionary. The RoomMember
|
||||
* will not be fully populated yet (e.g. no membership state) but will already
|
||||
* be available in the members dictionary.
|
||||
* @param event - The matrix event which caused this event to fire.
|
||||
* @param state - The room state whose RoomState.members dictionary
|
||||
* was updated with a new entry.
|
||||
* @param member - The room member that was added.
|
||||
* @example
|
||||
* ```
|
||||
* matrixClient.on("RoomState.newMember", function(event, state, member){
|
||||
* // add event listeners on 'member'
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
[RoomStateEvent.NewMember]: (event: MatrixEvent, state: RoomState, member: RoomMember) => void;
|
||||
[RoomStateEvent.Update]: (state: RoomState) => void;
|
||||
[RoomStateEvent.BeaconLiveness]: (state: RoomState, hasLiveBeacons: boolean) => void;
|
||||
@ -109,8 +149,11 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
|
||||
private modified = -1;
|
||||
|
||||
// XXX: Should be read-only
|
||||
// The room member dictionary, keyed on the user's ID.
|
||||
public members: Record<string, RoomMember> = {}; // userId: RoomMember
|
||||
// The state events dictionary, keyed on the event type and then the state_key value.
|
||||
public events = new Map<string, Map<string, MatrixEvent>>(); // Map<eventType, Map<stateKey, MatrixEvent>>
|
||||
// The pagination token for this state.
|
||||
public paginationToken: string | null = null;
|
||||
|
||||
public readonly beacons = new Map<BeaconIdentifier, Beacon>();
|
||||
@ -123,8 +166,8 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
|
||||
* It can be mutated by adding state events to it.
|
||||
* There are two types of room member associated with a state event:
|
||||
* normal member objects (accessed via getMember/getMembers) which mutate
|
||||
* with the state to represent the current state of that room/user, eg.
|
||||
* the object returned by getMember('@bob:example.com') will mutate to
|
||||
* with the state to represent the current state of that room/user, e.g.
|
||||
* the object returned by `getMember('@bob:example.com')` will mutate to
|
||||
* get a different display name if Bob later changes his display name
|
||||
* in the room.
|
||||
* There are also 'sentinel' members (accessed via getSentinelMember).
|
||||
@ -137,18 +180,12 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
|
||||
* after the display name change will return a new RoomMember object
|
||||
* with Bob's new display name.
|
||||
*
|
||||
* @constructor
|
||||
* @param {?string} roomId Optional. The ID of the room which has this state.
|
||||
* @param roomId - Optional. The ID of the room which has this state.
|
||||
* If none is specified it just tracks paginationTokens, useful for notifTimelineSet
|
||||
* @param {?object} oobMemberFlags Optional. The state of loading out of bound members.
|
||||
* @param oobMemberFlags - Optional. The state of loading out of bound members.
|
||||
* As the timeline might get reset while they are loading, this state needs to be inherited
|
||||
* and shared when the room state is cloned for the new timeline.
|
||||
* This should only be passed from clone.
|
||||
* @prop {Object.<string, RoomMember>} members The room member dictionary, keyed
|
||||
* on the user's ID.
|
||||
* @prop {Object.<string, Object.<string, MatrixEvent>>} events The state
|
||||
* events dictionary, keyed on the event type and then the state_key value.
|
||||
* @prop {string} paginationToken The pagination token for this state.
|
||||
*/
|
||||
public constructor(public readonly roomId: string, private oobMemberFlags = { status: OobStatus.NotStarted }) {
|
||||
super();
|
||||
@ -158,7 +195,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
|
||||
/**
|
||||
* Returns the number of joined members in this room
|
||||
* This method caches the result.
|
||||
* @return {number} The number of members in this room whose membership is 'join'
|
||||
* @returns The number of members in this room whose membership is 'join'
|
||||
*/
|
||||
public getJoinedMemberCount(): number {
|
||||
if (this.summaryJoinedMemberCount !== null) {
|
||||
@ -174,7 +211,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
|
||||
|
||||
/**
|
||||
* Set the joined member count explicitly (like from summary part of the sync response)
|
||||
* @param {number} count the amount of joined members
|
||||
* @param count - the amount of joined members
|
||||
*/
|
||||
public setJoinedMemberCount(count: number): void {
|
||||
this.summaryJoinedMemberCount = count;
|
||||
@ -182,7 +219,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
|
||||
|
||||
/**
|
||||
* Returns the number of invited members in this room
|
||||
* @return {number} The number of members in this room whose membership is 'invite'
|
||||
* @returns The number of members in this room whose membership is 'invite'
|
||||
*/
|
||||
public getInvitedMemberCount(): number {
|
||||
if (this.summaryInvitedMemberCount !== null) {
|
||||
@ -198,7 +235,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
|
||||
|
||||
/**
|
||||
* Set the amount of invited members in this room
|
||||
* @param {number} count the amount of invited members
|
||||
* @param count - the amount of invited members
|
||||
*/
|
||||
public setInvitedMemberCount(count: number): void {
|
||||
this.summaryInvitedMemberCount = count;
|
||||
@ -206,7 +243,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
|
||||
|
||||
/**
|
||||
* Get all RoomMembers in this room.
|
||||
* @return {Array<RoomMember>} A list of RoomMembers.
|
||||
* @returns A list of RoomMembers.
|
||||
*/
|
||||
public getMembers(): RoomMember[] {
|
||||
return Object.values(this.members);
|
||||
@ -214,8 +251,8 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
|
||||
|
||||
/**
|
||||
* Get all RoomMembers in this room, excluding the user IDs provided.
|
||||
* @param {Array<string>} excludedIds The user IDs to exclude.
|
||||
* @return {Array<RoomMember>} A list of RoomMembers.
|
||||
* @param excludedIds - The user IDs to exclude.
|
||||
* @returns A list of RoomMembers.
|
||||
*/
|
||||
public getMembersExcept(excludedIds: string[]): RoomMember[] {
|
||||
return this.getMembers().filter((m) => !excludedIds.includes(m.userId));
|
||||
@ -223,8 +260,8 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
|
||||
|
||||
/**
|
||||
* Get a room member by their user ID.
|
||||
* @param {string} userId The room member's user ID.
|
||||
* @return {RoomMember} The member or null if they do not exist.
|
||||
* @param userId - The room member's user ID.
|
||||
* @returns The member or null if they do not exist.
|
||||
*/
|
||||
public getMember(userId: string): RoomMember | null {
|
||||
return this.members[userId] || null;
|
||||
@ -236,8 +273,8 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
|
||||
* may no longer be represented correctly by Room.currentState or Room.oldState.
|
||||
* The term 'sentinel' refers to the fact that this RoomMember is an unchanging
|
||||
* guardian for state at this particular point in time.
|
||||
* @param {string} userId The room member's user ID.
|
||||
* @return {RoomMember} The member or null if they do not exist.
|
||||
* @param userId - The room member's user ID.
|
||||
* @returns The member or null if they do not exist.
|
||||
*/
|
||||
public getSentinelMember(userId: string): RoomMember | null {
|
||||
if (!userId) return null;
|
||||
@ -256,12 +293,12 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
|
||||
|
||||
/**
|
||||
* Get state events from the state of the room.
|
||||
* @param {string} eventType The event type of the state event.
|
||||
* @param {string} stateKey Optional. The state_key of the state event. If
|
||||
* this is <code>undefined</code> then all matching state events will be
|
||||
* @param eventType - The event type of the state event.
|
||||
* @param stateKey - Optional. The state_key of the state event. If
|
||||
* this is `undefined` then all matching state events will be
|
||||
* returned.
|
||||
* @return {MatrixEvent[]|MatrixEvent} A list of events if state_key was
|
||||
* <code>undefined</code>, else a single event (or null if no match found).
|
||||
* @returns A list of events if state_key was
|
||||
* `undefined`, else a single event (or null if no match found).
|
||||
*/
|
||||
public getStateEvents(eventType: EventType | string): MatrixEvent[];
|
||||
public getStateEvents(eventType: EventType | string, stateKey: string): MatrixEvent | null;
|
||||
@ -287,7 +324,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
|
||||
|
||||
/**
|
||||
* Creates a copy of this room state so that mutations to either won't affect the other.
|
||||
* @return {RoomState} the copy of the room state
|
||||
* @returns the copy of the room state
|
||||
*/
|
||||
public clone(): RoomState {
|
||||
const copy = new RoomState(this.roomId, this.oobMemberFlags);
|
||||
@ -333,7 +370,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
|
||||
* When lazy loading members while back-paginating,
|
||||
* the relevant room state for the timeline chunk at the end
|
||||
* of the chunk can be set with this method.
|
||||
* @param {MatrixEvent[]} events state events to prepend
|
||||
* @param events - state events to prepend
|
||||
*/
|
||||
public setUnknownStateEvents(events: MatrixEvent[]): void {
|
||||
const unknownStateEvents = events.filter((event) => {
|
||||
@ -345,16 +382,17 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
|
||||
|
||||
/**
|
||||
* Add an array of one or more state MatrixEvents, overwriting any existing
|
||||
* state with the same {type, stateKey} tuple. Will fire "RoomState.events"
|
||||
* state with the same `{type, stateKey}` tuple. Will fire "RoomState.events"
|
||||
* for every event added. May fire "RoomState.members" if there are
|
||||
* <code>m.room.member</code> events. May fire "RoomStateEvent.Marker" if there are
|
||||
* <code>UNSTABLE_MSC2716_MARKER</code> events.
|
||||
* @param {MatrixEvent[]} stateEvents a list of state events for this room.
|
||||
* @param {IMarkerFoundOptions} markerFoundOptions
|
||||
* @fires module:client~MatrixClient#event:"RoomState.members"
|
||||
* @fires module:client~MatrixClient#event:"RoomState.newMember"
|
||||
* @fires module:client~MatrixClient#event:"RoomState.events"
|
||||
* @fires module:client~MatrixClient#event:"RoomStateEvent.Marker"
|
||||
* `m.room.member` events. May fire "RoomStateEvent.Marker" if there are
|
||||
* `UNSTABLE_MSC2716_MARKER` events.
|
||||
* @param stateEvents - a list of state events for this room.
|
||||
*
|
||||
* @remarks
|
||||
* Fires {@link RoomStateEvent.Members}
|
||||
* Fires {@link RoomStateEvent.NewMember}
|
||||
* Fires {@link RoomStateEvent.Events}
|
||||
* Fires {@link RoomStateEvent.Marker}
|
||||
*/
|
||||
public setStateEvents(stateEvents: MatrixEvent[], markerFoundOptions?: IMarkerFoundOptions): void {
|
||||
this.updateModifiedTime();
|
||||
@ -479,10 +517,12 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
|
||||
* create it and emit the `RoomState.newMember` event.
|
||||
* This method makes sure the member is added to the members dictionary
|
||||
* before emitting, as this is done from setStateEvents and setOutOfBandMember.
|
||||
* @param {string} userId the id of the user to look up
|
||||
* @param {MatrixEvent} event the membership event for the (new) member. Used to emit.
|
||||
* @fires module:client~MatrixClient#event:"RoomState.newMember"
|
||||
* @returns {RoomMember} the member, existing or newly created.
|
||||
* @param userId - the id of the user to look up
|
||||
* @param event - the membership event for the (new) member. Used to emit.
|
||||
* @returns the member, existing or newly created.
|
||||
*
|
||||
* @remarks
|
||||
* Fires {@link RoomStateEvent.NewMember}
|
||||
*/
|
||||
private getOrCreateMember(userId: string, event: MatrixEvent): RoomMember {
|
||||
let member = this.members[userId];
|
||||
@ -578,7 +618,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
|
||||
/**
|
||||
* Get the out-of-band members loading state, whether loading is needed or not.
|
||||
* Note that loading might be in progress and hence isn't needed.
|
||||
* @return {boolean} whether or not the members of this room need to be loaded
|
||||
* @returns whether or not the members of this room need to be loaded
|
||||
*/
|
||||
public needsOutOfBandMembers(): boolean {
|
||||
return this.oobMemberFlags.status === OobStatus.NotStarted;
|
||||
@ -624,7 +664,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
|
||||
|
||||
/**
|
||||
* Sets the loaded out-of-band members.
|
||||
* @param {MatrixEvent[]} stateEvents array of membership state events
|
||||
* @param stateEvents - array of membership state events
|
||||
*/
|
||||
public setOutOfBandMembers(stateEvents: MatrixEvent[]): void {
|
||||
logger.log(`LL: RoomState about to set ${stateEvents.length} OOB members ...`);
|
||||
@ -639,7 +679,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
|
||||
|
||||
/**
|
||||
* Sets a single out of band member, used by both setOutOfBandMembers and clone
|
||||
* @param {MatrixEvent} stateEvent membership state event
|
||||
* @param stateEvent - membership state event
|
||||
*/
|
||||
private setOutOfBandMember(stateEvent: MatrixEvent): void {
|
||||
if (stateEvent.getType() !== EventType.RoomMember) {
|
||||
@ -668,7 +708,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
|
||||
|
||||
/**
|
||||
* Set the current typing event for this room.
|
||||
* @param {MatrixEvent} event The typing event
|
||||
* @param event - The typing event
|
||||
*/
|
||||
public setTypingEvent(event: MatrixEvent): void {
|
||||
Object.values(this.members).forEach(function(member) {
|
||||
@ -679,8 +719,8 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
|
||||
/**
|
||||
* Get the m.room.member event which has the given third party invite token.
|
||||
*
|
||||
* @param {string} token The token
|
||||
* @return {?MatrixEvent} The m.room.member event or null
|
||||
* @param token - The token
|
||||
* @returns The m.room.member event or null
|
||||
*/
|
||||
public getInviteForThreePidToken(token: string): MatrixEvent | null {
|
||||
return this.tokenToInvite[token] || null;
|
||||
@ -696,7 +736,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
|
||||
/**
|
||||
* Get the timestamp when this room state was last updated. This timestamp is
|
||||
* updated when this object has received new state events.
|
||||
* @return {number} The timestamp
|
||||
* @returns The timestamp
|
||||
*/
|
||||
public getLastModifiedTime(): number {
|
||||
return this.modified;
|
||||
@ -704,8 +744,8 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
|
||||
|
||||
/**
|
||||
* Get user IDs with the specified or similar display names.
|
||||
* @param {string} displayName The display name to get user IDs from.
|
||||
* @return {string[]} An array of user IDs or an empty array.
|
||||
* @param displayName - The display name to get user IDs from.
|
||||
* @returns An array of user IDs or an empty array.
|
||||
*/
|
||||
public getUserIdsWithDisplayName(displayName: string): string[] {
|
||||
return this.displayNameToUserIds.get(utils.removeHiddenChars(displayName)) ?? [];
|
||||
@ -714,9 +754,9 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
|
||||
/**
|
||||
* Returns true if userId is in room, event is not redacted and either sender of
|
||||
* mxEvent or has power level sufficient to redact events other than their own.
|
||||
* @param {MatrixEvent} mxEvent The event to test permission for
|
||||
* @param {string} userId The user ID of the user to test permission for
|
||||
* @return {boolean} true if the given used ID can redact given event
|
||||
* @param mxEvent - The event to test permission for
|
||||
* @param userId - The user ID of the user to test permission for
|
||||
* @returns true if the given used ID can redact given event
|
||||
*/
|
||||
public maySendRedactionForEvent(mxEvent: MatrixEvent, userId: string): boolean {
|
||||
const member = this.getMember(userId);
|
||||
@ -734,9 +774,9 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
|
||||
|
||||
/**
|
||||
* Returns true if the given power level is sufficient for action
|
||||
* @param {string} action The type of power level to check
|
||||
* @param {number} powerLevel The power level of the member
|
||||
* @return {boolean} true if the given power level is sufficient
|
||||
* @param action - The type of power level to check
|
||||
* @param powerLevel - The power level of the member
|
||||
* @returns true if the given power level is sufficient
|
||||
*/
|
||||
public hasSufficientPowerLevelFor(action: "ban" | "kick" | "redact", powerLevel: number): boolean {
|
||||
const powerLevelsEvent = this.getStateEvents(EventType.RoomPowerLevels, "");
|
||||
@ -756,8 +796,8 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
|
||||
|
||||
/**
|
||||
* Short-form for maySendEvent('m.room.message', userId)
|
||||
* @param {string} userId The user ID of the user to test permission for
|
||||
* @return {boolean} true if the given user ID should be permitted to send
|
||||
* @param userId - The user ID of the user to test permission for
|
||||
* @returns true if the given user ID should be permitted to send
|
||||
* message events into the given room.
|
||||
*/
|
||||
public maySendMessage(userId: string): boolean {
|
||||
@ -767,9 +807,9 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
|
||||
/**
|
||||
* Returns true if the given user ID has permission to send a normal
|
||||
* event of type `eventType` into this room.
|
||||
* @param {string} eventType The type of event to test
|
||||
* @param {string} userId The user ID of the user to test permission for
|
||||
* @return {boolean} true if the given user ID should be permitted to send
|
||||
* @param eventType - The type of event to test
|
||||
* @param userId - The user ID of the user to test permission for
|
||||
* @returns true if the given user ID should be permitted to send
|
||||
* the given type of event into this room,
|
||||
* according to the room's state.
|
||||
*/
|
||||
@ -780,9 +820,9 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
|
||||
/**
|
||||
* Returns true if the given MatrixClient has permission to send a state
|
||||
* event of type `stateEventType` into this room.
|
||||
* @param {string} stateEventType The type of state events to test
|
||||
* @param {MatrixClient} cli The client to test permission for
|
||||
* @return {boolean} true if the given client should be permitted to send
|
||||
* @param stateEventType - The type of state events to test
|
||||
* @param cli - The client to test permission for
|
||||
* @returns true if the given client should be permitted to send
|
||||
* the given type of state event into this room,
|
||||
* according to the room's state.
|
||||
*/
|
||||
@ -796,9 +836,9 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
|
||||
/**
|
||||
* Returns true if the given user ID has permission to send a state
|
||||
* event of type `stateEventType` into this room.
|
||||
* @param {string} stateEventType The type of state events to test
|
||||
* @param {string} userId The user ID of the user to test permission for
|
||||
* @return {boolean} true if the given user ID should be permitted to send
|
||||
* @param stateEventType - The type of state events to test
|
||||
* @param userId - The user ID of the user to test permission for
|
||||
* @returns true if the given user ID should be permitted to send
|
||||
* the given type of state event into this room,
|
||||
* according to the room's state.
|
||||
*/
|
||||
@ -809,12 +849,12 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
|
||||
/**
|
||||
* Returns true if the given user ID has permission to send a normal or state
|
||||
* event of type `eventType` into this room.
|
||||
* @param {string} eventType The type of event to test
|
||||
* @param {string} userId The user ID of the user to test permission for
|
||||
* @param {boolean} state If true, tests if the user may send a state
|
||||
* @param eventType - The type of event to test
|
||||
* @param userId - The user ID of the user to test permission for
|
||||
* @param state - If true, tests if the user may send a state
|
||||
event of this type. Otherwise tests whether
|
||||
they may send a regular event.
|
||||
* @return {boolean} true if the given user ID should be permitted to send
|
||||
* @returns true if the given user ID should be permitted to send
|
||||
* the given type of event into this room,
|
||||
* according to the room's state.
|
||||
*/
|
||||
@ -859,9 +899,9 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
|
||||
/**
|
||||
* Returns true if the given user ID has permission to trigger notification
|
||||
* of type `notifLevelKey`
|
||||
* @param {string} notifLevelKey The level of notification to test (eg. 'room')
|
||||
* @param {string} userId The user ID of the user to test permission for
|
||||
* @return {boolean} true if the given user ID has permission to trigger a
|
||||
* @param notifLevelKey - The level of notification to test (eg. 'room')
|
||||
* @param userId - The user ID of the user to test permission for
|
||||
* @returns true if the given user ID has permission to trigger a
|
||||
* notification of this type.
|
||||
*/
|
||||
public mayTriggerNotifOfType(notifLevelKey: string, userId: string): boolean {
|
||||
@ -887,7 +927,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
|
||||
|
||||
/**
|
||||
* Returns the join rule based on the m.room.join_rule state event, defaulting to `invite`.
|
||||
* @returns {string} the join_rule applied to this room
|
||||
* @returns the join_rule applied to this room
|
||||
*/
|
||||
public getJoinRule(): JoinRule {
|
||||
const joinRuleEvent = this.getStateEvents(EventType.RoomJoinRules, "");
|
||||
@ -897,7 +937,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
|
||||
|
||||
/**
|
||||
* Returns the history visibility based on the m.room.history_visibility state event, defaulting to `shared`.
|
||||
* @returns {HistoryVisibility} the history_visibility applied to this room
|
||||
* @returns the history_visibility applied to this room
|
||||
*/
|
||||
public getHistoryVisibility(): HistoryVisibility {
|
||||
const historyVisibilityEvent = this.getStateEvents(EventType.RoomHistoryVisibility, "");
|
||||
@ -907,7 +947,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
|
||||
|
||||
/**
|
||||
* Returns the guest access based on the m.room.guest_access state event, defaulting to `shared`.
|
||||
* @returns {GuestAccess} the guest_access applied to this room
|
||||
* @returns the guest_access applied to this room
|
||||
*/
|
||||
public getGuestAccess(): GuestAccess {
|
||||
const guestAccessEvent = this.getStateEvents(EventType.RoomGuestAccess, "");
|
||||
@ -959,47 +999,3 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires whenever the event dictionary in room state is updated.
|
||||
* @event module:client~MatrixClient#"RoomState.events"
|
||||
* @param {MatrixEvent} event The matrix event which caused this event to fire.
|
||||
* @param {RoomState} state The room state whose RoomState.events dictionary
|
||||
* was updated.
|
||||
* @param {MatrixEvent} prevEvent The event being replaced by the new state, if
|
||||
* known. Note that this can differ from `getPrevContent()` on the new state event
|
||||
* as this is the store's view of the last state, not the previous state provided
|
||||
* by the server.
|
||||
* @example
|
||||
* matrixClient.on("RoomState.events", function(event, state, prevEvent){
|
||||
* var newStateEvent = event;
|
||||
* });
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fires whenever a member in the members dictionary is updated in any way.
|
||||
* @event module:client~MatrixClient#"RoomState.members"
|
||||
* @param {MatrixEvent} event The matrix event which caused this event to fire.
|
||||
* @param {RoomState} state The room state whose RoomState.members dictionary
|
||||
* was updated.
|
||||
* @param {RoomMember} member The room member that was updated.
|
||||
* @example
|
||||
* matrixClient.on("RoomState.members", function(event, state, member){
|
||||
* var newMembershipState = member.membership;
|
||||
* });
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fires whenever a member is added to the members dictionary. The RoomMember
|
||||
* will not be fully populated yet (e.g. no membership state) but will already
|
||||
* be available in the members dictionary.
|
||||
* @event module:client~MatrixClient#"RoomState.newMember"
|
||||
* @param {MatrixEvent} event The matrix event which caused this event to fire.
|
||||
* @param {RoomState} state The room state whose RoomState.members dictionary
|
||||
* was updated with a new entry.
|
||||
* @param {RoomMember} member The room member that was added.
|
||||
* @example
|
||||
* matrixClient.on("RoomState.newMember", function(event, state, member){
|
||||
* // add event listeners on 'member'
|
||||
* });
|
||||
*/
|
||||
|
@ -14,10 +14,6 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @module models/room-summary
|
||||
*/
|
||||
|
||||
export interface IRoomSummary {
|
||||
"m.heroes": string[];
|
||||
"m.joined_member_count"?: number;
|
||||
@ -25,25 +21,23 @@ export interface IRoomSummary {
|
||||
}
|
||||
|
||||
interface IInfo {
|
||||
/** The title of the room (e.g. `m.room.name`) */
|
||||
title: string;
|
||||
/** The description of the room (e.g. `m.room.topic`) */
|
||||
desc?: string;
|
||||
/** The number of joined users. */
|
||||
numMembers?: number;
|
||||
/** The list of aliases for this room. */
|
||||
aliases?: string[];
|
||||
/** The timestamp for this room. */
|
||||
timestamp?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new Room Summary. A summary can be used for display on a recent
|
||||
* list, without having to load the entire room list into memory.
|
||||
* @constructor
|
||||
* @param {string} roomId Required. The ID of this room.
|
||||
* @param {Object} info Optional. The summary info. Additional keys are supported.
|
||||
* @param {string} info.title The title of the room (e.g. <code>m.room.name</code>)
|
||||
* @param {string} info.desc The description of the room (e.g.
|
||||
* <code>m.room.topic</code>)
|
||||
* @param {Number} info.numMembers The number of joined users.
|
||||
* @param {string[]} info.aliases The list of aliases for this room.
|
||||
* @param {Number} info.timestamp The timestamp for this room.
|
||||
* @param roomId - Required. The ID of this room.
|
||||
* @param info - Optional. The summary info. Additional keys are supported.
|
||||
*/
|
||||
export class RoomSummary {
|
||||
public constructor(public readonly roomId: string, info?: IInfo) {}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -14,10 +14,6 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @module models/search-result
|
||||
*/
|
||||
|
||||
import { EventContext } from "./event-context";
|
||||
import { EventMapper } from "../event-mapper";
|
||||
import { IResultContext, ISearchResult } from "../@types/search";
|
||||
@ -25,10 +21,6 @@ import { IResultContext, ISearchResult } from "../@types/search";
|
||||
export class SearchResult {
|
||||
/**
|
||||
* Create a SearchResponse from the response to /search
|
||||
* @static
|
||||
* @param {Object} jsonObj
|
||||
* @param {function} eventMapper
|
||||
* @return {SearchResult}
|
||||
*/
|
||||
|
||||
public static fromJson(jsonObj: ISearchResult, eventMapper: EventMapper): SearchResult {
|
||||
@ -54,11 +46,9 @@ export class SearchResult {
|
||||
/**
|
||||
* Construct a new SearchResult
|
||||
*
|
||||
* @param {number} rank where this SearchResult ranks in the results
|
||||
* @param {event-context.EventContext} context the matching event and its
|
||||
* @param rank - where this SearchResult ranks in the results
|
||||
* @param context - the matching event and its
|
||||
* context
|
||||
*
|
||||
* @constructor
|
||||
*/
|
||||
public constructor(public readonly rank: number, public readonly context: EventContext) {}
|
||||
}
|
||||
|
@ -247,10 +247,10 @@ export class Thread extends ReadReceipt<EmittedEvents, EventHandlerMap> {
|
||||
* Add an event to the thread and updates
|
||||
* the tail/root references if needed
|
||||
* Will fire "Thread.update"
|
||||
* @param event The event to add
|
||||
* @param {boolean} toStartOfTimeline whether the event is being added
|
||||
* @param event - The event to add
|
||||
* @param toStartOfTimeline - whether the event is being added
|
||||
* to the start (and not the end) of the timeline.
|
||||
* @param {boolean} emit whether to emit the Update event if the thread was updated or not.
|
||||
* @param emit - whether to emit the Update event if the thread was updated or not.
|
||||
*/
|
||||
public async addEvent(event: MatrixEvent, toStartOfTimeline: boolean, emit = true): Promise<void> {
|
||||
this.setEventMetadata(event);
|
||||
|
@ -69,7 +69,7 @@ export class TypedEventEmitter<
|
||||
return super.listenerCount(event);
|
||||
}
|
||||
|
||||
public listeners(event: Events | EventEmitterEvents): Function[] {
|
||||
public listeners(event: Events | EventEmitterEvents): ReturnType<EventEmitter["listeners"]> {
|
||||
return super.listeners(event);
|
||||
}
|
||||
|
||||
@ -119,7 +119,7 @@ export class TypedEventEmitter<
|
||||
return super.removeListener(event, listener);
|
||||
}
|
||||
|
||||
public rawListeners(event: Events | EventEmitterEvents): Function[] {
|
||||
public rawListeners(event: Events | EventEmitterEvents): ReturnType<EventEmitter["rawListeners"]> {
|
||||
return super.rawListeners(event);
|
||||
}
|
||||
}
|
||||
|
@ -14,10 +14,6 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @module models/user
|
||||
*/
|
||||
|
||||
import { MatrixEvent } from "./event";
|
||||
import { TypedEventEmitter } from "./typed-event-emitter";
|
||||
|
||||
@ -30,51 +26,132 @@ export enum UserEvent {
|
||||
}
|
||||
|
||||
export type UserEventHandlerMap = {
|
||||
/**
|
||||
* Fires whenever any user's display name changes.
|
||||
* @param event - The matrix event which caused this event to fire.
|
||||
* @param user - The user whose User.displayName changed.
|
||||
* @example
|
||||
* ```
|
||||
* matrixClient.on("User.displayName", function(event, user){
|
||||
* var newName = user.displayName;
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
[UserEvent.DisplayName]: (event: MatrixEvent | undefined, user: User) => void;
|
||||
/**
|
||||
* Fires whenever any user's avatar URL changes.
|
||||
* @param event - The matrix event which caused this event to fire.
|
||||
* @param user - The user whose User.avatarUrl changed.
|
||||
* @example
|
||||
* ```
|
||||
* matrixClient.on("User.avatarUrl", function(event, user){
|
||||
* var newUrl = user.avatarUrl;
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
[UserEvent.AvatarUrl]: (event: MatrixEvent | undefined, user: User) => void;
|
||||
/**
|
||||
* Fires whenever any user's presence changes.
|
||||
* @param event - The matrix event which caused this event to fire.
|
||||
* @param user - The user whose User.presence changed.
|
||||
* @example
|
||||
* ```
|
||||
* matrixClient.on("User.presence", function(event, user){
|
||||
* var newPresence = user.presence;
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
[UserEvent.Presence]: (event: MatrixEvent | undefined, user: User) => void;
|
||||
/**
|
||||
* Fires whenever any user's currentlyActive changes.
|
||||
* @param event - The matrix event which caused this event to fire.
|
||||
* @param user - The user whose User.currentlyActive changed.
|
||||
* @example
|
||||
* ```
|
||||
* matrixClient.on("User.currentlyActive", function(event, user){
|
||||
* var newCurrentlyActive = user.currentlyActive;
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
[UserEvent.CurrentlyActive]: (event: MatrixEvent | undefined, user: User) => void;
|
||||
/**
|
||||
* Fires whenever any user's lastPresenceTs changes,
|
||||
* ie. whenever any presence event is received for a user.
|
||||
* @param event - The matrix event which caused this event to fire.
|
||||
* @param user - The user whose User.lastPresenceTs changed.
|
||||
* @example
|
||||
* ```
|
||||
* matrixClient.on("User.lastPresenceTs", function(event, user){
|
||||
* var newlastPresenceTs = user.lastPresenceTs;
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
[UserEvent.LastPresenceTs]: (event: MatrixEvent | undefined, user: User) => void;
|
||||
};
|
||||
|
||||
export class User extends TypedEventEmitter<UserEvent, UserEventHandlerMap> {
|
||||
private modified = -1;
|
||||
|
||||
// XXX these should be read-only
|
||||
/**
|
||||
* The 'displayname' of the user if known.
|
||||
* @privateRemarks
|
||||
* Should be read-only
|
||||
*/
|
||||
public displayName?: string;
|
||||
public rawDisplayName?: string;
|
||||
/**
|
||||
* The 'avatar_url' of the user if known.
|
||||
* @privateRemarks
|
||||
* Should be read-only
|
||||
*/
|
||||
public avatarUrl?: string;
|
||||
/**
|
||||
* The presence status message if known.
|
||||
* @privateRemarks
|
||||
* Should be read-only
|
||||
*/
|
||||
public presenceStatusMsg?: string;
|
||||
/**
|
||||
* The presence enum if known.
|
||||
* @privateRemarks
|
||||
* Should be read-only
|
||||
*/
|
||||
public presence = "offline";
|
||||
/**
|
||||
* Timestamp (ms since the epoch) for when we last received presence data for this user.
|
||||
* We can subtract lastActiveAgo from this to approximate an absolute value for when a user was last active.
|
||||
* @privateRemarks
|
||||
* Should be read-only
|
||||
*/
|
||||
public lastActiveAgo = 0;
|
||||
/**
|
||||
* The time elapsed in ms since the user interacted proactively with the server,
|
||||
* or we saw a message from the user
|
||||
* @privateRemarks
|
||||
* Should be read-only
|
||||
*/
|
||||
public lastPresenceTs = 0;
|
||||
/**
|
||||
* Whether we should consider lastActiveAgo to be an approximation
|
||||
* and that the user should be seen as active 'now'
|
||||
* @privateRemarks
|
||||
* Should be read-only
|
||||
*/
|
||||
public currentlyActive = false;
|
||||
/**
|
||||
* The events describing this user.
|
||||
* @privateRemarks
|
||||
* Should be read-only
|
||||
*/
|
||||
public events: {
|
||||
/** The m.presence event for this user. */
|
||||
presence?: MatrixEvent;
|
||||
profile?: MatrixEvent;
|
||||
} = {};
|
||||
|
||||
/**
|
||||
* Construct a new User. A User must have an ID and can optionally have extra
|
||||
* information associated with it.
|
||||
* @constructor
|
||||
* @param {string} userId Required. The ID of this user.
|
||||
* @prop {string} userId The ID of the user.
|
||||
* @prop {Object} info The info object supplied in the constructor.
|
||||
* @prop {string} displayName The 'displayname' of the user if known.
|
||||
* @prop {string} avatarUrl The 'avatar_url' of the user if known.
|
||||
* @prop {string} presence The presence enum if known.
|
||||
* @prop {string} presenceStatusMsg The presence status message if known.
|
||||
* @prop {Number} lastActiveAgo The time elapsed in ms since the user interacted
|
||||
* proactively with the server, or we saw a message from the user
|
||||
* @prop {Number} lastPresenceTs Timestamp (ms since the epoch) for when we last
|
||||
* received presence data for this user. We can subtract
|
||||
* lastActiveAgo from this to approximate an absolute value for
|
||||
* when a user was last active.
|
||||
* @prop {Boolean} currentlyActive Whether we should consider lastActiveAgo to be
|
||||
* an approximation and that the user should be seen as active 'now'
|
||||
* @prop {Object} events The events describing this user.
|
||||
* @prop {MatrixEvent} events.presence The m.presence event for this user.
|
||||
* Construct a new User. A User must have an ID and can optionally have extra information associated with it.
|
||||
* @param userId - Required. The ID of this user.
|
||||
*/
|
||||
public constructor(public readonly userId: string) {
|
||||
super();
|
||||
@ -87,10 +164,12 @@ export class User extends TypedEventEmitter<UserEvent, UserEventHandlerMap> {
|
||||
* Update this User with the given presence event. May fire "User.presence",
|
||||
* "User.avatarUrl" and/or "User.displayName" if this event updates this user's
|
||||
* properties.
|
||||
* @param {MatrixEvent} event The <code>m.presence</code> event.
|
||||
* @fires module:client~MatrixClient#event:"User.presence"
|
||||
* @fires module:client~MatrixClient#event:"User.displayName"
|
||||
* @fires module:client~MatrixClient#event:"User.avatarUrl"
|
||||
* @param event - The `m.presence` event.
|
||||
*
|
||||
* @remarks
|
||||
* Fires {@link UserEvent.Presence}
|
||||
* Fires {@link UserEvent.DisplayName}
|
||||
* Fires {@link UserEvent.AvatarUrl}
|
||||
*/
|
||||
public setPresenceEvent(event: MatrixEvent): void {
|
||||
if (event.getType() !== "m.presence") {
|
||||
@ -142,7 +221,7 @@ export class User extends TypedEventEmitter<UserEvent, UserEventHandlerMap> {
|
||||
/**
|
||||
* Manually set this user's display name. No event is emitted in response to this
|
||||
* as there is no underlying MatrixEvent to emit with.
|
||||
* @param {string} name The new display name.
|
||||
* @param name - The new display name.
|
||||
*/
|
||||
public setDisplayName(name: string): void {
|
||||
const oldName = this.displayName;
|
||||
@ -155,7 +234,7 @@ export class User extends TypedEventEmitter<UserEvent, UserEventHandlerMap> {
|
||||
/**
|
||||
* Manually set this user's non-disambiguated display name. No event is emitted
|
||||
* in response to this as there is no underlying MatrixEvent to emit with.
|
||||
* @param {string} name The new display name.
|
||||
* @param name - The new display name.
|
||||
*/
|
||||
public setRawDisplayName(name?: string): void {
|
||||
this.rawDisplayName = name;
|
||||
@ -164,7 +243,7 @@ export class User extends TypedEventEmitter<UserEvent, UserEventHandlerMap> {
|
||||
/**
|
||||
* Manually set this user's avatar URL. No event is emitted in response to this
|
||||
* as there is no underlying MatrixEvent to emit with.
|
||||
* @param {string} url The new avatar URL.
|
||||
* @param url - The new avatar URL.
|
||||
*/
|
||||
public setAvatarUrl(url?: string): void {
|
||||
const oldUrl = this.avatarUrl;
|
||||
@ -185,7 +264,7 @@ export class User extends TypedEventEmitter<UserEvent, UserEventHandlerMap> {
|
||||
* Get the timestamp when this User was last updated. This timestamp is
|
||||
* updated when this User receives a new Presence event which has updated a
|
||||
* property on this object. It is updated <i>before</i> firing events.
|
||||
* @return {number} The timestamp
|
||||
* @returns The timestamp
|
||||
*/
|
||||
public getLastModifiedTime(): number {
|
||||
return this.modified;
|
||||
@ -194,65 +273,9 @@ export class User extends TypedEventEmitter<UserEvent, UserEventHandlerMap> {
|
||||
/**
|
||||
* Get the absolute timestamp when this User was last known active on the server.
|
||||
* It is *NOT* accurate if this.currentlyActive is true.
|
||||
* @return {number} The timestamp
|
||||
* @returns The timestamp
|
||||
*/
|
||||
public getLastActiveTs(): number {
|
||||
return this.lastPresenceTs - this.lastActiveAgo;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires whenever any user's lastPresenceTs changes,
|
||||
* ie. whenever any presence event is received for a user.
|
||||
* @event module:client~MatrixClient#"User.lastPresenceTs"
|
||||
* @param {MatrixEvent} event The matrix event which caused this event to fire.
|
||||
* @param {User} user The user whose User.lastPresenceTs changed.
|
||||
* @example
|
||||
* matrixClient.on("User.lastPresenceTs", function(event, user){
|
||||
* var newlastPresenceTs = user.lastPresenceTs;
|
||||
* });
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fires whenever any user's presence changes.
|
||||
* @event module:client~MatrixClient#"User.presence"
|
||||
* @param {MatrixEvent} event The matrix event which caused this event to fire.
|
||||
* @param {User} user The user whose User.presence changed.
|
||||
* @example
|
||||
* matrixClient.on("User.presence", function(event, user){
|
||||
* var newPresence = user.presence;
|
||||
* });
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fires whenever any user's currentlyActive changes.
|
||||
* @event module:client~MatrixClient#"User.currentlyActive"
|
||||
* @param {MatrixEvent} event The matrix event which caused this event to fire.
|
||||
* @param {User} user The user whose User.currentlyActive changed.
|
||||
* @example
|
||||
* matrixClient.on("User.currentlyActive", function(event, user){
|
||||
* var newCurrentlyActive = user.currentlyActive;
|
||||
* });
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fires whenever any user's display name changes.
|
||||
* @event module:client~MatrixClient#"User.displayName"
|
||||
* @param {MatrixEvent} event The matrix event which caused this event to fire.
|
||||
* @param {User} user The user whose User.displayName changed.
|
||||
* @example
|
||||
* matrixClient.on("User.displayName", function(event, user){
|
||||
* var newName = user.displayName;
|
||||
* });
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fires whenever any user's avatar URL changes.
|
||||
* @event module:client~MatrixClient#"User.avatarUrl"
|
||||
* @param {MatrixEvent} event The matrix event which caused this event to fire.
|
||||
* @param {User} user The user whose User.avatarUrl changed.
|
||||
* @example
|
||||
* matrixClient.on("User.avatarUrl", function(event, user){
|
||||
* var newUrl = user.avatarUrl;
|
||||
* });
|
||||
*/
|
||||
|
@ -38,10 +38,6 @@ import {
|
||||
} from "./@types/PushRules";
|
||||
import { EventType } from "./@types/event";
|
||||
|
||||
/**
|
||||
* @module pushprocessor
|
||||
*/
|
||||
|
||||
const RULEKINDS_IN_ORDER = [
|
||||
PushRuleKind.Override,
|
||||
PushRuleKind.ContentSpecific,
|
||||
@ -116,25 +112,27 @@ const DEFAULT_UNDERRIDE_RULES: IPushRule[] = [
|
||||
];
|
||||
|
||||
export interface IActionsObject {
|
||||
/** Whether this event should notify the user or not. */
|
||||
notify: boolean;
|
||||
/** How this event should be notified. */
|
||||
tweaks: Partial<Record<TweakName, any>>;
|
||||
}
|
||||
|
||||
export class PushProcessor {
|
||||
/**
|
||||
* Construct a Push Processor.
|
||||
* @constructor
|
||||
* @param {Object} client The Matrix client object to use
|
||||
* @param client - The Matrix client object to use
|
||||
*/
|
||||
public constructor(private readonly client: MatrixClient) {}
|
||||
|
||||
/**
|
||||
* Convert a list of actions into a object with the actions as keys and their values
|
||||
* eg. [ 'notify', { set_tweak: 'sound', value: 'default' } ]
|
||||
* becomes { notify: true, tweaks: { sound: 'default' } }
|
||||
* @param {array} actionList The actions list
|
||||
* @example
|
||||
* eg. `[ 'notify', { set_tweak: 'sound', value: 'default' } ]`
|
||||
* becomes `{ notify: true, tweaks: { sound: 'default' } }`
|
||||
* @param actionList - The actions list
|
||||
*
|
||||
* @return {object} A object with key 'notify' (true or false) and an object of actions
|
||||
* @returns A object with key 'notify' (true or false) and an object of actions
|
||||
*/
|
||||
public static actionListToActionsObject(actionList: PushRuleAction[]): IActionsObject {
|
||||
const actionObj: IActionsObject = { notify: false, tweaks: {} };
|
||||
@ -155,8 +153,8 @@ export class PushProcessor {
|
||||
* Rewrites conditions on a client's push rules to match the defaults
|
||||
* where applicable. Useful for upgrading push rules to more strict
|
||||
* conditions when the server is falling behind on defaults.
|
||||
* @param {object} incomingRules The client's existing push rules
|
||||
* @returns {object} The rewritten rules
|
||||
* @param incomingRules - The client's existing push rules
|
||||
* @returns The rewritten rules
|
||||
*/
|
||||
public static rewriteDefaultRules(incomingRules: IPushRules): IPushRules {
|
||||
let newRules: IPushRules = JSON.parse(JSON.stringify(incomingRules)); // deep clone
|
||||
@ -502,10 +500,6 @@ export class PushProcessor {
|
||||
|
||||
/**
|
||||
* Get the user's push actions for the given event
|
||||
*
|
||||
* @param {module:models/event.MatrixEvent} ev
|
||||
*
|
||||
* @return {PushAction}
|
||||
*/
|
||||
public actionsForEvent(ev: MatrixEvent): IActionsObject {
|
||||
return this.pushActionsForEventAndRulesets(ev, this.client.pushRules);
|
||||
@ -514,8 +508,8 @@ export class PushProcessor {
|
||||
/**
|
||||
* Get one of the users push rules by its ID
|
||||
*
|
||||
* @param {string} ruleId The ID of the rule to search for
|
||||
* @return {object} The push rule, or null if no such rule was found
|
||||
* @param ruleId - The ID of the rule to search for
|
||||
* @returns The push rule, or null if no such rule was found
|
||||
*/
|
||||
public getPushRuleById(ruleId: string): IPushRule | null {
|
||||
for (const scope of ['global'] as const) {
|
||||
@ -532,15 +526,3 @@ export class PushProcessor {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} PushAction
|
||||
* @type {Object}
|
||||
* @property {boolean} notify Whether this event should notify the user or not.
|
||||
* @property {Object} tweaks How this event should be notified.
|
||||
* @property {boolean} tweaks.highlight Whether this event should be highlighted
|
||||
* on the UI.
|
||||
* @property {boolean} tweaks.sound Whether this notification should produce a
|
||||
* noise.
|
||||
*/
|
||||
|
||||
|
@ -48,16 +48,17 @@ type Callback = {
|
||||
const callbackList: Callback[] = [];
|
||||
|
||||
// var debuglog = logger.log.bind(logger);
|
||||
/* istanbul ignore next */
|
||||
const debuglog = function(...params: any[]): void {};
|
||||
|
||||
/**
|
||||
* reimplementation of window.setTimeout, which will call the callback if
|
||||
* the wallclock time goes past the deadline.
|
||||
*
|
||||
* @param {function} func callback to be called after a delay
|
||||
* @param {Number} delayMs number of milliseconds to delay by
|
||||
* @param func - callback to be called after a delay
|
||||
* @param delayMs - number of milliseconds to delay by
|
||||
*
|
||||
* @return {Number} an identifier for this callback, which may be passed into
|
||||
* @returns an identifier for this callback, which may be passed into
|
||||
* clearTimeout later.
|
||||
*/
|
||||
export function setTimeout(func: (...params: any[]) => void, delayMs: number, ...params: any[]): number {
|
||||
@ -93,7 +94,7 @@ export function setTimeout(func: (...params: any[]) => void, delayMs: number, ..
|
||||
/**
|
||||
* reimplementation of window.clearTimeout, which mirrors setTimeout
|
||||
*
|
||||
* @param {Number} key result from an earlier setTimeout call
|
||||
* @param key - result from an earlier setTimeout call
|
||||
*/
|
||||
export function clearTimeout(key: number): void {
|
||||
if (callbackList.length === 0) {
|
||||
|
@ -67,9 +67,9 @@ export class MSC3906Rendezvous {
|
||||
private _code?: string;
|
||||
|
||||
/**
|
||||
* @param channel The secure channel used for communication
|
||||
* @param client The Matrix client in used on the device already logged in
|
||||
* @param onFailure Callback for when the rendezvous fails
|
||||
* @param channel - The secure channel used for communication
|
||||
* @param client - The Matrix client in used on the device already logged in
|
||||
* @param onFailure - Callback for when the rendezvous fails
|
||||
*/
|
||||
public constructor(
|
||||
private channel: RendezvousChannel<MSC3906RendezvousPayload>,
|
||||
@ -217,7 +217,7 @@ export class MSC3906Rendezvous {
|
||||
|
||||
/**
|
||||
* Verify the device and cross-sign it.
|
||||
* @param timeout time in milliseconds to wait for device to come online
|
||||
* @param timeout - time in milliseconds to wait for device to come online
|
||||
* @returns the new device info if the device was verified
|
||||
*/
|
||||
public async verifyNewDeviceOnExistingDevice(
|
||||
|
@ -28,7 +28,7 @@ export interface RendezvousChannel<T> {
|
||||
|
||||
/**
|
||||
* Send a payload via the channel.
|
||||
* @param data payload to send
|
||||
* @param data - payload to send
|
||||
*/
|
||||
send(data: T): Promise<void>;
|
||||
|
||||
|
@ -41,7 +41,7 @@ export interface RendezvousTransport<T> {
|
||||
|
||||
/**
|
||||
* Send data via the transport.
|
||||
* @param data the data itself
|
||||
* @param data - the data itself
|
||||
*/
|
||||
send(data: T): Promise<void>;
|
||||
|
||||
@ -52,7 +52,7 @@ export interface RendezvousTransport<T> {
|
||||
|
||||
/**
|
||||
* Cancel the rendezvous. This will call `onCancelled()` if it is set.
|
||||
* @param reason the reason for the cancellation/failure
|
||||
* @param reason - the reason for the cancellation/failure
|
||||
*/
|
||||
cancel(reason: RendezvousFailureReason): Promise<void>;
|
||||
}
|
||||
|
@ -14,10 +14,6 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @module room-hierarchy
|
||||
*/
|
||||
|
||||
import { Room } from "./models/room";
|
||||
import { IHierarchyRoom, IHierarchyRelation } from "./@types/spaces";
|
||||
import { MatrixClient } from "./client";
|
||||
@ -41,11 +37,10 @@ export class RoomHierarchy {
|
||||
*
|
||||
* A RoomHierarchy instance allows you to easily make use of the /hierarchy API and paginate it.
|
||||
*
|
||||
* @param {Room} root the root of this hierarchy
|
||||
* @param {number} pageSize the maximum number of rooms to return per page, can be overridden per load request.
|
||||
* @param {number} maxDepth the maximum depth to traverse the hierarchy to
|
||||
* @param {boolean} suggestedOnly whether to only return rooms with suggested=true.
|
||||
* @constructor
|
||||
* @param root - the root of this hierarchy
|
||||
* @param pageSize - the maximum number of rooms to return per page, can be overridden per load request.
|
||||
* @param maxDepth - the maximum depth to traverse the hierarchy to
|
||||
* @param suggestedOnly - whether to only return rooms with suggested=true.
|
||||
*/
|
||||
public constructor(
|
||||
public readonly root: Room,
|
||||
|
120
src/scheduler.ts
120
src/scheduler.ts
@ -17,7 +17,6 @@ limitations under the License.
|
||||
/**
|
||||
* This is an internal module which manages queuing, scheduling and retrying
|
||||
* of requests.
|
||||
* @module scheduler
|
||||
*/
|
||||
import * as utils from "./utils";
|
||||
import { logger } from './logger';
|
||||
@ -35,20 +34,13 @@ interface IQueueEntry<T> {
|
||||
attempts: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* The function to invoke to process (send) events in the queue.
|
||||
* @param event - The event to send.
|
||||
* @returns Resolved/rejected depending on the outcome of the request.
|
||||
*/
|
||||
type ProcessFunction<T> = (event: MatrixEvent) => Promise<T>;
|
||||
|
||||
/**
|
||||
* Construct a scheduler for Matrix. Requires
|
||||
* {@link module:scheduler~MatrixScheduler#setProcessFunction} to be provided
|
||||
* with a way of processing events.
|
||||
* @constructor
|
||||
* @param {module:scheduler~retryAlgorithm} retryAlgorithm Optional. The retry
|
||||
* algorithm to apply when determining when to try to send an event again.
|
||||
* Defaults to {@link module:scheduler~MatrixScheduler.RETRY_BACKOFF_RATELIMIT}.
|
||||
* @param {module:scheduler~queueAlgorithm} queueAlgorithm Optional. The queuing
|
||||
* algorithm to apply when determining which events should be sent before the
|
||||
* given event. Defaults to {@link module:scheduler~MatrixScheduler.QUEUE_MESSAGES}.
|
||||
*/
|
||||
// eslint-disable-next-line camelcase
|
||||
export class MatrixScheduler<T = ISendEventResponse> {
|
||||
/**
|
||||
@ -56,11 +48,8 @@ export class MatrixScheduler<T = ISendEventResponse> {
|
||||
* times of 2, 4, 8, and 16 seconds (30s total) after which we give up. If the
|
||||
* failure was due to a rate limited request, the time specified in the error is
|
||||
* waited before being retried.
|
||||
* @param {MatrixEvent} event
|
||||
* @param {Number} attempts Number of attempts that have been made, including the one that just failed (ie. starting at 1)
|
||||
* @param {MatrixError} err
|
||||
* @return {Number}
|
||||
* @see module:scheduler~retryAlgorithm
|
||||
* @param attempts - Number of attempts that have been made, including the one that just failed (ie. starting at 1)
|
||||
* @see retryAlgorithm
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
public static RETRY_BACKOFF_RATELIMIT(event: MatrixEvent | null, attempts: number, err: MatrixError): number {
|
||||
@ -90,11 +79,9 @@ export class MatrixScheduler<T = ISendEventResponse> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Queues <code>m.room.message</code> events and lets other events continue
|
||||
* Queues `m.room.message` events and lets other events continue
|
||||
* concurrently.
|
||||
* @param {MatrixEvent} event
|
||||
* @return {string}
|
||||
* @see module:scheduler~queueAlgorithm
|
||||
* @see queueAlgorithm
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
public static QUEUE_MESSAGES(event: MatrixEvent): string | null {
|
||||
@ -116,16 +103,52 @@ export class MatrixScheduler<T = ISendEventResponse> {
|
||||
private activeQueues: string[] = [];
|
||||
private procFn: ProcessFunction<T> | null = null;
|
||||
|
||||
/**
|
||||
* Construct a scheduler for Matrix. Requires
|
||||
* {@link MatrixScheduler#setProcessFunction} to be provided
|
||||
* with a way of processing events.
|
||||
* @param retryAlgorithm - Optional. The retry
|
||||
* algorithm to apply when determining when to try to send an event again.
|
||||
* Defaults to {@link MatrixScheduler.RETRY_BACKOFF_RATELIMIT}.
|
||||
* @param queueAlgorithm - Optional. The queuing
|
||||
* algorithm to apply when determining which events should be sent before the
|
||||
* given event. Defaults to {@link MatrixScheduler.QUEUE_MESSAGES}.
|
||||
*/
|
||||
public constructor(
|
||||
/**
|
||||
* The retry algorithm to apply when retrying events. To stop retrying, return
|
||||
* `-1`. If this event was part of a queue, it will be removed from
|
||||
* the queue.
|
||||
* @param event - The event being retried.
|
||||
* @param attempts - The number of failed attempts. This will always be \>= 1.
|
||||
* @param err - The most recent error message received when trying
|
||||
* to send this event.
|
||||
* @returns The number of milliseconds to wait before trying again. If
|
||||
* this is 0, the request will be immediately retried. If this is
|
||||
* `-1`, the event will be marked as
|
||||
* {@link EventStatus.NOT_SENT} and will not be retried.
|
||||
*/
|
||||
public readonly retryAlgorithm = MatrixScheduler.RETRY_BACKOFF_RATELIMIT,
|
||||
/**
|
||||
* The queuing algorithm to apply to events. This function must be idempotent as
|
||||
* it may be called multiple times with the same event. All queues created are
|
||||
* serviced in a FIFO manner. To send the event ASAP, return `null`
|
||||
* which will not put this event in a queue. Events that fail to send that form
|
||||
* part of a queue will be removed from the queue and the next event in the
|
||||
* queue will be sent.
|
||||
* @param event - The event to be sent.
|
||||
* @returns The name of the queue to put the event into. If a queue with
|
||||
* this name does not exist, it will be created. If this is `null`,
|
||||
* the event is not put into a queue and will be sent concurrently.
|
||||
*/
|
||||
public readonly queueAlgorithm = MatrixScheduler.QUEUE_MESSAGES,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Retrieve a queue based on an event. The event provided does not need to be in
|
||||
* the queue.
|
||||
* @param {MatrixEvent} event An event to get the queue for.
|
||||
* @return {?Array<MatrixEvent>} A shallow copy of events in the queue or null.
|
||||
* @param event - An event to get the queue for.
|
||||
* @returns A shallow copy of events in the queue or null.
|
||||
* Modifying this array will not modify the list itself. Modifying events in
|
||||
* this array <i>will</i> modify the underlying event in the queue.
|
||||
* @see MatrixScheduler.removeEventFromQueue To remove an event from the queue.
|
||||
@ -143,8 +166,8 @@ export class MatrixScheduler<T = ISendEventResponse> {
|
||||
/**
|
||||
* Remove this event from the queue. The event is equal to another event if they
|
||||
* have the same ID returned from event.getId().
|
||||
* @param {MatrixEvent} event The event to remove.
|
||||
* @return {boolean} True if this event was removed.
|
||||
* @param event - The event to remove.
|
||||
* @returns True if this event was removed.
|
||||
*/
|
||||
public removeEventFromQueue(event: MatrixEvent): boolean {
|
||||
const name = this.queueAlgorithm(event);
|
||||
@ -168,7 +191,7 @@ export class MatrixScheduler<T = ISendEventResponse> {
|
||||
* Set the process function. Required for events in the queue to be processed.
|
||||
* If set after events have been added to the queue, this will immediately start
|
||||
* processing them.
|
||||
* @param {module:scheduler~processFn} fn The function that can process events
|
||||
* @param fn - The function that can process events
|
||||
* in the queue.
|
||||
*/
|
||||
public setProcessFunction(fn: ProcessFunction<T>): void {
|
||||
@ -178,8 +201,8 @@ export class MatrixScheduler<T = ISendEventResponse> {
|
||||
|
||||
/**
|
||||
* Queue an event if it is required and start processing queues.
|
||||
* @param {MatrixEvent} event The event that may be queued.
|
||||
* @return {?Promise} A promise if the event was queued, which will be
|
||||
* @param event - The event that may be queued.
|
||||
* @returns A promise if the event was queued, which will be
|
||||
* resolved or rejected in due time, else null.
|
||||
*/
|
||||
public queueEvent(event: MatrixEvent): Promise<T> | null {
|
||||
@ -283,46 +306,9 @@ export class MatrixScheduler<T = ISendEventResponse> {
|
||||
}
|
||||
}
|
||||
|
||||
/* istanbul ignore next */
|
||||
function debuglog(...args: any[]): void {
|
||||
if (DEBUG) {
|
||||
logger.log(...args);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The retry algorithm to apply when retrying events. To stop retrying, return
|
||||
* <code>-1</code>. If this event was part of a queue, it will be removed from
|
||||
* the queue.
|
||||
* @callback retryAlgorithm
|
||||
* @param {MatrixEvent} event The event being retried.
|
||||
* @param {Number} attempts The number of failed attempts. This will always be
|
||||
* >= 1.
|
||||
* @param {MatrixError} err The most recent error message received when trying
|
||||
* to send this event.
|
||||
* @return {Number} The number of milliseconds to wait before trying again. If
|
||||
* this is 0, the request will be immediately retried. If this is
|
||||
* <code>-1</code>, the event will be marked as
|
||||
* {@link module:models/event.EventStatus.NOT_SENT} and will not be retried.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The queuing algorithm to apply to events. This function must be idempotent as
|
||||
* it may be called multiple times with the same event. All queues created are
|
||||
* serviced in a FIFO manner. To send the event ASAP, return <code>null</code>
|
||||
* which will not put this event in a queue. Events that fail to send that form
|
||||
* part of a queue will be removed from the queue and the next event in the
|
||||
* queue will be sent.
|
||||
* @callback queueAlgorithm
|
||||
* @param {MatrixEvent} event The event to be sent.
|
||||
* @return {string} The name of the queue to put the event into. If a queue with
|
||||
* this name does not exist, it will be created. If this is <code>null</code>,
|
||||
* the event is not put into a queue and will be sent concurrently.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The function to invoke to process (send) events in the queue.
|
||||
* @callback processFn
|
||||
* @param {MatrixEvent} event The event to send.
|
||||
* @return {Promise} Resolved/rejected depending on the outcome of the request.
|
||||
*/
|
||||
|
||||
|
@ -458,7 +458,7 @@ export class SlidingSyncSdk {
|
||||
|
||||
/**
|
||||
* Sync rooms the user has left.
|
||||
* @return {Promise} Resolved when they've been added to the store.
|
||||
* @returns Resolved when they've been added to the store.
|
||||
*/
|
||||
public async syncLeftRooms(): Promise<Room[]> {
|
||||
return []; // TODO
|
||||
@ -467,8 +467,8 @@ export class SlidingSyncSdk {
|
||||
/**
|
||||
* Peek into a room. This will result in the room in question being synced so it
|
||||
* is accessible via getRooms(). Live updates for the room will be provided.
|
||||
* @param {string} roomId The room ID to peek into.
|
||||
* @return {Promise} A promise which resolves once the room has been added to the
|
||||
* @param roomId - The room ID to peek into.
|
||||
* @returns A promise which resolves once the room has been added to the
|
||||
* store.
|
||||
*/
|
||||
public async peek(_roomId: string): Promise<Room> {
|
||||
@ -485,8 +485,7 @@ export class SlidingSyncSdk {
|
||||
|
||||
/**
|
||||
* Returns the current state of this sync object
|
||||
* @see module:client~MatrixClient#event:"sync"
|
||||
* @return {?String}
|
||||
* @see MatrixClient#event:"sync"
|
||||
*/
|
||||
public getSyncState(): SyncState | null {
|
||||
return this.syncState;
|
||||
@ -498,7 +497,6 @@ export class SlidingSyncSdk {
|
||||
* such data.
|
||||
* Sync errors, if available, are put in the 'error' key of
|
||||
* this object.
|
||||
* @return {?Object}
|
||||
*/
|
||||
public getSyncStateData(): ISyncStateData | null {
|
||||
return this.syncStateData ?? null;
|
||||
@ -765,12 +763,11 @@ export class SlidingSyncSdk {
|
||||
|
||||
/**
|
||||
* Injects events into a room's model.
|
||||
* @param {Room} room
|
||||
* @param {MatrixEvent[]} stateEventList A list of state events. This is the state
|
||||
* @param stateEventList - A list of state events. This is the state
|
||||
* at the *START* of the timeline list if it is supplied.
|
||||
* @param {MatrixEvent[]} [timelineEventList] A list of timeline events. Lower index
|
||||
* @param timelineEventList - A list of timeline events. Lower index
|
||||
* is earlier in time. Higher index is later.
|
||||
* @param {number} numLive the number of events in timelineEventList which just happened,
|
||||
* @param numLive - the number of events in timelineEventList which just happened,
|
||||
* supplied from the server.
|
||||
*/
|
||||
public injectRoomEvents(
|
||||
@ -933,8 +930,8 @@ export class SlidingSyncSdk {
|
||||
|
||||
/**
|
||||
* Sets the sync state and emits an event to say so
|
||||
* @param {String} newState The new state string
|
||||
* @param {Object} data Object of additional data to emit in the event
|
||||
* @param newState - The new state string
|
||||
* @param data - Object of additional data to emit in the event
|
||||
*/
|
||||
private updateSyncState(newState: SyncState, data?: ISyncStateData): void {
|
||||
const old = this.syncState;
|
||||
@ -948,7 +945,7 @@ export class SlidingSyncSdk {
|
||||
* as appropriate.
|
||||
* This must be called after the room the events belong to has been stored.
|
||||
*
|
||||
* @param {MatrixEvent[]} [timelineEventList] A list of timeline events. Lower index
|
||||
* @param timelineEventList - A list of timeline events. Lower index
|
||||
* is earlier in time. Higher index is later.
|
||||
*/
|
||||
private addNotifications(timelineEventList: MatrixEvent[]): void {
|
||||
|
@ -156,7 +156,7 @@ export enum SlidingSyncState {
|
||||
|
||||
/**
|
||||
* Internal Class. SlidingList represents a single list in sliding sync. The list can have filters,
|
||||
* multiple sliding windows, and maintains the index->room_id mapping.
|
||||
* multiple sliding windows, and maintains the index-\>room_id mapping.
|
||||
*/
|
||||
class SlidingList {
|
||||
private list!: MSC3575List;
|
||||
@ -168,7 +168,7 @@ class SlidingList {
|
||||
|
||||
/**
|
||||
* Construct a new sliding list.
|
||||
* @param {MSC3575List} list The range, sort and filter values to use for this list.
|
||||
* @param list - The range, sort and filter values to use for this list.
|
||||
*/
|
||||
public constructor(list: MSC3575List) {
|
||||
this.replaceList(list);
|
||||
@ -177,7 +177,7 @@ class SlidingList {
|
||||
/**
|
||||
* Mark this list as modified or not. Modified lists will return sticky params with calls to getList.
|
||||
* This is useful for the first time the list is sent, or if the list has changed in some way.
|
||||
* @param modified True to mark this list as modified so all sticky parameters will be re-sent.
|
||||
* @param modified - True to mark this list as modified so all sticky parameters will be re-sent.
|
||||
*/
|
||||
public setModified(modified: boolean): void {
|
||||
this.isModified = modified;
|
||||
@ -185,7 +185,7 @@ class SlidingList {
|
||||
|
||||
/**
|
||||
* Update the list range for this list. Does not affect modified status as list ranges are non-sticky.
|
||||
* @param newRanges The new ranges for the list
|
||||
* @param newRanges - The new ranges for the list
|
||||
*/
|
||||
public updateListRange(newRanges: number[][]): void {
|
||||
this.list.ranges = JSON.parse(JSON.stringify(newRanges));
|
||||
@ -193,7 +193,7 @@ class SlidingList {
|
||||
|
||||
/**
|
||||
* Replace list parameters. All fields will be replaced with the new list parameters.
|
||||
* @param list The new list parameters
|
||||
* @param list - The new list parameters
|
||||
*/
|
||||
public replaceList(list: MSC3575List): void {
|
||||
list.filters = list.filters || {};
|
||||
@ -213,7 +213,7 @@ class SlidingList {
|
||||
|
||||
/**
|
||||
* Return a copy of the list suitable for a request body.
|
||||
* @param {boolean} forceIncludeAllParams True to forcibly include all params even if the list
|
||||
* @param forceIncludeAllParams - True to forcibly include all params even if the list
|
||||
* hasn't been modified. Callers may want to do this if they are modifying the list prior to calling
|
||||
* updateList.
|
||||
*/
|
||||
@ -235,7 +235,7 @@ class SlidingList {
|
||||
* a b c d _ f COMMAND: DELETE 7;
|
||||
* e a b c d f COMMAND: INSERT 0 e;
|
||||
* c=3 is wrong as we are not tracking it, ergo we need to see if `i` is in range else drop it
|
||||
* @param i The index to check
|
||||
* @param i - The index to check
|
||||
* @returns True if the index is within a sliding window
|
||||
*/
|
||||
public isIndexInRange(i: number): boolean {
|
||||
@ -274,13 +274,13 @@ export interface Extension<Req extends {}, Res extends {}> {
|
||||
/**
|
||||
* A function which is called when the request JSON is being formed.
|
||||
* Returns the data to insert under this key.
|
||||
* @param isInitial True when this is part of the initial request (send sticky params)
|
||||
* @param isInitial - True when this is part of the initial request (send sticky params)
|
||||
* @returns The request JSON to send.
|
||||
*/
|
||||
onRequest(isInitial: boolean): Req | undefined;
|
||||
/**
|
||||
* A function which is called when there is response JSON under this extension.
|
||||
* @param data The response JSON under the extension name.
|
||||
* @param data - The response JSON under the extension name.
|
||||
*/
|
||||
onResponse(data: Res): void;
|
||||
/**
|
||||
@ -368,11 +368,11 @@ export class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, SlidingSync
|
||||
|
||||
/**
|
||||
* Create a new sliding sync instance
|
||||
* @param {string} proxyBaseUrl The base URL of the sliding sync proxy
|
||||
* @param {MSC3575List[]} lists The lists to use for sliding sync.
|
||||
* @param {MSC3575RoomSubscription} roomSubscriptionInfo The params to use for room subscriptions.
|
||||
* @param {MatrixClient} client The client to use for /sync calls.
|
||||
* @param {number} timeoutMS The number of milliseconds to wait for a response.
|
||||
* @param proxyBaseUrl - The base URL of the sliding sync proxy
|
||||
* @param lists - The lists to use for sliding sync.
|
||||
* @param roomSubscriptionInfo - The params to use for room subscriptions.
|
||||
* @param client - The client to use for /sync calls.
|
||||
* @param timeoutMS - The number of milliseconds to wait for a response.
|
||||
*/
|
||||
public constructor(
|
||||
private readonly proxyBaseUrl: string,
|
||||
@ -388,9 +388,9 @@ export class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, SlidingSync
|
||||
/**
|
||||
* Add a custom room subscription, referred to by an arbitrary name. If a subscription with this
|
||||
* name already exists, it is replaced. No requests are sent by calling this method.
|
||||
* @param name The name of the subscription. Only used to reference this subscription in
|
||||
* @param name - The name of the subscription. Only used to reference this subscription in
|
||||
* useCustomSubscription.
|
||||
* @param sub The subscription information.
|
||||
* @param sub - The subscription information.
|
||||
*/
|
||||
public addCustomSubscription(name: string, sub: MSC3575RoomSubscription): void {
|
||||
this.customSubscriptions.set(name, sub);
|
||||
@ -399,8 +399,8 @@ export class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, SlidingSync
|
||||
/**
|
||||
* Use a custom subscription previously added via addCustomSubscription. No requests are sent
|
||||
* by calling this method. Use modifyRoomSubscriptions to resend subscription information.
|
||||
* @param roomId The room to use the subscription in.
|
||||
* @param name The name of the subscription. If this name is unknown, the default subscription
|
||||
* @param roomId - The room to use the subscription in.
|
||||
* @param name - The name of the subscription. If this name is unknown, the default subscription
|
||||
* will be used.
|
||||
*/
|
||||
public useCustomSubscription(roomId: string, name: string): void {
|
||||
@ -419,7 +419,7 @@ export class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, SlidingSync
|
||||
|
||||
/**
|
||||
* Get the room data for a list.
|
||||
* @param index The list index
|
||||
* @param index - The list index
|
||||
* @returns The list data which contains the rooms in this list
|
||||
*/
|
||||
public getListData(index: number): {joinedCount: number, roomIndexToRoomId: Record<number, string>} | null {
|
||||
@ -435,7 +435,7 @@ export class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, SlidingSync
|
||||
/**
|
||||
* Get the full list parameters for a list index. This function is provided for callers to use
|
||||
* in conjunction with setList to update fields on an existing list.
|
||||
* @param index The list index to get the list for.
|
||||
* @param index - The list index to get the list for.
|
||||
* @returns A copy of the list or undefined.
|
||||
*/
|
||||
public getList(index: number): MSC3575List | null {
|
||||
@ -449,9 +449,9 @@ export class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, SlidingSync
|
||||
* Set new ranges for an existing list. Calling this function when _only_ the ranges have changed
|
||||
* is more efficient than calling setList(index,list) as this function won't resend sticky params,
|
||||
* whereas setList always will.
|
||||
* @param index The list index to modify
|
||||
* @param ranges The new ranges to apply.
|
||||
* @return A promise which resolves to the transaction ID when it has been received down sync
|
||||
* @param index - The list index to modify
|
||||
* @param ranges - The new ranges to apply.
|
||||
* @returns A promise which resolves to the transaction ID when it has been received down sync
|
||||
* (or rejects with the transaction ID if the action was not applied e.g the request was cancelled
|
||||
* immediately after sending, in which case the action will be applied in the subsequent request)
|
||||
*/
|
||||
@ -463,9 +463,9 @@ export class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, SlidingSync
|
||||
/**
|
||||
* Add or replace a list. Calling this function will interrupt the /sync request to resend new
|
||||
* lists.
|
||||
* @param index The index to modify
|
||||
* @param list The new list parameters.
|
||||
* @return A promise which resolves to the transaction ID when it has been received down sync
|
||||
* @param index - The index to modify
|
||||
* @param list - The new list parameters.
|
||||
* @returns A promise which resolves to the transaction ID when it has been received down sync
|
||||
* (or rejects with the transaction ID if the action was not applied e.g the request was cancelled
|
||||
* immediately after sending, in which case the action will be applied in the subsequent request)
|
||||
*/
|
||||
@ -491,8 +491,8 @@ export class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, SlidingSync
|
||||
* Modify the room subscriptions for the sync API. Calling this function will interrupt the
|
||||
* /sync request to resend new subscriptions. If the /sync stream has not started, this will
|
||||
* prepare the room subscriptions for when start() is called.
|
||||
* @param s The new desired room subscriptions.
|
||||
* @return A promise which resolves to the transaction ID when it has been received down sync
|
||||
* @param s - The new desired room subscriptions.
|
||||
* @returns A promise which resolves to the transaction ID when it has been received down sync
|
||||
* (or rejects with the transaction ID if the action was not applied e.g the request was cancelled
|
||||
* immediately after sending, in which case the action will be applied in the subsequent request)
|
||||
*/
|
||||
@ -504,8 +504,8 @@ export class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, SlidingSync
|
||||
/**
|
||||
* Modify which events to retrieve for room subscriptions. Invalidates all room subscriptions
|
||||
* such that they will be sent up afresh.
|
||||
* @param rs The new room subscription fields to fetch.
|
||||
* @return A promise which resolves to the transaction ID when it has been received down sync
|
||||
* @param rs - The new room subscription fields to fetch.
|
||||
* @returns A promise which resolves to the transaction ID when it has been received down sync
|
||||
* (or rejects with the transaction ID if the action was not applied e.g the request was cancelled
|
||||
* immediately after sending, in which case the action will be applied in the subsequent request)
|
||||
*/
|
||||
@ -517,7 +517,7 @@ export class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, SlidingSync
|
||||
|
||||
/**
|
||||
* Register an extension to send with the /sync request.
|
||||
* @param ext The extension to register.
|
||||
* @param ext - The extension to register.
|
||||
*/
|
||||
public registerExtension(ext: Extension<any, any>): void {
|
||||
if (this.extensions[ext.name()]) {
|
||||
@ -552,8 +552,8 @@ export class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, SlidingSync
|
||||
|
||||
/**
|
||||
* Invoke all attached room data listeners.
|
||||
* @param {string} roomId The room which received some data.
|
||||
* @param {object} roomData The raw sliding sync response JSON.
|
||||
* @param roomId - The room which received some data.
|
||||
* @param roomData - The raw sliding sync response JSON.
|
||||
*/
|
||||
private invokeRoomDataListeners(roomId: string, roomData: MSC3575RoomData): void {
|
||||
if (!roomData.required_state) { roomData.required_state = []; }
|
||||
@ -563,9 +563,9 @@ export class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, SlidingSync
|
||||
|
||||
/**
|
||||
* Invoke all attached lifecycle listeners.
|
||||
* @param {SlidingSyncState} state The Lifecycle state
|
||||
* @param {object} resp The raw sync response JSON
|
||||
* @param {Error?} err Any error that occurred when making the request e.g. network errors.
|
||||
* @param state - The Lifecycle state
|
||||
* @param resp - The raw sync response JSON
|
||||
* @param err - Any error that occurred when making the request e.g. network errors.
|
||||
*/
|
||||
private invokeLifecycleListeners(
|
||||
state: SlidingSyncState,
|
||||
|
@ -42,141 +42,133 @@ export interface IStore {
|
||||
// for when it falls back to being a memory store due to errors.
|
||||
on?: (event: EventEmitterEvents | "degraded", handler: (...args: any[]) => void) => void;
|
||||
|
||||
/** @return {Promise<boolean>} whether or not the database was newly created in this session. */
|
||||
/** @returns whether or not the database was newly created in this session. */
|
||||
isNewlyCreated(): Promise<boolean>;
|
||||
|
||||
/**
|
||||
* Get the sync token.
|
||||
* @return {string}
|
||||
*/
|
||||
getSyncToken(): string | null;
|
||||
|
||||
/**
|
||||
* Set the sync token.
|
||||
* @param {string} token
|
||||
*/
|
||||
setSyncToken(token: string): void;
|
||||
|
||||
/**
|
||||
* Store the given room.
|
||||
* @param {Room} room The room to be stored. All properties must be stored.
|
||||
* @param room - The room to be stored. All properties must be stored.
|
||||
*/
|
||||
storeRoom(room: Room): void;
|
||||
|
||||
/**
|
||||
* Retrieve a room by its' room ID.
|
||||
* @param {string} roomId The room ID.
|
||||
* @return {Room} The room or null.
|
||||
* @param roomId - The room ID.
|
||||
* @returns The room or null.
|
||||
*/
|
||||
getRoom(roomId: string): Room | null;
|
||||
|
||||
/**
|
||||
* Retrieve all known rooms.
|
||||
* @return {Room[]} A list of rooms, which may be empty.
|
||||
* @returns A list of rooms, which may be empty.
|
||||
*/
|
||||
getRooms(): Room[];
|
||||
|
||||
/**
|
||||
* Permanently delete a room.
|
||||
* @param {string} roomId
|
||||
*/
|
||||
removeRoom(roomId: string): void;
|
||||
|
||||
/**
|
||||
* Retrieve a summary of all the rooms.
|
||||
* @return {RoomSummary[]} A summary of each room.
|
||||
* @returns A summary of each room.
|
||||
*/
|
||||
getRoomSummaries(): RoomSummary[];
|
||||
|
||||
/**
|
||||
* Store a User.
|
||||
* @param {User} user The user to store.
|
||||
* @param user - The user to store.
|
||||
*/
|
||||
storeUser(user: User): void;
|
||||
|
||||
/**
|
||||
* Retrieve a User by its' user ID.
|
||||
* @param {string} userId The user ID.
|
||||
* @return {User} The user or null.
|
||||
* @param userId - The user ID.
|
||||
* @returns The user or null.
|
||||
*/
|
||||
getUser(userId: string): User | null;
|
||||
|
||||
/**
|
||||
* Retrieve all known users.
|
||||
* @return {User[]} A list of users, which may be empty.
|
||||
* @returns A list of users, which may be empty.
|
||||
*/
|
||||
getUsers(): User[];
|
||||
|
||||
/**
|
||||
* Retrieve scrollback for this room.
|
||||
* @param {Room} room The matrix room
|
||||
* @param {number} limit The max number of old events to retrieve.
|
||||
* @return {Array<Object>} An array of objects which will be at most 'limit'
|
||||
* @param room - The matrix room
|
||||
* @param limit - The max number of old events to retrieve.
|
||||
* @returns An array of objects which will be at most 'limit'
|
||||
* length and at least 0. The objects are the raw event JSON.
|
||||
*/
|
||||
scrollback(room: Room, limit: number): MatrixEvent[];
|
||||
|
||||
/**
|
||||
* Store events for a room.
|
||||
* @param {Room} room The room to store events for.
|
||||
* @param {Array<MatrixEvent>} events The events to store.
|
||||
* @param {string} token The token associated with these events.
|
||||
* @param {boolean} toStart True if these are paginated results.
|
||||
* @param room - The room to store events for.
|
||||
* @param events - The events to store.
|
||||
* @param token - The token associated with these events.
|
||||
* @param toStart - True if these are paginated results.
|
||||
*/
|
||||
storeEvents(room: Room, events: MatrixEvent[], token: string | null, toStart: boolean): void;
|
||||
|
||||
/**
|
||||
* Store a filter.
|
||||
* @param {Filter} filter
|
||||
*/
|
||||
storeFilter(filter: Filter): void;
|
||||
|
||||
/**
|
||||
* Retrieve a filter.
|
||||
* @param {string} userId
|
||||
* @param {string} filterId
|
||||
* @return {?Filter} A filter or null.
|
||||
* @returns A filter or null.
|
||||
*/
|
||||
getFilter(userId: string, filterId: string): Filter | null;
|
||||
|
||||
/**
|
||||
* Retrieve a filter ID with the given name.
|
||||
* @param {string} filterName The filter name.
|
||||
* @return {?string} The filter ID or null.
|
||||
* @param filterName - The filter name.
|
||||
* @returns The filter ID or null.
|
||||
*/
|
||||
getFilterIdByName(filterName: string): string | null;
|
||||
|
||||
/**
|
||||
* Set a filter name to ID mapping.
|
||||
* @param {string} filterName
|
||||
* @param {string} filterId
|
||||
*/
|
||||
setFilterIdByName(filterName: string, filterId?: string): void;
|
||||
|
||||
/**
|
||||
* Store user-scoped account data events
|
||||
* @param {Array<MatrixEvent>} events The events to store.
|
||||
* @param events - The events to store.
|
||||
*/
|
||||
storeAccountDataEvents(events: MatrixEvent[]): void;
|
||||
|
||||
/**
|
||||
* Get account data event by event type
|
||||
* @param {string} eventType The event type being queried
|
||||
* @param eventType - The event type being queried
|
||||
*/
|
||||
getAccountData(eventType: EventType | string): MatrixEvent | undefined;
|
||||
|
||||
/**
|
||||
* setSyncData does nothing as there is no backing data store.
|
||||
*
|
||||
* @param {Object} syncData The sync data
|
||||
* @return {Promise} An immediately resolved promise.
|
||||
* @param syncData - The sync data
|
||||
* @returns An immediately resolved promise.
|
||||
*/
|
||||
setSyncData(syncData: ISyncResponse): Promise<void>;
|
||||
|
||||
/**
|
||||
* We never want to save because we have nothing to save to.
|
||||
*
|
||||
* @return {boolean} If the store wants to save
|
||||
* @returns If the store wants to save
|
||||
*/
|
||||
wantsSave(): boolean;
|
||||
|
||||
@ -187,19 +179,19 @@ export interface IStore {
|
||||
|
||||
/**
|
||||
* Startup does nothing.
|
||||
* @return {Promise} An immediately resolved promise.
|
||||
* @returns An immediately resolved promise.
|
||||
*/
|
||||
startup(): Promise<void>;
|
||||
|
||||
/**
|
||||
* @return {Promise} Resolves with a sync response to restore the
|
||||
* @returns Promise which resolves with a sync response to restore the
|
||||
* client state to where it was at the last save, or null if there
|
||||
* is no saved sync data.
|
||||
*/
|
||||
getSavedSync(): Promise<ISavedSync | null>;
|
||||
|
||||
/**
|
||||
* @return {Promise} If there is a saved sync, the nextBatch token
|
||||
* @returns If there is a saved sync, the nextBatch token
|
||||
* for this sync, otherwise null.
|
||||
*/
|
||||
getSavedSyncToken(): Promise<string | null>;
|
||||
@ -207,16 +199,15 @@ export interface IStore {
|
||||
/**
|
||||
* Delete all data from this store. Does nothing since this store
|
||||
* doesn't store anything.
|
||||
* @return {Promise} An immediately resolved promise.
|
||||
* @returns An immediately resolved promise.
|
||||
*/
|
||||
deleteAllData(): Promise<void>;
|
||||
|
||||
/**
|
||||
* Returns the out-of-band membership events for this room that
|
||||
* were previously loaded.
|
||||
* @param {string} roomId
|
||||
* @returns {event[]} the events, potentially an empty array if OOB loading didn't yield any new members
|
||||
* @returns {null} in case the members for this room haven't been stored yet
|
||||
* @returns the events, potentially an empty array if OOB loading didn't yield any new members
|
||||
* @returns in case the members for this room haven't been stored yet
|
||||
*/
|
||||
getOutOfBandMembers(roomId: string): Promise<IStateEventWithRoomId[] | null>;
|
||||
|
||||
@ -224,9 +215,8 @@ export interface IStore {
|
||||
* Stores the out-of-band membership events for this room. Note that
|
||||
* it still makes sense to store an empty array as the OOB status for the room is
|
||||
* marked as fetched, and getOutOfBandMembers will return an empty array instead of null
|
||||
* @param {string} roomId
|
||||
* @param {event[]} membershipEvents the membership events to store
|
||||
* @returns {Promise} when all members have been stored
|
||||
* @param membershipEvents - the membership events to store
|
||||
* @returns when all members have been stored
|
||||
*/
|
||||
setOutOfBandMembers(roomId: string, membershipEvents: IStateEventWithRoomId[]): Promise<void>;
|
||||
|
||||
|
@ -51,12 +51,12 @@ const VERSION = DB_MIGRATIONS.length;
|
||||
|
||||
/**
|
||||
* Helper method to collect results from a Cursor and promiseify it.
|
||||
* @param {ObjectStore|Index} store The store to perform openCursor on.
|
||||
* @param {IDBKeyRange=} keyRange Optional key range to apply on the cursor.
|
||||
* @param {Function} resultMapper A function which is repeatedly called with a
|
||||
* @param store - The store to perform openCursor on.
|
||||
* @param keyRange - Optional key range to apply on the cursor.
|
||||
* @param resultMapper - A function which is repeatedly called with a
|
||||
* Cursor.
|
||||
* Return the data you want to keep.
|
||||
* @return {Promise<T[]>} Resolves to an array of whatever you returned from
|
||||
* @returns Promise which resolves to an array of whatever you returned from
|
||||
* resultMapper.
|
||||
*/
|
||||
function selectQuery<T>(
|
||||
@ -134,11 +134,10 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend {
|
||||
* Does the actual reading from and writing to the indexeddb
|
||||
*
|
||||
* Construct a new Indexed Database store backend. This requires a call to
|
||||
* <code>connect()</code> before this store can be used.
|
||||
* @constructor
|
||||
* @param {Object} indexedDB The Indexed DB interface e.g
|
||||
* <code>window.indexedDB</code>
|
||||
* @param {string=} dbName Optional database name. The same name must be used
|
||||
* `connect()` before this store can be used.
|
||||
* @param indexedDB - The Indexed DB interface e.g
|
||||
* `window.indexedDB`
|
||||
* @param dbName - Optional database name. The same name must be used
|
||||
* to open the same database.
|
||||
*/
|
||||
public constructor(private readonly indexedDB: IDBFactory, dbName = "default") {
|
||||
@ -149,7 +148,7 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend {
|
||||
/**
|
||||
* Attempt to connect to the database. This can fail if the user does not
|
||||
* grant permission.
|
||||
* @return {Promise} Resolves if successfully connected.
|
||||
* @returns Promise which resolves if successfully connected.
|
||||
*/
|
||||
public connect(): Promise<void> {
|
||||
if (!this.disconnected) {
|
||||
@ -195,14 +194,14 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend {
|
||||
});
|
||||
}
|
||||
|
||||
/** @return {boolean} whether or not the database was newly created in this session. */
|
||||
/** @returns whether or not the database was newly created in this session. */
|
||||
public isNewlyCreated(): Promise<boolean> {
|
||||
return Promise.resolve(this._isNewlyCreated);
|
||||
}
|
||||
|
||||
/**
|
||||
* Having connected, load initial data from the database and prepare for use
|
||||
* @return {Promise} Resolves on success
|
||||
* @returns Promise which resolves on success
|
||||
*/
|
||||
private init(): Promise<unknown> {
|
||||
return Promise.all([
|
||||
@ -223,9 +222,8 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend {
|
||||
/**
|
||||
* Returns the out-of-band membership events for this room that
|
||||
* were previously loaded.
|
||||
* @param {string} roomId
|
||||
* @returns {Promise<event[]>} the events, potentially an empty array if OOB loading didn't yield any new members
|
||||
* @returns {null} in case the members for this room haven't been stored yet
|
||||
* @returns the events, potentially an empty array if OOB loading didn't yield any new members
|
||||
* @returns in case the members for this room haven't been stored yet
|
||||
*/
|
||||
public getOutOfBandMembers(roomId: string): Promise<IStateEventWithRoomId[] | null> {
|
||||
return new Promise<IStateEventWithRoomId[] | null>((resolve, reject) => {
|
||||
@ -273,8 +271,7 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend {
|
||||
* Stores the out-of-band membership events for this room. Note that
|
||||
* it still makes sense to store an empty array as the OOB status for the room is
|
||||
* marked as fetched, and getOutOfBandMembers will return an empty array instead of null
|
||||
* @param {string} roomId
|
||||
* @param {event[]} membershipEvents the membership events to store
|
||||
* @param membershipEvents - the membership events to store
|
||||
*/
|
||||
public async setOutOfBandMembers(roomId: string, membershipEvents: IStateEventWithRoomId[]): Promise<void> {
|
||||
logger.log(`LL: backend about to store ${membershipEvents.length}` +
|
||||
@ -339,7 +336,7 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend {
|
||||
/**
|
||||
* Clear the entire database. This should be used when logging out of a client
|
||||
* to prevent mixing data between accounts.
|
||||
* @return {Promise} Resolved when the database is cleared.
|
||||
* @returns Resolved when the database is cleared.
|
||||
*/
|
||||
public clearDatabase(): Promise<void> {
|
||||
return new Promise((resolve) => {
|
||||
@ -366,11 +363,11 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {boolean=} copy If false, the data returned is from internal
|
||||
* @param copy - If false, the data returned is from internal
|
||||
* buffers and must not be mutated. Otherwise, a copy is made before
|
||||
* returning such that the data can be safely mutated. Default: true.
|
||||
*
|
||||
* @return {Promise} Resolves with a sync response to restore the
|
||||
* @returns Promise which resolves with a sync response to restore the
|
||||
* client state to where it was at the last save, or null if there
|
||||
* is no saved sync data.
|
||||
*/
|
||||
@ -421,9 +418,9 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend {
|
||||
|
||||
/**
|
||||
* Persist rooms /sync data along with the next batch token.
|
||||
* @param {string} nextBatch The next_batch /sync value.
|
||||
* @param {Object} roomsData The 'rooms' /sync data from a SyncAccumulator
|
||||
* @return {Promise} Resolves if the data was persisted.
|
||||
* @param nextBatch - The next_batch /sync value.
|
||||
* @param roomsData - The 'rooms' /sync data from a SyncAccumulator
|
||||
* @returns Promise which resolves if the data was persisted.
|
||||
*/
|
||||
private persistSyncData(
|
||||
nextBatch: string,
|
||||
@ -447,8 +444,8 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend {
|
||||
/**
|
||||
* Persist a list of account data events. Events with the same 'type' will
|
||||
* be replaced.
|
||||
* @param {Object[]} accountData An array of raw user-scoped account data events
|
||||
* @return {Promise} Resolves if the events were persisted.
|
||||
* @param accountData - An array of raw user-scoped account data events
|
||||
* @returns Promise which resolves if the events were persisted.
|
||||
*/
|
||||
private persistAccountData(accountData: IMinimalEvent[]): Promise<void> {
|
||||
return utils.promiseTry<void>(() => {
|
||||
@ -466,8 +463,8 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend {
|
||||
* Users with the same 'userId' will be replaced.
|
||||
* Presence events should be the event in its raw form (not the Event
|
||||
* object)
|
||||
* @param {Object[]} tuples An array of [userid, event] tuples
|
||||
* @return {Promise} Resolves if the users were persisted.
|
||||
* @param tuples - An array of [userid, event] tuples
|
||||
* @returns Promise which resolves if the users were persisted.
|
||||
*/
|
||||
private persistUserPresenceEvents(tuples: UserTuple[]): Promise<void> {
|
||||
return utils.promiseTry<void>(() => {
|
||||
@ -487,7 +484,7 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend {
|
||||
* Load all user presence events from the database. This is not cached.
|
||||
* FIXME: It would probably be more sensible to store the events in the
|
||||
* sync.
|
||||
* @return {Promise<Object[]>} A list of presence events in their raw form.
|
||||
* @returns A list of presence events in their raw form.
|
||||
*/
|
||||
public getUserPresenceEvents(): Promise<UserTuple[]> {
|
||||
return utils.promiseTry<UserTuple[]>(() => {
|
||||
@ -501,7 +498,7 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend {
|
||||
|
||||
/**
|
||||
* Load all the account data events from the database. This is not cached.
|
||||
* @return {Promise<Object[]>} A list of raw global account events.
|
||||
* @returns A list of raw global account events.
|
||||
*/
|
||||
private loadAccountData(): Promise<IMinimalEvent[]> {
|
||||
logger.log(`LocalIndexedDBStoreBackend: loading account data...`);
|
||||
@ -519,7 +516,7 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend {
|
||||
|
||||
/**
|
||||
* Load the sync data from the database.
|
||||
* @return {Promise<Object>} An object with "roomsData" and "nextBatch" keys.
|
||||
* @returns An object with "roomsData" and "nextBatch" keys.
|
||||
*/
|
||||
private loadSyncData(): Promise<ISyncData> {
|
||||
logger.log(`LocalIndexedDBStoreBackend: loading sync data...`);
|
||||
|
@ -36,10 +36,9 @@ export class RemoteIndexedDBStoreBackend implements IIndexedDBBackend {
|
||||
* worker.
|
||||
*
|
||||
* Construct a new Indexed Database store backend. This requires a call to
|
||||
* <code>connect()</code> before this store can be used.
|
||||
* @constructor
|
||||
* @param {Function} workerFactory Factory which produces a Worker
|
||||
* @param {string=} dbName Optional database name. The same name must be used
|
||||
* `connect()` before this store can be used.
|
||||
* @param workerFactory - Factory which produces a Worker
|
||||
* @param dbName - Optional database name. The same name must be used
|
||||
* to open the same database.
|
||||
*/
|
||||
public constructor(
|
||||
@ -50,7 +49,7 @@ export class RemoteIndexedDBStoreBackend implements IIndexedDBBackend {
|
||||
/**
|
||||
* Attempt to connect to the database. This can fail if the user does not
|
||||
* grant permission.
|
||||
* @return {Promise} Resolves if successfully connected.
|
||||
* @returns Promise which resolves if successfully connected.
|
||||
*/
|
||||
public connect(): Promise<void> {
|
||||
return this.ensureStarted().then(() => this.doCmd('connect'));
|
||||
@ -59,19 +58,19 @@ export class RemoteIndexedDBStoreBackend implements IIndexedDBBackend {
|
||||
/**
|
||||
* Clear the entire database. This should be used when logging out of a client
|
||||
* to prevent mixing data between accounts.
|
||||
* @return {Promise} Resolved when the database is cleared.
|
||||
* @returns Resolved when the database is cleared.
|
||||
*/
|
||||
public clearDatabase(): Promise<void> {
|
||||
return this.ensureStarted().then(() => this.doCmd('clearDatabase'));
|
||||
}
|
||||
|
||||
/** @return {Promise<boolean>} whether or not the database was newly created in this session. */
|
||||
/** @returns whether or not the database was newly created in this session. */
|
||||
public isNewlyCreated(): Promise<boolean> {
|
||||
return this.doCmd('isNewlyCreated');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {Promise} Resolves with a sync response to restore the
|
||||
* @returns Promise which resolves with a sync response to restore the
|
||||
* client state to where it was at the last save, or null if there
|
||||
* is no saved sync data.
|
||||
*/
|
||||
@ -94,9 +93,8 @@ export class RemoteIndexedDBStoreBackend implements IIndexedDBBackend {
|
||||
/**
|
||||
* Returns the out-of-band membership events for this room that
|
||||
* were previously loaded.
|
||||
* @param {string} roomId
|
||||
* @returns {event[]} the events, potentially an empty array if OOB loading didn't yield any new members
|
||||
* @returns {null} in case the members for this room haven't been stored yet
|
||||
* @returns the events, potentially an empty array if OOB loading didn't yield any new members
|
||||
* @returns in case the members for this room haven't been stored yet
|
||||
*/
|
||||
public getOutOfBandMembers(roomId: string): Promise<IStateEventWithRoomId[] | null> {
|
||||
return this.doCmd('getOutOfBandMembers', [roomId]);
|
||||
@ -106,9 +104,8 @@ export class RemoteIndexedDBStoreBackend implements IIndexedDBBackend {
|
||||
* Stores the out-of-band membership events for this room. Note that
|
||||
* it still makes sense to store an empty array as the OOB status for the room is
|
||||
* marked as fetched, and getOutOfBandMembers will return an empty array instead of null
|
||||
* @param {string} roomId
|
||||
* @param {event[]} membershipEvents the membership events to store
|
||||
* @returns {Promise} when all members have been stored
|
||||
* @param membershipEvents - the membership events to store
|
||||
* @returns when all members have been stored
|
||||
*/
|
||||
public setOutOfBandMembers(roomId: string, membershipEvents: IStateEventWithRoomId[]): Promise<void> {
|
||||
return this.doCmd('setOutOfBandMembers', [roomId, membershipEvents]);
|
||||
@ -128,7 +125,7 @@ export class RemoteIndexedDBStoreBackend implements IIndexedDBBackend {
|
||||
|
||||
/**
|
||||
* Load all user presence events from the database. This is not cached.
|
||||
* @return {Promise<Object[]>} A list of presence events in their raw form.
|
||||
* @returns A list of presence events in their raw form.
|
||||
*/
|
||||
public getUserPresenceEvents(): Promise<UserTuple[]> {
|
||||
return this.doCmd('getUserPresenceEvents');
|
||||
|
@ -27,12 +27,14 @@ interface ICmd {
|
||||
* This class lives in the webworker and drives a LocalIndexedDBStoreBackend
|
||||
* controlled by messages from the main process.
|
||||
*
|
||||
* @example
|
||||
* It should be instantiated by a web worker script provided by the application
|
||||
* in a script, for example:
|
||||
*
|
||||
* ```
|
||||
* import {IndexedDBStoreWorker} from 'matrix-js-sdk/lib/indexeddb-worker.js';
|
||||
* const remoteWorker = new IndexedDBStoreWorker(postMessage);
|
||||
* onmessage = remoteWorker.onMessage;
|
||||
* ```
|
||||
*
|
||||
* Note that it is advisable to import this class by referencing the file directly to
|
||||
* avoid a dependency on the whole js-sdk.
|
||||
@ -42,7 +44,7 @@ export class IndexedDBStoreWorker {
|
||||
private backend?: LocalIndexedDBStoreBackend;
|
||||
|
||||
/**
|
||||
* @param {function} postMessage The web worker postMessage function that
|
||||
* @param postMessage - The web worker postMessage function that
|
||||
* should be used to communicate back to the main script.
|
||||
*/
|
||||
public constructor(private readonly postMessage: InstanceType<typeof Worker>["postMessage"]) {}
|
||||
@ -51,7 +53,7 @@ export class IndexedDBStoreWorker {
|
||||
* Passes a message event from the main script into the class. This method
|
||||
* can be directly assigned to the web worker `onmessage` variable.
|
||||
*
|
||||
* @param {Object} ev The message event
|
||||
* @param ev - The message event
|
||||
*/
|
||||
public onMessage = (ev: MessageEvent): void => {
|
||||
const msg: ICmd = ev.data;
|
||||
|
@ -32,7 +32,6 @@ import { IStoredClientOpts } from "../client";
|
||||
|
||||
/**
|
||||
* This is an internal module. See {@link IndexedDBStore} for the public class.
|
||||
* @module store/indexeddb
|
||||
*/
|
||||
|
||||
// If this value is too small we'll be writing very often which will cause
|
||||
@ -43,8 +42,11 @@ import { IStoredClientOpts } from "../client";
|
||||
const WRITE_DELAY_MS = 1000 * 60 * 5; // once every 5 minutes
|
||||
|
||||
interface IOpts extends IBaseOpts {
|
||||
/** The Indexed DB interface e.g. `window.indexedDB` */
|
||||
indexedDB: IDBFactory;
|
||||
/** Optional database name. The same name must be used to open the same database. */
|
||||
dbName?: string;
|
||||
/** Optional factory to spin up a Worker to execute the IDB transactions within. */
|
||||
workerFactory?: () => Worker;
|
||||
}
|
||||
|
||||
@ -57,6 +59,10 @@ export class IndexedDBStore extends MemoryStore {
|
||||
return LocalIndexedDBStoreBackend.exists(indexedDB, dbName);
|
||||
}
|
||||
|
||||
/**
|
||||
* The backend instance.
|
||||
* Call through to this API if you need to perform specific indexeddb actions like deleting the database.
|
||||
*/
|
||||
public readonly backend: IIndexedDBBackend;
|
||||
|
||||
private startedUp = false;
|
||||
@ -74,10 +80,10 @@ export class IndexedDBStore extends MemoryStore {
|
||||
* the contents of the store to an IndexedDB backend.
|
||||
*
|
||||
* All data is still kept in-memory but can be loaded from disk by calling
|
||||
* <code>startup()</code>. This can make startup times quicker as a complete
|
||||
* `startup()`. This can make startup times quicker as a complete
|
||||
* sync from the server is not required. This does not reduce memory usage as all
|
||||
* the data is eagerly fetched when <code>startup()</code> is called.
|
||||
* <pre>
|
||||
* the data is eagerly fetched when `startup()` is called.
|
||||
* ```
|
||||
* let opts = { indexedDB: window.indexedDB, localStorage: window.localStorage };
|
||||
* let store = new IndexedDBStore(opts);
|
||||
* await store.startup(); // load from indexed db
|
||||
@ -90,24 +96,9 @@ export class IndexedDBStore extends MemoryStore {
|
||||
* console.log("Started up, now with go faster stripes!");
|
||||
* }
|
||||
* });
|
||||
* </pre>
|
||||
* ```
|
||||
*
|
||||
* @constructor
|
||||
* @extends MemoryStore
|
||||
* @param {Object} opts Options object.
|
||||
* @param {Object} opts.indexedDB The Indexed DB interface e.g.
|
||||
* <code>window.indexedDB</code>
|
||||
* @param {string=} opts.dbName Optional database name. The same name must be used
|
||||
* to open the same database.
|
||||
* @param {string=} opts.workerScript Optional URL to a script to invoke a web
|
||||
* worker with to run IndexedDB queries on the web worker. The IndexedDbStoreWorker
|
||||
* class is provided for this purpose and requires the application to provide a
|
||||
* trivial wrapper script around it.
|
||||
* @param {Object=} opts.workerApi The webWorker API object. If omitted, the global Worker
|
||||
* object will be used if it exists.
|
||||
* @prop {IndexedDBStoreBackend} backend The backend instance. Call through to
|
||||
* this API if you need to perform specific indexeddb actions like deleting the
|
||||
* database.
|
||||
* @param opts - Options object.
|
||||
*/
|
||||
public constructor(opts: IOpts) {
|
||||
super(opts);
|
||||
@ -126,7 +117,7 @@ export class IndexedDBStore extends MemoryStore {
|
||||
public on = this.emitter.on.bind(this.emitter);
|
||||
|
||||
/**
|
||||
* @return {Promise} Resolved when loaded from indexed db.
|
||||
* @returns Resolved when loaded from indexed db.
|
||||
*/
|
||||
public startup(): Promise<void> {
|
||||
if (this.startedUp) {
|
||||
@ -152,7 +143,7 @@ export class IndexedDBStore extends MemoryStore {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {Promise} Resolves with a sync response to restore the
|
||||
* @returns Promise which resolves with a sync response to restore the
|
||||
* client state to where it was at the last save, or null if there
|
||||
* is no saved sync data.
|
||||
*/
|
||||
@ -160,13 +151,13 @@ export class IndexedDBStore extends MemoryStore {
|
||||
return this.backend.getSavedSync();
|
||||
}, "getSavedSync");
|
||||
|
||||
/** @return {Promise<boolean>} whether or not the database was newly created in this session. */
|
||||
/** @returns whether or not the database was newly created in this session. */
|
||||
public isNewlyCreated = this.degradable((): Promise<boolean> => {
|
||||
return this.backend.isNewlyCreated();
|
||||
}, "isNewlyCreated");
|
||||
|
||||
/**
|
||||
* @return {Promise} If there is a saved sync, the nextBatch token
|
||||
* @returns If there is a saved sync, the nextBatch token
|
||||
* for this sync, otherwise null.
|
||||
*/
|
||||
public getSavedSyncToken = this.degradable((): Promise<string | null> => {
|
||||
@ -175,7 +166,7 @@ export class IndexedDBStore extends MemoryStore {
|
||||
|
||||
/**
|
||||
* Delete all data from this store.
|
||||
* @return {Promise} Resolves if the data was deleted from the database.
|
||||
* @returns Promise which resolves if the data was deleted from the database.
|
||||
*/
|
||||
public deleteAllData = this.degradable((): Promise<void> => {
|
||||
super.deleteAllData();
|
||||
@ -193,7 +184,7 @@ export class IndexedDBStore extends MemoryStore {
|
||||
* not could change between calling this function and calling
|
||||
* save().
|
||||
*
|
||||
* @return {boolean} True if calling save() will actually save
|
||||
* @returns True if calling save() will actually save
|
||||
* (at the time this function is called).
|
||||
*/
|
||||
public wantsSave(): boolean {
|
||||
@ -204,8 +195,8 @@ export class IndexedDBStore extends MemoryStore {
|
||||
/**
|
||||
* Possibly write data to the database.
|
||||
*
|
||||
* @param {boolean} force True to force a save to happen
|
||||
* @return {Promise} Promise resolves after the write completes
|
||||
* @param force - True to force a save to happen
|
||||
* @returns Promise resolves after the write completes
|
||||
* (or immediately if no write is performed)
|
||||
*/
|
||||
public save(force = false): Promise<void> {
|
||||
@ -241,9 +232,8 @@ export class IndexedDBStore extends MemoryStore {
|
||||
/**
|
||||
* Returns the out-of-band membership events for this room that
|
||||
* were previously loaded.
|
||||
* @param {string} roomId
|
||||
* @returns {event[]} the events, potentially an empty array if OOB loading didn't yield any new members
|
||||
* @returns {null} in case the members for this room haven't been stored yet
|
||||
* @returns the events, potentially an empty array if OOB loading didn't yield any new members
|
||||
* @returns in case the members for this room haven't been stored yet
|
||||
*/
|
||||
public getOutOfBandMembers = this.degradable((roomId: string): Promise<IStateEventWithRoomId[] | null> => {
|
||||
return this.backend.getOutOfBandMembers(roomId);
|
||||
@ -253,9 +243,8 @@ export class IndexedDBStore extends MemoryStore {
|
||||
* Stores the out-of-band membership events for this room. Note that
|
||||
* it still makes sense to store an empty array as the OOB status for the room is
|
||||
* marked as fetched, and getOutOfBandMembers will return an empty array instead of null
|
||||
* @param {string} roomId
|
||||
* @param {event[]} membershipEvents the membership events to store
|
||||
* @returns {Promise} when all members have been stored
|
||||
* @param membershipEvents - the membership events to store
|
||||
* @returns when all members have been stored
|
||||
*/
|
||||
public setOutOfBandMembers = this.degradable(
|
||||
(roomId: string, membershipEvents: IStateEventWithRoomId[]): Promise<void> => {
|
||||
@ -287,9 +276,9 @@ export class IndexedDBStore extends MemoryStore {
|
||||
* When IndexedDB fails via any of these paths, we degrade this back to a `MemoryStore`
|
||||
* in place so that the current operation and all future ones are in-memory only.
|
||||
*
|
||||
* @param {Function} func The degradable work to do.
|
||||
* @param {String} fallback The method name for fallback.
|
||||
* @returns {Function} A wrapped member function.
|
||||
* @param func - The degradable work to do.
|
||||
* @param fallback - The method name for fallback.
|
||||
* @returns A wrapped member function.
|
||||
*/
|
||||
private degradable<A extends Array<any>, R = void>(
|
||||
func: DegradableFn<A, R>,
|
||||
@ -368,8 +357,8 @@ export class IndexedDBStore extends MemoryStore {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} roomId ID of the current room
|
||||
* @returns {string} Storage key to retrieve pending events
|
||||
* @param roomId - ID of the current room
|
||||
* @returns Storage key to retrieve pending events
|
||||
*/
|
||||
function pendingEventsKey(roomId: string): string {
|
||||
return `mx_pending_events_${roomId}`;
|
||||
|
@ -16,7 +16,6 @@ limitations under the License.
|
||||
|
||||
/**
|
||||
* This is an internal module. See {@link MemoryStore} for the public class.
|
||||
* @module store/memory
|
||||
*/
|
||||
|
||||
import { EventType } from "../@types/event";
|
||||
@ -43,16 +42,10 @@ function isValidFilterId(filterId?: string | number | null): boolean {
|
||||
}
|
||||
|
||||
export interface IOpts {
|
||||
/** The local storage instance to persist some forms of data such as tokens. Rooms will NOT be stored. */
|
||||
localStorage?: Storage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new in-memory data store for the Matrix Client.
|
||||
* @constructor
|
||||
* @param {Object=} opts Config options
|
||||
* @param {Storage} opts.localStorage The local storage instance to persist
|
||||
* some forms of data such as tokens. Rooms will NOT be stored.
|
||||
*/
|
||||
export class MemoryStore implements IStore {
|
||||
private rooms: Record<string, Room> = {}; // roomId: Room
|
||||
private users: Record<string, User> = {}; // userId: User
|
||||
@ -69,26 +62,30 @@ export class MemoryStore implements IStore {
|
||||
private pendingToDeviceBatches: IndexedToDeviceBatch[] = [];
|
||||
private nextToDeviceBatchId = 0;
|
||||
|
||||
/**
|
||||
* Construct a new in-memory data store for the Matrix Client.
|
||||
* @param opts - Config options
|
||||
*/
|
||||
public constructor(opts: IOpts = {}) {
|
||||
this.localStorage = opts.localStorage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the token to stream from.
|
||||
* @return {string} The token or null.
|
||||
* @returns The token or null.
|
||||
*/
|
||||
public getSyncToken(): string | null {
|
||||
return this.syncToken;
|
||||
}
|
||||
|
||||
/** @return {Promise<boolean>} whether or not the database was newly created in this session. */
|
||||
/** @returns whether or not the database was newly created in this session. */
|
||||
public isNewlyCreated(): Promise<boolean> {
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the token to stream from.
|
||||
* @param {string} token The token to stream from.
|
||||
* @param token - The token to stream from.
|
||||
*/
|
||||
public setSyncToken(token: string): void {
|
||||
this.syncToken = token;
|
||||
@ -96,7 +93,7 @@ export class MemoryStore implements IStore {
|
||||
|
||||
/**
|
||||
* Store the given room.
|
||||
* @param {Room} room The room to be stored. All properties must be stored.
|
||||
* @param room - The room to be stored. All properties must be stored.
|
||||
*/
|
||||
public storeRoom(room: Room): void {
|
||||
this.rooms[room.roomId] = room;
|
||||
@ -112,9 +109,6 @@ export class MemoryStore implements IStore {
|
||||
/**
|
||||
* Called when a room member in a room being tracked by this store has been
|
||||
* updated.
|
||||
* @param {MatrixEvent} event
|
||||
* @param {RoomState} state
|
||||
* @param {RoomMember} member
|
||||
*/
|
||||
private onRoomMember = (event: MatrixEvent | null, state: RoomState, member: RoomMember): void => {
|
||||
if (member.membership === "invite") {
|
||||
@ -138,8 +132,8 @@ export class MemoryStore implements IStore {
|
||||
|
||||
/**
|
||||
* Retrieve a room by its' room ID.
|
||||
* @param {string} roomId The room ID.
|
||||
* @return {Room} The room or null.
|
||||
* @param roomId - The room ID.
|
||||
* @returns The room or null.
|
||||
*/
|
||||
public getRoom(roomId: string): Room | null {
|
||||
return this.rooms[roomId] || null;
|
||||
@ -147,7 +141,7 @@ export class MemoryStore implements IStore {
|
||||
|
||||
/**
|
||||
* Retrieve all known rooms.
|
||||
* @return {Room[]} A list of rooms, which may be empty.
|
||||
* @returns A list of rooms, which may be empty.
|
||||
*/
|
||||
public getRooms(): Room[] {
|
||||
return Object.values(this.rooms);
|
||||
@ -155,7 +149,6 @@ export class MemoryStore implements IStore {
|
||||
|
||||
/**
|
||||
* Permanently delete a room.
|
||||
* @param {string} roomId
|
||||
*/
|
||||
public removeRoom(roomId: string): void {
|
||||
if (this.rooms[roomId]) {
|
||||
@ -166,7 +159,7 @@ export class MemoryStore implements IStore {
|
||||
|
||||
/**
|
||||
* Retrieve a summary of all the rooms.
|
||||
* @return {RoomSummary[]} A summary of each room.
|
||||
* @returns A summary of each room.
|
||||
*/
|
||||
public getRoomSummaries(): RoomSummary[] {
|
||||
return Object.values(this.rooms).map(function(room) {
|
||||
@ -176,7 +169,7 @@ export class MemoryStore implements IStore {
|
||||
|
||||
/**
|
||||
* Store a User.
|
||||
* @param {User} user The user to store.
|
||||
* @param user - The user to store.
|
||||
*/
|
||||
public storeUser(user: User): void {
|
||||
this.users[user.userId] = user;
|
||||
@ -184,8 +177,8 @@ export class MemoryStore implements IStore {
|
||||
|
||||
/**
|
||||
* Retrieve a User by its' user ID.
|
||||
* @param {string} userId The user ID.
|
||||
* @return {User} The user or null.
|
||||
* @param userId - The user ID.
|
||||
* @returns The user or null.
|
||||
*/
|
||||
public getUser(userId: string): User | null {
|
||||
return this.users[userId] || null;
|
||||
@ -193,7 +186,7 @@ export class MemoryStore implements IStore {
|
||||
|
||||
/**
|
||||
* Retrieve all known users.
|
||||
* @return {User[]} A list of users, which may be empty.
|
||||
* @returns A list of users, which may be empty.
|
||||
*/
|
||||
public getUsers(): User[] {
|
||||
return Object.values(this.users);
|
||||
@ -201,9 +194,9 @@ export class MemoryStore implements IStore {
|
||||
|
||||
/**
|
||||
* Retrieve scrollback for this room.
|
||||
* @param {Room} room The matrix room
|
||||
* @param {number} limit The max number of old events to retrieve.
|
||||
* @return {Array<Object>} An array of objects which will be at most 'limit'
|
||||
* @param room - The matrix room
|
||||
* @param limit - The max number of old events to retrieve.
|
||||
* @returns An array of objects which will be at most 'limit'
|
||||
* length and at least 0. The objects are the raw event JSON.
|
||||
*/
|
||||
public scrollback(room: Room, limit: number): MatrixEvent[] {
|
||||
@ -212,10 +205,10 @@ export class MemoryStore implements IStore {
|
||||
|
||||
/**
|
||||
* Store events for a room. The events have already been added to the timeline
|
||||
* @param {Room} room The room to store events for.
|
||||
* @param {Array<MatrixEvent>} events The events to store.
|
||||
* @param {string} token The token associated with these events.
|
||||
* @param {boolean} toStart True if these are paginated results.
|
||||
* @param room - The room to store events for.
|
||||
* @param events - The events to store.
|
||||
* @param token - The token associated with these events.
|
||||
* @param toStart - True if these are paginated results.
|
||||
*/
|
||||
public storeEvents(room: Room, events: MatrixEvent[], token: string | null, toStart: boolean): void {
|
||||
// no-op because they've already been added to the room instance.
|
||||
@ -223,7 +216,6 @@ export class MemoryStore implements IStore {
|
||||
|
||||
/**
|
||||
* Store a filter.
|
||||
* @param {Filter} filter
|
||||
*/
|
||||
public storeFilter(filter: Filter): void {
|
||||
if (!filter?.userId || !filter?.filterId) return;
|
||||
@ -235,9 +227,7 @@ export class MemoryStore implements IStore {
|
||||
|
||||
/**
|
||||
* Retrieve a filter.
|
||||
* @param {string} userId
|
||||
* @param {string} filterId
|
||||
* @return {?Filter} A filter or null.
|
||||
* @returns A filter or null.
|
||||
*/
|
||||
public getFilter(userId: string, filterId: string): Filter | null {
|
||||
if (!this.filters[userId] || !this.filters[userId][filterId]) {
|
||||
@ -248,8 +238,8 @@ export class MemoryStore implements IStore {
|
||||
|
||||
/**
|
||||
* Retrieve a filter ID with the given name.
|
||||
* @param {string} filterName The filter name.
|
||||
* @return {?string} The filter ID or null.
|
||||
* @param filterName - The filter name.
|
||||
* @returns The filter ID or null.
|
||||
*/
|
||||
public getFilterIdByName(filterName: string): string | null {
|
||||
if (!this.localStorage) {
|
||||
@ -272,8 +262,6 @@ export class MemoryStore implements IStore {
|
||||
|
||||
/**
|
||||
* Set a filter name to ID mapping.
|
||||
* @param {string} filterName
|
||||
* @param {string} filterId
|
||||
*/
|
||||
public setFilterIdByName(filterName: string, filterId?: string): void {
|
||||
if (!this.localStorage) {
|
||||
@ -293,7 +281,7 @@ export class MemoryStore implements IStore {
|
||||
* Store user-scoped account data events.
|
||||
* N.B. that account data only allows a single event per type, so multiple
|
||||
* events with the same type will replace each other.
|
||||
* @param {Array<MatrixEvent>} events The events to store.
|
||||
* @param events - The events to store.
|
||||
*/
|
||||
public storeAccountDataEvents(events: MatrixEvent[]): void {
|
||||
events.forEach((event) => {
|
||||
@ -303,8 +291,8 @@ export class MemoryStore implements IStore {
|
||||
|
||||
/**
|
||||
* Get account data event by event type
|
||||
* @param {string} eventType The event type being queried
|
||||
* @return {?MatrixEvent} the user account_data event of given type, if any
|
||||
* @param eventType - The event type being queried
|
||||
* @returns the user account_data event of given type, if any
|
||||
*/
|
||||
public getAccountData(eventType: EventType | string): MatrixEvent | undefined {
|
||||
return this.accountData[eventType];
|
||||
@ -313,8 +301,8 @@ export class MemoryStore implements IStore {
|
||||
/**
|
||||
* setSyncData does nothing as there is no backing data store.
|
||||
*
|
||||
* @param {Object} syncData The sync data
|
||||
* @return {Promise} An immediately resolved promise.
|
||||
* @param syncData - The sync data
|
||||
* @returns An immediately resolved promise.
|
||||
*/
|
||||
public setSyncData(syncData: ISyncResponse): Promise<void> {
|
||||
return Promise.resolve();
|
||||
@ -323,7 +311,7 @@ export class MemoryStore implements IStore {
|
||||
/**
|
||||
* We never want to save becase we have nothing to save to.
|
||||
*
|
||||
* @return {boolean} If the store wants to save
|
||||
* @returns If the store wants to save
|
||||
*/
|
||||
public wantsSave(): boolean {
|
||||
return false;
|
||||
@ -331,21 +319,21 @@ export class MemoryStore implements IStore {
|
||||
|
||||
/**
|
||||
* Save does nothing as there is no backing data store.
|
||||
* @param {bool} force True to force a save (but the memory
|
||||
* @param force - True to force a save (but the memory
|
||||
* store still can't save anything)
|
||||
*/
|
||||
public save(force: boolean): void {}
|
||||
|
||||
/**
|
||||
* Startup does nothing as this store doesn't require starting up.
|
||||
* @return {Promise} An immediately resolved promise.
|
||||
* @returns An immediately resolved promise.
|
||||
*/
|
||||
public startup(): Promise<void> {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {Promise} Resolves with a sync response to restore the
|
||||
* @returns Promise which resolves with a sync response to restore the
|
||||
* client state to where it was at the last save, or null if there
|
||||
* is no saved sync data.
|
||||
*/
|
||||
@ -354,7 +342,7 @@ export class MemoryStore implements IStore {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {Promise} If there is a saved sync, the nextBatch token
|
||||
* @returns If there is a saved sync, the nextBatch token
|
||||
* for this sync, otherwise null.
|
||||
*/
|
||||
public getSavedSyncToken(): Promise<string | null> {
|
||||
@ -363,7 +351,7 @@ export class MemoryStore implements IStore {
|
||||
|
||||
/**
|
||||
* Delete all data from this store.
|
||||
* @return {Promise} An immediately resolved promise.
|
||||
* @returns An immediately resolved promise.
|
||||
*/
|
||||
public deleteAllData(): Promise<void> {
|
||||
this.rooms = {
|
||||
@ -387,9 +375,8 @@ export class MemoryStore implements IStore {
|
||||
/**
|
||||
* Returns the out-of-band membership events for this room that
|
||||
* were previously loaded.
|
||||
* @param {string} roomId
|
||||
* @returns {event[]} the events, potentially an empty array if OOB loading didn't yield any new members
|
||||
* @returns {null} in case the members for this room haven't been stored yet
|
||||
* @returns the events, potentially an empty array if OOB loading didn't yield any new members
|
||||
* @returns in case the members for this room haven't been stored yet
|
||||
*/
|
||||
public getOutOfBandMembers(roomId: string): Promise<IStateEventWithRoomId[] | null> {
|
||||
return Promise.resolve(this.oobMembers[roomId] || null);
|
||||
@ -399,9 +386,8 @@ export class MemoryStore implements IStore {
|
||||
* Stores the out-of-band membership events for this room. Note that
|
||||
* it still makes sense to store an empty array as the OOB status for the room is
|
||||
* marked as fetched, and getOutOfBandMembers will return an empty array instead of null
|
||||
* @param {string} roomId
|
||||
* @param {event[]} membershipEvents the membership events to store
|
||||
* @returns {Promise} when all members have been stored
|
||||
* @param membershipEvents - the membership events to store
|
||||
* @returns when all members have been stored
|
||||
*/
|
||||
public setOutOfBandMembers(roomId: string, membershipEvents: IStateEventWithRoomId[]): Promise<void> {
|
||||
this.oobMembers[roomId] = membershipEvents;
|
||||
|
@ -16,7 +16,6 @@ limitations under the License.
|
||||
|
||||
/**
|
||||
* This is an internal module.
|
||||
* @module store/stub
|
||||
*/
|
||||
|
||||
import { EventType } from "../@types/event";
|
||||
@ -33,20 +32,18 @@ import { IStoredClientOpts } from "../client";
|
||||
|
||||
/**
|
||||
* Construct a stub store. This does no-ops on most store methods.
|
||||
* @constructor
|
||||
*/
|
||||
export class StubStore implements IStore {
|
||||
public readonly accountData = {}; // stub
|
||||
private fromToken: string | null = null;
|
||||
|
||||
/** @return {Promise<boolean>} whether or not the database was newly created in this session. */
|
||||
/** @returns whether or not the database was newly created in this session. */
|
||||
public isNewlyCreated(): Promise<boolean> {
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the sync token.
|
||||
* @return {string}
|
||||
*/
|
||||
public getSyncToken(): string | null {
|
||||
return this.fromToken;
|
||||
@ -54,7 +51,6 @@ export class StubStore implements IStore {
|
||||
|
||||
/**
|
||||
* Set the sync token.
|
||||
* @param {string} token
|
||||
*/
|
||||
public setSyncToken(token: string): void {
|
||||
this.fromToken = token;
|
||||
@ -62,14 +58,11 @@ export class StubStore implements IStore {
|
||||
|
||||
/**
|
||||
* No-op.
|
||||
* @param {Room} room
|
||||
*/
|
||||
public storeRoom(room: Room): void {}
|
||||
|
||||
/**
|
||||
* No-op.
|
||||
* @param {string} roomId
|
||||
* @return {null}
|
||||
*/
|
||||
public getRoom(roomId: string): Room | null {
|
||||
return null;
|
||||
@ -77,7 +70,7 @@ export class StubStore implements IStore {
|
||||
|
||||
/**
|
||||
* No-op.
|
||||
* @return {Array} An empty array.
|
||||
* @returns An empty array.
|
||||
*/
|
||||
public getRooms(): Room[] {
|
||||
return [];
|
||||
@ -85,7 +78,6 @@ export class StubStore implements IStore {
|
||||
|
||||
/**
|
||||
* Permanently delete a room.
|
||||
* @param {string} roomId
|
||||
*/
|
||||
public removeRoom(roomId: string): void {
|
||||
return;
|
||||
@ -93,7 +85,7 @@ export class StubStore implements IStore {
|
||||
|
||||
/**
|
||||
* No-op.
|
||||
* @return {Array} An empty array.
|
||||
* @returns An empty array.
|
||||
*/
|
||||
public getRoomSummaries(): RoomSummary[] {
|
||||
return [];
|
||||
@ -101,14 +93,11 @@ export class StubStore implements IStore {
|
||||
|
||||
/**
|
||||
* No-op.
|
||||
* @param {User} user
|
||||
*/
|
||||
public storeUser(user: User): void {}
|
||||
|
||||
/**
|
||||
* No-op.
|
||||
* @param {string} userId
|
||||
* @return {null}
|
||||
*/
|
||||
public getUser(userId: string): User | null {
|
||||
return null;
|
||||
@ -116,7 +105,6 @@ export class StubStore implements IStore {
|
||||
|
||||
/**
|
||||
* No-op.
|
||||
* @return {User[]}
|
||||
*/
|
||||
public getUsers(): User[] {
|
||||
return [];
|
||||
@ -124,9 +112,6 @@ export class StubStore implements IStore {
|
||||
|
||||
/**
|
||||
* No-op.
|
||||
* @param {Room} room
|
||||
* @param {number} limit
|
||||
* @return {Array}
|
||||
*/
|
||||
public scrollback(room: Room, limit: number): MatrixEvent[] {
|
||||
return [];
|
||||
@ -134,24 +119,21 @@ export class StubStore implements IStore {
|
||||
|
||||
/**
|
||||
* Store events for a room.
|
||||
* @param {Room} room The room to store events for.
|
||||
* @param {Array<MatrixEvent>} events The events to store.
|
||||
* @param {string} token The token associated with these events.
|
||||
* @param {boolean} toStart True if these are paginated results.
|
||||
* @param room - The room to store events for.
|
||||
* @param events - The events to store.
|
||||
* @param token - The token associated with these events.
|
||||
* @param toStart - True if these are paginated results.
|
||||
*/
|
||||
public storeEvents(room: Room, events: MatrixEvent[], token: string | null, toStart: boolean): void {}
|
||||
|
||||
/**
|
||||
* Store a filter.
|
||||
* @param {Filter} filter
|
||||
*/
|
||||
public storeFilter(filter: Filter): void {}
|
||||
|
||||
/**
|
||||
* Retrieve a filter.
|
||||
* @param {string} userId
|
||||
* @param {string} filterId
|
||||
* @return {?Filter} A filter or null.
|
||||
* @returns A filter or null.
|
||||
*/
|
||||
public getFilter(userId: string, filterId: string): Filter | null {
|
||||
return null;
|
||||
@ -159,8 +141,8 @@ export class StubStore implements IStore {
|
||||
|
||||
/**
|
||||
* Retrieve a filter ID with the given name.
|
||||
* @param {string} filterName The filter name.
|
||||
* @return {?string} The filter ID or null.
|
||||
* @param filterName - The filter name.
|
||||
* @returns The filter ID or null.
|
||||
*/
|
||||
public getFilterIdByName(filterName: string): string | null {
|
||||
return null;
|
||||
@ -168,20 +150,18 @@ export class StubStore implements IStore {
|
||||
|
||||
/**
|
||||
* Set a filter name to ID mapping.
|
||||
* @param {string} filterName
|
||||
* @param {string} filterId
|
||||
*/
|
||||
public setFilterIdByName(filterName: string, filterId?: string): void {}
|
||||
|
||||
/**
|
||||
* Store user-scoped account data events
|
||||
* @param {Array<MatrixEvent>} events The events to store.
|
||||
* @param events - The events to store.
|
||||
*/
|
||||
public storeAccountDataEvents(events: MatrixEvent[]): void {}
|
||||
|
||||
/**
|
||||
* Get account data event by event type
|
||||
* @param {string} eventType The event type being queried
|
||||
* @param eventType - The event type being queried
|
||||
*/
|
||||
public getAccountData(eventType: EventType | string): MatrixEvent | undefined {
|
||||
return undefined;
|
||||
@ -190,8 +170,8 @@ export class StubStore implements IStore {
|
||||
/**
|
||||
* setSyncData does nothing as there is no backing data store.
|
||||
*
|
||||
* @param {Object} syncData The sync data
|
||||
* @return {Promise} An immediately resolved promise.
|
||||
* @param syncData - The sync data
|
||||
* @returns An immediately resolved promise.
|
||||
*/
|
||||
public setSyncData(syncData: ISyncResponse): Promise<void> {
|
||||
return Promise.resolve();
|
||||
@ -200,7 +180,7 @@ export class StubStore implements IStore {
|
||||
/**
|
||||
* We never want to save because we have nothing to save to.
|
||||
*
|
||||
* @return {boolean} If the store wants to save
|
||||
* @returns If the store wants to save
|
||||
*/
|
||||
public wantsSave(): boolean {
|
||||
return false;
|
||||
@ -213,14 +193,14 @@ export class StubStore implements IStore {
|
||||
|
||||
/**
|
||||
* Startup does nothing.
|
||||
* @return {Promise} An immediately resolved promise.
|
||||
* @returns An immediately resolved promise.
|
||||
*/
|
||||
public startup(): Promise<void> {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {Promise} Resolves with a sync response to restore the
|
||||
* @returns Promise which resolves with a sync response to restore the
|
||||
* client state to where it was at the last save, or null if there
|
||||
* is no saved sync data.
|
||||
*/
|
||||
@ -229,7 +209,7 @@ export class StubStore implements IStore {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {Promise} If there is a saved sync, the nextBatch token
|
||||
* @returns If there is a saved sync, the nextBatch token
|
||||
* for this sync, otherwise null.
|
||||
*/
|
||||
public getSavedSyncToken(): Promise<string | null> {
|
||||
@ -239,7 +219,7 @@ export class StubStore implements IStore {
|
||||
/**
|
||||
* Delete all data from this store. Does nothing since this store
|
||||
* doesn't store anything.
|
||||
* @return {Promise} An immediately resolved promise.
|
||||
* @returns An immediately resolved promise.
|
||||
*/
|
||||
public deleteAllData(): Promise<void> {
|
||||
return Promise.resolve();
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user