1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-07-31 15:24:23 +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:
Michael Telatynski
2022-12-07 18:01:54 +00:00
committed by GitHub
parent a9e7a46c56
commit c4006d752a
111 changed files with 3970 additions and 4772 deletions

View File

@ -2,6 +2,7 @@ module.exports = {
plugins: [ plugins: [
"matrix-org", "matrix-org",
"import", "import",
"jsdoc",
], ],
extends: [ extends: [
"plugin:matrix-org/babel", "plugin:matrix-org/babel",
@ -45,7 +46,7 @@ module.exports = {
// restrict EventEmitters to force callers to use TypedEventEmitter // restrict EventEmitters to force callers to use TypedEventEmitter
"no-restricted-imports": ["error", { "no-restricted-imports": ["error", {
name: "events", name: "events",
message: "Please use TypedEventEmitter instead" message: "Please use TypedEventEmitter instead",
}], }],
"import/no-restricted-paths": ["error", { "import/no-restricted-paths": ["error", {
@ -61,6 +62,9 @@ module.exports = {
files: [ files: [
"**/*.ts", "**/*.ts",
], ],
plugins: [
"eslint-plugin-tsdoc",
],
extends: [ extends: [
"plugin:matrix-org/typescript", "plugin:matrix-org/typescript",
], ],
@ -84,6 +88,23 @@ module.exports = {
"quotes": "off", "quotes": "off",
// We use a `logger` intermediary module // We use a `logger` intermediary module
"no-console": "error", "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: [ files: [

View File

@ -88,8 +88,8 @@
"@types/node": "18", "@types/node": "18",
"@types/sdp-transform": "^2.4.5", "@types/sdp-transform": "^2.4.5",
"@types/uuid": "7", "@types/uuid": "7",
"@typescript-eslint/eslint-plugin": "^5.6.0", "@typescript-eslint/eslint-plugin": "^5.45.0",
"@typescript-eslint/parser": "^5.6.0", "@typescript-eslint/parser": "^5.45.0",
"allchange": "^1.0.6", "allchange": "^1.0.6",
"babel-jest": "^29.0.0", "babel-jest": "^29.0.0",
"babelify": "^10.0.0", "babelify": "^10.0.0",
@ -101,7 +101,9 @@
"eslint-config-google": "^0.14.0", "eslint-config-google": "^0.14.0",
"eslint-import-resolver-typescript": "^3.5.1", "eslint-import-resolver-typescript": "^3.5.1",
"eslint-plugin-import": "^2.26.0", "eslint-plugin-import": "^2.26.0",
"eslint-plugin-jsdoc": "^39.6.4",
"eslint-plugin-matrix-org": "^0.8.0", "eslint-plugin-matrix-org": "^0.8.0",
"eslint-plugin-tsdoc": "^0.2.17",
"eslint-plugin-unicorn": "^45.0.0", "eslint-plugin-unicorn": "^45.0.0",
"exorcist": "^2.0.0", "exorcist": "^2.0.0",
"fake-indexeddb": "^4.0.0", "fake-indexeddb": "^4.0.0",

View File

@ -105,7 +105,7 @@ export class TestClient {
/** /**
* stop the client * 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> { public async stop(): Promise<void> {
this.client.stopClient(); this.client.stopClient();
@ -135,7 +135,7 @@ export class TestClient {
* set up an expectation that the keys will be uploaded, and wait for * set up an expectation that the keys will be uploaded, and wait for
* that to happen. * that to happen.
* *
* @returns {Promise} for the one-time keys * @returns Promise for the one-time keys
*/ */
public awaitOneTimeKeyUpload(): Promise<Record<string, IOneTimeKey>> { public awaitOneTimeKeyUpload(): Promise<Record<string, IOneTimeKey>> {
if (Object.keys(this.oneTimeKeys!).length != 0) { 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`. * 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) { public expectKeyQuery(response: IDownloadKeyResult) {
this.httpBackend.when('POST', '/keys/query').respond<IDownloadKeyResult>( this.httpBackend.when('POST', '/keys/query').respond<IDownloadKeyResult>(
@ -202,7 +202,7 @@ export class TestClient {
/** /**
* get the uploaded curve25519 device key * get the uploaded curve25519 device key
* *
* @return {string} base64 device key * @returns base64 device key
*/ */
public getDeviceKey(): string { public getDeviceKey(): string {
const keyId = 'curve25519:' + this.deviceId; const keyId = 'curve25519:' + this.deviceId;
@ -212,7 +212,7 @@ export class TestClient {
/** /**
* get the uploaded ed25519 device key * get the uploaded ed25519 device key
* *
* @return {string} base64 device key * @returns base64 device key
*/ */
public getSigningKey(): string { public getSigningKey(): string {
const keyId = 'ed25519:' + this.deviceId; const keyId = 'ed25519:' + this.deviceId;

View File

@ -26,9 +26,7 @@ const ROOM_ID = "!room:id";
* get a /sync response which contains a single e2e room (ROOM_ID), with the * get a /sync response which contains a single e2e room (ROOM_ID), with the
* members given * members given
* *
* @param {string[]} roomMembers * @returns sync response
*
* @return {object} sync response
*/ */
function getSyncResponse(roomMembers: string[]) { function getSyncResponse(roomMembers: string[]) {
const stateEvents = [ const stateEvents = [

View File

@ -60,7 +60,7 @@ async function bobUploadsDeviceKeys(): Promise<void> {
/** /**
* Set an expectation that querier will query uploader's keys; then flush the http request. * 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> { function expectQueryKeys(querier: TestClient, uploader: TestClient): Promise<number> {
// can't query keys before bob has uploaded them // 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. * 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> { async function expectAliClaimKeys(): Promise<void> {
const keys = await bobTestClient.awaitOneTimeKeyUpload(); 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 * Ali sends a message, first claiming e2e keys. Set the expectations and
* check the results. * 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> { async function aliSendsFirstMessage(): Promise<OlmPayload> {
// eslint-disable-next-line @typescript-eslint/no-unused-vars // 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 * Ali sends a message without first claiming e2e keys. Set the expectations
* and check the results. * 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> { async function aliSendsMessage(): Promise<OlmPayload> {
// eslint-disable-next-line @typescript-eslint/no-unused-vars // 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 * Bob sends a message, first querying (but not claiming) e2e keys. Set the
* expectations and check the results. * 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> { async function bobSendsReplyMessage(): Promise<OlmPayload> {
// eslint-disable-next-line @typescript-eslint/no-unused-vars // 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 * 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> { async function expectAliSendMessageRequest(): Promise<OlmPayload> {
const content = await expectSendMessageRequest(aliTestClient.httpBackend); 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 * 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> { async function expectBobSendMessageRequest(): Promise<OlmPayload> {
const content = await expectSendMessageRequest(bobTestClient.httpBackend); 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 * Send an initial sync response to the client (which just includes the member
* list for our test room). * list for our test room).
* *
* @param {TestClient} testClient * @returns which resolves when the sync has been flushed.
* @returns {Promise} which resolves when the sync has been flushed.
*/ */
function firstSync(testClient: TestClient): Promise<void> { function firstSync(testClient: TestClient): Promise<void> {
// send a sync response including our test room. // send a sync response including our test room.

View File

@ -1658,8 +1658,8 @@ describe("MatrixClient syncing", () => {
/** /**
* waits for the MatrixClient to emit one or more 'sync' events. * waits for the MatrixClient to emit one or more 'sync' events.
* *
* @param {Number?} numSyncs number of syncs to wait for * @param numSyncs - number of syncs to wait for
* @returns {Promise} promise which resolves after the sync events have happened * @returns promise which resolves after the sync events have happened
*/ */
function awaitSyncEvent(numSyncs?: number) { function awaitSyncEvent(numSyncs?: number) {
return utils.syncPromise(client!, numSyncs); return utils.syncPromise(client!, numSyncs);

View File

@ -220,8 +220,8 @@ describe("megolm", () => {
* Get the device keys for testOlmAccount in a format suitable for a * Get the device keys for testOlmAccount in a format suitable for a
* response to /keys/query * response to /keys/query
* *
* @param {string} userId The user ID to query for * @param userId - The user ID to query for
* @returns {IDownloadKeyResult} The fake query response * @returns The fake query response
*/ */
function getTestKeysQueryResponse(userId: string): IDownloadKeyResult { function getTestKeysQueryResponse(userId: string): IDownloadKeyResult {
const testE2eKeys = JSON.parse(testOlmAccount.identity_keys()); 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 * Get a one-time key for testOlmAccount in a format suitable for a
* response to /keys/claim * response to /keys/claim
* @param {string} userId The user ID to query for * @param userId - The user ID to query for
* @returns {IClaimOTKsResult} The fake key claim response * @returns The fake key claim response
*/ */
function getTestKeysClaimResponse(userId: string): IClaimOTKsResult { function getTestKeysClaimResponse(userId: string): IClaimOTKsResult {
testOlmAccount.generate_one_time_keys(1); testOlmAccount.generate_one_time_keys(1);

View File

@ -1446,11 +1446,11 @@ function timeout(delayMs: number, reason: string): { promise: Promise<never>, ca
/** /**
* Listen until a callback returns data. * Listen until a callback returns data.
* @param {EventEmitter} emitter The event emitter * @param emitter - The event emitter
* @param {string} eventName The event to listen for * @param 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 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. * @param 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, * @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. * the promise is rejected.
*/ */
function listenUntil<T>( function listenUntil<T>(

View File

@ -13,9 +13,9 @@ import { eventMapperFor } from "../../src/event-mapper";
/** /**
* Return a promise that is resolved when the client next emits a * Return a promise that is resolved when the client next emits a
* SYNCING event. * SYNCING event.
* @param {Object} client The client * @param client - The client
* @param {Number=} count Number of syncs to wait for (default 1) * @param count - Number of syncs to wait for (default 1)
* @return {Promise} Resolves once the client has emitted a SYNCING event * @returns Promise which resolves once the client has emitted a SYNCING event
*/ */
export function syncPromise(client: MatrixClient, count = 1): Promise<void> { export function syncPromise(client: MatrixClient, count = 1): Promise<void> {
if (count <= 0) { 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. * Create a spy for an object and automatically spy its methods.
* @param {*} constr The class constructor (used with 'new') * @param constr - The class constructor (used with 'new')
* @param {string} name The name of the class * @param name - The name of the class
* @return {Object} An instantiated object with spied methods/properties. * @returns An instantiated object with spied methods/properties.
*/ */
export function mock<T>(constr: { new(...args: any[]): T }, name: string): T { 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/ // 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 let testEventIndex = 1; // counter for events, easier for comparison of randomly generated events
/** /**
* Create an Event. * Create an Event.
* @param {Object} opts Values for the event. * @param opts - Values for the event.
* @param {string} opts.type The event.type * @param opts.type - The event.type
* @param {string} opts.room The event.room_id * @param opts.room - The event.room_id
* @param {string} opts.sender The event.sender * @param opts.sender - The event.sender
* @param {string} opts.skey Optional. The state key (auto inserts empty string) * @param opts.skey - Optional. The state key (auto inserts empty string)
* @param {Object} opts.content The event.content * @param opts.content - The event.content
* @param {boolean} opts.event True to make a MatrixEvent. * @param 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. * @param client - If passed along with opts.event=true will be used to set up re-emitters.
* @return {Object} a JSON object representing this event. * @returns a JSON object representing this event.
*/ */
export function mkEvent(opts: IEventOpts & { event: true }, client?: MatrixClient): MatrixEvent; export function mkEvent(opts: IEventOpts & { event: true }, client?: MatrixClient): MatrixEvent;
export function mkEvent(opts: IEventOpts & { event?: false }, client?: MatrixClient): Partial<IEvent>; export function mkEvent(opts: IEventOpts & { event?: false }, client?: MatrixClient): Partial<IEvent>;
@ -160,8 +160,8 @@ interface IPresenceOpts {
/** /**
* Create an m.presence event. * Create an m.presence event.
* @param {Object} opts Values for the presence. * @param opts - Values for the presence.
* @return {Object|MatrixEvent} The event * @returns The event
*/ */
export function mkPresence(opts: IPresenceOpts & { event: true }): MatrixEvent; export function mkPresence(opts: IPresenceOpts & { event: true }): MatrixEvent;
export function mkPresence(opts: IPresenceOpts & { event?: false }): Partial<IEvent>; export function mkPresence(opts: IPresenceOpts & { event?: false }): Partial<IEvent>;
@ -193,16 +193,16 @@ interface IMembershipOpts {
/** /**
* Create an m.room.member event. * Create an m.room.member event.
* @param {Object} opts Values for the membership. * @param opts - Values for the membership.
* @param {string} opts.room The room ID for the event. * @param opts.room - The room ID for the event.
* @param {string} opts.mship The content.membership for the event. * @param opts.mship - The content.membership for the event.
* @param {string} opts.sender The sender user ID for the event. * @param opts.sender - The sender user ID for the event.
* @param {string} opts.skey The target user ID for the event if applicable * @param opts.skey - The target user ID for the event if applicable
* e.g. for invites/bans. * e.g. for invites/bans.
* @param {string} opts.name The content.displayname for the event. * @param opts.name - The content.displayname for the event.
* @param {string} opts.url The content.avatar_url for the event. * @param opts.url - The content.avatar_url for the event.
* @param {boolean} opts.event True to make a MatrixEvent. * @param opts.event - True to make a MatrixEvent.
* @return {Object|MatrixEvent} The event * @returns The event
*/ */
export function mkMembership(opts: IMembershipOpts & { event: true }): MatrixEvent; export function mkMembership(opts: IMembershipOpts & { event: true }): MatrixEvent;
export function mkMembership(opts: IMembershipOpts & { event?: false }): Partial<IEvent>; export function mkMembership(opts: IMembershipOpts & { event?: false }): Partial<IEvent>;
@ -250,13 +250,13 @@ export interface IMessageOpts {
/** /**
* Create an m.room.message event. * Create an m.room.message event.
* @param {Object} opts Values for the message * @param opts - Values for the message
* @param {string} opts.room The room ID for the event. * @param opts.room - The room ID for the event.
* @param {string} opts.user The user ID for the event. * @param opts.user - The user ID for the event.
* @param {string} opts.msg Optional. The content.body for the event. * @param opts.msg - Optional. The content.body for the event.
* @param {boolean} opts.event True to make a MatrixEvent. * @param 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. * @param client - If passed along with opts.event=true will be used to set up re-emitters.
* @return {Object|MatrixEvent} The event * @returns The event
*/ */
export function mkMessage(opts: IMessageOpts & { event: true }, client?: MatrixClient): MatrixEvent; export function mkMessage(opts: IMessageOpts & { event: true }, client?: MatrixClient): MatrixEvent;
export function mkMessage(opts: IMessageOpts & { event?: false }, client?: MatrixClient): Partial<IEvent>; export function mkMessage(opts: IMessageOpts & { event?: false }, client?: MatrixClient): Partial<IEvent>;
@ -290,14 +290,14 @@ interface IReplyMessageOpts extends IMessageOpts {
/** /**
* Create a reply message. * Create a reply message.
* *
* @param {Object} opts Values for the message * @param opts - Values for the message
* @param {string} opts.room The room ID for the event. * @param opts.room - The room ID for the event.
* @param {string} opts.user The user ID for the event. * @param opts.user - The user ID for the event.
* @param {string} opts.msg Optional. The content.body for the event. * @param opts.msg - Optional. The content.body for the event.
* @param {MatrixEvent} opts.replyToMessage The replied message * @param opts.replyToMessage - The replied message
* @param {boolean} opts.event True to make a MatrixEvent. * @param 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. * @param client - If passed along with opts.event=true will be used to set up re-emitters.
* @return {Object|MatrixEvent} The event * @returns The event
*/ */
export function mkReplyMessage(opts: IReplyMessageOpts & { event: true }, client?: MatrixClient): MatrixEvent; export function mkReplyMessage(opts: IReplyMessageOpts & { event: true }, client?: MatrixClient): MatrixEvent;
export function mkReplyMessage(opts: IReplyMessageOpts & { event?: false }, client?: MatrixClient): Partial<IEvent>; export function mkReplyMessage(opts: IReplyMessageOpts & { event?: false }, client?: MatrixClient): Partial<IEvent>;
@ -329,8 +329,6 @@ export function mkReplyMessage(
/** /**
* A mock implementation of webstorage * A mock implementation of webstorage
*
* @constructor
*/ */
export class MockStorageApi implements Storage { export class MockStorageApi implements Storage {
private data: Record<string, any> = {}; 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. * If an event is being decrypted, wait for it to finish being decrypted.
* *
* @param {MatrixEvent} event * @returns promise which resolves (to `event`) when the event has been decrypted
* @returns {Promise} promise which resolves (to `event`) when the event has been decrypted
*/ */
export async function awaitDecryption( export async function awaitDecryption(
event: MatrixEvent, { waitOnDecryptionFailure = false } = {}, event: MatrixEvent, { waitOnDecryptionFailure = false } = {},

View File

@ -16,7 +16,6 @@ limitations under the License.
/** /**
* This is an internal module. See {@link MatrixClient} for the public class. * This is an internal module. See {@link MatrixClient} for the public class.
* @module client
*/ */
import { mocked } from "jest-mock"; import { mocked } from "jest-mock";

View File

@ -18,7 +18,7 @@ export interface IIdentityServerProvider {
/** /**
* Gets an access token for use against the identity server, * Gets an access token for use against the identity server,
* for the associated client. * for the associated client.
* @returns {Promise<string>} Resolves to the access token. * @returns Promise which resolves to the access token.
*/ */
getAccessToken(): Promise<string>; getAccessToken(): Promise<string>;
} }

View File

@ -35,7 +35,8 @@ import { MAssetEvent, MLocationEvent, MTimestampEvent } from "./location";
* To achieve an arbitrary number of only owner-writable state events * To achieve an arbitrary number of only owner-writable state events
* we introduce a variable suffix to the event type * we introduce a variable suffix to the event type
* *
* Eg * @example
* ```
* { * {
* "type": "m.beacon_info.@matthew:matrix.org.1", * "type": "m.beacon_info.@matthew:matrix.org.1",
* "state_key": "@matthew:matrix.org", * "state_key": "@matthew:matrix.org",
@ -58,6 +59,7 @@ import { MAssetEvent, MLocationEvent, MTimestampEvent } from "./location";
* // more content as described below * // more content as described below
* } * }
* } * }
* ```
*/ */
/** /**
@ -78,20 +80,23 @@ export type MBeaconInfoContent = {
/** /**
* m.beacon_info Event example from the spec * m.beacon_info Event example from the spec
* https://github.com/matrix-org/matrix-spec-proposals/pull/3672 * https://github.com/matrix-org/matrix-spec-proposals/pull/3672
* @example
* ```
* { * {
"type": "m.beacon_info", * "type": "m.beacon_info",
"state_key": "@matthew:matrix.org", * "state_key": "@matthew:matrix.org",
"content": { * "content": {
"m.beacon_info": { * "m.beacon_info": {
"description": "The Matthew Tracker", // same as an `m.location` description * "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 * "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.ts": 1436829458432, // creation timestamp of the beacon on the client
"m.asset": { * "m.asset": {
"type": "m.self" // the type of asset being tracked as per MSC3488 * "type": "m.self" // the type of asset being tracked as per MSC3488
} * }
} * }
} * }
* ```
*/ */
/** /**
@ -107,22 +112,24 @@ export type MBeaconInfoEventContent = &
/** /**
* m.beacon event example * m.beacon event example
* https://github.com/matrix-org/matrix-spec-proposals/pull/3672 * https://github.com/matrix-org/matrix-spec-proposals/pull/3672
* * @example
* ```
* { * {
"type": "m.beacon", * "type": "m.beacon",
"sender": "@matthew:matrix.org", * "sender": "@matthew:matrix.org",
"content": { * "content": {
"m.relates_to": { // from MSC2674: https://github.com/matrix-org/matrix-doc/pull/2674 * "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 * "rel_type": "m.reference", // from MSC3267: https://github.com/matrix-org/matrix-doc/pull/3267
"event_id": "$beacon_info" * "event_id": "$beacon_info"
}, * },
"m.location": { * "m.location": {
"uri": "geo:51.5008,0.1247;u=35", * "uri": "geo:51.5008,0.1247;u=35",
"description": "Arbitrary beacon information" * "description": "Arbitrary beacon information"
}, * },
"m.ts": 1636829458432, * "m.ts": 1636829458432,
} * }
} * }
* ```
*/ */
/** /**

View File

@ -171,17 +171,21 @@ export const UNSTABLE_MSC2716_MARKER = new UnstableValue("m.room.marker", "org.m
* eventual removal. * eventual removal.
* *
* Schema (TypeScript): * Schema (TypeScript):
* ```
* { * {
* service_members?: string[] * service_members?: string[]
* } * }
* ```
* *
* Example: * @example
* ```
* { * {
* "service_members": [ * "service_members": [
* "@helperbot:localhost", * "@helperbot:localhost",
* "@reminderbot:alice.tdl" * "@reminderbot:alice.tdl"
* ] * ]
* } * }
* ```
*/ */
export const UNSTABLE_ELEMENT_FUNCTIONAL_USERS = new UnstableValue( export const UNSTABLE_ELEMENT_FUNCTIONAL_USERS = new UnstableValue(
"io.element.functional_members", "io.element.functional_members",

View File

@ -54,17 +54,31 @@ export interface ISendEventResponse {
} }
export interface IPresenceOpts { export interface IPresenceOpts {
// One of "online", "offline" or "unavailable"
presence: "online" | "offline" | "unavailable"; presence: "online" | "offline" | "unavailable";
// The status message to attach.
status_msg?: string; status_msg?: string;
} }
export interface IPaginateOpts { export interface IPaginateOpts {
// true to fill backwards, false to go forwards
backwards?: boolean; backwards?: boolean;
// number of events to request
limit?: number; limit?: number;
} }
export interface IGuestAccessOpts { 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; 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; allowRead: boolean;
} }
@ -74,7 +88,9 @@ export interface ISearchOpts {
} }
export interface IEventSearchOpts { export interface IEventSearchOpts {
// a JSON filter object to pass in the request
filter?: IRoomEventFilter; filter?: IRoomEventFilter;
// the term to search for
term: string; term: string;
} }
@ -92,9 +108,13 @@ export interface ICreateRoomStateEvent {
} }
export interface ICreateRoomOpts { export interface ICreateRoomOpts {
// The alias localpart to assign to this room.
room_alias_name?: string; room_alias_name?: string;
// Either 'public' or 'private'.
visibility?: Visibility; visibility?: Visibility;
// The name to give this room.
name?: string; name?: string;
// The topic to give this room.
topic?: string; topic?: string;
preset?: Preset; preset?: Preset;
power_level_content_override?: { power_level_content_override?: {
@ -111,6 +131,7 @@ export interface ICreateRoomOpts {
}; };
creation_content?: object; creation_content?: object;
initial_state?: ICreateRoomStateEvent[]; initial_state?: ICreateRoomStateEvent[];
// A list of user IDs to invite to this room.
invite?: string[]; invite?: string[];
invite_3pid?: IInvite3PID[]; invite_3pid?: IInvite3PID[];
is_direct?: boolean; is_direct?: boolean;
@ -121,7 +142,10 @@ export interface IRoomDirectoryOptions {
server?: string; server?: string;
limit?: number; limit?: number;
since?: string; since?: string;
// Filter parameters
filter?: { filter?: {
// String to search for
generic_search_term?: string; generic_search_term?: string;
room_types?: Array<RoomType | null>; room_types?: Array<RoomType | null>;
}; };

View File

@ -21,10 +21,9 @@ import { UnstableValue } from "../NamespacedValue";
/** /**
* Extensible topic event type based on MSC3765 * Extensible topic event type based on MSC3765
* https://github.com/matrix-org/matrix-spec-proposals/pull/3765 * https://github.com/matrix-org/matrix-spec-proposals/pull/3765
*/ *
* @example
/** * ```
* Eg
* { * {
* "type": "m.room.topic, * "type": "m.room.topic,
* "state_key": "", * "state_key": "",
@ -39,6 +38,7 @@ import { UnstableValue } from "../NamespacedValue";
* }], * }],
* } * }
* } * }
* ```
*/ */
/** /**

View File

@ -15,8 +15,6 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/** @module auto-discovery */
import { IClientWellKnown, IWellKnownConfig } from "./client"; import { IClientWellKnown, IWellKnownConfig } from "./client";
import { logger } from './logger'; import { logger } from './logger';
import { MatrixError, Method, timeoutSignal } from "./http-api"; 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 auto discovery failed. The client is expected to communicate
* the error to the user and refuse logging in. * the error to the user and refuse logging in.
* @return {string}
* @constructor
*/ */
public static readonly FAIL_ERROR = AutoDiscoveryAction.FAIL_ERROR; 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 * action it would for PROMPT while also warning the user about
* what went wrong. The client may also treat this the same as * what went wrong. The client may also treat this the same as
* a FAIL_ERROR state. * a FAIL_ERROR state.
* @return {string}
* @constructor
*/ */
public static readonly FAIL_PROMPT = AutoDiscoveryAction.FAIL_PROMPT; 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 * The auto discovery didn't fail but did not find anything of
* interest. The client is expected to prompt the user for more * interest. The client is expected to prompt the user for more
* information, or fail if it prefers. * information, or fail if it prefers.
* @return {string}
* @constructor
*/ */
public static readonly PROMPT = AutoDiscoveryAction.PROMPT; public static readonly PROMPT = AutoDiscoveryAction.PROMPT;
/** /**
* The auto discovery was successful. * The auto discovery was successful.
* @return {string}
* @constructor
*/ */
public static readonly SUCCESS = AutoDiscoveryAction.SUCCESS; public static readonly SUCCESS = AutoDiscoveryAction.SUCCESS;
@ -125,9 +115,9 @@ export class AutoDiscovery {
* and identity server URL the client would want. Additional details * and identity server URL the client would want. Additional details
* may also be included, and will be transparently brought into the * may also be included, and will be transparently brought into the
* response object unaltered. * 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. * 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 * configuration, which may include error states. Rejects on unexpected
* failure, not when verification fails. * failure, not when verification fails.
*/ */
@ -284,9 +274,9 @@ export class AutoDiscovery {
* and identity server URL the client would want. Additional details * and identity server URL the client would want. Additional details
* may also be discovered, and will be transparently included in the * may also be discovered, and will be transparently included in the
* response object unaltered. * 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". * 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 * configuration, which may include error states. Rejects on unexpected
* failure, not when discovery fails. * failure, not when discovery fails.
*/ */
@ -354,8 +344,8 @@ export class AutoDiscovery {
* Gets the raw discovery client configuration for the given domain name. * 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 * Should only be used if there's no validation to be done on the resulting
* object, otherwise use findClientConfig(). * object, otherwise use findClientConfig().
* @param {string} domain The domain to get the client config for. * @param domain - The domain to get the client config for.
* @returns {Promise<object>} Resolves to the domain's client config. Can * @returns Promise which resolves to the domain's client config. Can
* be an empty object. * be an empty object.
*/ */
public static async getRawClientConfig(domain?: string): Promise<IClientWellKnown> { 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 * 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. * is suitable for the requirements laid out by .well-known auto discovery.
* If valid, the URL will also be stripped of any trailing slashes. * If valid, the URL will also be stripped of any trailing slashes.
* @param {string} url The potentially invalid URL to sanitize. * @param url - The potentially invalid URL to sanitize.
* @return {string|boolean} The sanitized URL or a falsey value if the URL is invalid. * @returns The sanitized URL or a falsey value if the URL is invalid.
* @private * @internal
*/ */
private static sanitizeWellKnownUrl(url?: string | null): string | false { private static sanitizeWellKnownUrl(url?: string | null): string | false {
if (!url) return false; if (!url) return false;
@ -430,9 +420,9 @@ export class AutoDiscovery {
* action: One of SUCCESS, IGNORE, or FAIL_PROMPT. * action: One of SUCCESS, IGNORE, or FAIL_PROMPT.
* reason: Relatively human-readable description of what went wrong. * reason: Relatively human-readable description of what went wrong.
* error: The actual Error, if one exists. * error: The actual Error, if one exists.
* @param {string} url The URL to fetch a JSON object from. * @param url - The URL to fetch a JSON object from.
* @return {Promise<object>} Resolves to the returned state. * @returns Promise which resolves to the returned state.
* @private * @internal
*/ */
private static async fetchWellKnownObject(url: string): Promise<IWellKnownConfig> { private static async fetchWellKnownObject(url: string): Promise<IWellKnownConfig> {
let response: Response; let response: Response;

File diff suppressed because it is too large Load Diff

View File

@ -14,8 +14,6 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/** @module ContentHelpers */
import { isProvided, REFERENCE_RELATION } from "matrix-events-sdk"; import { isProvided, REFERENCE_RELATION } from "matrix-events-sdk";
import { MBeaconEventContent, MBeaconInfoContent, MBeaconInfoEventContent } from "./@types/beacon"; import { MBeaconEventContent, MBeaconInfoContent, MBeaconInfoEventContent } from "./@types/beacon";
@ -37,9 +35,9 @@ import { IContent } from "./models/event";
/** /**
* Generates the content for a HTML Message event * Generates the content for a HTML Message event
* @param {string} body the plaintext body of the message * @param body - the plaintext body of the message
* @param {string} htmlBody the HTML representation of the message * @param htmlBody - the HTML representation of the message
* @returns {{msgtype: string, format: string, body: string, formatted_body: string}} * @returns
*/ */
export function makeHtmlMessage(body: string, htmlBody: string): IContent { export function makeHtmlMessage(body: string, htmlBody: string): IContent {
return { return {
@ -52,9 +50,9 @@ export function makeHtmlMessage(body: string, htmlBody: string): IContent {
/** /**
* Generates the content for a HTML Notice event * Generates the content for a HTML Notice event
* @param {string} body the plaintext body of the notice * @param body - the plaintext body of the notice
* @param {string} htmlBody the HTML representation of the notice * @param htmlBody - the HTML representation of the notice
* @returns {{msgtype: string, format: string, body: string, formatted_body: string}} * @returns
*/ */
export function makeHtmlNotice(body: string, htmlBody: string): IContent { export function makeHtmlNotice(body: string, htmlBody: string): IContent {
return { return {
@ -67,9 +65,9 @@ export function makeHtmlNotice(body: string, htmlBody: string): IContent {
/** /**
* Generates the content for a HTML Emote event * Generates the content for a HTML Emote event
* @param {string} body the plaintext body of the emote * @param body - the plaintext body of the emote
* @param {string} htmlBody the HTML representation of the emote * @param htmlBody - the HTML representation of the emote
* @returns {{msgtype: string, format: string, body: string, formatted_body: string}} * @returns
*/ */
export function makeHtmlEmote(body: string, htmlBody: string): IContent { export function makeHtmlEmote(body: string, htmlBody: string): IContent {
return { return {
@ -82,8 +80,8 @@ export function makeHtmlEmote(body: string, htmlBody: string): IContent {
/** /**
* Generates the content for a Plaintext Message event * Generates the content for a Plaintext Message event
* @param {string} body the plaintext body of the emote * @param body - the plaintext body of the emote
* @returns {{msgtype: string, body: string}} * @returns
*/ */
export function makeTextMessage(body: string): IContent { export function makeTextMessage(body: string): IContent {
return { return {
@ -94,8 +92,8 @@ export function makeTextMessage(body: string): IContent {
/** /**
* Generates the content for a Plaintext Notice event * Generates the content for a Plaintext Notice event
* @param {string} body the plaintext body of the notice * @param body - the plaintext body of the notice
* @returns {{msgtype: string, body: string}} * @returns
*/ */
export function makeNotice(body: string): IContent { export function makeNotice(body: string): IContent {
return { return {
@ -106,8 +104,8 @@ export function makeNotice(body: string): IContent {
/** /**
* Generates the content for a Plaintext Emote event * Generates the content for a Plaintext Emote event
* @param {string} body the plaintext body of the emote * @param body - the plaintext body of the emote
* @returns {{msgtype: string, body: string}} * @returns
*/ */
export function makeEmoteMessage(body: string): IContent { export function makeEmoteMessage(body: string): IContent {
return { return {
@ -139,11 +137,11 @@ export const getTextForLocationEvent = (
/** /**
* Generates the content for a Location event * Generates the content for a Location event
* @param uri a geo:// uri 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 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 description - the (optional) label for this location on the map
* @param assetType the (optional) asset type of this location e.g. "m.self" * @param assetType - the (optional) asset type of this location e.g. "m.self"
* @param text optional. A text for the location * @param text - optional. A text for the location
*/ */
export const makeLocationContent = ( export const makeLocationContent = (
// this is first but optional // this is first but optional

View File

@ -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 See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/**
* @module content-repo
*/
import * as utils from "./utils"; import * as utils from "./utils";
/** /**
* Get the HTTP URL for an MXC URI. * Get the HTTP URL for an MXC URI.
* @param {string} baseUrl The base homeserver url which has a content repo. * @param baseUrl - The base homeserver url which has a content repo.
* @param {string} mxc The mxc:// URI. * @param mxc - The mxc:// URI.
* @param {Number} width The desired width of the thumbnail. * @param width - The desired width of the thumbnail.
* @param {Number} height The desired height of the thumbnail. * @param height - The desired height of the thumbnail.
* @param {string} resizeMethod The thumbnail resize method to use, either * @param resizeMethod - The thumbnail resize method to use, either
* "crop" or "scale". * "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 * directly. Fetching such URLs will leak information about the user to
* anyone they share a room with. If false, will return the emptry string * anyone they share a room with. If false, will return the emptry string
* for such URLs. * for such URLs.
* @return {string} The complete URL to the content. * @returns The complete URL to the content.
*/ */
export function getHttpUriForMxc( export function getHttpUriForMxc(
baseUrl: string, baseUrl: string,

View File

@ -16,7 +16,6 @@ limitations under the License.
/** /**
* Cross signing methods * Cross signing methods
* @module crypto/CrossSigning
*/ */
import { PkSigning } from "@matrix-org/olm"; import { PkSigning } from "@matrix-org/olm";
@ -67,12 +66,10 @@ export class CrossSigningInfo {
/** /**
* Information about a user's cross-signing keys * Information about a user's cross-signing keys
* *
* @class * @param userId - the user that the information is about
* * @param callbacks - Callbacks used to interact with the app
* @param {string} userId the user that the information is about
* @param {object} callbacks Callbacks used to interact with the app
* Requires getCrossSigningKey and saveCrossSigningKeys * 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 constructor(
public readonly userId: string, public readonly userId: string,
@ -102,10 +99,10 @@ export class CrossSigningInfo {
/** /**
* Calls the app callback to ask for a private key * Calls the app callback to ask for a private key
* *
* @param {string} type The key type ("master", "self_signing", or "user_signing") * @param type - The key type ("master", "self_signing", or "user_signing")
* @param {string} expectedPubkey The matching public key or undefined to use * @param expectedPubkey - The matching public key or undefined to use
* the stored public key for the given key type. * 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]> { public async getCrossSigningKey(type: string, expectedPubkey?: string): Promise<[string, PkSigning]> {
const shouldCache = ["master", "self_signing", "user_signing"].indexOf(type) >= 0; 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 * XXX: This could be static, be we often seem to have an instance when we
* want to know this anyway... * want to know this anyway...
* *
* @param {SecretStorage} secretStorage The secret store using account data * @param secretStorage - The secret store using account data
* @returns {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 * with, or null if it is not present or not encrypted with a trusted
* key * key
*/ */
@ -194,8 +191,8 @@ export class CrossSigningInfo {
* typically called in conjunction with the creation of new cross-signing * typically called in conjunction with the creation of new cross-signing
* keys. * keys.
* *
* @param {Map} keys The keys to store * @param keys - The keys to store
* @param {SecretStorage} secretStorage The secret store using account data * @param secretStorage - The secret store using account data
*/ */
public static async storeInSecretStorage( public static async storeInSecretStorage(
keys: Map<string, Uint8Array>, keys: Map<string, Uint8Array>,
@ -211,10 +208,10 @@ export class CrossSigningInfo {
* Get private keys from secret storage created by some other device. This * Get private keys from secret storage created by some other device. This
* also passes the private keys to the app-specific callback. * 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". * "self_signing", or "user_signing".
* @param {SecretStorage} secretStorage The secret store using account data * @param secretStorage - The secret store using account data
* @return {Uint8Array} The private key * @returns The private key
*/ */
public static async getFromSecretStorage(type: string, secretStorage: SecretStorage): Promise<Uint8Array | null> { public static async getFromSecretStorage(type: string, secretStorage: SecretStorage): Promise<Uint8Array | null> {
const encodedKey = await secretStorage.get(`m.cross_signing.${type}`); 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. * 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. * "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> { public async isStoredInKeyCache(type?: string): Promise<boolean> {
const cacheCallbacks = this.cacheCallbacks; const cacheCallbacks = this.cacheCallbacks;
@ -246,7 +243,7 @@ export class CrossSigningInfo {
/** /**
* Get cross-signing private keys from the local cache. * 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>> { public async getCrossSigningKeysFromCache(): Promise<Map<string, Uint8Array>> {
const keys = new Map(); 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 * Get the ID used to identify the user. This can also be used to test for
* the existence of a given key type. * 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". * "self_signing", or "user_signing". Defaults to "master".
* *
* @return {string} the ID * @returns the ID
*/ */
public getId(type = "master"): string | null { public getId(type = "master"): string | null {
if (!this.keys[type]) return 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 * will be held in this class, while the private keys are passed off to the
* `saveCrossSigningKeys` application callback. * `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> { public async resetKeys(level?: CrossSigningLevel): Promise<void> {
if (!this.callbacks.saveCrossSigningKeys) { if (!this.callbacks.saveCrossSigningKeys) {
@ -502,9 +499,9 @@ export class CrossSigningInfo {
/** /**
* Check whether a given user is trusted. * 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 { public checkUserTrust(userCrossSigning: CrossSigningInfo): UserTrustLevel {
// if we're checking our own key, then it's trusted if the master key // 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. * Check whether a given device is trusted.
* *
* @param {CrossSigningInfo} userCrossSigning Cross signing info for user * @param userCrossSigning - Cross signing info for user
* @param {module:crypto/deviceinfo} device The device to check * @param device - The device to check
* @param {boolean} localTrust Whether the device is trusted locally * @param localTrust - Whether the device is trusted locally
* @param {boolean} trustCrossSignedDevices Whether we trust cross signed devices * @param trustCrossSignedDevices - Whether we trust cross signed devices
* *
* @returns {DeviceTrustLevel} * @returns
*/ */
public checkDeviceTrust( public checkDeviceTrust(
userCrossSigning: CrossSigningInfo, userCrossSigning: CrossSigningInfo,
@ -580,7 +577,7 @@ export class CrossSigningInfo {
} }
/** /**
* @returns {object} Cache callbacks * @returns Cache callbacks
*/ */
public getCacheCallbacks(): ICacheCallbacks { public getCacheCallbacks(): ICacheCallbacks {
return this.cacheCallbacks; 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 { public isVerified(): boolean {
return this.isCrossSigningVerified(); 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 { public isCrossSigningVerified(): boolean {
return this.crossSigningVerified; 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). * the history of verifications observed by this device).
*/ */
public wasCrossSigningVerified(): boolean { 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 { public isTofu(): boolean {
return this.tofu; 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 { public isVerified(): boolean {
return Boolean(this.isLocallyVerified() || ( 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 { public isCrossSigningVerified(): boolean {
return this.crossSigningVerified; return this.crossSigningVerified;
} }
/** /**
* @returns {boolean} true if this device is verified locally * @returns true if this device is verified locally
*/ */
public isLocallyVerified(): boolean { public isLocallyVerified(): boolean {
return this.localVerified; 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 * that is trusted on first use
*/ */
public isTofu(): boolean { public isTofu(): boolean {
@ -757,9 +754,9 @@ export type KeysDuringVerification = [[string, PkSigning], [string, PkSigning],
/** /**
* Request cross-signing keys from another device during verification. * Request cross-signing keys from another device during verification.
* *
* @param {MatrixClient} baseApis base Matrix API interface * @param baseApis - base Matrix API interface
* @param {string} userId The user ID being verified * @param userId - The user ID being verified
* @param {string} deviceId The device ID being verified * @param deviceId - The device ID being verified
*/ */
export async function requestKeysDuringVerification( export async function requestKeysDuringVerification(
baseApis: MatrixClient, baseApis: MatrixClient,

View File

@ -15,8 +15,6 @@ limitations under the License.
*/ */
/** /**
* @module crypto/DeviceList
*
* Manages the list of other users' devices * 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; type EmittedEvents = CryptoEvent.WillUpdateDevices | CryptoEvent.DevicesUpdated | CryptoEvent.UserCrossSigningUpdated;
/**
* @alias module:crypto/DeviceList
*/
export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHandlerMap> { export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHandlerMap> {
private devices: { [userId: string]: { [deviceId: string]: IDevice } } = {}; 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 * The actual save will be delayed by a short amount of time to
* aggregate multiple writes to the database. * 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 * 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. * 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 * it was not (eg. because no changes were pending). The promise
* will only resolve once the data is saved, so may take some time * will only resolve once the data is saved, so may take some time
* to resolve. * to resolve.
@ -236,7 +231,7 @@ export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHand
/** /**
* Gets the sync token last set with setSyncToken * Gets the sync token last set with setSyncToken
* *
* @return {string} The sync token * @returns The sync token
*/ */
public getSyncToken(): string | null { public getSyncToken(): string | null {
return this.syncToken; 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 * those changed will not be synced from the server if a new client starts
* up with that data. * up with that data.
* *
* @param {string} st The sync token * @param st - The sync token
*/ */
public setSyncToken(st: string | null): void { public setSyncToken(st: string | null): void {
this.syncToken = st; 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, * 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 * downloading and storing them if they're not (or if forceDownload is
* true). * true).
* @param {Array} userIds The users to fetch. * @param userIds - The users to fetch.
* @param {boolean} forceDownload Always download the keys even if cached. * @param forceDownload - Always download the keys even if cached.
* *
* @return {Promise} A promise which resolves to a map userId->deviceId->{@link * @returns A promise which resolves to a map userId-\>deviceId-\>{@link DeviceInfo}.
* module:crypto/deviceinfo|DeviceInfo}.
*/ */
public downloadKeys(userIds: string[], forceDownload: boolean): Promise<DeviceInfoMap> { public downloadKeys(userIds: string[], forceDownload: boolean): Promise<DeviceInfoMap> {
const usersToDownload: string[] = []; 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 * 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 { private getDevicesFromStore(userIds: string[]): DeviceInfoMap {
const stored: 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 * 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[] { public getKnownUserIds(): string[] {
return Object.keys(this.devices); 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 * 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. * managed to get a list of devices for this user yet.
*/ */
public getStoredDevicesForUser(userId: string): DeviceInfo[] | null { 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 * 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. * there is no data for this user.
*/ */
public getRawStoredDevicesForUser(userId: string): Record<string, IDevice> { 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 * 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 * if we don't know about this device
*/ */
public getStoredDevice(userId: string, deviceId: string): DeviceInfo | undefined { 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 * Get a user ID by one of their device's curve25519 identity key
* *
* @param {string} algorithm encryption algorithm * @param algorithm - encryption algorithm
* @param {string} senderKey curve25519 key to match * @param senderKey - curve25519 key to match
* *
* @return {string} user ID * @returns user ID
*/ */
public getUserByIdentityKey(algorithm: string, senderKey: string): string | null { public getUserByIdentityKey(algorithm: string, senderKey: string): string | null {
if (algorithm !== olmlib.OLM_ALGORITHM && algorithm !== olmlib.MEGOLM_ALGORITHM) { 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 * Find a device by curve25519 identity key
* *
* @param {string} algorithm encryption algorithm * @param algorithm - encryption algorithm
* @param {string} senderKey curve25519 key to match * @param senderKey - curve25519 key to match
*
* @return {module:crypto/deviceinfo?}
*/ */
public getDeviceByIdentityKey(algorithm: string, senderKey: string): DeviceInfo | null { public getDeviceByIdentityKey(algorithm: string, senderKey: string): DeviceInfo | null {
const userId = this.getUserByIdentityKey(algorithm, senderKey); 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 * Replaces the list of devices for a user with the given device list
* *
* @param {string} userId The user ID * @param userId - The user ID
* @param {Object} devices New device info for user * @param devices - New device info for user
*/ */
public storeDevicesForUser(userId: string, devices: Record<string, IDevice>): void { public storeDevicesForUser(userId: string, devices: Record<string, IDevice>): void {
this.setRawStoredDevicesForUser(userId, devices); 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 * will download the device list for the user, and that subsequent calls to
* invalidateUserDeviceList will trigger more updates. * invalidateUserDeviceList will trigger more updates.
* *
* @param {String} userId
*/ */
public startTrackingDeviceList(userId: string): void { public startTrackingDeviceList(userId: string): void {
// sanity-check the userId. This is mostly paranoia, but if synapse // 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 * complete; it will just mean that we don't think that we have an up-to-date
* list for future calls to downloadKeys. * list for future calls to downloadKeys.
* *
* @param {String} userId
*/ */
public stopTrackingDeviceList(userId: string): void { public stopTrackingDeviceList(userId: string): void {
if (this.deviceTrackingStatus[userId]) { 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 * This doesn't actually set off an update, so that several users can be
* batched together. Call refreshOutdatedDeviceLists() for that. * batched together. Call refreshOutdatedDeviceLists() for that.
* *
* @param {String} userId
*/ */
public invalidateUserDeviceList(userId: string): void { public invalidateUserDeviceList(userId: string): void {
if (this.deviceTrackingStatus[userId]) { 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 * 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). * is no need to wait for this (it's mostly for the unit tests).
*/ */
public refreshOutdatedDeviceLists(): Promise<void> { 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 * Set the stored device data for a user, in raw object form
* Used only by internal class DeviceListUpdateSerialiser * 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 { public setRawStoredDevicesForUser(userId: string, devices: Record<string, IDevice>): void {
// remove old devices from userByIdentityKey // remove old devices from userByIdentityKey
@ -602,9 +589,9 @@ export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHand
* device list tracking status for them, and the * device list tracking status for them, and the
* keyDownloadsInProgressByUser map for them. * 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 * been updated. rejects if there was a problem updating any of the
* users. * users.
*/ */
@ -689,9 +676,9 @@ class DeviceListUpdateSerialiser {
private syncToken?: string; // The sync token we send with the requests private syncToken?: string; // The sync token we send with the requests
/* /*
* @param {object} baseApis Base API object * @param baseApis - Base API object
* @param {object} olmDevice The Olm Device * @param olmDevice - The Olm Device
* @param {object} deviceList The device list object, the device list to be updated * @param deviceList - The device list object, the device list to be updated
*/ */
public constructor( public constructor(
private readonly baseApis: MatrixClient, private readonly baseApis: MatrixClient,
@ -702,12 +689,12 @@ class DeviceListUpdateSerialiser {
/** /**
* Make a key query request for the given users * 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 * 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 * been updated. rejects if there was a problem updating any of the
* users. * users.
*/ */

View File

@ -58,8 +58,8 @@ export class EncryptionSetupBuilder {
private sessionBackupPrivateKey?: Uint8Array; private sessionBackupPrivateKey?: Uint8Array;
/** /**
* @param {Object.<String, MatrixEvent>} accountData pre-existing account data, will only be read, not written. * @param 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 delegateCryptoCallbacks - crypto callbacks to delegate to if the key isn't in cache yet
*/ */
public constructor(accountData: Record<string, MatrixEvent>, delegateCryptoCallbacks?: ICryptoCallbacks) { public constructor(accountData: Record<string, MatrixEvent>, delegateCryptoCallbacks?: ICryptoCallbacks) {
this.accountDataClientAdapter = new AccountDataClientAdapter(accountData); this.accountDataClientAdapter = new AccountDataClientAdapter(accountData);
@ -70,13 +70,13 @@ export class EncryptionSetupBuilder {
/** /**
* Adds new cross-signing public keys * 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. * flow when uploading device signing keys.
* Args: * 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 * the auth data as an object. Can be called multiple times, first with
* an empty authDict, to obtain the flows. * 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 { public addCrossSigningKeys(authUpload: ICrossSigningKeys["authUpload"], keys: ICrossSigningKeys["keys"]): void {
this.crossSigningKeys = { authUpload, keys }; this.crossSigningKeys = { authUpload, keys };
@ -88,7 +88,7 @@ export class EncryptionSetupBuilder {
* Used either to create a new key backup, or add signatures * Used either to create a new key backup, or add signatures
* from the new MSK. * 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 { public addSessionBackup(keyBackupInfo: IKeyBackupInfo): void {
this.keyBackupInfo = keyBackupInfo; this.keyBackupInfo = keyBackupInfo;
@ -99,7 +99,6 @@ export class EncryptionSetupBuilder {
* *
* Used after fixing the format of the key * Used after fixing the format of the key
* *
* @param {Uint8Array} privateKey
*/ */
public addSessionBackupPrivateKeyToCache(privateKey: Uint8Array): void { public addSessionBackupPrivateKeyToCache(privateKey: Uint8Array): void {
this.sessionBackupPrivateKey = privateKey; this.sessionBackupPrivateKey = privateKey;
@ -109,9 +108,6 @@ export class EncryptionSetupBuilder {
* Add signatures from a given user and device/x-sign key * Add signatures from a given user and device/x-sign key
* Used to sign the new cross-signing key with the device 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 { public addKeySignature(userId: string, deviceId: string, signature: ISignedKey): void {
if (!this.keySignatures) { if (!this.keySignatures) {
@ -122,18 +118,12 @@ export class EncryptionSetupBuilder {
userSignatures[deviceId] = signature; userSignatures[deviceId] = signature;
} }
/**
* @param {String} type
* @param {Object} content
* @return {Promise}
*/
public async setAccountData(type: string, content: object): Promise<void> { public async setAccountData(type: string, content: object): Promise<void> {
await this.accountDataClientAdapter.setAccountData(type, content); await this.accountDataClientAdapter.setAccountData(type, content);
} }
/** /**
* builds the operation containing all the parts that have been added to the builder * builds the operation containing all the parts that have been added to the builder
* @return {EncryptionSetupOperation}
*/ */
public buildOperation(): EncryptionSetupOperation { public buildOperation(): EncryptionSetupOperation {
const accountData = this.accountDataClientAdapter.values; 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, * This does not yet store the operation in a way that it can be restored,
* but that is the idea in the future. * but that is the idea in the future.
*
* @param {Crypto} crypto
* @return {Promise}
*/ */
public async persist(crypto: Crypto): Promise<void> { public async persist(crypto: Crypto): Promise<void> {
// store private keys in cache // store private keys in cache
@ -187,10 +174,6 @@ export class EncryptionSetupBuilder {
*/ */
export class EncryptionSetupOperation { export class EncryptionSetupOperation {
/** /**
* @param {Map<String, Object>} accountData
* @param {Object} crossSigningKeys
* @param {Object} keyBackupInfo
* @param {Object} keySignatures
*/ */
public constructor( public constructor(
private readonly accountData: Map<string, object>, 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. * 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> { public async apply(crypto: Crypto): Promise<void> {
const baseApis = crypto.baseApis; const baseApis = crypto.baseApis;
@ -270,23 +252,21 @@ class AccountDataClientAdapter
public readonly values = new Map<string, MatrixEvent>(); 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>) { public constructor(private readonly existingValues: Record<string, MatrixEvent>) {
super(); super();
} }
/** /**
* @param {String} type * @returns the content of the account data
* @return {Promise<Object>} the content of the account data
*/ */
public getAccountDataFromServer<T extends {[k: string]: any}>(type: string): Promise<T> { public getAccountDataFromServer<T extends {[k: string]: any}>(type: string): Promise<T> {
return Promise.resolve(this.getAccountData(type) as T); return Promise.resolve(this.getAccountData(type) as T);
} }
/** /**
* @param {String} type * @returns the content of the account data
* @return {Object} the content of the account data
*/ */
public getAccountData(type: string): IContent | null { public getAccountData(type: string): IContent | null {
const modifiedValue = this.values.get(type); const modifiedValue = this.values.get(type);
@ -300,11 +280,6 @@ class AccountDataClientAdapter
return null; return null;
} }
/**
* @param {String} type
* @param {Object} content
* @return {Promise}
*/
public setAccountData(type: string, content: any): Promise<{}> { public setAccountData(type: string, content: any): Promise<{}> {
const lastEvent = this.values.get(type); const lastEvent = this.values.get(type);
this.values.set(type, content); this.values.set(type, content);

View File

@ -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 { interface IInitOpts {
fromExportedDevice?: IExportedDevice; fromExportedDevice?: IExportedDevice;
pickleKey?: string; pickleKey?: string;
} }
/** /** data stored in the session store about an inbound group session */
* 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.
*/
export interface InboundGroupSessionData { export interface InboundGroupSessionData {
room_id: string; // eslint-disable-line camelcase room_id: string; // eslint-disable-line camelcase
/** pickled Olm.InboundGroupSession */
session: string; session: string;
keysClaimed: Record<string, string>; keysClaimed: Record<string, string>;
/** Devices involved in forwarding this session to us (normally empty). */
forwardingCurve25519KeyChain: string[]; forwardingCurve25519KeyChain: string[];
/** whether this session is untrusted. */
untrusted?: boolean; untrusted?: boolean;
/** whether this session exists during the room being set to shared history. */
sharedHistory?: boolean; sharedHistory?: boolean;
} }
@ -134,20 +113,13 @@ type OneTimeKeys = { curve25519: { [keyId: string]: string } };
* OlmAccount and a number of OlmSessions. * OlmAccount and a number of OlmSessions.
* *
* Accounts and sessions are kept pickled in the cryptoStore. * 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 { export class OlmDevice {
public pickleKey = "DEFAULT_KEY"; // set by consumers 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; 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; public deviceEd25519Key: string | null = null;
private maxOneTimeKeys: number | 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] { public static getOlmVersion(): [number, number, number] {
return global.Olm.get_library_version(); return global.Olm.get_library_version();
@ -202,12 +174,11 @@ export class OlmDevice {
* *
* Reads the device keys from the OlmAccount object. * Reads the device keys from the OlmAccount object.
* *
* @param {object} opts * @param fromExportedDevice - (Optional) data from exported device
* @param {object} opts.fromExportedDevice (Optional) data from exported device
* that must be re-created. * that must be re-created.
* If present, opts.pickleKey is ignored * If present, opts.pickleKey is ignored
* (exported data already provides a pickle key) * (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> { public async init({ pickleKey, fromExportedDevice }: IInitOpts = {}): Promise<void> {
let e2eKeys; let e2eKeys;
@ -245,9 +216,9 @@ export class OlmDevice {
* Note that for now only the “account” and “sessions” stores are populated; * Note that for now only the “account” and “sessions” stores are populated;
* Other stores will be as with a new device. * 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. * 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> { private async initialiseFromExportedDevice(exportedData: IExportedDevice, account: Account): Promise<void> {
await this.cryptoStore.doTxn( await this.cryptoStore.doTxn(
@ -305,9 +276,8 @@ export class OlmDevice {
* This function requires a live transaction object from cryptoStore.doTxn() * This function requires a live transaction object from cryptoStore.doTxn()
* and therefore may only be called in a doTxn() callback. * and therefore may only be called in a doTxn() callback.
* *
* @param {*} txn Opaque transaction object from cryptoStore.doTxn() * @param txn - Opaque transaction object from cryptoStore.doTxn()
* @param {function} func * @internal
* @private
*/ */
private getAccount(txn: unknown, func: (account: Account) => void): void { private getAccount(txn: unknown, func: (account: Account) => void): void {
this.cryptoStore.getAccount(txn, (pickledAccount: string | null) => { this.cryptoStore.getAccount(txn, (pickledAccount: string | null) => {
@ -326,9 +296,9 @@ export class OlmDevice {
* This function requires a live transaction object from cryptoStore.doTxn() * This function requires a live transaction object from cryptoStore.doTxn()
* and therefore may only be called in a doTxn() callback. * and therefore may only be called in a doTxn() callback.
* *
* @param {*} txn Opaque transaction object from cryptoStore.doTxn() * @param txn - Opaque transaction object from cryptoStore.doTxn()
* @param {object} Olm.Account object * @param Olm.Account object
* @private * @internal
*/ */
private storeAccount(txn: unknown, account: Account): void { private storeAccount(txn: unknown, account: Account): void {
this.cryptoStore.storeAccount(txn, account.pickle(this.pickleKey)); this.cryptoStore.storeAccount(txn, account.pickle(this.pickleKey));
@ -338,7 +308,7 @@ export class OlmDevice {
* Export data for re-creating the Olm device later. * Export data for re-creating the Olm device later.
* TODO export data other than just account and (P2P) sessions. * 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> { public async export(): Promise<IExportedDevice> {
const result: Partial<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* * function and will be freed as soon the callback returns. It is *not*
* usable for the rest of the lifetime of the transaction. * usable for the rest of the lifetime of the transaction.
* *
* @param {string} deviceKey * @param txn - Opaque transaction object from cryptoStore.doTxn()
* @param {string} sessionId * @internal
* @param {*} txn Opaque transaction object from cryptoStore.doTxn()
* @param {function} func
* @private
*/ */
private getSession( private getSession(
deviceKey: string, deviceKey: string,
@ -397,9 +364,7 @@ export class OlmDevice {
* function with it. The session object is destroyed once the function * function with it. The session object is destroyed once the function
* returns. * returns.
* *
* @param {object} sessionInfo * @internal
* @param {function} func
* @private
*/ */
private unpickleSession( private unpickleSession(
sessionInfo: ISessionInfo, sessionInfo: ISessionInfo,
@ -419,10 +384,9 @@ export class OlmDevice {
/** /**
* store our OlmSession in the session store * store our OlmSession in the session store
* *
* @param {string} deviceKey * @param sessionInfo - `{session: OlmSession, lastReceivedMessageTs: int}`
* @param {object} sessionInfo {session: OlmSession, lastReceivedMessageTs: int} * @param txn - Opaque transaction object from cryptoStore.doTxn()
* @param {*} txn Opaque transaction object from cryptoStore.doTxn() * @internal
* @private
*/ */
private saveSession(deviceKey: string, sessionInfo: IUnpickledSessionInfo, txn: unknown): void { private saveSession(deviceKey: string, sessionInfo: IUnpickledSessionInfo, txn: unknown): void {
const sessionId = sessionInfo.session.session_id(); const sessionId = sessionInfo.session.session_id();
@ -435,9 +399,8 @@ export class OlmDevice {
/** /**
* get an OlmUtility and call the given function * get an OlmUtility and call the given function
* *
* @param {function} func * @returns result of func
* @return {object} result of func * @internal
* @private
*/ */
private getUtility<T>(func: (utility: Utility) => T): T { private getUtility<T>(func: (utility: Utility) => T): T {
const utility = new global.Olm.Utility(); const utility = new global.Olm.Utility();
@ -451,8 +414,8 @@ export class OlmDevice {
/** /**
* Signs a message with the ed25519 key for this account. * Signs a message with the ed25519 key for this account.
* *
* @param {string} message message to be signed * @param message - message to be signed
* @return {Promise<string>} base64-encoded signature * @returns base64-encoded signature
*/ */
public async sign(message: string): Promise<string> { public async sign(message: string): Promise<string> {
let result: string; let result: string;
@ -469,7 +432,7 @@ export class OlmDevice {
/** /**
* Get the current (unused, unpublished) one-time keys for this account. * 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 * <tt>curve25519</tt>, which is itself an object mapping key id to Curve25519
* key. * key.
*/ */
@ -490,7 +453,7 @@ export class OlmDevice {
/** /**
* Get the maximum number of one-time keys we can store. * Get the maximum number of one-time keys we can store.
* *
* @return {number} number of keys * @returns number of keys
*/ */
public maxNumberOfOneTimeKeys(): number { public maxNumberOfOneTimeKeys(): number {
return this.maxOneTimeKeys ?? -1; return this.maxOneTimeKeys ?? -1;
@ -514,8 +477,8 @@ export class OlmDevice {
/** /**
* Generate some new one-time keys * Generate some new one-time keys
* *
* @param {number} numKeys number of keys to generate * @param numKeys - number of keys to generate
* @return {Promise} Resolved once the account is saved back having generated the keys * @returns Resolved once the account is saved back having generated the keys
*/ */
public generateOneTimeKeys(numKeys: number): Promise<void> { public generateOneTimeKeys(numKeys: number): Promise<void> {
return this.cryptoStore.doTxn( return this.cryptoStore.doTxn(
@ -532,7 +495,7 @@ export class OlmDevice {
/** /**
* Generate a new fallback keys * 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> { public async generateFallbackKey(): Promise<void> {
await this.cryptoStore.doTxn( await this.cryptoStore.doTxn(
@ -576,9 +539,9 @@ export class OlmDevice {
* *
* The new session will be stored in the cryptoStore. * The new session will be stored in the cryptoStore.
* *
* @param {string} theirIdentityKey remote user's Curve25519 identity key * @param theirIdentityKey - remote user's Curve25519 identity key
* @param {string} theirOneTimeKey remote user's one-time Curve25519 key * @param theirOneTimeKey - remote user's one-time Curve25519 key
* @return {string} sessionId for the outbound session. * @returns sessionId for the outbound session.
*/ */
public async createOutboundSession(theirIdentityKey: string, theirOneTimeKey: string): Promise<string> { public async createOutboundSession(theirIdentityKey: string, theirOneTimeKey: string): Promise<string> {
let newSessionId: string; let newSessionId: string;
@ -615,15 +578,14 @@ export class OlmDevice {
/** /**
* Generate a new inbound session, given an incoming message * Generate a new inbound session, given an incoming message
* *
* @param {string} theirDeviceIdentityKey remote user's Curve25519 identity key * @param theirDeviceIdentityKey - remote user's Curve25519 identity key
* @param {number} messageType messageType field from the received message (must be 0) * @param messageType - messageType field from the received message (must be 0)
* @param {string} ciphertext base64-encoded body from the received message * @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 * session id of new session
* *
* @raises {Error} if the received message was not valid (for instance, it * @throws Error if the received message was not valid (for instance, it didn't use a valid one-time key).
* didn't use a valid one-time key).
*/ */
public async createInboundSession( public async createInboundSession(
theirDeviceIdentityKey: string, theirDeviceIdentityKey: string,
@ -676,9 +638,9 @@ export class OlmDevice {
/** /**
* Get a list of known session IDs for the given device * 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 * 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[]> { public async getSessionIdsForDevice(theirDeviceIdentityKey: string): Promise<string[]> {
const log = logger.withPrefix("[getSessionIdsForDevice]"); 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 * 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 * 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 * This should only be set to true of the calling function is the function
* that marked the session as being in-progress. * that marked the session as being in-progress.
* @param {PrefixedLogger} [log] A possibly customised log * @param log - A possibly customised log
* @return {Promise<?string>} session id, or null if no established session * @returns session id, or null if no established session
*/ */
public async getSessionIdForDevice( public async getSessionIdForDevice(
theirDeviceIdentityKey: string, theirDeviceIdentityKey: string,
@ -759,12 +721,11 @@ export class OlmDevice {
* the keys 'hasReceivedMessage' (true if the session has received an incoming * the keys 'hasReceivedMessage' (true if the session has received an incoming
* message and is therefore past the pre-key stage), and 'sessionId'. * message and is therefore past the pre-key stage), and 'sessionId'.
* *
* @param {string} deviceIdentityKey Curve25519 identity key for the device * @param deviceIdentityKey - Curve25519 identity key for the 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 * This should only be set to true of the calling function is the function
* that marked the session as being in-progress. * that marked the session as being in-progress.
* @param {Logger} [log] A possibly customised log * @param log - A possibly customised log
* @return {Array.<{sessionId: string, hasReceivedMessage: boolean}>}
*/ */
public async getSessionInfoForDevice( public async getSessionInfoForDevice(
deviceIdentityKey: string, deviceIdentityKey: string,
@ -813,12 +774,12 @@ export class OlmDevice {
/** /**
* Encrypt an outgoing message using an existing session * 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 * remote device
* @param {string} sessionId the id of the active session * @param sessionId - the id of the active session
* @param {string} payloadString payload to be encrypted and sent * @param payloadString - payload to be encrypted and sent
* *
* @return {Promise<string>} ciphertext * @returns ciphertext
*/ */
public async encryptMessage( public async encryptMessage(
theirDeviceIdentityKey: string, theirDeviceIdentityKey: string,
@ -849,13 +810,13 @@ export class OlmDevice {
/** /**
* Decrypt an incoming message using an existing session * 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 * remote device
* @param {string} sessionId the id of the active session * @param sessionId - the id of the active session
* @param {number} messageType messageType field from the received message * @param messageType - messageType field from the received message
* @param {string} ciphertext base64-encoded body from the received message * @param ciphertext - base64-encoded body from the received message
* *
* @return {Promise<string>} decrypted payload. * @returns decrypted payload.
*/ */
public async decryptMessage( public async decryptMessage(
theirDeviceIdentityKey: string, theirDeviceIdentityKey: string,
@ -886,13 +847,13 @@ export class OlmDevice {
/** /**
* Determine if an incoming messages is a prekey message matching an existing session * 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 * remote device
* @param {string} sessionId the id of the active session * @param sessionId - the id of the active session
* @param {number} messageType messageType field from the received message * @param messageType - messageType field from the received message
* @param {string} ciphertext base64-encoded body 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. * the given session.
*/ */
public async matchesSession( public async matchesSession(
@ -937,8 +898,7 @@ export class OlmDevice {
/** /**
* store an OutboundGroupSession in outboundGroupSessionStore * store an OutboundGroupSession in outboundGroupSessionStore
* *
* @param {Olm.OutboundGroupSession} session * @internal
* @private
*/ */
private saveOutboundGroupSession(session: OutboundGroupSession): void { private saveOutboundGroupSession(session: OutboundGroupSession): void {
this.outboundGroupSessionStore[session.session_id()] = session.pickle(this.pickleKey); this.outboundGroupSessionStore[session.session_id()] = session.pickle(this.pickleKey);
@ -948,10 +908,8 @@ export class OlmDevice {
* extract an OutboundGroupSession from outboundGroupSessionStore and call the * extract an OutboundGroupSession from outboundGroupSessionStore and call the
* given function * given function
* *
* @param {string} sessionId * @returns result of func
* @param {function} func * @internal
* @return {object} result of func
* @private
*/ */
private getOutboundGroupSession<T>(sessionId: string, func: (session: OutboundGroupSession) => T): T { private getOutboundGroupSession<T>(sessionId: string, func: (session: OutboundGroupSession) => T): T {
const pickled = this.outboundGroupSessionStore[sessionId]; const pickled = this.outboundGroupSessionStore[sessionId];
@ -971,7 +929,7 @@ export class OlmDevice {
/** /**
* Generate a new outbound group session * Generate a new outbound group session
* *
* @return {string} sessionId for the outbound session. * @returns sessionId for the outbound session.
*/ */
public createOutboundGroupSession(): string { public createOutboundGroupSession(): string {
const session = new global.Olm.OutboundGroupSession(); const session = new global.Olm.OutboundGroupSession();
@ -987,10 +945,10 @@ export class OlmDevice {
/** /**
* Encrypt an outgoing message with an outbound group session * Encrypt an outgoing message with an outbound group session
* *
* @param {string} sessionId the id of the outboundgroupsession * @param sessionId - the id of the outboundgroupsession
* @param {string} payloadString payload to be encrypted and sent * @param payloadString - payload to be encrypted and sent
* *
* @return {string} ciphertext * @returns ciphertext
*/ */
public encryptGroupMessage(sessionId: string, payloadString: string): string { public encryptGroupMessage(sessionId: string, payloadString: string): string {
logger.log(`encrypting msg with megolm session ${sessionId}`); logger.log(`encrypting msg with megolm session ${sessionId}`);
@ -1007,9 +965,9 @@ export class OlmDevice {
/** /**
* Get the session keys for an outbound group session * 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. * base64-encoded secret key.
*/ */
public getOutboundGroupSessionKey(sessionId: string): IOutboundGroupSessionKey { public getOutboundGroupSessionKey(sessionId: string): IOutboundGroupSessionKey {
@ -1028,9 +986,9 @@ export class OlmDevice {
* Unpickle a session from a sessionData object and invoke the given function. * Unpickle a session from a sessionData object and invoke the given function.
* The session is valid only until func returns. * The session is valid only until func returns.
* *
* @param {Object} sessionData Object describing the session. * @param sessionData - Object describing the session.
* @param {function(Olm.InboundGroupSession)} func Invoked with the unpickled session * @param func - Invoked with the unpickled session
* @return {*} result of func * @returns result of func
*/ */
private unpickleInboundGroupSession<T>( private unpickleInboundGroupSession<T>(
sessionData: InboundGroupSessionData, sessionData: InboundGroupSessionData,
@ -1048,15 +1006,12 @@ export class OlmDevice {
/** /**
* extract an InboundGroupSession from the crypto store and call the given function * 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. * sessions for any room.
* @param {string} senderKey * @param txn - Opaque transaction object from cryptoStore.doTxn()
* @param {string} sessionId * @param func - function to call.
* @param {*} txn Opaque transaction object from cryptoStore.doTxn()
* @param {function(Olm.InboundGroupSession, InboundGroupSessionData)} func
* function to call.
* *
* @private * @internal
*/ */
private getInboundGroupSession( private getInboundGroupSession(
roomId: string, roomId: string,
@ -1095,16 +1050,16 @@ export class OlmDevice {
/** /**
* Add an inbound group session to the session store * Add an inbound group session to the session store
* *
* @param {string} roomId room in which this session will be used * @param roomId - room in which this session will be used
* @param {string} senderKey base64-encoded curve25519 key of the sender * @param senderKey - base64-encoded curve25519 key of the sender
* @param {Array<string>} forwardingCurve25519KeyChain Devices involved in forwarding * @param forwardingCurve25519KeyChain - Devices involved in forwarding
* this session to us. * this session to us.
* @param {string} sessionId session identifier * @param sessionId - session identifier
* @param {string} sessionKey base64-encoded secret key * @param sessionKey - base64-encoded secret key
* @param {Object<string, string>} keysClaimed Other keys the sender claims. * @param keysClaimed - Other keys the sender claims.
* @param {boolean} exportFormat true if the megolm keys are in export format * @param exportFormat - true if the megolm keys are in export format
* (ie, they lack an ed25519 signature) * (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( public async addInboundGroupSession(
roomId: string, roomId: string,
@ -1216,11 +1171,11 @@ export class OlmDevice {
/** /**
* Record in the data store why an inbound group session was withheld. * Record in the data store why an inbound group session was withheld.
* *
* @param {string} roomId room that the session belongs to * @param roomId - room that the session belongs to
* @param {string} senderKey base64-encoded curve25519 key of the sender * @param senderKey - base64-encoded curve25519 key of the sender
* @param {string} sessionId session identifier * @param sessionId - session identifier
* @param {string} code reason code * @param code - reason code
* @param {string} reason human-readable version of `code` * @param reason - human-readable version of `code`
*/ */
public async addInboundGroupSessionWithheld( public async addInboundGroupSessionWithheld(
roomId: string, roomId: string,
@ -1248,18 +1203,14 @@ export class OlmDevice {
/** /**
* Decrypt a received message with an inbound group session * Decrypt a received message with an inbound group session
* *
* @param {string} roomId room in which the message was received * @param roomId - room in which the message was received
* @param {string} senderKey base64-encoded curve25519 key of the sender * @param senderKey - base64-encoded curve25519 key of the sender
* @param {string} sessionId session identifier * @param sessionId - session identifier
* @param {string} body base64-encoded body of the encrypted message * @param body - base64-encoded body of the encrypted message
* @param {string} eventId ID of the event being decrypted * @param eventId - ID of the event being decrypted
* @param {Number} timestamp timestamp of the event being decrypted * @param timestamp - timestamp of the event being decrypted
* *
* @return {null} the sessionId is unknown * @returns null if the sessionId is unknown
*
* @return {Promise<{result: string, senderKey: string,
* forwardingCurve25519KeyChain: Array<string>,
* keysClaimed: Object<string, string>}>}
*/ */
public async decryptGroupMessage( public async decryptGroupMessage(
roomId: string, roomId: string,
@ -1375,11 +1326,11 @@ export class OlmDevice {
/** /**
* Determine if we have the keys for a given megolm session * Determine if we have the keys for a given megolm session
* *
* @param {string} roomId room in which the message was received * @param roomId - room in which the message was received
* @param {string} senderKey base64-encoded curve25519 key of the sender * @param senderKey - base64-encoded curve25519 key of the sender
* @param {string} sessionId session identifier * @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> { public async hasInboundSessionKeys(roomId: string, senderKey: string, sessionId: string): Promise<boolean> {
let result: boolean; let result: boolean;
@ -1418,16 +1369,13 @@ export class OlmDevice {
/** /**
* Extract the keys to a given megolm session, for sharing * Extract the keys to a given megolm session, for sharing
* *
* @param {string} roomId room in which the message was received * @param roomId - room in which the message was received
* @param {string} senderKey base64-encoded curve25519 key of the sender * @param senderKey - base64-encoded curve25519 key of the sender
* @param {string} sessionId session identifier * @param sessionId - session identifier
* @param {number} chainIndex The chain index at which to export the session. * @param chainIndex - The chain index at which to export the session.
* If omitted, export at the first index we know about. * If omitted, export at the first index we know about.
* *
* @returns {Promise<{chain_index: number, key: string, * @returns
* forwarding_curve25519_key_chain: Array<string>,
* sender_claimed_ed25519_key: string
* }>}
* details of the session key. The key is a base64-encoded megolm key in * details of the session key. The key is a base64-encoded megolm key in
* export format. * export format.
* *
@ -1492,10 +1440,10 @@ export class OlmDevice {
/** /**
* Export an inbound group session * Export an inbound group session
* *
* @param {string} senderKey base64-encoded curve25519 key of the sender * @param senderKey - base64-encoded curve25519 key of the sender
* @param {string} sessionId session identifier * @param sessionId - session identifier
* @param {ISessionInfo} sessionData The session object from the store * @param sessionData - The session object from the store
* @return {module:crypto/OlmDevice.MegolmSessionData} exported session data * @returns exported session data
*/ */
public exportInboundGroupSession( public exportInboundGroupSession(
senderKey: string, senderKey: string,
@ -1539,11 +1487,11 @@ export class OlmDevice {
/** /**
* Verify an ed25519 signature. * Verify an ed25519 signature.
* *
* @param {string} key ed25519 key * @param key - ed25519 key
* @param {string} message message which was signed * @param message - message which was signed
* @param {string} signature base64-encoded signature to be checked * @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 * too small then the message will be "OLM.INVALID_BASE64". If the signature
* was invalid then the message will be "OLM.BAD_MESSAGE_MAC". * 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. * 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 { function calculateWithheldMessage(withheld: IWithheld): string {
if (withheld.code && withheld.code in WITHHELD_MESSAGES) { if (withheld.code && withheld.code in WITHHELD_MESSAGES) {

View File

@ -27,17 +27,17 @@ import { EventType, ToDeviceMessageId } from "../@types/event";
* *
* See https://docs.google.com/document/d/1m4gQkcnJkxNuBmb5NoFCIadIY-DyqqNAS3lloE73BlQ * See https://docs.google.com/document/d/1m4gQkcnJkxNuBmb5NoFCIadIY-DyqqNAS3lloE73BlQ
* for draft documentation on what we're supposed to be implementing here. * 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 // delay between deciding we want some keys, and sending out the request, to
// allow for (a) it turning up anyway, (b) grouping requests together // allow for (a) it turning up anyway, (b) grouping requests together
const SEND_KEY_REQUESTS_DELAY_MS = 500; 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: * The state machine looks like:
* ```
* *
* | (cancellation sent) * | (cancellation sent)
* | .-------------------------------------------------. * | .-------------------------------------------------.
@ -60,8 +60,7 @@ const SEND_KEY_REQUESTS_DELAY_MS = 500;
* | (cancellation sent) | * | (cancellation sent) |
* V | * V |
* (deleted) <---------------------------+ * (deleted) <---------------------------+
* * ```
* @enum {number}
*/ */
export enum RoomKeyRequestState { export enum RoomKeyRequestState {
/** request not yet sent */ /** 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 * Otherwise, a request is added to the pending list, and a job is started
* in the background to send it. * in the background to send it.
* *
* @param {module:crypto~RoomKeyRequestBody} requestBody * @param resend - whether to resend the key request if there is
* @param {Array<{userId: string, deviceId: string}>} recipients
* @param {boolean} resend whether to resend the key request if there is
* already one * 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 * pending list (or we have established that a similar request already
* exists) * exists)
*/ */
@ -239,9 +236,8 @@ export class OutgoingRoomKeyRequestManager {
/** /**
* Cancel room key requests, if any match the given requestBody * 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. * pending list.
*/ */
public cancelRoomKeyRequest(requestBody: IRoomKeyRequestBody): Promise<unknown> { public cancelRoomKeyRequest(requestBody: IRoomKeyRequestBody): Promise<unknown> {
@ -324,11 +320,10 @@ export class OutgoingRoomKeyRequestManager {
/** /**
* Look for room key requests by target device and state * Look for room key requests by target device and state
* *
* @param {string} userId Target user ID * @param userId - Target user ID
* @param {string} deviceId Target device ID * @param deviceId - Target device ID
* *
* @return {Promise} resolves to a list of all the * @returns resolves to a list of all the {@link OutgoingRoomKeyRequest}
* {@link module:crypto/store/base~OutgoingRoomKeyRequest}
*/ */
public getOutgoingSentRoomKeyRequest(userId: string, deviceId: string): Promise<OutgoingRoomKeyRequest[]> { public getOutgoingSentRoomKeyRequest(userId: string, deviceId: string): Promise<OutgoingRoomKeyRequest[]> {
return this.cryptoStore.getOutgoingRoomKeyRequestsByTarget(userId, deviceId, [RoomKeyRequestState.Sent]); 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 * 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. * don't really expect the other end to even care about the cancellation.
* For example, after initialization or self-verification. * 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[]> { public async cancelAndResendAllOutgoingRequests(): Promise<void[]> {
const outgoings = await this.cryptoStore.getAllOutgoingRoomKeyRequestsByState(RoomKeyRequestState.Sent); const outgoings = await this.cryptoStore.getAllOutgoingRoomKeyRequestsByState(RoomKeyRequestState.Sent);

View File

@ -15,8 +15,6 @@ limitations under the License.
*/ */
/** /**
* @module crypto/RoomList
*
* Manages the list of encrypted rooms * Manages the list of encrypted rooms
*/ */
@ -31,9 +29,6 @@ export interface IRoomEncryption {
} }
/* eslint-enable camelcase */ /* eslint-enable camelcase */
/**
* @alias module:crypto/RoomList
*/
export class RoomList { export class RoomList {
// Object of roomId -> room e2e info object (body of the m.room.encryption event) // Object of roomId -> room e2e info object (body of the m.room.encryption event)
private roomEncryption: Record<string, IRoomEncryption> = {}; private roomEncryption: Record<string, IRoomEncryption> = {};

View File

@ -66,7 +66,6 @@ interface ISecretInfo {
/** /**
* Implements Secure Secret Storage and Sharing (MSC1946) * Implements Secure Secret Storage and Sharing (MSC1946)
* @module crypto/SecretStorage
*/ */
export class SecretStorage<B extends MatrixClient | undefined = MatrixClient> { export class SecretStorage<B extends MatrixClient | undefined = MatrixClient> {
private requests = new Map<string, ISecretRequestInternal>(); private requests = new Map<string, ISecretRequestInternal>();
@ -119,15 +118,15 @@ export class SecretStorage<B extends MatrixClient | undefined = MatrixClient> {
/** /**
* Add a key for encrypting secrets. * Add a key for encrypting secrets.
* *
* @param {string} algorithm the algorithm used by the key. * @param algorithm - the algorithm used by the key.
* @param {object} opts the options for the algorithm. The properties used * @param opts - the options for the algorithm. The properties used
* depend on the algorithm given. * 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. * ID will be generated.
* *
* @return {object} An object with: * @returns An object with:
* keyId: {string} the ID of the key * keyId: the ID of the key
* keyInfo: {object} details about the key (iv, mac, passphrase) * keyInfo: details about the key (iv, mac, passphrase)
*/ */
public async addKey( public async addKey(
algorithm: string, algorithm: string,
@ -176,9 +175,9 @@ export class SecretStorage<B extends MatrixClient | undefined = MatrixClient> {
/** /**
* Get the key information for a given ID. * 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. * 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. * the form [keyId, keyInfo]. Otherwise, null is returned.
* XXX: why is this an array when addKey returns an object? * 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. * 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. * 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> { public async hasKey(keyId?: string): Promise<boolean> {
return Boolean(await this.getKey(keyId)); 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 * Check whether a key matches what we expect based on the key info
* *
* @param {Uint8Array} key the key to check * @param key - the key to check
* @param {object} info the key info * @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> { public async checkKey(key: Uint8Array, info: ISecretStorageKeyInfo): Promise<boolean> {
if (info.algorithm === SECRET_STORAGE_ALGORITHM_V1_AES) { 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 * Store an encrypted secret on the server
* *
* @param {string} name The name of the secret * @param name - The name of the secret
* @param {string} secret The secret contents. * @param secret - The secret contents.
* @param {Array} keys The IDs of the keys to use to encrypt the secret * @param keys - The IDs of the keys to use to encrypt the secret
* or null/undefined to use the default key. * or null/undefined to use the default key.
*/ */
public async store(name: string, secret: string, keys?: string[] | null): Promise<void> { 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. * 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> { public async get(name: string): Promise<string | undefined> {
const secretInfo = await this.accountDataAdapter.getAccountDataFromServer<ISecretInfo>(name); 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. * 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 * with, or null if it is not present or not encrypted with a trusted
* key * key
*/ */
@ -361,8 +360,8 @@ export class SecretStorage<B extends MatrixClient | undefined = MatrixClient> {
/** /**
* Request a secret from another device * Request a secret from another device
* *
* @param {string} name the name of the secret to request * @param name - the name of the secret to request
* @param {string[]} devices the devices to request the secret from * @param devices - the devices to request the secret from
*/ */
public request(this: SecretStorage<MatrixClient>, name: string, devices: string[]): ISecretRequest { public request(this: SecretStorage<MatrixClient>, name: string, devices: string[]): ISecretRequest {
const requestId = this.baseApis.makeTxnId(); const requestId = this.baseApis.makeTxnId();

View File

@ -22,18 +22,21 @@ const zeroSalt = new Uint8Array(8);
export interface IEncryptedPayload { export interface IEncryptedPayload {
[key: string]: any; // extensible [key: string]: any; // extensible
/** the initialization vector in base64 */
iv: string; iv: string;
/** the ciphertext in base64 */
ciphertext: string; ciphertext: string;
/** the HMAC in base64 */
mac: string; mac: string;
} }
/** /**
* encrypt a string * encrypt a string
* *
* @param {string} data the plaintext to encrypt * @param data - the plaintext to encrypt
* @param {Uint8Array} key the encryption key to use * @param key - the encryption key to use
* @param {string} name the name of the secret * @param name - the name of the secret
* @param {string} ivStr the initialization vector to use * @param ivStr - the initialization vector to use
*/ */
export async function encryptAES( export async function encryptAES(
data: string, data: string,
@ -83,12 +86,9 @@ export async function encryptAES(
/** /**
* decrypt a string * decrypt a string
* *
* @param {object} data the encrypted data * @param data - the encrypted data
* @param {string} data.ciphertext the ciphertext in base64 * @param key - the encryption key to use
* @param {string} data.iv the initialization vector in base64 * @param name - the name of the secret
* @param {string} data.mac the HMAC in base64
* @param {Uint8Array} key the encryption key to use
* @param {string} name the name of the secret
*/ */
export async function decryptAES(data: IEncryptedPayload, key: Uint8Array, name: string): Promise<string> { export async function decryptAES(data: IEncryptedPayload, key: Uint8Array, name: string): Promise<string> {
const [aesKey, hmacKey] = await deriveKeys(key, name); 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. /** Calculate the MAC for checking the key.
* *
* @param {Uint8Array} key the key to use * @param key - the key to use
* @param {string} [iv] The initialization vector as a base64-encoded string. * @param iv - The initialization vector as a base64-encoded string.
* If omitted, a random initialization vector will be created. * 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> { export function calculateKeyCheck(key: Uint8Array, iv?: string): Promise<IEncryptedPayload> {
return encryptAES(ZERO_STR, key, "", iv); return encryptAES(ZERO_STR, key, "", iv);

View File

@ -16,8 +16,6 @@ limitations under the License.
/** /**
* Internal module. Defines the base classes of the encryption implementations * Internal module. Defines the base classes of the encryption implementations
*
* @module
*/ */
import { MatrixClient } from "../../client"; import { MatrixClient } from "../../client";
@ -35,46 +33,36 @@ import { DeviceInfo } from "../deviceinfo";
import { IRoomEncryption } from "../RoomList"; import { IRoomEncryption } from "../RoomList";
/** /**
* map of registered encryption algorithm classes. A map from string to {@link * Map of registered encryption algorithm classes. A map from string to {@link EncryptionAlgorithm} class
* module:crypto/algorithms/base.EncryptionAlgorithm|EncryptionAlgorithm} class
*
* @type {Object.<string, function(new: module:crypto/algorithms/base.EncryptionAlgorithm)>}
*/ */
export const ENCRYPTION_CLASSES = new Map<string, new (params: IParams) => EncryptionAlgorithm>(); export const ENCRYPTION_CLASSES = new Map<string, new (params: IParams) => EncryptionAlgorithm>();
export type DecryptionClassParams<P extends IParams = IParams> = Omit<P, "deviceId" | "config">; export type DecryptionClassParams<P extends IParams = IParams> = Omit<P, "deviceId" | "config">;
/** /**
* map of registered encryption algorithm classes. Map from string to {@link * map of registered encryption algorithm classes. Map from string to {@link DecryptionAlgorithm} class
* module:crypto/algorithms/base.DecryptionAlgorithm|DecryptionAlgorithm} class
*
* @type {Object.<string, function(new: module:crypto/algorithms/base.DecryptionAlgorithm)>}
*/ */
export const DECRYPTION_CLASSES = new Map<string, new (params: DecryptionClassParams) => DecryptionAlgorithm>(); export const DECRYPTION_CLASSES = new Map<string, new (params: DecryptionClassParams) => DecryptionAlgorithm>();
export interface IParams { export interface IParams {
/** The UserID for the local user */
userId: string; userId: string;
/** The identifier for this device. */
deviceId: string; deviceId: string;
/** crypto core */
crypto: Crypto; crypto: Crypto;
/** olm.js wrapper */
olmDevice: OlmDevice; olmDevice: OlmDevice;
/** base matrix api interface */
baseApis: MatrixClient; baseApis: MatrixClient;
/** The ID of the room we will be sending to */
roomId?: string; roomId?: string;
/** The body of the m.room.encryption event */
config: IRoomEncryption & object; config: IRoomEncryption & object;
} }
/** /**
* base type for encryption implementations * 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 { export abstract class EncryptionAlgorithm {
protected readonly userId: string; protected readonly userId: string;
@ -84,6 +72,9 @@ export abstract class EncryptionAlgorithm {
protected readonly baseApis: MatrixClient; protected readonly baseApis: MatrixClient;
protected readonly roomId?: string; protected readonly roomId?: string;
/**
* @param params - parameters
*/
public constructor(params: IParams) { public constructor(params: IParams) {
this.userId = params.userId; this.userId = params.userId;
this.deviceId = params.deviceId; 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 * Perform any background tasks that can be done before a message is ready to
* send, in order to speed up sending of the message. * 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 {} public prepareToEncrypt(room: Room): void {}
/** /**
* Encrypt a message event * Encrypt a message event
* *
* @method module:crypto/algorithms/base.EncryptionAlgorithm.encryptMessage
* @public * @public
* @abstract
* *
* @param {module:models/room} room * @param content - event content
* @param {string} eventType
* @param {object} 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>; public abstract encryptMessage(room: Room, eventType: string, content: IContent): Promise<IEncryptedContent>;
/** /**
* Called when the membership of a member of the room changes. * Called when the membership of a member of the room changes.
* *
* @param {module:models/event.MatrixEvent} event event causing the change * @param event - event causing the change
* @param {module:models/room-member} member user whose membership changed * @param member - user whose membership changed
* @param {string=} oldMembership previous membership * @param oldMembership - previous membership
* @public * @public
* @abstract
*/ */
public onRoomMembership(event: MatrixEvent, member: RoomMember, oldMembership?: string): void {} public onRoomMembership(event: MatrixEvent, member: RoomMember, oldMembership?: string): void {}
@ -139,15 +125,6 @@ export abstract class EncryptionAlgorithm {
/** /**
* base type for decryption implementations * 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 { export abstract class DecryptionAlgorithm {
protected readonly userId: string; protected readonly userId: string;
@ -167,12 +144,9 @@ export abstract class DecryptionAlgorithm {
/** /**
* Decrypt an event * Decrypt an event
* *
* @method module:crypto/algorithms/base.DecryptionAlgorithm#decryptEvent * @param event - undecrypted event
* @abstract
* *
* @param {MatrixEvent} event undecrypted event * @returns promise which
*
* @return {Promise<module:crypto~EventDecryptionResult>} promise which
* resolves once we have finished decrypting. Rejects with an * resolves once we have finished decrypting. Rejects with an
* `algorithms.DecryptionError` if there is a problem decrypting the event. * `algorithms.DecryptionError` if there is a problem decrypting the event.
*/ */
@ -181,9 +155,7 @@ export abstract class DecryptionAlgorithm {
/** /**
* Handle a key event * Handle a key event
* *
* @method module:crypto/algorithms/base.DecryptionAlgorithm#onRoomKeyEvent * @param params - event key event
*
* @param {module:models/event.MatrixEvent} params event key event
*/ */
public async onRoomKeyEvent(params: MatrixEvent): Promise<void> { public async onRoomKeyEvent(params: MatrixEvent): Promise<void> {
// ignore by default // ignore by default
@ -192,8 +164,7 @@ export abstract class DecryptionAlgorithm {
/** /**
* Import a room key * Import a room key
* *
* @param {module:crypto/OlmDevice.MegolmSessionData} session * @param opts - object
* @param {object} opts object
*/ */
public async importRoomKey(session: IMegolmSessionData, opts: object): Promise<void> { public async importRoomKey(session: IMegolmSessionData, opts: object): Promise<void> {
// ignore by default // 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 * Determine if we have the keys necessary to respond to a room key request
* *
* @param {module:crypto~IncomingRoomKeyRequest} keyRequest * @returns true if we have the keys and could (theoretically) share
* @return {Promise<boolean>} true if we have the keys and could (theoretically) share
* them; else false. * them; else false.
*/ */
public hasKeysForKeyRequest(keyRequest: IncomingRoomKeyRequest): Promise<boolean> { public hasKeysForKeyRequest(keyRequest: IncomingRoomKeyRequest): Promise<boolean> {
@ -213,7 +183,6 @@ export abstract class DecryptionAlgorithm {
/** /**
* Send the response to a room key request * Send the response to a room key request
* *
* @param {module:crypto~IncomingRoomKeyRequest} keyRequest
*/ */
public shareKeysWithDevice(keyRequest: IncomingRoomKeyRequest): void { public shareKeysWithDevice(keyRequest: IncomingRoomKeyRequest): void {
throw new Error("shareKeysWithDevice not supported for this DecryptionAlgorithm"); 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 * Retry decrypting all the events from a sender that haven't been
* decrypted yet. * decrypted yet.
* *
* @param {string} senderKey the sender's key * @param senderKey - the sender's key
*/ */
public async retryDecryptionFromSender(senderKey: string): Promise<boolean> { public async retryDecryptionFromSender(senderKey: string): Promise<boolean> {
// ignore by default // ignore by default
@ -237,13 +206,10 @@ export abstract class DecryptionAlgorithm {
/** /**
* Exception thrown when decryption fails * Exception thrown when decryption fails
* *
* @alias module:crypto/algorithms/base.DecryptionError * @param msg - user-visible message describing the problem
* @param {string} 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. * to the user.
*
* @extends Error
*/ */
export class DecryptionError extends Error { export class DecryptionError extends Error {
public readonly detailedString: string; public readonly detailedString: string;
@ -268,16 +234,14 @@ function detailedStringForDecryptionError(err: DecryptionError, details?: Record
return result; return result;
} }
export class UnknownDeviceError extends Error {
/** /**
* Exception thrown specifically when we want to warn the user to consider * Exception thrown specifically when we want to warn the user to consider
* the security of their conversation before continuing * the security of their conversation before continuing
* *
* @param {string} msg message describing the problem * @param msg - message describing the problem
* @param {Object} devices userId -> {deviceId -> object} * @param devices - set of unknown devices per user we're warning about
* set of unknown devices per user we're warning about
* @extends Error
*/ */
export class UnknownDeviceError extends Error {
public constructor( public constructor(
msg: string, msg: string,
public readonly devices: Record<string, Record<string, object>>, 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 * 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 * @param encryptor - {@link EncryptionAlgorithm} implementation
* module:crypto/algorithms/base.EncryptionAlgorithm|EncryptionAlgorithm}
* implementation
* *
* @param {class} decryptor {@link * @param decryptor - {@link DecryptionAlgorithm} implementation
* module:crypto/algorithms/base.DecryptionAlgorithm|DecryptionAlgorithm}
* implementation
*/ */
export function registerAlgorithm<P extends IParams = IParams>( export function registerAlgorithm<P extends IParams = IParams>(
algorithm: string, algorithm: string,

View File

@ -14,10 +14,6 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/**
* @module crypto/algorithms
*/
import "./olm"; import "./olm";
import "./megolm"; import "./megolm";

View File

@ -16,8 +16,6 @@ limitations under the License.
/** /**
* Defines m.olm encryption/decryption * Defines m.olm encryption/decryption
*
* @module crypto/algorithms/megolm
*/ */
import { v4 as uuidv4 } from "uuid"; import { v4 as uuidv4 } from "uuid";
@ -123,37 +121,27 @@ interface SharedWithData {
} }
/** /**
* @private * @internal
* @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}
*/ */
class OutboundSessionInfo { class OutboundSessionInfo {
/** number of times this session has been used */
public useCount = 0; public useCount = 0;
/** when the session was created (ms since the epoch) */
public creationTime: number; public creationTime: number;
/** devices with which we have shared the session key `userId -> {deviceId -> SharedWithData}` */
public sharedWithDevices: Record<string, Record<string, SharedWithData>> = {}; public sharedWithDevices: Record<string, Record<string, SharedWithData>> = {};
public blockedDevicesNotified: Record<string, Record<string, boolean>> = {}; 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) { public constructor(public readonly sessionId: string, public readonly sharedHistory = false) {
this.creationTime = new Date().getTime(); this.creationTime = new Date().getTime();
} }
/** /**
* Check if it's time to rotate the session * Check if it's time to rotate the session
*
* @param {Number} rotationPeriodMsgs
* @param {Number} rotationPeriodMs
* @return {Boolean}
*/ */
public needsRotation(rotationPeriodMsgs: number, rotationPeriodMs: number): boolean { public needsRotation(rotationPeriodMsgs: number, rotationPeriodMs: number): boolean {
const sessionLifetime = new Date().getTime() - this.creationTime; 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 * Determine if this session has been shared with devices which it shouldn't
* have been. * have been.
* *
* @param {Object} devicesInRoom userId -> {deviceId -> object} * @param devicesInRoom - `userId -> {deviceId -> object}`
* devices we should shared the session with. * 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. * in devicesInRoom.
*/ */
public sharedWithTooManyDevices(devicesInRoom: Record<string, Record<string, object>>): boolean { public sharedWithTooManyDevices(devicesInRoom: Record<string, Record<string, object>>): boolean {
@ -228,11 +216,7 @@ class OutboundSessionInfo {
/** /**
* Megolm encryption implementation * Megolm encryption implementation
* *
* @constructor * @param params - parameters, as per {@link EncryptionAlgorithm}
* @extends {module:crypto/algorithms/EncryptionAlgorithm}
*
* @param {object} params parameters, as per
* {@link module:crypto/algorithms/EncryptionAlgorithm}
*/ */
export class MegolmEncryption extends EncryptionAlgorithm { export class MegolmEncryption extends EncryptionAlgorithm {
// the most recent attempt to set up a session. This is used to serialise // 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 devicesInRoom - The devices in this room, indexed by user ID
* @param {Object} devicesInRoom The devices in this room, indexed by user ID * @param blocked - The devices that are blocked, indexed by user ID
* @param {Object} blocked The devices that are blocked, indexed by user ID * @param singleOlmCreationPhase - Only perform one round of olm
* @param {boolean} [singleOlmCreationPhase] Only perform one round of olm
* session creation * session creation
* *
* @return {Promise} Promise which resolves to the * @returns Promise which resolves to the
* OutboundSessionInfo when setup is complete. * OutboundSessionInfo when setup is complete.
*/ */
private async ensureOutboundSession( 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> { private async prepareNewSession(sharedHistory: boolean): Promise<OutboundSessionInfo> {
const sessionId = this.olmDevice.createOutboundGroupSession(); 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 * Determines what devices in devicesByUser don't have an olm session as given
* in devicemap. * 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. * olmlib.ensureOlmSessionsForDevices.
* @param {object} devicesByUser a map of user IDs to array of deviceInfo * @param devicesByUser - a map of user IDs to array of deviceInfo
* @param {array} [noOlmDevices] an array to fill with devices that don't have * @param noOlmDevices - an array to fill with devices that don't have
* olm sessions * 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. * noOlmDevices is specified, then noOlmDevices will be returned.
*/ */
private getDevicesWithoutSessions( private getDevicesWithoutSessions(
@ -558,11 +540,11 @@ export class MegolmEncryption extends EncryptionAlgorithm {
* Splits the user device map into multiple chunks to reduce the number of * Splits the user device map into multiple chunks to reduce the number of
* devices we encrypt to per API call. * 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>( private splitDevices<T extends DeviceInfo | IBlockedDevice>(
devicesByUser: Record<string, Record<string, { device: T }>>, 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 * @param userDeviceMap - mapping from userId to deviceInfo
* 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. * for the given userDeviceMap is generated and has been sent.
*/ */
private encryptAndSendKeysToDevices( 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. * for the given userDeviceMap is generated and has been sent.
*/ */
private async sendBlockedNotificationsToDevices( 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 * Re-shares a megolm session key with devices if the key has already been
* sent to them. * sent to them.
* *
* @param {string} senderKey The key of the originating device for the session * @param senderKey - The key of the originating device for the session
* @param {string} sessionId ID of the outbound session to share * @param sessionId - ID of the outbound session to share
* @param {string} userId ID of the user who owns the target device * @param userId - ID of the user who owns the target device
* @param {module:crypto/deviceinfo} device The target device * @param device - The target device
*/ */
public async reshareKeyWithDevice( public async reshareKeyWithDevice(
senderKey: string, 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 * 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 * @param devicesByUser - map from userid to list of devices
* map from userid to list of devices
* *
* @param {array<object>} errorDevices * @param errorDevices - array that will be populated with the devices that we can't get an
* array that will be populated with the devices that we can't get an
* olm session for * 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. * 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. * failed to respond to one-time-key requests.
*/ */
private async shareKeyWithDevices( private async shareKeyWithDevices(
@ -866,11 +842,9 @@ export class MegolmEncryption extends EncryptionAlgorithm {
/** /**
* Notify devices that we weren't able to create olm sessions. * 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 * create olm sessions for, as returned by shareKeyWithDevices
*/ */
private async notifyFailedOlmDevices( private async notifyFailedOlmDevices(
@ -927,10 +901,8 @@ export class MegolmEncryption extends EncryptionAlgorithm {
/** /**
* Notify blocked devices that they have been blocked. * Notify blocked devices that they have been blocked.
* *
* @param {module:crypto/algorithms/megolm.OutboundSessionInfo} session
* *
* @param {object<string, object>} devicesByUser * @param devicesByUser - map from userid to device ID to blocked data
* map from userid to device ID to blocked data
*/ */
private async notifyBlockedDevices( private async notifyBlockedDevices(
session: OutboundSessionInfo, 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 * Perform any background tasks that can be done before a message is ready to
* send, in order to speed up sending of the message. * 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 { public prepareToEncrypt(room: Room): void {
if (this.encryptionPreparation != null) { if (this.encryptionPreparation != null) {
@ -1008,13 +980,9 @@ export class MegolmEncryption extends EncryptionAlgorithm {
} }
/** /**
* @inheritdoc * @param content - plaintext event content
* *
* @param {module:models/room} room * @returns Promise which resolves to the new event body
* @param {string} eventType
* @param {object} content plaintext event content
*
* @return {Promise} Promise which resolves to the new event body
*/ */
public async encryptMessage(room: Room, eventType: string, content: IContent): Promise<IMegolmEncryptedContent> { public async encryptMessage(room: Room, eventType: string, content: IContent): Promise<IMegolmEncryptedContent> {
logger.log(`Starting to encrypt event for ${this.roomId}`); 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 * 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. * 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. * devices we should shared the session with.
*/ */
private checkForUnknownDevices(devicesInRoom: DeviceInfoMap): void { 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 * Remove unknown devices from a set of devices. The devicesInRoom parameter
* will be modified. * will be modified.
* *
* @param {Object} devicesInRoom userId -> {deviceId -> object} * @param devicesInRoom - `userId -> {deviceId -> object}`
* devices we should shared the session with. * devices we should shared the session with.
*/ */
private removeUnknownDevices(devicesInRoom: DeviceInfoMap): void { 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 * 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) * 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 * first element is a map from userId to deviceId to deviceInfo indicating
* the devices that messages should be encrypted to, and whose second * the devices that messages should be encrypted to, and whose second
* element is a map from userId to deviceId to data indicating the devices * 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 * Megolm decryption implementation
* *
* @constructor * @param params - parameters, as per {@link DecryptionAlgorithm}
* @extends {module:crypto/algorithms/DecryptionAlgorithm}
*
* @param {object} params parameters, as per
* {@link module:crypto/algorithms/DecryptionAlgorithm}
*/ */
export class MegolmDecryption extends DecryptionAlgorithm { export class MegolmDecryption extends DecryptionAlgorithm {
// events which we couldn't decrypt due to unknown sessions / // 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 * 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 * decrypting, or rejects with an `algorithms.DecryptionError` if there is a
* problem decrypting the event. * 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. * 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 { private addEventToPendingList(event: MatrixEvent): void {
const content = event.getWireContent(); 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. * 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 { private removeEventFromPendingList(event: MatrixEvent): void {
const content = event.getWireContent(); 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> { public async onRoomKeyEvent(event: MatrixEvent): Promise<void> {
const content = event.getContent<Partial<IMessage["content"]>>(); const content = event.getContent<Partial<IMessage["content"]>>();
let senderKey = event.getSenderKey()!; let senderKey = event.getSenderKey()!;
@ -1619,9 +1571,7 @@ export class MegolmDecryption extends DecryptionAlgorithm {
} }
/** /**
* @inheritdoc * @param event - key event
*
* @param {module:models/event.MatrixEvent} event key event
*/ */
public async onRoomKeyWithheldEvent(event: MatrixEvent): Promise<void> { public async onRoomKeyWithheldEvent(event: MatrixEvent): Promise<void> {
const content = event.getContent(); const content = event.getContent();
@ -1706,9 +1656,6 @@ export class MegolmDecryption extends DecryptionAlgorithm {
} }
} }
/**
* @inheritdoc
*/
public hasKeysForKeyRequest(keyRequest: IncomingRoomKeyRequest): Promise<boolean> { public hasKeysForKeyRequest(keyRequest: IncomingRoomKeyRequest): Promise<boolean> {
const body = keyRequest.requestBody; const body = keyRequest.requestBody;
@ -1720,9 +1667,6 @@ export class MegolmDecryption extends DecryptionAlgorithm {
); );
} }
/**
* @inheritdoc
*/
public shareKeysWithDevice(keyRequest: IncomingRoomKeyRequest): void { public shareKeysWithDevice(keyRequest: IncomingRoomKeyRequest): void {
const userId = keyRequest.userId; const userId = keyRequest.userId;
const deviceId = keyRequest.deviceId; const deviceId = keyRequest.deviceId;
@ -1808,19 +1752,15 @@ export class MegolmDecryption extends DecryptionAlgorithm {
} }
/** /**
* @inheritdoc * @param untrusted - whether the key should be considered as untrusted
* * @param source - where the key came from
* @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
*/ */
public importRoomKey( public importRoomKey(
session: IMegolmSessionData, session: IMegolmSessionData,
opts: { untrusted?: boolean, source?: string } = {}, { untrusted, source }: { untrusted?: boolean, source?: string } = {},
): Promise<void> { ): Promise<void> {
const extraSessionData: OlmGroupSessionExtraData = {}; const extraSessionData: OlmGroupSessionExtraData = {};
if (opts.untrusted || session.untrusted) { if (untrusted || session.untrusted) {
extraSessionData.untrusted = true; extraSessionData.untrusted = true;
} }
if (session["org.matrix.msc3061.shared_history"]) { if (session["org.matrix.msc3061.shared_history"]) {
@ -1836,7 +1776,7 @@ export class MegolmDecryption extends DecryptionAlgorithm {
true, true,
extraSessionData, extraSessionData,
).then(() => { ).then(() => {
if (opts.source !== "backup") { if (source !== "backup") {
// don't wait for it to complete // don't wait for it to complete
this.crypto.backupManager.backupGroupSession( this.crypto.backupManager.backupGroupSession(
session.sender_key, session.session_id, 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 * Have another go at decrypting events after we receive a key. Resolves once
* decryption has been re-attempted on all events. * decryption has been re-attempted on all events.
* *
* @private * @internal
* @param {String} senderKey * @param forceRedecryptIfUntrusted - whether messages that were already
* @param {String} sessionId
* @param {Boolean} forceRedecryptIfUntrusted whether messages that were already
* successfully decrypted using untrusted keys should be re-decrypted * 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 * decrypted with trusted keys
*/ */
private async retryDecryption( private async retryDecryption(

View File

@ -16,8 +16,6 @@ limitations under the License.
/** /**
* Defines m.olm encryption/decryption * Defines m.olm encryption/decryption
*
* @module crypto/algorithms/olm
*/ */
import { logger } from '../../logger'; import { logger } from '../../logger';
@ -44,21 +42,17 @@ export interface IMessage {
/** /**
* Olm encryption implementation * Olm encryption implementation
* *
* @constructor * @param params - parameters, as per {@link EncryptionAlgorithm}
* @extends {module:crypto/algorithms/EncryptionAlgorithm}
*
* @param {object} params parameters, as per
* {@link module:crypto/algorithms/EncryptionAlgorithm}
*/ */
class OlmEncryption extends EncryptionAlgorithm { class OlmEncryption extends EncryptionAlgorithm {
private sessionPrepared = false; private sessionPrepared = false;
private prepPromise: Promise<void> | null = null; private prepPromise: Promise<void> | null = null;
/** /**
* @private * @internal
* @param {string[]} roomMembers list of currently-joined users in the room * @param roomMembers - list of currently-joined users in the room
* @return {Promise} Promise which resolves when setup is complete * @returns Promise which resolves when setup is complete
*/ */
private ensureSession(roomMembers: string[]): Promise<void> { private ensureSession(roomMembers: string[]): Promise<void> {
if (this.prepPromise) { if (this.prepPromise) {
@ -83,13 +77,9 @@ class OlmEncryption extends EncryptionAlgorithm {
} }
/** /**
* @inheritdoc * @param content - plaintext event content
* *
* @param {module:models/room} room * @returns Promise which resolves to the new event body
* @param {string} eventType
* @param {object} content plaintext event content
*
* @return {Promise} Promise which resolves to the new event body
*/ */
public async encryptMessage(room: Room, eventType: string, content: IContent): Promise<IOlmEncryptedContent> { public async encryptMessage(room: Room, eventType: string, content: IContent): Promise<IOlmEncryptedContent> {
// pick the list of recipients based on the membership list. // pick the list of recipients based on the membership list.
@ -150,19 +140,12 @@ class OlmEncryption extends EncryptionAlgorithm {
/** /**
* Olm decryption implementation * Olm decryption implementation
* *
* @constructor * @param params - parameters, as per {@link DecryptionAlgorithm}
* @extends {module:crypto/algorithms/DecryptionAlgorithm}
* @param {object} params parameters, as per
* {@link module:crypto/algorithms/DecryptionAlgorithm}
*/ */
class OlmDecryption extends DecryptionAlgorithm { class OlmDecryption extends DecryptionAlgorithm {
/** /**
* @inheritdoc
*
* @param {MatrixEvent} event
*
* returns a promise which resolves to a * 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 * decrypting. Rejects with an `algorithms.DecryptionError` if there is a
* problem decrypting the event. * problem decrypting the event.
*/ */
@ -275,10 +258,10 @@ class OlmDecryption extends DecryptionAlgorithm {
/** /**
* Attempt to decrypt an Olm message * Attempt to decrypt an Olm message
* *
* @param {string} theirDeviceIdentityKey Curve25519 identity key of the sender * @param theirDeviceIdentityKey - Curve25519 identity key of the sender
* @param {object} message message object, with 'type' and 'body' fields * @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> { private decryptMessage(theirDeviceIdentityKey: string, message: IMessage): Promise<string> {
// This is a wrapper that serialises decryptions of prekey messages, because // This is a wrapper that serialises decryptions of prekey messages, because

View File

@ -66,8 +66,7 @@ export interface IRecoveryKey {
export interface ICreateSecretStorageOpts { export interface ICreateSecretStorageOpts {
/** /**
* Function called to await a secret storage key creation flow. * Function called to await a secret storage key creation flow.
* Returns: * @returns Promise resolving to an object with public key metadata, encoded private
* {Promise<Object>} Object with public key metadata, encoded private
* recovery key which should be disposed of after displaying to the user, * recovery key which should be disposed of after displaying to the user,
* and raw private key to avoid round tripping if needed. * and raw private key to avoid round tripping if needed.
*/ */
@ -131,6 +130,7 @@ export interface IImportOpts {
} }
export interface IImportRoomKeysOpts { export interface IImportRoomKeysOpts {
/** called with an object that has a "stage" param */
progressCallback?: (stage: IImportOpts) => void; progressCallback?: (stage: IImportOpts) => void;
untrusted?: boolean; untrusted?: boolean;
source?: string; // TODO: Enum source?: string; // TODO: Enum

View File

@ -15,8 +15,6 @@ limitations under the License.
*/ */
/** /**
* @module crypto/backup
*
* Classes for dealing with key backup. * Classes for dealing with key backup.
*/ */
@ -134,7 +132,7 @@ export class BackupManager {
* *
* Throws an error if a problem is detected. * 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 { public static checkBackupVersion(info: IKeyBackupInfo): void {
const Algorithm = algorithmsByName[info.algorithm]; const Algorithm = algorithmsByName[info.algorithm];
@ -276,7 +274,7 @@ export class BackupManager {
* Forces a re-check of the key backup and enables/disables it * Forces a re-check of the key backup and enables/disables it
* as appropriate. * as appropriate.
* *
* @return {Object} Object with backup info (as returned by * @returns Object with backup info (as returned by
* getKeyBackupVersion) in backupInfo and * getKeyBackupVersion) in backupInfo and
* trust information (as returned by isKeyBackupTrusted) * trust information (as returned by isKeyBackupTrusted)
* in trustInfo. * in trustInfo.
@ -309,15 +307,7 @@ export class BackupManager {
/** /**
* Check if the given backup info is trusted. * Check if the given backup info is trusted.
* *
* @param {IKeyBackupInfo} backupInfo key backup info dict from /room_keys/version * @param 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],
* ]
* }
*/ */
public async isKeyBackupTrusted(backupInfo?: IKeyBackupInfo): Promise<TrustInfo> { public async isKeyBackupTrusted(backupInfo?: IKeyBackupInfo): Promise<TrustInfo> {
const ret = { const ret = {
@ -432,7 +422,7 @@ export class BackupManager {
* Schedules sending all keys waiting to be sent to the backup, if not already * Schedules sending all keys waiting to be sent to the backup, if not already
* scheduled. Retries if necessary. * 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> { public async scheduleKeyBackupSend(maxDelay = 10000): Promise<void> {
if (this.sendingBackups) return; if (this.sendingBackups) return;
@ -490,8 +480,8 @@ export class BackupManager {
* Take some e2e keys waiting to be backed up and send them * Take some e2e keys waiting to be backed up and send them
* to the backup. * to the backup.
* *
* @param {number} limit Maximum number of keys to back up * @param limit - Maximum number of keys to back up
* @returns {number} Number of sessions backed up * @returns Number of sessions backed up
*/ */
public async backupPendingKeys(limit: number): Promise<number> { public async backupPendingKeys(limit: number): Promise<number> {
const sessions = await this.baseApis.crypto!.cryptoStore.getSessionsNeedingBackup(limit); 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 * Marks all group sessions as needing to be backed up without scheduling
* them to upload in the background. * 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). * (which will be equal to the number of sessions in the store).
*/ */
public async flagAllGroupSessionsForBackup(): Promise<number> { 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 * 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> { public countSessionsNeedingBackup(): Promise<number> {
return this.baseApis.crypto!.cryptoStore.countSessionsNeedingBackup(); return this.baseApis.crypto!.cryptoStore.countSessionsNeedingBackup();

View File

@ -16,10 +16,6 @@ limitations under the License.
import { ISignatures } from "../@types/signed"; import { ISignatures } from "../@types/signed";
/**
* @module crypto/deviceinfo
*/
export interface IDevice { export interface IDevice {
keys: Record<string, string>; keys: Record<string, string>;
algorithms: string[]; algorithms: string[];
@ -37,36 +33,15 @@ enum DeviceVerification {
/** /**
* Information about a user's device * 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
* &lt;key type&gt;:&lt;id&gt; -> &lt;base64-encoded key&gt;>
*
* @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 { export class DeviceInfo {
/** /**
* rehydrate a DeviceInfo from the session store * rehydrate a DeviceInfo from the session store
* *
* @param {object} obj raw object from session store * @param obj - raw object from session store
* @param {string} deviceId id of the device * @param deviceId - id of the device
* *
* @return {module:crypto~DeviceInfo} new DeviceInfo * @returns new DeviceInfo
*/ */
public static fromStorage(obj: Partial<IDevice>, deviceId: string): DeviceInfo { public static fromStorage(obj: Partial<IDevice>, deviceId: string): DeviceInfo {
const res = new DeviceInfo(deviceId); const res = new DeviceInfo(deviceId);
@ -79,28 +54,36 @@ export class DeviceInfo {
return res; return res;
} }
/**
* @enum
*/
public static DeviceVerification = { public static DeviceVerification = {
VERIFIED: DeviceVerification.Verified, VERIFIED: DeviceVerification.Verified,
UNVERIFIED: DeviceVerification.Unverified, UNVERIFIED: DeviceVerification.Unverified,
BLOCKED: DeviceVerification.Blocked, BLOCKED: DeviceVerification.Blocked,
}; };
/** list of algorithms supported by this device */
public algorithms: string[] = []; public algorithms: string[] = [];
/** a map from `<key type>:<id> -> <base64-encoded key>` */
public keys: Record<string, string> = {}; public keys: Record<string, string> = {};
/** whether the device has been verified/blocked by the user */
public verified = DeviceVerification.Unverified; 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; public known = false;
/** additional data from the homeserver */
public unsigned: Record<string, any> = {}; public unsigned: Record<string, any> = {};
public signatures: ISignatures = {}; public signatures: ISignatures = {};
/**
* @param deviceId - id of the device
*/
public constructor(public readonly deviceId: string) {} public constructor(public readonly deviceId: string) {}
/** /**
* Prepare a DeviceInfo for JSON serialisation in the session store * 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 { public toStorage(): IDevice {
return { return {
@ -116,7 +99,7 @@ export class DeviceInfo {
/** /**
* Get the fingerprint for this device (ie, the Ed25519 key) * 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 { public getFingerprint(): string {
return this.keys["ed25519:" + this.deviceId]; return this.keys["ed25519:" + this.deviceId];
@ -125,7 +108,7 @@ export class DeviceInfo {
/** /**
* Get the identity key for this device (ie, the Curve25519 key) * 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 { public getIdentityKey(): string {
return this.keys["curve25519:" + this.deviceId]; return this.keys["curve25519:" + this.deviceId];
@ -134,7 +117,7 @@ export class DeviceInfo {
/** /**
* Get the configured display name for this device, if any * Get the configured display name for this device, if any
* *
* @return {string?} displayname * @returns displayname
*/ */
public getDisplayName(): string | null { public getDisplayName(): string | null {
return this.unsigned.device_display_name || null; return this.unsigned.device_display_name || null;
@ -143,7 +126,7 @@ export class DeviceInfo {
/** /**
* Returns true if this device is blocked * Returns true if this device is blocked
* *
* @return {Boolean} true if blocked * @returns true if blocked
*/ */
public isBlocked(): boolean { public isBlocked(): boolean {
return this.verified == DeviceVerification.Blocked; return this.verified == DeviceVerification.Blocked;
@ -152,7 +135,7 @@ export class DeviceInfo {
/** /**
* Returns true if this device is verified * Returns true if this device is verified
* *
* @return {Boolean} true if verified * @returns true if verified
*/ */
public isVerified(): boolean { public isVerified(): boolean {
return this.verified == DeviceVerification.Verified; return this.verified == DeviceVerification.Verified;
@ -161,7 +144,7 @@ export class DeviceInfo {
/** /**
* Returns true if this device is unverified * Returns true if this device is unverified
* *
* @return {Boolean} true if unverified * @returns true if unverified
*/ */
public isUnverified(): boolean { public isUnverified(): boolean {
return this.verified == DeviceVerification.Unverified; return this.verified == DeviceVerification.Unverified;
@ -170,7 +153,7 @@ export class DeviceInfo {
/** /**
* Returns true if the user knows about this device's existence * Returns true if the user knows about this device's existence
* *
* @return {Boolean} true if known * @returns true if known
*/ */
public isKnown(): boolean { public isKnown(): boolean {
return this.known === true; return this.known === true;

File diff suppressed because it is too large Load Diff

View File

@ -59,6 +59,10 @@ export interface IKeyBackupInfo {
/* eslint-enable camelcase */ /* eslint-enable camelcase */
export interface IKeyBackupPrepareOpts { export interface IKeyBackupPrepareOpts {
/**
* Whether to use Secure Secret Storage to store the key encrypting key backups.
* Optional, defaults to false.
*/
secureSecretStorage: boolean; secureSecretStorage: boolean;
} }

View File

@ -15,8 +15,6 @@ limitations under the License.
*/ */
/** /**
* @module olmlib
*
* Utilities common to olm encryption algorithms * Utilities common to olm encryption algorithms
*/ */
@ -55,22 +53,20 @@ export const MEGOLM_ALGORITHM = Algorithm.Megolm;
export const MEGOLM_BACKUP_ALGORITHM = Algorithm.MegolmBackup; export const MEGOLM_BACKUP_ALGORITHM = Algorithm.MegolmBackup;
export interface IOlmSessionResult { export interface IOlmSessionResult {
/** device info */
device: DeviceInfo; device: DeviceInfo;
/** base64 olm session id; null if no session could be established */
sessionId: string | null; sessionId: string | null;
} }
/** /**
* Encrypt an event payload for an Olm device * 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 * of the m.room.encrypted event to which to add our result
* *
* @param {string} ourUserId * @param olmDevice - olm.js wrapper
* @param {string} ourDeviceId * @param payloadFields - fields to include in the encrypted payload
* @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
* *
* Returns a promise which resolves (to undefined) when the payload * Returns a promise which resolves (to undefined) when the payload
* has been encrypted into `resultsObject` * has been encrypted into `resultsObject`
@ -145,17 +141,14 @@ interface IExistingOlmSession {
* Get the existing olm sessions for the given devices, and the devices that * Get the existing olm sessions for the given devices, and the devices that
* don't have olm sessions. * don't have olm sessions.
* *
* @param {module:crypto/OlmDevice} olmDevice
* *
* @param {MatrixClient} baseApis
* *
* @param {object<string, module:crypto/deviceinfo[]>} devicesByUser * @param devicesByUser - map from userid to list of devices to ensure sessions for
* 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 * 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 * 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( export async function getExistingOlmSessions(
olmDevice: OlmDevice, olmDevice: OlmDevice,
@ -197,27 +190,22 @@ export async function getExistingOlmSessions(
/** /**
* Try to make sure we have established olm sessions for the given devices. * 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 force - If true, establish a new session even if one
*
* @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
* already exists. * 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. * 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. * 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 * an Object mapping from userId to deviceId to
* {@link module:crypto~OlmSessionResult} * {@link OlmSessionResult}
*/ */
export async function ensureOlmSessionsForDevices( export async function ensureOlmSessionsForDevices(
olmDevice: OlmDevice, olmDevice: OlmDevice,
@ -442,15 +430,15 @@ export interface IObject {
/** /**
* Verify the signature on an object * 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, * Returns a promise which resolves (to undefined) if the the signature is good,
* or rejects with an Error if it is bad. * 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 * 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 * 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 * seed
* @param {string} userId The user ID who owns the signing key * @param userId - The user ID who owns the signing key
* @param {string} pubKey The public key (ignored if key is a seed) * @param pubKey - The public key (ignored if key is a seed)
* @returns {string} the signature for the object * @returns the signature for the object
*/ */
export function pkSign(obj: object & IObject, key: Uint8Array | PkSigning, userId: string, pubKey: string): string { export function pkSign(obj: object & IObject, key: Uint8Array | PkSigning, userId: string, pubKey: string): string {
let createdKey = false; let createdKey = false;
@ -521,9 +509,9 @@ export function pkSign(obj: object & IObject, key: Uint8Array | PkSigning, userI
/** /**
* Verify a signed JSON object * Verify a signed JSON object
* @param {Object} obj Object to verify * @param obj - Object to verify
* @param {string} pubKey The public key to use to verify * @param pubKey - The public key to use to verify
* @param {string} userId The user ID who signed the object * @param userId - The user ID who signed the object
*/ */
export function pkVerify(obj: IObject, pubKey: string, userId: string): void { export function pkVerify(obj: IObject, pubKey: string, userId: string): void {
const keyId = "ed25519:" + pubKey; const keyId = "ed25519:" + pubKey;
@ -563,8 +551,8 @@ export function isOlmEncrypted(event: MatrixEvent): boolean {
/** /**
* Encode a typed array of uint8 as base64. * Encode a typed array of uint8 as base64.
* @param {Uint8Array} uint8Array The data to encode. * @param uint8Array - The data to encode.
* @return {string} The base64. * @returns The base64.
*/ */
export function encodeBase64(uint8Array: ArrayBuffer | Uint8Array): string { export function encodeBase64(uint8Array: ArrayBuffer | Uint8Array): string {
return Buffer.from(uint8Array).toString("base64"); 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. * Encode a typed array of uint8 as unpadded base64.
* @param {Uint8Array} uint8Array The data to encode. * @param uint8Array - The data to encode.
* @return {string} The unpadded base64. * @returns The unpadded base64.
*/ */
export function encodeUnpaddedBase64(uint8Array: ArrayBuffer | Uint8Array): string { export function encodeUnpaddedBase64(uint8Array: ArrayBuffer | Uint8Array): string {
return encodeBase64(uint8Array).replace(/=+$/g, ''); 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. * Decode a base64 string to a typed array of uint8.
* @param {string} base64 The base64 to decode. * @param base64 - The base64 to decode.
* @return {Uint8Array} The decoded data. * @returns The decoded data.
*/ */
export function decodeBase64(base64: string): Uint8Array { export function decodeBase64(base64: string): Uint8Array {
return Buffer.from(base64, "base64"); return Buffer.from(base64, "base64");

View File

@ -30,8 +30,6 @@ import { IEncryptedPayload } from "../aes";
/** /**
* Internal module. Definitions for storage for the crypto module * Internal module. Definitions for storage for the crypto module
*
* @module
*/ */
export interface SecretStorePrivateKeys { export interface SecretStorePrivateKeys {
@ -46,8 +44,6 @@ export interface SecretStorePrivateKeys {
/** /**
* Abstraction of things that can store data required for end-to-end encryption * Abstraction of things that can store data required for end-to-end encryption
*
* @interface CryptoStore
*/ */
export interface CryptoStore { export interface CryptoStore {
startup(): Promise<CryptoStore>; startup(): Promise<CryptoStore>;
@ -197,32 +193,29 @@ export interface IWithheld {
/** /**
* Represents an outgoing room key request * 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 { 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; requestId: string;
requestTxnId?: string; requestTxnId?: string;
/**
* Transaction id for the cancellation, if any
*/
cancellationTxnId?: string; cancellationTxnId?: string;
/**
* List of recipients for the request
*/
recipients: IRoomKeyRequestRecipient[]; recipients: IRoomKeyRequestRecipient[];
/**
* Parameters for the request
*/
requestBody: IRoomKeyRequestBody; requestBody: IRoomKeyRequestBody;
/**
* current state of this request (states are defined in {@link OutgoingRoomKeyRequestManager})
*/
state: RoomKeyRequestState; state: RoomKeyRequestState;
} }

View File

@ -39,14 +39,11 @@ const PROFILE_TRANSACTIONS = false;
* Implementation of a CryptoStore which is backed by an existing * Implementation of a CryptoStore which is backed by an existing
* IndexedDB connection. Generally you want IndexedDBCryptoStore * IndexedDB connection. Generally you want IndexedDBCryptoStore
* which connects to the database and defers to one of these. * which connects to the database and defers to one of these.
*
* @implements {module:crypto/store/base~CryptoStore}
*/ */
export class Backend implements CryptoStore { export class Backend implements CryptoStore {
private nextTxnId = 0; private nextTxnId = 0;
/** /**
* @param {IDBDatabase} db
*/ */
public constructor(private db: IDBDatabase) { public constructor(private db: IDBDatabase) {
// make sure we close the db on `onversionchange` - otherwise // 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, * Look for an existing outgoing room key request, and if none is found,
* add a new one * add a new one
* *
* @param {module:crypto/store/base~OutgoingRoomKeyRequest} request
* *
* @returns {Promise} resolves to * @returns resolves to
* {@link module:crypto/store/base~OutgoingRoomKeyRequest}: either the * {@link OutgoingRoomKeyRequest}: either the
* same instance as passed in, or the existing one. * same instance as passed in, or the existing one.
*/ */
public getOrAddOutgoingRoomKeyRequest(request: OutgoingRoomKeyRequest): Promise<OutgoingRoomKeyRequest> { public getOrAddOutgoingRoomKeyRequest(request: OutgoingRoomKeyRequest): Promise<OutgoingRoomKeyRequest> {
@ -113,11 +109,10 @@ export class Backend implements CryptoStore {
/** /**
* Look for an existing room key request * Look for an existing room key request
* *
* @param {module:crypto~RoomKeyRequestBody} requestBody * @param requestBody - existing request to look for
* existing request to look for
* *
* @return {Promise} resolves to the matching * @returns resolves to the matching
* {@link module:crypto/store/base~OutgoingRoomKeyRequest}, or null if * {@link OutgoingRoomKeyRequest}, or null if
* not found * not found
*/ */
public getOutgoingRoomKeyRequest(requestBody: IRoomKeyRequestBody): Promise<OutgoingRoomKeyRequest | null> { 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 * look for an existing room key request in the db
* *
* @private * @internal
* @param {IDBTransaction} txn database transaction * @param txn - database transaction
* @param {module:crypto~RoomKeyRequestBody} requestBody * @param requestBody - existing request to look for
* existing request to look for * @param callback - function to call with the results of the
* @param {Function} callback function to call with the results of the
* search. Either passed a matching * search. Either passed a matching
* {@link module:crypto/store/base~OutgoingRoomKeyRequest}, or null if * {@link OutgoingRoomKeyRequest}, or null if
* not found. * not found.
*/ */
// eslint-disable-next-line @typescript-eslint/naming-convention // eslint-disable-next-line @typescript-eslint/naming-convention
@ -181,10 +175,10 @@ export class Backend implements CryptoStore {
/** /**
* Look for room key requests by state * 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 * @returns resolves to the a
* {@link module:crypto/store/base~OutgoingRoomKeyRequest}, or null if * {@link OutgoingRoomKeyRequest}, or null if
* there are no pending requests in those states. If there are multiple * there are no pending requests in those states. If there are multiple
* requests in those states, an arbitrary one is chosen. * requests in those states, an arbitrary one is chosen.
*/ */
@ -233,8 +227,7 @@ export class Backend implements CryptoStore {
/** /**
* *
* @param {Number} wantedState * @returns All elements in a given state
* @return {Promise<Array<*>>} All elements in a given state
*/ */
public getAllOutgoingRoomKeyRequestsByState(wantedState: number): Promise<OutgoingRoomKeyRequest[]> { public getAllOutgoingRoomKeyRequestsByState(wantedState: number): Promise<OutgoingRoomKeyRequest[]> {
return new Promise((resolve, reject) => { 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 * Look for an existing room key request by id and state, and update it if
* found * found
* *
* @param {string} requestId ID of request to update * @param requestId - ID of request to update
* @param {number} expectedState state we expect to find the request in * @param expectedState - state we expect to find the request in
* @param {Object} updates name/value map of updates to apply * @param updates - name/value map of updates to apply
* *
* @returns {Promise} resolves to * @returns resolves to
* {@link module:crypto/store/base~OutgoingRoomKeyRequest} * {@link OutgoingRoomKeyRequest}
* updated request, or null if no matching row was found * updated request, or null if no matching row was found
*/ */
public updateOutgoingRoomKeyRequest( 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 * Look for an existing room key request by id and state, and delete it if
* found * found
* *
* @param {string} requestId ID of request to update * @param requestId - ID of request to update
* @param {number} expectedState state we expect to find the request in * @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( public deleteOutgoingRoomKeyRequest(
requestId: string, requestId: string,

View File

@ -39,15 +39,11 @@ import { InboundGroupSessionData } from "../OlmDevice";
/** /**
* Internal module. indexeddb storage for e2e. * Internal module. indexeddb storage for e2e.
*
* @module
*/ */
/** /**
* An implementation of CryptoStore, which is normally backed by an indexeddb, * An implementation of CryptoStore, which is normally backed by an indexeddb,
* but with fallback to MemoryCryptoStore. * but with fallback to MemoryCryptoStore.
*
* @implements {module:crypto/store/base~CryptoStore}
*/ */
export class IndexedDBCryptoStore implements CryptoStore { export class IndexedDBCryptoStore implements CryptoStore {
public static STORE_ACCOUNT = 'account'; public static STORE_ACCOUNT = 'account';
@ -70,8 +66,8 @@ export class IndexedDBCryptoStore implements CryptoStore {
/** /**
* Create a new IndexedDBCryptoStore * Create a new IndexedDBCryptoStore
* *
* @param {IDBFactory} indexedDB global indexedDB instance * @param indexedDB - global indexedDB instance
* @param {string} dbName name of db to connect to * @param dbName - name of db to connect to
*/ */
public constructor(private readonly indexedDB: IDBFactory, private readonly dbName: string) {} 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. * 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 * or a MemoryCryptoStore
*/ */
public startup(): Promise<CryptoStore> { public startup(): Promise<CryptoStore> {
@ -167,7 +163,7 @@ export class IndexedDBCryptoStore implements CryptoStore {
/** /**
* Delete all data from this store. * 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> { public deleteAllData(): Promise<void> {
return new Promise<void>((resolve, reject) => { 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, * Look for an existing outgoing room key request, and if none is found,
* add a new one * add a new one
* *
* @param {module:crypto/store/base~OutgoingRoomKeyRequest} request
* *
* @returns {Promise} resolves to * @returns resolves to
* {@link module:crypto/store/base~OutgoingRoomKeyRequest}: either the * {@link OutgoingRoomKeyRequest}: either the
* same instance as passed in, or the existing one. * same instance as passed in, or the existing one.
*/ */
public getOrAddOutgoingRoomKeyRequest(request: OutgoingRoomKeyRequest): Promise<OutgoingRoomKeyRequest> { public getOrAddOutgoingRoomKeyRequest(request: OutgoingRoomKeyRequest): Promise<OutgoingRoomKeyRequest> {
@ -219,11 +214,10 @@ export class IndexedDBCryptoStore implements CryptoStore {
/** /**
* Look for an existing room key request * Look for an existing room key request
* *
* @param {module:crypto~RoomKeyRequestBody} requestBody * @param requestBody - existing request to look for
* existing request to look for
* *
* @return {Promise} resolves to the matching * @returns resolves to the matching
* {@link module:crypto/store/base~OutgoingRoomKeyRequest}, or null if * {@link OutgoingRoomKeyRequest}, or null if
* not found * not found
*/ */
public getOutgoingRoomKeyRequest(requestBody: IRoomKeyRequestBody): Promise<OutgoingRoomKeyRequest | null> { public getOutgoingRoomKeyRequest(requestBody: IRoomKeyRequestBody): Promise<OutgoingRoomKeyRequest | null> {
@ -233,10 +227,10 @@ export class IndexedDBCryptoStore implements CryptoStore {
/** /**
* Look for room key requests by state * 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 * @returns resolves to the a
* {@link module:crypto/store/base~OutgoingRoomKeyRequest}, or null if * {@link OutgoingRoomKeyRequest}, or null if
* there are no pending requests in those states. If there are multiple * there are no pending requests in those states. If there are multiple
* requests in those states, an arbitrary one is chosen. * 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 * Look for room key requests by state
* unlike above, return a list of all entries in one state. * unlike above, return a list of all entries in one state.
* *
* @param {Number} wantedState * @returns Returns an array of requests in the given state
* @return {Promise<Array<*>>} Returns an array of requests in the given state
*/ */
public getAllOutgoingRoomKeyRequestsByState(wantedState: number): Promise<OutgoingRoomKeyRequest[]> { public getAllOutgoingRoomKeyRequestsByState(wantedState: number): Promise<OutgoingRoomKeyRequest[]> {
return this.backend!.getAllOutgoingRoomKeyRequestsByState(wantedState); return this.backend!.getAllOutgoingRoomKeyRequestsByState(wantedState);
@ -258,12 +251,12 @@ export class IndexedDBCryptoStore implements CryptoStore {
/** /**
* Look for room key requests by target device and state * Look for room key requests by target device and state
* *
* @param {string} userId Target user ID * @param userId - Target user ID
* @param {string} deviceId Target device ID * @param deviceId - Target device ID
* @param {Array<Number>} wantedStates list of acceptable states * @param wantedStates - list of acceptable states
* *
* @return {Promise} resolves to a list of all the * @returns resolves to a list of all the
* {@link module:crypto/store/base~OutgoingRoomKeyRequest} * {@link OutgoingRoomKeyRequest}
*/ */
public getOutgoingRoomKeyRequestsByTarget( public getOutgoingRoomKeyRequestsByTarget(
userId: string, 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 * Look for an existing room key request by id and state, and update it if
* found * found
* *
* @param {string} requestId ID of request to update * @param requestId - ID of request to update
* @param {number} expectedState state we expect to find the request in * @param expectedState - state we expect to find the request in
* @param {Object} updates name/value map of updates to apply * @param updates - name/value map of updates to apply
* *
* @returns {Promise} resolves to * @returns resolves to
* {@link module:crypto/store/base~OutgoingRoomKeyRequest} * {@link OutgoingRoomKeyRequest}
* updated request, or null if no matching row was found * updated request, or null if no matching row was found
*/ */
public updateOutgoingRoomKeyRequest( 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 * Look for an existing room key request by id and state, and delete it if
* found * found
* *
* @param {string} requestId ID of request to update * @param requestId - ID of request to update
* @param {number} expectedState state we expect to find the request in * @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( public deleteOutgoingRoomKeyRequest(
requestId: string, requestId: string,
@ -319,8 +312,8 @@ export class IndexedDBCryptoStore implements CryptoStore {
* Get the account pickle from the store. * Get the account pickle from the store.
* This requires an active transaction. See doTxn(). * This requires an active transaction. See doTxn().
* *
* @param {*} txn An active transaction. See doTxn(). * @param txn - An active transaction. See doTxn().
* @param {function(string)} func Called with the account pickle * @param func - Called with the account pickle
*/ */
public getAccount(txn: IDBTransaction, func: (accountPickle: string | null) => void): void { public getAccount(txn: IDBTransaction, func: (accountPickle: string | null) => void): void {
this.backend!.getAccount(txn, func); this.backend!.getAccount(txn, func);
@ -330,8 +323,8 @@ export class IndexedDBCryptoStore implements CryptoStore {
* Write the account pickle to the store. * Write the account pickle to the store.
* This requires an active transaction. See doTxn(). * This requires an active transaction. See doTxn().
* *
* @param {*} txn An active transaction. See doTxn(). * @param txn - An active transaction. See doTxn().
* @param {string} accountPickle The new account pickle to store. * @param accountPickle - The new account pickle to store.
*/ */
public storeAccount(txn: IDBTransaction, accountPickle: string): void { public storeAccount(txn: IDBTransaction, accountPickle: string): void {
this.backend!.storeAccount(txn, accountPickle); 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, * Get the public part of the cross-signing keys (eg. self-signing key,
* user signing key). * user signing key).
* *
* @param {*} txn An active transaction. See doTxn(). * @param txn - An active transaction. See doTxn().
* @param {function(string)} func Called with the account keys object: * @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 * `{ key_type: base64 encoded seed }` where key type = user_signing_key_seed or self_signing_key_seed
*/ */
public getCrossSigningKeys( public getCrossSigningKeys(
txn: IDBTransaction, txn: IDBTransaction,
@ -353,9 +346,9 @@ export class IndexedDBCryptoStore implements CryptoStore {
} }
/** /**
* @param {*} txn An active transaction. See doTxn(). * @param txn - An active transaction. See doTxn().
* @param {function(string)} func Called with the private key * @param func - Called with the private key
* @param {string} type A key type * @param type - A key type
*/ */
public getSecretStorePrivateKey<K extends keyof SecretStorePrivateKeys>( public getSecretStorePrivateKey<K extends keyof SecretStorePrivateKeys>(
txn: IDBTransaction, txn: IDBTransaction,
@ -368,8 +361,8 @@ export class IndexedDBCryptoStore implements CryptoStore {
/** /**
* Write the cross-signing keys back to the store * Write the cross-signing keys back to the store
* *
* @param {*} txn An active transaction. See doTxn(). * @param txn - An active transaction. See doTxn().
* @param {string} keys keys object as getCrossSigningKeys() * @param keys - keys object as getCrossSigningKeys()
*/ */
public storeCrossSigningKeys(txn: IDBTransaction, keys: Record<string, ICrossSigningKey>): void { public storeCrossSigningKeys(txn: IDBTransaction, keys: Record<string, ICrossSigningKey>): void {
this.backend!.storeCrossSigningKeys(txn, keys); this.backend!.storeCrossSigningKeys(txn, keys);
@ -378,9 +371,9 @@ export class IndexedDBCryptoStore implements CryptoStore {
/** /**
* Write the cross-signing private keys back to the store * Write the cross-signing private keys back to the store
* *
* @param {*} txn An active transaction. See doTxn(). * @param txn - An active transaction. See doTxn().
* @param {string} type The type of cross-signing private key to store * @param type - The type of cross-signing private key to store
* @param {string} key keys object as getCrossSigningKeys() * @param key - keys object as getCrossSigningKeys()
*/ */
public storeSecretStorePrivateKey<K extends keyof SecretStorePrivateKeys>( public storeSecretStorePrivateKey<K extends keyof SecretStorePrivateKeys>(
txn: IDBTransaction, txn: IDBTransaction,
@ -394,8 +387,8 @@ export class IndexedDBCryptoStore implements CryptoStore {
/** /**
* Returns the number of end-to-end sessions in the store * Returns the number of end-to-end sessions in the store
* @param {*} txn An active transaction. See doTxn(). * @param txn - An active transaction. See doTxn().
* @param {function(int)} func Called with the count of sessions * @param func - Called with the count of sessions
*/ */
public countEndToEndSessions(txn: IDBTransaction, func: (count: number) => void): void { public countEndToEndSessions(txn: IDBTransaction, func: (count: number) => void): void {
this.backend!.countEndToEndSessions(txn, func); 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 * Retrieve a specific end-to-end session between the logged-in user
* and another device. * and another device.
* @param {string} deviceKey The public key of the other device. * @param deviceKey - The public key of the other device.
* @param {string} sessionId The ID of the session to retrieve * @param sessionId - The ID of the session to retrieve
* @param {*} txn An active transaction. See doTxn(). * @param txn - An active transaction. See doTxn().
* @param {function(object)} func Called with A map from sessionId * @param func - Called with A map from sessionId
* to session information object with 'session' key being the * to session information object with 'session' key being the
* Base64 end-to-end session and lastReceivedMessageTs being the * Base64 end-to-end session and lastReceivedMessageTs being the
* timestamp in milliseconds at which the session last received * 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 * Retrieve the end-to-end sessions between the logged-in user and another
* device. * device.
* @param {string} deviceKey The public key of the other device. * @param deviceKey - The public key of the other device.
* @param {*} txn An active transaction. See doTxn(). * @param txn - An active transaction. See doTxn().
* @param {function(object)} func Called with A map from sessionId * @param func - Called with A map from sessionId
* to session information object with 'session' key being the * to session information object with 'session' key being the
* Base64 end-to-end session and lastReceivedMessageTs being the * Base64 end-to-end session and lastReceivedMessageTs being the
* timestamp in milliseconds at which the session last received * timestamp in milliseconds at which the session last received
@ -443,8 +436,8 @@ export class IndexedDBCryptoStore implements CryptoStore {
/** /**
* Retrieve all end-to-end sessions * Retrieve all end-to-end sessions
* @param {*} txn An active transaction. See doTxn(). * @param txn - An active transaction. See doTxn().
* @param {function(object)} func Called one for each session with * @param func - Called one for each session with
* an object with, deviceKey, lastReceivedMessageTs, sessionId * an object with, deviceKey, lastReceivedMessageTs, sessionId
* and session keys. * and session keys.
*/ */
@ -454,10 +447,10 @@ export class IndexedDBCryptoStore implements CryptoStore {
/** /**
* Store a session between the logged-in user and another device * Store a session between the logged-in user and another device
* @param {string} deviceKey The public key of the other device. * @param deviceKey - The public key of the other device.
* @param {string} sessionId The ID for this end-to-end session. * @param sessionId - The ID for this end-to-end session.
* @param {string} sessionInfo Session information object * @param sessionInfo - Session information object
* @param {*} txn An active transaction. See doTxn(). * @param txn - An active transaction. See doTxn().
*/ */
public storeEndToEndSession( public storeEndToEndSession(
deviceKey: string, deviceKey: string,
@ -485,10 +478,10 @@ export class IndexedDBCryptoStore implements CryptoStore {
/** /**
* Retrieve the end-to-end inbound group session for a given * Retrieve the end-to-end inbound group session for a given
* server key and session ID * server key and session ID
* @param {string} senderCurve25519Key The sender's curve 25519 key * @param senderCurve25519Key - The sender's curve 25519 key
* @param {string} sessionId The ID of the session * @param sessionId - The ID of the session
* @param {*} txn An active transaction. See doTxn(). * @param txn - An active transaction. See doTxn().
* @param {function(object)} func Called with A map from sessionId * @param func - Called with A map from sessionId
* to Base64 end-to-end session. * to Base64 end-to-end session.
*/ */
public getEndToEndInboundGroupSession( public getEndToEndInboundGroupSession(
@ -502,10 +495,10 @@ export class IndexedDBCryptoStore implements CryptoStore {
/** /**
* Fetches all inbound group sessions in the store * Fetches all inbound group sessions in the store
* @param {*} txn An active transaction. See doTxn(). * @param txn - An active transaction. See doTxn().
* @param {function(object)} func Called once for each group session * @param func - Called once for each group session
* in the store with an object having keys {senderKey, sessionId, * in the store with an object having keys `{senderKey, sessionId, sessionData}`,
* sessionData}, then once with null to indicate the end of the list. * then once with null to indicate the end of the list.
*/ */
public getAllEndToEndInboundGroupSessions( public getAllEndToEndInboundGroupSessions(
txn: IDBTransaction, txn: IDBTransaction,
@ -518,10 +511,10 @@ export class IndexedDBCryptoStore implements CryptoStore {
* Adds an end-to-end inbound group session to the store. * Adds an end-to-end inbound group session to the store.
* If there already exists an inbound group session with the same * If there already exists an inbound group session with the same
* senderCurve25519Key and sessionID, the session will not be added. * senderCurve25519Key and sessionID, the session will not be added.
* @param {string} senderCurve25519Key The sender's curve 25519 key * @param senderCurve25519Key - The sender's curve 25519 key
* @param {string} sessionId The ID of the session * @param sessionId - The ID of the session
* @param {object} sessionData The session data structure * @param sessionData - The session data structure
* @param {*} txn An active transaction. See doTxn(). * @param txn - An active transaction. See doTxn().
*/ */
public addEndToEndInboundGroupSession( public addEndToEndInboundGroupSession(
senderCurve25519Key: string, senderCurve25519Key: string,
@ -536,10 +529,10 @@ export class IndexedDBCryptoStore implements CryptoStore {
* Writes an end-to-end inbound group session to the store. * Writes an end-to-end inbound group session to the store.
* If there already exists an inbound group session with the same * If there already exists an inbound group session with the same
* senderCurve25519Key and sessionID, it will be overwritten. * senderCurve25519Key and sessionID, it will be overwritten.
* @param {string} senderCurve25519Key The sender's curve 25519 key * @param senderCurve25519Key - The sender's curve 25519 key
* @param {string} sessionId The ID of the session * @param sessionId - The ID of the session
* @param {object} sessionData The session data structure * @param sessionData - The session data structure
* @param {*} txn An active transaction. See doTxn(). * @param txn - An active transaction. See doTxn().
*/ */
public storeEndToEndInboundGroupSession( public storeEndToEndInboundGroupSession(
senderCurve25519Key: string, 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 * 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. * 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 { public storeEndToEndDeviceData(deviceData: IDeviceData, txn: IDBTransaction): void {
this.backend!.storeEndToEndDeviceData(deviceData, txn); this.backend!.storeEndToEndDeviceData(deviceData, txn);
@ -578,8 +570,8 @@ export class IndexedDBCryptoStore implements CryptoStore {
/** /**
* Get the state of all tracked devices * Get the state of all tracked devices
* *
* @param {*} txn An active transaction. See doTxn(). * @param txn - An active transaction. See doTxn().
* @param {function(Object)} func Function called with the * @param func - Function called with the
* device data * device data
*/ */
public getEndToEndDeviceData(txn: IDBTransaction, func: (deviceData: IDeviceData | null) => void): void { 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. * Store the end-to-end state for a room.
* @param {string} roomId The room's ID. * @param roomId - The room's ID.
* @param {object} roomInfo The end-to-end info for the room. * @param roomInfo - The end-to-end info for the room.
* @param {*} txn An active transaction. See doTxn(). * @param txn - An active transaction. See doTxn().
*/ */
public storeEndToEndRoom(roomId: string, roomInfo: IRoomEncryption, txn: IDBTransaction): void { public storeEndToEndRoom(roomId: string, roomInfo: IRoomEncryption, txn: IDBTransaction): void {
this.backend!.storeEndToEndRoom(roomId, roomInfo, txn); this.backend!.storeEndToEndRoom(roomId, roomInfo, txn);
} }
/** /**
* Get an object of roomId->roomInfo for all e2e rooms in the store * Get an object of `roomId->roomInfo` for all e2e rooms in the store
* @param {*} txn An active transaction. See doTxn(). * @param txn - An active transaction. See doTxn().
* @param {function(Object)} func Function called with the end to end encrypted rooms * @param func - Function called with the end-to-end encrypted rooms
*/ */
public getEndToEndRooms(txn: IDBTransaction, func: (rooms: Record<string, IRoomEncryption>) => void): void { public getEndToEndRooms(txn: IDBTransaction, func: (rooms: Record<string, IRoomEncryption>) => void): void {
this.backend!.getEndToEndRooms(txn, func); 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. * 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. * 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[]> { public getSessionsNeedingBackup(limit: number): Promise<ISession[]> {
return this.backend!.getSessionsNeedingBackup(limit); 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. * Count the inbound group sessions that need to be backed up.
* @param {*} txn An active transaction. See doTxn(). (optional) * @param txn - An active transaction. See doTxn(). (optional)
* @returns {Promise} resolves to the number of sessions * @returns resolves to the number of sessions
*/ */
public countSessionsNeedingBackup(txn?: IDBTransaction): Promise<number> { public countSessionsNeedingBackup(txn?: IDBTransaction): Promise<number> {
return this.backend!.countSessionsNeedingBackup(txn); return this.backend!.countSessionsNeedingBackup(txn);
@ -630,9 +622,9 @@ export class IndexedDBCryptoStore implements CryptoStore {
/** /**
* Unmark sessions as needing to be backed up. * Unmark sessions as needing to be backed up.
* @param {Array<object>} sessions The sessions that need to be backed up. * @param sessions - The sessions that need to be backed up.
* @param {*} txn An active transaction. See doTxn(). (optional) * @param txn - An active transaction. See doTxn(). (optional)
* @returns {Promise} resolves when the sessions are unmarked * @returns resolves when the sessions are unmarked
*/ */
public unmarkSessionsNeedingBackup(sessions: ISession[], txn?: IDBTransaction): Promise<void> { public unmarkSessionsNeedingBackup(sessions: ISession[], txn?: IDBTransaction): Promise<void> {
return this.backend!.unmarkSessionsNeedingBackup(sessions, txn); return this.backend!.unmarkSessionsNeedingBackup(sessions, txn);
@ -640,9 +632,9 @@ export class IndexedDBCryptoStore implements CryptoStore {
/** /**
* Mark sessions as needing to be backed up. * Mark sessions as needing to be backed up.
* @param {Array<object>} sessions The sessions that need to be backed up. * @param sessions - The sessions that need to be backed up.
* @param {*} txn An active transaction. See doTxn(). (optional) * @param txn - An active transaction. See doTxn(). (optional)
* @returns {Promise} resolves when the sessions are marked * @returns resolves when the sessions are marked
*/ */
public markSessionsNeedingBackup(sessions: ISession[], txn?: IDBTransaction): Promise<void> { public markSessionsNeedingBackup(sessions: ISession[], txn?: IDBTransaction): Promise<void> {
return this.backend!.markSessionsNeedingBackup(sessions, txn); return this.backend!.markSessionsNeedingBackup(sessions, txn);
@ -650,10 +642,10 @@ export class IndexedDBCryptoStore implements CryptoStore {
/** /**
* Add a shared-history group session for a room. * Add a shared-history group session for a room.
* @param {string} roomId The room that the key belongs to * @param roomId - The room that the key belongs to
* @param {string} senderKey The sender's curve 25519 key * @param senderKey - The sender's curve 25519 key
* @param {string} sessionId The ID of the session * @param sessionId - The ID of the session
* @param {*} txn An active transaction. See doTxn(). (optional) * @param txn - An active transaction. See doTxn(). (optional)
*/ */
public addSharedHistoryInboundGroupSession( public addSharedHistoryInboundGroupSession(
roomId: string, roomId: string,
@ -666,9 +658,9 @@ export class IndexedDBCryptoStore implements CryptoStore {
/** /**
* Get the shared-history group session for a room. * Get the shared-history group session for a room.
* @param {string} roomId The room that the key belongs to * @param roomId - The room that the key belongs to
* @param {*} txn An active transaction. See doTxn(). (optional) * @param txn - An active transaction. See doTxn(). (optional)
* @returns {Promise} Resolves to an array of [senderKey, sessionId] * @returns Promise which resolves to an array of [senderKey, sessionId]
*/ */
public getSharedHistoryInboundGroupSessions( public getSharedHistoryInboundGroupSessions(
roomId: string, roomId: string,
@ -704,16 +696,16 @@ export class IndexedDBCryptoStore implements CryptoStore {
* only be called within a callback of either this function or * only be called within a callback of either this function or
* one of the store functions operating on the same transaction. * 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'. * 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 * options representing all types of object that will be
* accessed or written to with this transaction. * 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 * transaction object: an opaque object that should be passed
* to store functions. * to store functions.
* @param {Logger} [log] A possibly customised log * @param log - A possibly customised log
* @return {Promise} Promise that resolves with the result of the `func` * @returns Promise that resolves with the result of the `func`
* when the transaction is complete. If the backend is * when the transaction is complete. If the backend is
* async (ie. the indexeddb backend) any of the callback * async (ie. the indexeddb backend) any of the callback
* functions throwing an exception will cause this promise to * functions throwing an exception will cause this promise to

View File

@ -28,8 +28,6 @@ import { InboundGroupSessionData } from "../OlmDevice";
* some things backed by localStorage. It exists because indexedDB * some things backed by localStorage. It exists because indexedDB
* is broken in Firefox private mode or set to, "will not remember * is broken in Firefox private mode or set to, "will not remember
* history". * history".
*
* @module
*/ */
const E2E_PREFIX = "crypto."; const E2E_PREFIX = "crypto.";
@ -62,9 +60,6 @@ function keyEndToEndRoomsPrefix(roomId: string): string {
return KEY_ROOMS_PREFIX + roomId; return KEY_ROOMS_PREFIX + roomId;
} }
/**
* @implements {module:crypto/store/base~CryptoStore}
*/
export class LocalStorageCryptoStore extends MemoryCryptoStore { export class LocalStorageCryptoStore extends MemoryCryptoStore {
public static exists(store: Storage): boolean { public static exists(store: Storage): boolean {
const length = store.length; const length = store.length;
@ -364,7 +359,7 @@ export class LocalStorageCryptoStore extends MemoryCryptoStore {
/** /**
* Delete all data from this store. * 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> { public deleteAllData(): Promise<void> {
this.store.removeItem(KEY_END_TO_END_ACCOUNT); this.store.removeItem(KEY_END_TO_END_ACCOUNT);

View File

@ -35,13 +35,8 @@ import { InboundGroupSessionData } from "../OlmDevice";
/** /**
* Internal module. in-memory storage for e2e. * Internal module. in-memory storage for e2e.
*
* @module
*/ */
/**
* @implements {module:crypto/store/base~CryptoStore}
*/
export class MemoryCryptoStore implements CryptoStore { export class MemoryCryptoStore implements CryptoStore {
private outgoingRoomKeyRequests: OutgoingRoomKeyRequest[] = []; private outgoingRoomKeyRequests: OutgoingRoomKeyRequest[] = [];
private account: string | null = null; private account: string | null = null;
@ -65,7 +60,7 @@ export class MemoryCryptoStore implements CryptoStore {
* *
* This must be called before the store can be used. * 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> { public async startup(): Promise<CryptoStore> {
// No startup work to do for the memory store. // No startup work to do for the memory store.
@ -75,7 +70,7 @@ export class MemoryCryptoStore implements CryptoStore {
/** /**
* Delete all data from this store. * 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> { public deleteAllData(): Promise<void> {
return Promise.resolve(); 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, * Look for an existing outgoing room key request, and if none is found,
* add a new one * add a new one
* *
* @param {module:crypto/store/base~OutgoingRoomKeyRequest} request
* *
* @returns {Promise} resolves to * @returns resolves to
* {@link module:crypto/store/base~OutgoingRoomKeyRequest}: either the * {@link OutgoingRoomKeyRequest}: either the
* same instance as passed in, or the existing one. * same instance as passed in, or the existing one.
*/ */
public getOrAddOutgoingRoomKeyRequest(request: OutgoingRoomKeyRequest): Promise<OutgoingRoomKeyRequest> { public getOrAddOutgoingRoomKeyRequest(request: OutgoingRoomKeyRequest): Promise<OutgoingRoomKeyRequest> {
@ -122,11 +116,10 @@ export class MemoryCryptoStore implements CryptoStore {
/** /**
* Look for an existing room key request * Look for an existing room key request
* *
* @param {module:crypto~RoomKeyRequestBody} requestBody * @param requestBody - existing request to look for
* existing request to look for
* *
* @return {Promise} resolves to the matching * @returns resolves to the matching
* {@link module:crypto/store/base~OutgoingRoomKeyRequest}, or null if * {@link OutgoingRoomKeyRequest}, or null if
* not found * not found
*/ */
public getOutgoingRoomKeyRequest(requestBody: IRoomKeyRequestBody): Promise<OutgoingRoomKeyRequest | null> { public getOutgoingRoomKeyRequest(requestBody: IRoomKeyRequestBody): Promise<OutgoingRoomKeyRequest | null> {
@ -138,10 +131,9 @@ export class MemoryCryptoStore implements CryptoStore {
* *
* @internal * @internal
* *
* @param {module:crypto~RoomKeyRequestBody} requestBody * @param requestBody - existing request to look for
* existing request to look for
* *
* @return {module:crypto/store/base~OutgoingRoomKeyRequest?} * @returns
* the matching request, or null if not found * the matching request, or null if not found
*/ */
// eslint-disable-next-line @typescript-eslint/naming-convention // eslint-disable-next-line @typescript-eslint/naming-convention
@ -157,10 +149,10 @@ export class MemoryCryptoStore implements CryptoStore {
/** /**
* Look for room key requests by state * 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 * @returns resolves to the a
* {@link module:crypto/store/base~OutgoingRoomKeyRequest}, or null if * {@link OutgoingRoomKeyRequest}, or null if
* there are no pending requests in those states * there are no pending requests in those states
*/ */
public getOutgoingRoomKeyRequestByState(wantedStates: number[]): Promise<OutgoingRoomKeyRequest | null> { public getOutgoingRoomKeyRequestByState(wantedStates: number[]): Promise<OutgoingRoomKeyRequest | null> {
@ -176,8 +168,7 @@ export class MemoryCryptoStore implements CryptoStore {
/** /**
* *
* @param {Number} wantedState * @returns All OutgoingRoomKeyRequests in state
* @return {Promise<Array<*>>} All OutgoingRoomKeyRequests in state
*/ */
public getAllOutgoingRoomKeyRequestsByState(wantedState: number): Promise<OutgoingRoomKeyRequest[]> { public getAllOutgoingRoomKeyRequestsByState(wantedState: number): Promise<OutgoingRoomKeyRequest[]> {
return Promise.resolve( 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 * Look for an existing room key request by id and state, and update it if
* found * found
* *
* @param {string} requestId ID of request to update * @param requestId - ID of request to update
* @param {number} expectedState state we expect to find the request in * @param expectedState - state we expect to find the request in
* @param {Object} updates name/value map of updates to apply * @param updates - name/value map of updates to apply
* *
* @returns {Promise} resolves to * @returns resolves to
* {@link module:crypto/store/base~OutgoingRoomKeyRequest} * {@link OutgoingRoomKeyRequest}
* updated request, or null if no matching row was found * updated request, or null if no matching row was found
*/ */
public updateOutgoingRoomKeyRequest( 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 * Look for an existing room key request by id and state, and delete it if
* found * found
* *
* @param {string} requestId ID of request to update * @param requestId - ID of request to update
* @param {number} expectedState state we expect to find the request in * @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( public deleteOutgoingRoomKeyRequest(
requestId: string, requestId: string,

View File

@ -17,7 +17,6 @@ limitations under the License.
/** /**
* Base class for verification methods. * Base class for verification methods.
* @module crypto/verification/Base
*/ */
import { MatrixEvent } from '../../models/event'; import { MatrixEvent } from '../../models/event';
@ -74,21 +73,19 @@ export class VerificationBase<
* *
* <p>Subclasses must have a NAME class property.</p> * <p>Subclasses must have a NAME class property.</p>
* *
* @class * @param channel - the verification channel to send verification messages over.
*
* @param {Object} channel the verification channel to send verification messages over.
* TODO: Channel types * 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 * 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 * this verification, if any
*/ */
public constructor( public constructor(
@ -279,7 +276,7 @@ export class VerificationBase<
/** /**
* Begin the key verification * Begin the key verification
* *
* @returns {Promise} Promise which resolves when the verification has * @returns Promise which resolves when the verification has
* completed. * completed.
*/ */
public verify(): Promise<void> { public verify(): Promise<void> {

View File

@ -16,8 +16,6 @@ limitations under the License.
/** /**
* Error messages. * Error messages.
*
* @module crypto/verification/Error
*/ */
import { MatrixEvent } from "../../models/event"; import { MatrixEvent } from "../../models/event";

View File

@ -17,7 +17,6 @@ limitations under the License.
/** /**
* Verification method that is illegal to have (cannot possibly * Verification method that is illegal to have (cannot possibly
* do verification with this method). * do verification with this method).
* @module crypto/verification/IllegalMethod
*/ */
import { VerificationBase as Base, VerificationEvent, VerificationEventHandlerMap } from "./Base"; import { VerificationBase as Base, VerificationEvent, VerificationEventHandlerMap } from "./Base";
@ -26,10 +25,6 @@ import { MatrixClient } from "../../client";
import { MatrixEvent } from "../../models/event"; import { MatrixEvent } from "../../models/event";
import { VerificationRequest } from "./request/VerificationRequest"; import { VerificationRequest } from "./request/VerificationRequest";
/**
* @class crypto/verification/IllegalMethod/IllegalMethod
* @extends {module:crypto/verification/Base}
*/
export class IllegalMethod extends Base<VerificationEvent, VerificationEventHandlerMap> { export class IllegalMethod extends Base<VerificationEvent, VerificationEventHandlerMap> {
public static factory( public static factory(
channel: IVerificationChannel, channel: IVerificationChannel,

View File

@ -16,7 +16,6 @@ limitations under the License.
/** /**
* QR code key verification. * QR code key verification.
* @module crypto/verification/QRCode
*/ */
import { VerificationBase as Base, VerificationEventHandlerMap } from "./Base"; import { VerificationBase as Base, VerificationEventHandlerMap } from "./Base";
@ -44,10 +43,6 @@ type EventHandlerMap = {
[QrCodeEvent.ShowReciprocateQr]: (qr: IReciprocateQr) => void; [QrCodeEvent.ShowReciprocateQr]: (qr: IReciprocateQr) => void;
} & VerificationEventHandlerMap; } & VerificationEventHandlerMap;
/**
* @class crypto/verification/QRCode/ReciprocateQRCode
* @extends {module:crypto/verification/Base}
*/
export class ReciprocateQRCode extends Base<QrCodeEvent, EventHandlerMap> { export class ReciprocateQRCode extends Base<QrCodeEvent, EventHandlerMap> {
public reciprocateQREvent?: IReciprocateQr; public reciprocateQREvent?: IReciprocateQr;

View File

@ -16,7 +16,6 @@ limitations under the License.
/** /**
* Short Authentication String (SAS) verification. * Short Authentication String (SAS) verification.
* @module crypto/verification/SAS
*/ */
import anotherjson from 'another-json'; import anotherjson from 'another-json';
@ -232,10 +231,6 @@ type EventHandlerMap = {
[SasEvent.ShowSas]: (sas: ISasEvent) => void; [SasEvent.ShowSas]: (sas: ISasEvent) => void;
} & VerificationEventHandlerMap; } & VerificationEventHandlerMap;
/**
* @alias module:crypto/verification/SAS
* @extends {module:crypto/verification/Base}
*/
export class SAS extends Base<SasEvent, EventHandlerMap> { export class SAS extends Base<SasEvent, EventHandlerMap> {
private waitingForAccept?: boolean; private waitingForAccept?: boolean;
public ourSASPubKey?: string; public ourSASPubKey?: string;

View File

@ -17,11 +17,11 @@ limitations under the License.
/** /**
* Implementation of decimal encoding of SAS as per: * Implementation of decimal encoding of SAS as per:
* https://spec.matrix.org/v1.4/client-server-api/#sas-method-decimal * 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 * @returns the derived three numbers between 1000 and 9191 inclusive
*/ */
export function generateDecimalSas(sasBytes: number[]): [number, number, number] { export function generateDecimalSas(sasBytes: number[]): [number, number, number] {
/** /*
* +--------+--------+--------+--------+--------+ * +--------+--------+--------+--------+--------+
* | Byte 0 | Byte 1 | Byte 2 | Byte 3 | Byte 4 | * | Byte 0 | Byte 1 | Byte 2 | Byte 3 | Byte 4 |
* +--------+--------+--------+--------+--------+ * +--------+--------+--------+--------+--------+

View File

@ -40,9 +40,9 @@ export class InRoomChannel implements IVerificationChannel {
private requestEventId?: string; private requestEventId?: string;
/** /**
* @param {MatrixClient} client the matrix client, to send messages with and get current user & device from. * @param 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 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 userId - id of user that the verification request is directed at, should be present in the room.
*/ */
public constructor( public constructor(
private readonly client: MatrixClient, private readonly client: MatrixClient,
@ -78,8 +78,8 @@ export class InRoomChannel implements IVerificationChannel {
} }
/** /**
* @param {MatrixEvent} event the event to get the timestamp of * @param event - the event to get the timestamp of
* @return {number} the timestamp when the event was sent * @returns the timestamp when the event was sent
*/ */
public getTimestamp(event: MatrixEvent): number { public getTimestamp(event: MatrixEvent): number {
return event.getTs(); 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 * 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 * @param type - the event type to check
* @returns {boolean} boolean flag * @returns boolean flag
*/ */
public static canCreateRequest(type: string): boolean { public static canCreateRequest(type: string): boolean {
return type === REQUEST_TYPE; 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 * Extract the transaction id used by a given key verification event, if any
* @param {MatrixEvent} event the event * @param event - the event
* @returns {string} the transaction id * @returns the transaction id
*/ */
public static getTransactionId(event: MatrixEvent): string | undefined { public static getTransactionId(event: MatrixEvent): string | undefined {
if (InRoomChannel.getEventType(event) === REQUEST_TYPE) { 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 * 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. * so we can prevent channels being created by invalid events.
* `handleEvent` can do more checks and choose to ignore invalid events. * `handleEvent` can do more checks and choose to ignore invalid events.
* @param {MatrixEvent} event the event to validate * @param event - the event to validate
* @param {MatrixClient} client the client to get the current user and device id from * @param 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 * @returns whether the event is valid and should be passed to handleEvent
*/ */
public static validateEvent(event: MatrixEvent, client: MatrixClient): boolean { public static validateEvent(event: MatrixEvent, client: MatrixClient): boolean {
const txnId = InRoomChannel.getTransactionId(event); 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 * 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 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 * to the symbolic one to keep things in unison with ToDeviceChannel
* @param {MatrixEvent} event the event to get the type of * @param event - the event to get the type of
* @returns {string} the "symbolic" event type * @returns the "symbolic" event type
*/ */
public static getEventType(event: MatrixEvent): string { public static getEventType(event: MatrixEvent): string {
const type = event.getType(); 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. * Changes the state of the channel, request, and verifier in response to a key verification event.
* @param {MatrixEvent} event to handle * @param event - to handle
* @param {VerificationRequest} request the request to forward handling to * @param request - the request to forward handling to
* @param {boolean} isLiveEvent whether this is an even received through sync or not * @param 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. * @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> { public async handleEvent(event: MatrixEvent, request: VerificationRequest, isLiveEvent = false): Promise<void> {
// prevent processing the same event multiple times, as under // 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. * so it has the same format as returned by `completeContent` before sending.
* The relation can not appear on the event content because of encryption, * The relation can not appear on the event content because of encryption,
* relations are excluded from encryption. * relations are excluded from encryption.
* @param {MatrixEvent} event the received event * @param event - the received event
* @returns {Object} the content object with the relation added again * @returns the content object with the relation added again
*/ */
public completedContentFromEvent(event: MatrixEvent): Record<string, any> { public completedContentFromEvent(event: MatrixEvent): Record<string, any> {
// ensure m.related_to is included in e2ee rooms // 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 * This is public so verification methods (SAS uses this) can get the exact
* content that will be sent independent of the used channel, * content that will be sent independent of the used channel,
* as they need to calculate the hash of it. * as they need to calculate the hash of it.
* @param {string} type the event type * @param type - the event type
* @param {object} content the (incomplete) content * @param content - the (incomplete) content
* @returns {object} the complete content, as it will be sent. * @returns the complete content, as it will be sent.
*/ */
public completeContent(type: string, content: Record<string, any>): Record<string, any> { public completeContent(type: string, content: Record<string, any>): Record<string, any> {
content = Object.assign({}, content); 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`. * Send an event over the channel with the content not having gone through `completeContent`.
* @param {string} type the event type * @param type - the event type
* @param {object} uncompletedContent the (incomplete) content * @param uncompletedContent - the (incomplete) content
* @returns {Promise} the promise of the request * @returns the promise of the request
*/ */
public send(type: string, uncompletedContent: Record<string, any>): Promise<void> { public send(type: string, uncompletedContent: Record<string, any>): Promise<void> {
const content = this.completeContent(type, uncompletedContent); 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. * Send an event over the channel with the content having gone through `completeContent` already.
* @param {string} type the event type * @param type - the event type
* @param {object} content * @returns the promise of the request
* @returns {Promise} the promise of the request
*/ */
public async sendCompleted(type: string, content: Record<string, any>): Promise<void> { public async sendCompleted(type: string, content: Record<string, any>): Promise<void> {
let sendType = type; let sendType = type;

View File

@ -69,8 +69,8 @@ export class ToDeviceChannel implements IVerificationChannel {
/** /**
* Extract the transaction id used by a given key verification event, if any * Extract the transaction id used by a given key verification event, if any
* @param {MatrixEvent} event the event * @param event - the event
* @returns {string} the transaction id * @returns the transaction id
*/ */
public static getTransactionId(event: MatrixEvent): string { public static getTransactionId(event: MatrixEvent): string {
const content = event.getContent(); 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 * 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 * @param type - the event type to check
* @returns {boolean} boolean flag * @returns boolean flag
*/ */
public static canCreateRequest(type: string): boolean { public static canCreateRequest(type: string): boolean {
return type === REQUEST_TYPE || type === START_TYPE; 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 * 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. * so we can prevent channels being created by invalid events.
* `handleEvent` can do more checks and choose to ignore invalid events. * `handleEvent` can do more checks and choose to ignore invalid events.
* @param {MatrixEvent} event the event to validate * @param event - the event to validate
* @param {MatrixClient} client the client to get the current user and device id from * @param 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 * @returns whether the event is valid and should be passed to handleEvent
*/ */
public static validateEvent(event: MatrixEvent, client: MatrixClient): boolean { public static validateEvent(event: MatrixEvent, client: MatrixClient): boolean {
if (event.isCancelled()) { if (event.isCancelled()) {
@ -137,8 +137,8 @@ export class ToDeviceChannel implements IVerificationChannel {
} }
/** /**
* @param {MatrixEvent} event the event to get the timestamp of * @param event - the event to get the timestamp of
* @return {number} the timestamp when the event was sent * @returns the timestamp when the event was sent
*/ */
public getTimestamp(event: MatrixEvent): number { public getTimestamp(event: MatrixEvent): number {
const content = event.getContent(); 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. * Changes the state of the channel, request, and verifier in response to a key verification event.
* @param {MatrixEvent} event to handle * @param event - to handle
* @param {VerificationRequest} request the request to forward handling to * @param request - the request to forward handling to
* @param {boolean} isLiveEvent whether this is an even received through sync or not * @param 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. * @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> { public async handleEvent(event: MatrixEvent, request: Request, isLiveEvent = false): Promise<void> {
const type = event.getType(); const type = event.getType();
@ -196,9 +196,9 @@ export class ToDeviceChannel implements IVerificationChannel {
} }
/** /**
* See {InRoomChannel.completedContentFromEvent} why this is needed. * See {@link InRoomChannel#completedContentFromEvent} for why this is needed.
* @param {MatrixEvent} event the received event * @param event - the received event
* @returns {Object} the content object * @returns the content object
*/ */
public completedContentFromEvent(event: MatrixEvent): Record<string, any> { public completedContentFromEvent(event: MatrixEvent): Record<string, any> {
return event.getContent(); 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 * This is public so verification methods (SAS uses this) can get the exact
* content that will be sent independent of the used channel, * content that will be sent independent of the used channel,
* as they need to calculate the hash of it. * as they need to calculate the hash of it.
* @param {string} type the event type * @param type - the event type
* @param {object} content the (incomplete) content * @param content - the (incomplete) content
* @returns {object} the complete content, as it will be sent. * @returns the complete content, as it will be sent.
*/ */
public completeContent(type: string, content: Record<string, any>): Record<string, any> { public completeContent(type: string, content: Record<string, any>): Record<string, any> {
// make a copy // 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`. * Send an event over the channel with the content not having gone through `completeContent`.
* @param {string} type the event type * @param type - the event type
* @param {object} uncompletedContent the (incomplete) content * @param uncompletedContent - the (incomplete) content
* @returns {Promise} the promise of the request * @returns the promise of the request
*/ */
public send(type: string, uncompletedContent: Record<string, any> = {}): Promise<void> { public send(type: string, uncompletedContent: Record<string, any> = {}): Promise<void> {
// create transaction id when sending request // 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. * Send an event over the channel with the content having gone through `completeContent` already.
* @param {string} type the event type * @param type - the event type
* @param {object} content * @returns the promise of the request
* @returns {Promise} the promise of the request
*/ */
public async sendCompleted(type: string, content: Record<string, any>): Promise<void> { public async sendCompleted(type: string, content: Record<string, any>): Promise<void> {
let result; 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. * 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 { public static makeTransactionId(): string {
return randomString(32); return randomString(32);

View File

@ -81,6 +81,9 @@ export enum VerificationRequestEvent {
} }
type EventHandlerMap = { type EventHandlerMap = {
/**
* Fires whenever the state of the request object has changed.
*/
[VerificationRequestEvent.Change]: () => void; [VerificationRequestEvent.Change]: () => void;
}; };
@ -88,7 +91,6 @@ type EventHandlerMap = {
* State machine for verification requests. * State machine for verification requests.
* Things that differ based on what channel is used to * Things that differ based on what channel is used to
* send and receive verification events are put in `InRoomChannel` or `ToDeviceChannel`. * 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< export class VerificationRequest<
C extends IVerificationChannel = IVerificationChannel, C extends IVerificationChannel = IVerificationChannel,
@ -129,10 +131,10 @@ export class VerificationRequest<
/** /**
* Stateless validation logic not specific to the channel. * Stateless validation logic not specific to the channel.
* Invoked by the same static method in either 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 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 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 * @param 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 * @returns whether the event is valid and should be passed to handleEvent
*/ */
public static validateEvent(type: string, event: MatrixEvent, client: MatrixClient): boolean { public static validateEvent(type: string, event: MatrixEvent, client: MatrixClient): boolean {
const content = event.getContent(); const content = event.getContent();
@ -234,7 +236,7 @@ export class VerificationRequest<
/** /**
* The key verification request event. * 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 { public get requestEvent(): MatrixEvent | undefined {
return this.getEventByEither(REQUEST_TYPE); 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: * 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. * 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. * For methods that need to be supported by both ends, use the `methods` property.
* @param {string} method the method to check * @param method - the method to check
* @param {boolean} force to check even if the phase is not ready or started yet, internal usage * @param 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 */ * @returns whether or not the other party said the supported the method */
public otherPartySupportsMethod(method: string, force = false): boolean { public otherPartySupportsMethod(method: string, force = false): boolean {
if (!force && !this.ready && !this.started) { if (!force && !this.ready && !this.started) {
return false; return false;
@ -398,7 +400,7 @@ export class VerificationRequest<
* given the events sent so far in the verification. This is the * given the events sent so far in the verification. This is the
* same algorithm used to determine which device to send the * same algorithm used to determine which device to send the
* verification to when no specific device is specified. * verification to when no specific device is specified.
* @returns {{userId: *, deviceId: *}} The device information * @returns The device information
*/ */
public get targetDevice(): ITargetDevice { public get targetDevice(): ITargetDevice {
const theirFirstEvent = const theirFirstEvent =
@ -415,10 +417,10 @@ export class VerificationRequest<
/* Start the key verification, creating a verifier and sending a .start event. /* 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. * 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 method - the name of the verification method to use.
* @param {string?} targetDevice.userId the id of the user to direct this request to * @param 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 * @param targetDevice.deviceId the id of the device to direct this request to
* @returns {VerifierBase} the verifier of the given method * @returns the verifier of the given method
*/ */
public beginKeyVerification( public beginKeyVerification(
method: VerificationMethod, method: VerificationMethod,
@ -448,7 +450,7 @@ export class VerificationRequest<
/** /**
* sends the initial .request event. * 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> { public async sendRequest(): Promise<void> {
if (!this.observeOnly && this._phase === PHASE_UNSENT) { if (!this.observeOnly && this._phase === PHASE_UNSENT) {
@ -459,9 +461,9 @@ export class VerificationRequest<
/** /**
* Cancels the request, sending a cancellation to the other party * Cancels the request, sending a cancellation to the other party
* @param {string?} error.reason the error reason to send the cancellation with * @param reason - the error reason to send the cancellation with
* @param {string?} error.code the error code to send the cancellation with * @param code - the error code to send the cancellation with
* @returns {Promise} resolves when the event has been sent. * @returns resolves when the event has been sent.
*/ */
public async cancel({ reason = "User declined", code = "m.user" } = {}): Promise<void> { public async cancel({ reason = "User declined", code = "m.user" } = {}): Promise<void> {
if (!this.observeOnly && this._phase !== PHASE_CANCELLED) { 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 * 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> { public async accept(): Promise<void> {
if (!this.observeOnly && this.phase === PHASE_REQUESTED && !this.initiatedByMe) { 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. * 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. * Takes the request as an argument.
* @returns {Promise} that resolves once the callback returns true * @returns that resolves once the callback returns true
* @throws {Error} when the request is cancelled * @throws Error when the request is cancelled
*/ */
public waitFor(fn: (request: VerificationRequest) => boolean): Promise<VerificationRequest> { public waitFor(fn: (request: VerificationRequest) => boolean): Promise<VerificationRequest> {
return new Promise((resolve, reject) => { 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. * 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 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 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 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 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 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. * 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( public async handleEvent(
type: string, type: string,

View File

@ -85,7 +85,7 @@ export interface ICapabilities {
/** /**
* Whether this client needs access to TURN servers. * Whether this client needs access to TURN servers.
* @default false * @defaultValue false
*/ */
turnServers?: boolean; turnServers?: boolean;
} }

View File

@ -20,8 +20,11 @@ import { IEvent, MatrixEvent, MatrixEventEvent } from "./models/event";
export type EventMapper = (obj: Partial<IEvent>) => MatrixEvent; export type EventMapper = (obj: Partial<IEvent>) => MatrixEvent;
export interface MapperOpts { export interface MapperOpts {
// don't re-emit events emitted on an event mapped by this mapper on the client
preventReEmit?: boolean; preventReEmit?: boolean;
// decrypt event proactively
decrypt?: boolean; decrypt?: boolean;
// the event is a to_device event
toDevice?: boolean; toDevice?: boolean;
} }

View File

@ -22,16 +22,12 @@ import {
THREAD_RELATION_TYPE, THREAD_RELATION_TYPE,
} from "./models/thread"; } from "./models/thread";
/**
* @module filter-component
*/
/** /**
* Checks if a value matches a given field value, which may be a * terminated * Checks if a value matches a given field value, which may be a * terminated
* wildcard pattern. * wildcard pattern.
* @param {String} actualValue The value to be compared * @param actualValue - The value to be compared
* @param {String} filterValue The filter pattern to be compared * @param filterValue - The filter pattern to be compared
* @return {boolean} true if the actualValue matches the filterValue * @returns true if the actualValue matches the filterValue
*/ */
function matchesWildcard(actualValue: string, filterValue: string): boolean { function matchesWildcard(actualValue: string, filterValue: string): boolean {
if (filterValue.endsWith("*")) { 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 * N.B. that synapse refers to these as 'Filters', and what js-sdk refers to as
* 'Filters' are referred to as 'FilterCollections'. * 'Filters' are referred to as 'FilterCollections'.
*
* @constructor
* @param {Object} filterJson the definition of this filter JSON, e.g. { 'contains_url': true }
*/ */
export class FilterComponent { export class FilterComponent {
public constructor(private filterJson: IFilterComponent, public readonly userId?: string | undefined | null) {} public constructor(private filterJson: IFilterComponent, public readonly userId?: string | undefined | null) {}
/** /**
* Checks with the filter component matches the given event * Checks with the filter component matches the given event
* @param {MatrixEvent} event event to be checked against the filter * @param event - event to be checked against the filter
* @return {boolean} true if the event matches the filter * @returns true if the event matches the filter
*/ */
public check(event: MatrixEvent): boolean { public check(event: MatrixEvent): boolean {
const bundledRelationships = event.getUnsigned()?.["m.relations"] || {}; const bundledRelationships = event.getUnsigned()?.["m.relations"] || {};
@ -122,13 +115,13 @@ export class FilterComponent {
/** /**
* Checks whether the filter component matches the given event fields. * Checks whether the filter component matches the given event fields.
* @param {String} roomId the roomId for the event being checked * @param roomId - the roomId for the event being checked
* @param {String} sender the sender of the event being checked * @param sender - the sender of the event being checked
* @param {String} eventType the type of the event being checked * @param eventType - the type of the event being checked
* @param {boolean} containsUrl whether the event contains a content.url field * @param containsUrl - whether the event contains a content.url field
* @param {boolean} relationTypes whether has aggregated relation of the given type * @param relationTypes - whether has aggregated relation of the given type
* @param {boolean} relationSenders whether one of the relation is sent by the user listed * @param relationSenders - whether one of the relation is sent by the user listed
* @return {boolean} true if the event fields match the filter * @returns true if the event fields match the filter
*/ */
private checkFields( private checkFields(
roomId: string | undefined, roomId: string | undefined,
@ -194,8 +187,8 @@ export class FilterComponent {
/** /**
* Filters a list of events down to those which match this filter component * Filters a list of events down to those which match this filter component
* @param {MatrixEvent[]} events Events to be checked against the filter component * @param events - Events to be checked against the filter component
* @return {MatrixEvent[]} events which matched the filter component * @returns events which matched the filter component
*/ */
public filter(events: MatrixEvent[]): MatrixEvent[] { public filter(events: MatrixEvent[]): MatrixEvent[] {
return events.filter(this.check, this); 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 * Returns the limit field for a given filter component, providing a default of
* 10 if none is otherwise specified. Cargo-culted from Synapse. * 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 { public limit(): number {
return this.filterJson.limit !== undefined ? this.filterJson.limit : 10; return this.filterJson.limit !== undefined ? this.filterJson.limit : 10;

View File

@ -14,10 +14,6 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/**
* @module filter
*/
import { import {
EventType, EventType,
RelationType, RelationType,
@ -27,9 +23,6 @@ import { FilterComponent, IFilterComponent } from "./filter-component";
import { MatrixEvent } from "./models/event"; import { MatrixEvent } from "./models/event";
/** /**
* @param {Object} obj
* @param {string} keyNesting
* @param {*} val
*/ */
function setProp(obj: Record<string, any>, keyNesting: string, val: any): void { function setProp(obj: Record<string, any>, keyNesting: string, val: any): void {
const nestedKeys = keyNesting.split(".") as [keyof typeof obj]; const nestedKeys = keyNesting.split(".") as [keyof typeof obj];
@ -78,14 +71,6 @@ interface IRoomFilter {
} }
/* eslint-enable camelcase */ /* 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 { export class Filter {
public static LAZY_LOADING_MESSAGES_FILTER = { public static LAZY_LOADING_MESSAGES_FILTER = {
lazy_load_members: true, lazy_load_members: true,
@ -93,11 +78,6 @@ export class Filter {
/** /**
* Create a filter from existing data. * 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 { public static fromJson(userId: string | undefined | null, filterId: string, jsonObj: IFilterDefinition): Filter {
const filter = new Filter(userId, filterId); const filter = new Filter(userId, filterId);
@ -109,11 +89,16 @@ export class Filter {
private roomFilter?: FilterComponent; private roomFilter?: FilterComponent;
private roomTimelineFilter?: 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) {} public constructor(public readonly userId: string | undefined | null, public filterId?: string) {}
/** /**
* Get the ID of this filter on your homeserver (if known) * Get the ID of this filter on your homeserver (if known)
* @return {?string} The filter ID * @returns The filter ID
*/ */
public getFilterId(): string | undefined { public getFilterId(): string | undefined {
return this.filterId; return this.filterId;
@ -121,7 +106,7 @@ export class Filter {
/** /**
* Get the JSON body of the filter. * Get the JSON body of the filter.
* @return {Object} The filter definition * @returns The filter definition
*/ */
public getDefinition(): IFilterDefinition { public getDefinition(): IFilterDefinition {
return this.definition; return this.definition;
@ -129,7 +114,7 @@ export class Filter {
/** /**
* Set the JSON body of the filter * Set the JSON body of the filter
* @param {Object} definition The filter definition * @param definition - The filter definition
*/ */
public setDefinition(definition: IFilterDefinition): void { public setDefinition(definition: IFilterDefinition): void {
this.definition = definition; this.definition = definition;
@ -198,7 +183,7 @@ export class Filter {
/** /**
* Get the room.timeline filter component of the 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 { public getRoomTimelineFilterComponent(): FilterComponent | undefined {
return this.roomTimelineFilter; return this.roomTimelineFilter;
@ -207,8 +192,8 @@ export class Filter {
/** /**
* Filter the list of events based on whether they are allowed in a timeline * Filter the list of events based on whether they are allowed in a timeline
* based on this filter * based on this filter
* @param {MatrixEvent[]} events the list of events being filtered * @param events - the list of events being filtered
* @return {MatrixEvent[]} the list of events which match the filter * @returns the list of events which match the filter
*/ */
public filterRoomTimeline(events: MatrixEvent[]): MatrixEvent[] { public filterRoomTimeline(events: MatrixEvent[]): MatrixEvent[] {
if (this.roomFilter) { if (this.roomFilter) {
@ -222,7 +207,7 @@ export class Filter {
/** /**
* Set the max number of events to return for each room's timeline. * 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 { public setTimelineLimit(limit: number): void {
setProp(this.definition, "room.timeline.limit", limit); setProp(this.definition, "room.timeline.limit", limit);
@ -230,7 +215,6 @@ export class Filter {
/** /**
* Enable threads unread notification * Enable threads unread notification
* @param {boolean} enabled
*/ */
public setUnreadThreadNotifications(enabled: boolean): void { public setUnreadThreadNotifications(enabled: boolean): void {
this.definition = { this.definition = {
@ -251,7 +235,7 @@ export class Filter {
/** /**
* Control whether left rooms should be included in responses. * 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. * in responses.
*/ */
public setIncludeLeaveRooms(includeLeave: boolean): void { public setIncludeLeaveRooms(includeLeave: boolean): void {

View File

@ -26,9 +26,8 @@ interface IErrorJson extends Partial<IUsageLimit> {
/** /**
* Construct a generic HTTP error. This is a JavaScript Error with additional information * Construct a generic HTTP error. This is a JavaScript Error with additional information
* specific to HTTP responses. * specific to HTTP responses.
* @constructor * @param msg - The error message to include.
* @param {string} msg The error message to include. * @param httpStatus - The HTTP response status code.
* @param {number} httpStatus The HTTP response status code.
*/ */
export class HTTPError extends Error { export class HTTPError extends Error {
public constructor(msg: string, public readonly httpStatus?: number) { public constructor(msg: string, public readonly httpStatus?: number) {
@ -36,21 +35,18 @@ export class HTTPError extends Error {
} }
} }
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 * Construct a Matrix error. This is a JavaScript Error with additional
* information specific to the standard Matrix error response. * information specific to the standard Matrix error response.
* @constructor * @param errorJson - The Matrix error JSON returned from the homeserver.
* @param {Object} errorJson The Matrix error JSON returned from the homeserver. * @param httpStatus - The numeric HTTP status code given
* @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 {
public readonly errcode?: string;
public data: IErrorJson;
public constructor( public constructor(
errorJson: IErrorJson = {}, errorJson: IErrorJson = {},
public readonly httpStatus?: number, 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 * 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, * 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. * the request timed out, or the internet connection on the client side went down.
* @constructor
*/ */
export class ConnectionError extends Error { export class ConnectionError extends Error {
public constructor(message: string, cause?: Error) { public constructor(message: string, cause?: Error) {

View File

@ -16,7 +16,6 @@ limitations under the License.
/** /**
* This is an internal module. See {@link MatrixHttpApi} for the public class. * This is an internal module. See {@link MatrixHttpApi} for the public class.
* @module http-api
*/ */
import * as utils from "../utils"; import * as utils from "../utils";
@ -64,13 +63,13 @@ export class FetchHttpApi<O extends IHttpOpts> {
/** /**
* Sets the base URL for the identity server * 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 { public setIdBaseUrl(url: string): void {
this.opts.idBaseUrl = url; this.opts.idBaseUrl = url;
} }
public idServerRequest<T extends {}>( public idServerRequest<T extends Record<string, unknown>>(
method: Method, method: Method,
path: string, path: string,
params: Record<string, string | string[]> | undefined, params: Record<string, string | string[]> | undefined,
@ -104,35 +103,29 @@ export class FetchHttpApi<O extends IHttpOpts> {
/** /**
* Perform an authorised request to the homeserver. * Perform an authorised request to the homeserver.
* @param {string} method The HTTP method e.g. "GET". * @param method - The HTTP method e.g. "GET".
* @param {string} path The HTTP path <b>after</b> the supplied prefix e.g. * @param path - The HTTP path <b>after</b> the supplied prefix e.g.
* "/createRoom". * "/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. * 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`. * this is treated as `opts.localTimeoutMs`.
* *
* @param {Number=} opts.localTimeoutMs The maximum amount of time to wait before * @returns Promise which resolves to
* timing out the request. If not specified, there is no timeout. * ```
* * {
* @param {string=} opts.prefix The full prefix to use e.g. * data: {Object},
* "/_matrix/client/v2_alpha". If not specified, uses this.opts.prefix. * headers: {Object},
* * code: {Number},
* @param {string=} opts.baseUrl The alternative base url to use. * }
* If not specified, uses this.opts.baseUrl * ```
* * If `onlyData` is set, this will resolve to the `data` object only.
* @param {Object=} opts.headers map of additional request headers * @returns Rejects with an error if a problem occurred.
* * This includes network problems and Matrix-specific error JSON.
* @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.
*/ */
public authedRequest<T>( public authedRequest<T>(
method: Method, method: Method,
@ -176,30 +169,28 @@ export class FetchHttpApi<O extends IHttpOpts> {
/** /**
* Perform a request to the homeserver without any credentials. * Perform a request to the homeserver without any credentials.
* @param {string} method The HTTP method e.g. "GET". * @param method - The HTTP method e.g. "GET".
* @param {string} path The HTTP path <b>after</b> the supplied prefix e.g. * @param path - The HTTP path <b>after</b> the supplied prefix e.g.
* "/createRoom". * "/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. * 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 * @returns Promise which resolves to
* timing out the request. If not specified, there is no timeout. * ```
* * {
* @param {string=} opts.prefix The full prefix to use e.g. * data: {Object},
* "/_matrix/client/v2_alpha". If not specified, uses this.opts.prefix. * headers: {Object},
* * code: {Number},
* @param {Object=} opts.headers map of additional request headers * }
* * ```
* @return {Promise} Resolves to <code>{data: {Object}, * If `onlyData</code> is set, this will resolve to the <code>data`
* headers: {Object}, code: {Number}}</code>.
* If <code>onlyData</code> is set, this will resolve to the <code>data</code>
* object only. * 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. * occurred. This includes network problems and Matrix-specific error JSON.
*/ */
public request<T>( public request<T>(
@ -215,21 +206,16 @@ export class FetchHttpApi<O extends IHttpOpts> {
/** /**
* Perform a request to an arbitrary URL. * Perform a request to an arbitrary URL.
* @param {string} method The HTTP method e.g. "GET". * @param method - The HTTP method e.g. "GET".
* @param {string} url The HTTP URL object. * @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 * @returns Promise which resolves to data unless `onlyData` is specified as false,
* 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,
* where the resolved value will be a fetch Response object. * 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. * occurred. This includes network problems and Matrix-specific error JSON.
*/ */
public async requestOtherUrl<T>( 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. * 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 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 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 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. * @param baseUrl - The baseUrl to use e.g. "https://matrix.org/", defaulting to this.opts.baseUrl.
* @return {string} URL * @returns URL
*/ */
public getUrl( public getUrl(
path: string, path: string,

View File

@ -35,27 +35,13 @@ export class MatrixHttpApi<O extends IHttpOpts> extends FetchHttpApi<O> {
/** /**
* Upload content to the homeserver * 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, * can be sent to XMLHttpRequest.send (typically a File). Under node.js,
* a Buffer, String or ReadStream. * 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 * @returns Promise which resolves to response object, as
* 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
* determined by this.opts.onlyData, opts.rawResponse, and * determined by this.opts.onlyData, opts.rawResponse, and
* opts.onlyContentUri. Rejects with an error (usually a MatrixError). * 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. * 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. * path and query parameters respectively.
*/ */
public getContentUri(): IContentUri { public getContentUri(): IContentUri {

View File

@ -32,11 +32,25 @@ export interface IHttpOpts {
} }
export interface IRequestOpts { export interface IRequestOpts {
/**
* The alternative base url to use.
* If not specified, uses this.opts.baseUrl
*/
baseUrl?: string; baseUrl?: string;
/**
* The full prefix to use e.g.
* "/_matrix/client/v2_alpha". If not specified, uses this.opts.prefix.
*/
prefix?: string; prefix?: string;
/**
* map of additional request headers
*/
headers?: Record<string, string>; headers?: Record<string, string>;
abortSignal?: AbortSignal; abortSignal?: AbortSignal;
/**
* The maximum amount of time to wait before
* timing out the request. If not specified, there is no timeout.
*/
localTimeoutMs?: number; localTimeoutMs?: number;
keepAlive?: boolean; // defaults to false keepAlive?: boolean; // defaults to false
json?: boolean; // defaults to true json?: boolean; // defaults to true
@ -62,7 +76,29 @@ export enum HttpApiEvent {
} }
export type HttpApiEventHandlerMap = { 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; [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; [HttpApiEvent.NoConsent]: (message: string, consentUri: string) => void;
}; };
@ -72,9 +108,26 @@ export interface UploadProgress {
} }
export interface UploadOpts { export interface UploadOpts {
/**
* Name to give the file on the server. Defaults to <tt>file.name</tt>.
*/
name?: string; name?: string;
/**
* Content-type for the upload. Defaults to
* <tt>file.type</tt>, or <tt>applicaton/octet-stream</tt>.
*/
type?: string; 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; 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; progressHandler?(progress: UploadProgress): void;
abortController?: AbortController; abortController?: AbortController;
} }

View File

@ -67,9 +67,9 @@ export function anySignal(signals: AbortSignal[]): {
* If it is a JSON response, we will parse it into a MatrixError. Otherwise * If it is a JSON response, we will parse it into a MatrixError. Otherwise
* we return a generic Error. * we return a generic Error.
* *
* @param {XMLHttpRequest|Response} response response object * @param response - response object
* @param {String} body raw body of the response * @param body - raw body of the response
* @returns {Error} * @returns
*/ */
export function parseErrorResponse(response: XMLHttpRequest | Response, body?: string): Error { export function parseErrorResponse(response: XMLHttpRequest | Response, body?: string): Error {
let contentType: ParsedMediaType | null; 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. * returns null if no content-type header could be found.
* *
* @param {XMLHttpRequest|Response} response response object * @param response - response object
* @returns {{type: String, parameters: Object}?} parsed content-type header, or null if not found * @returns parsed content-type header, or null if not found
*/ */
function getResponseContentType(response: XMLHttpRequest | Response): ParsedMediaType | null { function getResponseContentType(response: XMLHttpRequest | Response): ParsedMediaType | null {
let contentType: string | null; let contentType: string | null;
@ -124,10 +124,10 @@ function getResponseContentType(response: XMLHttpRequest | Response): ParsedMedi
/** /**
* Retries a network operation run in a callback. * Retries a network operation run in a callback.
* @param {number} maxAttempts maximum attempts to try * @param 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. * @param 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 * @returns the result of the network operation
* @throws {ConnectionError} If after maxAttempts the callback still throws ConnectionError * @throws {@link ConnectionError} If after maxAttempts the callback still throws ConnectionError
*/ */
export async function retryNetworkOperation<T>(maxAttempts: number, callback: () => Promise<T>): Promise<T> { export async function retryNetworkOperation<T>(maxAttempts: number, callback: () => Promise<T>): Promise<T> {
let attempts = 0; let attempts = 0;

View File

@ -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 * 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. * we do that and then delete it did not exist before.
* *
* @param {Object} indexedDB The `indexedDB` interface * @param indexedDB - The `indexedDB` interface
* @param {string} dbName The database name to test for * @param dbName - The database name to test for
* @returns {boolean} Whether the database exists * @returns Whether the database exists
*/ */
export function exists(indexedDB: IDBFactory, dbName: string): Promise<boolean> { export function exists(indexedDB: IDBFactory, dbName: string): Promise<boolean> {
return new Promise<boolean>((resolve, reject) => { return new Promise<boolean>((resolve, reject) => {

View File

@ -20,6 +20,6 @@ limitations under the License.
* to be used separately * to be used separately
*/ */
/** The {@link module:indexeddb-store-worker~IndexedDBStoreWorker} class. */ /** The {@link IndexedDBStoreWorker} class. */
export { IndexedDBStoreWorker } from "./store/indexeddb-store-worker"; export { IndexedDBStoreWorker } from "./store/indexeddb-store-worker";

View File

@ -16,8 +16,6 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/** @module interactive-auth */
import { logger } from './logger'; import { logger } from './logger';
import { MatrixClient } from "./client"; import { MatrixClient } from "./client";
import { defer, IDeferred } from "./utils"; import { defer, IDeferred } from "./utils";
@ -31,8 +29,11 @@ interface IFlow {
} }
export interface IInputs { export interface IInputs {
// An email address. If supplied, a flow using email verification will be chosen.
emailAddress?: string; emailAddress?: string;
// An ISO two letter country code. Gives the country that opts.phoneNumber should be resolved relative to.
phoneCountry?: string; phoneCountry?: string;
// A phone number. If supplied, a flow using phone number validation will be chosen.
phoneNumber?: string; phoneNumber?: string;
registrationToken?: string; registrationToken?: string;
} }
@ -106,15 +107,66 @@ class NoAuthFlowFoundError extends Error {
} }
interface IOpts { interface IOpts {
/**
* A matrix client to use for the auth process
*/
matrixClient: MatrixClient; matrixClient: MatrixClient;
/**
* Error response from the last request. If null, a request will be made with no auth before starting.
*/
authData?: IAuthData; 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; inputs?: IInputs;
/**
* If resuming an existing interactive auth session, the sessionId of that session.
*/
sessionId?: string; sessionId?: string;
/**
* If resuming an existing interactive auth session, the client secret for that session
*/
clientSecret?: string; clientSecret?: string;
/**
* If returning from having completed m.login.email.identity auth, the sid for the email verification session.
*/
emailSid?: string; 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>; 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; 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 }>; 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; busyChanged?(busy: boolean): void;
startAuthStage?(nextStage: string): Promise<void>; // LEGACY startAuthStage?(nextStage: string): Promise<void>; // LEGACY
} }
@ -131,70 +183,7 @@ interface IOpts {
* callbacks, and information gathered from the user can be submitted with * callbacks, and information gathered from the user can be submitted with
* submitAuthDict. * submitAuthDict.
* *
* @constructor * @param opts - options object
* @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.
*
*/ */
export class InteractiveAuth { export class InteractiveAuth {
private readonly matrixClient: MatrixClient; private readonly matrixClient: MatrixClient;
@ -236,7 +225,7 @@ export class InteractiveAuth {
/** /**
* begin the authentication process. * 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 * or rejects with the error on failure. Rejects with NoAuthFlowFoundError if
* no suitable authentication flow can be found * no suitable authentication flow can be found
*/ */
@ -307,7 +296,7 @@ export class InteractiveAuth {
/** /**
* get the auth session ID * get the auth session ID
* *
* @return {string} session id * @returns session id
*/ */
public getSessionId(): string | undefined { public getSessionId(): string | undefined {
return this.data?.session; return this.data?.session;
@ -317,7 +306,7 @@ export class InteractiveAuth {
* get the client secret used for validation sessions * get the client secret used for validation sessions
* with the identity server. * with the identity server.
* *
* @return {string} client secret * @returns client secret
*/ */
public getClientSecret(): string { public getClientSecret(): string {
return this.clientSecret; return this.clientSecret;
@ -326,8 +315,8 @@ export class InteractiveAuth {
/** /**
* get the server params for a given stage * get the server params for a given stage
* *
* @param {string} loginType login type for the stage * @param loginType - login type for the stage
* @return {object?} any parameters from the server for this stage * @returns any parameters from the server for this stage
*/ */
public getStageParams(loginType: string): Record<string, any> | undefined { public getStageParams(loginType: string): Record<string, any> | undefined {
return this.data.params?.[loginType]; return this.data.params?.[loginType];
@ -342,10 +331,10 @@ export class InteractiveAuth {
* make attemptAuth resolve/reject, or cause the startAuthStage callback * make attemptAuth resolve/reject, or cause the startAuthStage callback
* to be called for a new stage. * 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 * include a `type` property denoting the login type, as well as any
* other params for that stage. * 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 * 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. * 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 * Gets the sid for the email validation session
* Specific to m.login.email.identity * 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 { public getEmailSid(): string | undefined {
return this.emailSid; return this.emailSid;
@ -410,7 +399,7 @@ export class InteractiveAuth {
* of the email validation. * of the email validation.
* Specific to m.login.email.identity * 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 { public setEmailSid(sid: string): void {
this.emailSid = sid; this.emailSid = sid;
@ -448,9 +437,9 @@ export class InteractiveAuth {
* Fire off a request, and either resolve the promise, or call * Fire off a request, and either resolve the promise, or call
* startAuthStage. * startAuthStage.
* *
* @private * @internal
* @param {object?} auth new auth dict, including session id * @param auth - new auth dict, including session id
* @param {boolean?} background If true, this request is a background poll, so it * @param background - If true, this request is a background poll, so it
* failing will not result in the attemptAuth promise being rejected. * 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 * This can be set to true for requests that just poll to see if auth has
* been completed elsewhere. * been completed elsewhere.
@ -526,8 +515,8 @@ export class InteractiveAuth {
/** /**
* Pick the next stage and call the callback * Pick the next stage and call the callback
* *
* @private * @internal
* @throws {NoAuthFlowFoundError} If no suitable authentication flow can be found * @throws {@link NoAuthFlowFoundError} If no suitable authentication flow can be found
*/ */
private startNextAuthStage(): void { private startNextAuthStage(): void {
const nextStage = this.chooseStage(); const nextStage = this.chooseStage();
@ -559,9 +548,9 @@ export class InteractiveAuth {
/** /**
* Pick the next auth stage * Pick the next auth stage
* *
* @private * @internal
* @return {string?} login type * @returns login type
* @throws {NoAuthFlowFoundError} If no suitable authentication flow can be found * @throws {@link NoAuthFlowFoundError} If no suitable authentication flow can be found
*/ */
private chooseStage(): AuthType | undefined { private chooseStage(): AuthType | undefined {
if (this.chosenFlow === null) { if (this.chosenFlow === null) {
@ -584,9 +573,9 @@ export class InteractiveAuth {
* this could result in the email not being used which would leave * this could result in the email not being used which would leave
* the account with no means to reset a password. * the account with no means to reset a password.
* *
* @private * @internal
* @return {object} flow * @returns flow
* @throws {NoAuthFlowFoundError} If no suitable authentication flow can be found * @throws {@link NoAuthFlowFoundError} If no suitable authentication flow can be found
*/ */
private chooseFlow(): IFlow { private chooseFlow(): IFlow {
const flows = this.data.flows || []; const flows = this.data.flows || [];
@ -625,9 +614,8 @@ export class InteractiveAuth {
/** /**
* Get the first uncompleted stage in the given flow * Get the first uncompleted stage in the given flow
* *
* @private * @internal
* @param {object} flow * @returns login type
* @return {string} login type
*/ */
private firstUncompletedStage(flow: IFlow): AuthType | undefined { private firstUncompletedStage(flow: IFlow): AuthType | undefined {
const completed = this.data.completed || []; const completed = this.data.completed || [];

View File

@ -15,10 +15,6 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/**
* @module logger
*/
import log, { Logger } from "loglevel"; import log, { Logger } from "loglevel";
// This is to demonstrate, that you can use any namespace you want. // 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. * Can be tailored down to specific use cases if needed.
*/ */
export const logger = log.getLogger(DEFAULT_NAMESPACE) as PrefixedLogger; export const logger = log.getLogger(DEFAULT_NAMESPACE) as PrefixedLogger;

View File

@ -70,8 +70,7 @@ let cryptoStoreFactory = (): CryptoStore => new MemoryCryptoStore;
/** /**
* Configure a different factory to be used for creating crypto stores * Configure a different factory to be used for creating crypto stores
* *
* @param {Function} fac a function which will return a new * @param fac - a function which will return a new {@link CryptoStore}
* {@link module:crypto.store.base~CryptoStore}.
*/ */
export function setCryptoStoreFactory(fac: () => CryptoStore): void { export function setCryptoStoreFactory(fac: () => CryptoStore): void {
cryptoStoreFactory = fac; 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. * except that the 'request', 'store' and 'scheduler' dependencies are satisfied.
* @param {Object} opts The configuration options for this client. These configuration * @param opts - The configuration options for this client. These configuration
* options will be passed directly to {@link module:client.MatrixClient}. * options will be passed directly to {@link 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 {module:crypto.store.base~CryptoStore=} opts.cryptoStore * @returns A new matrix client.
* crypto store implementation. Calls the factory supplied to * @see {@link MatrixClient} for the full list of options for
* {@link setCryptoStoreFactory} if unspecified; or if no factory has been * `opts`.
* 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>.
*/ */
export function createClient(opts: ICreateClientOpts): MatrixClient { export function createClient(opts: ICreateClientOpts): MatrixClient {
return new MatrixClient(amendClientOpts(opts)); return new MatrixClient(amendClientOpts(opts));

View File

@ -67,7 +67,7 @@ export class MSC3089Branch {
/** /**
* Deletes the file from the tree, including all prior edits/versions. * 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> { public async delete(): Promise<void> {
await this.client.sendStateEvent(this.roomId, UNSTABLE_MSC3089_BRANCH.name, {}, this.id); 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. * 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 { public getName(): string {
return this.indexEvent.getContent()['name'] || "Unnamed File"; return this.indexEvent.getContent()['name'] || "Unnamed File";
@ -87,8 +87,8 @@ export class MSC3089Branch {
/** /**
* Sets the name for this file. * Sets the name for this file.
* @param {string} name The new name for this file. * @param name - The new name for this file.
* @returns {Promise<void>} Resolves when complete. * @returns Promise which resolves when complete.
*/ */
public async setName(name: string): Promise<void> { public async setName(name: string): Promise<void> {
await this.client.sendStateEvent(this.roomId, UNSTABLE_MSC3089_BRANCH.name, { 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. * Gets whether or not a file is locked.
* @returns {boolean} True if locked, false otherwise. * @returns True if locked, false otherwise.
*/ */
public isLocked(): boolean { public isLocked(): boolean {
return this.indexEvent.getContent()['locked'] || false; return this.indexEvent.getContent()['locked'] || false;
@ -107,8 +107,8 @@ export class MSC3089Branch {
/** /**
* Sets a file as locked or unlocked. * Sets a file as locked or unlocked.
* @param {boolean} locked True to lock the file, false otherwise. * @param locked - True to lock the file, false otherwise.
* @returns {Promise<void>} Resolves when complete. * @returns Promise which resolves when complete.
*/ */
public async setLocked(locked: boolean): Promise<void> { public async setLocked(locked: boolean): Promise<void> {
await this.client.sendStateEvent(this.roomId, UNSTABLE_MSC3089_BRANCH.name, { 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. * 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 }> { public async getFileInfo(): Promise<{ info: IEncryptedFile, httpUrl: string }> {
const event = await this.getFileEvent(); const event = await this.getFileEvent();
@ -136,7 +136,7 @@ export class MSC3089Branch {
/** /**
* Gets the event the file points to. * 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> { public async getFileEvent(): Promise<MatrixEvent> {
const room = this.client.getRoom(this.roomId); 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(). * 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 name - The name of the file.
* @param {File | String | Buffer | ReadStream | Blob} encryptedContents The encrypted contents. * @param encryptedContents - The encrypted contents.
* @param {Partial<IEncryptedFile>} info The encrypted file information. * @param info - The encrypted file information.
* @param {IContent} additionalContent Optional event content fields to include in the message. * @param additionalContent - Optional event content fields to include in the message.
* @returns {Promise<ISendEventResponse>} Resolves to the file event's sent response. * @returns Promise which resolves to the file event's sent response.
*/ */
public async createNewVersion( public async createNewVersion(
name: string, name: string,
@ -200,7 +200,7 @@ export class MSC3089Branch {
/** /**
* Gets the file's version history, starting at this file. * 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. * first element being the current version and the last element being the first version.
*/ */
public async getVersionHistory(): Promise<MSC3089Branch[]> { public async getVersionHistory(): Promise<MSC3089Branch[]> {

View File

@ -111,8 +111,8 @@ export class MSC3089TreeSpace {
/** /**
* Sets the name of the tree space. * Sets the name of the tree space.
* @param {string} name The new name for the space. * @param name - The new name for the space.
* @returns {Promise<void>} Resolves when complete. * @returns Promise which resolves when complete.
*/ */
public async setName(name: string): Promise<void> { public async setName(name: string): Promise<void> {
await this.client.sendStateEvent(this.roomId, EventType.RoomName, { name }, ""); 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 * Invites a user to the tree space. They will be given the default Viewer
* permission level unless specified elsewhere. * permission level unless specified elsewhere.
* @param {string} userId The user ID to invite. * @param userId - The user ID to invite.
* @param {boolean} andSubspaces True (default) to invite the user to all * @param andSubspaces - True (default) to invite the user to all
* directories/subspaces too, recursively. * 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) * 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 * in the tree. Keys will not be shared if the room is lacking appropriate
* history visibility (by default, history visibility is "shared" in trees, * history visibility (by default, history visibility is "shared" in trees,
* which is an appropriate visibility for these purposes). * 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> { public async invite(userId: string, andSubspaces = true, shareHistoryKeys = true): Promise<void> {
const promises: Promise<void>[] = [this.retryInvite(userId)]; 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 * 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 * 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. * 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 userId - The user ID to change the role of.
* @param {TreePermissions} role The role to assign. * @param role - The role to assign.
* @returns {Promise<void>} Resolves when complete. * @returns Promise which resolves when complete.
*/ */
public async setPermissions(userId: string, role: TreePermissions): Promise<void> { public async setPermissions(userId: string, role: TreePermissions): Promise<void> {
const currentPls = this.room.currentState.getStateEvents(EventType.RoomPowerLevels, ""); 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 * 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 * in the space) will be considered Viewers. Appropriate membership checks need to be performed
* elsewhere. * elsewhere.
* @param {string} userId The user ID to check permissions of. * @param userId - The user ID to check permissions of.
* @returns {TreePermissions} The permissions for the user, defaulting to Viewer. * @returns The permissions for the user, defaulting to Viewer.
*/ */
public getPermissions(userId: string): TreePermissions { public getPermissions(userId: string): TreePermissions {
const currentPls = this.room.currentState.getStateEvents(EventType.RoomPowerLevels, ""); 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. * Creates a directory under this tree space, represented as another tree space.
* @param {string} name The name for the directory. * @param name - The name for the directory.
* @returns {Promise<MSC3089TreeSpace>} Resolves to the created directory. * @returns Promise which resolves to the created directory.
*/ */
public async createDirectory(name: string): Promise<MSC3089TreeSpace> { public async createDirectory(name: string): Promise<MSC3089TreeSpace> {
const directory = await this.client.unstableCreateFileTree(name); 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. * 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[] { public getDirectories(): MSC3089TreeSpace[] {
const trees: 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 * 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. * into children and instead only look one level deep.
* @param {string} roomId The room ID (directory ID) to find. * @param roomId - The room ID (directory ID) to find.
* @returns {MSC3089TreeSpace | undefined} The directory, or undefined if not found. * @returns The directory, or undefined if not found.
*/ */
public getDirectory(roomId: string): MSC3089TreeSpace | undefined { public getDirectory(roomId: string): MSC3089TreeSpace | undefined {
return this.getDirectories().find(r => r.roomId === roomId); 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**. * 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> { public async delete(): Promise<void> {
const subdirectories = this.getDirectories(); 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 * Gets the current order index for this directory. Note that if this is the top level space
* then -1 will be returned. * then -1 will be returned.
* @returns {number} The order index of this space. * @returns The order index of this space.
*/ */
public getOrder(): number { public getOrder(): number {
if (this.isTopLevel) return -1; 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 * 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 * 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. * 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. * @param index - The new order index for this space.
* @returns {Promise<void>} Resolves when complete. * @returns Promise which resolves when complete.
* @throws Throws if this is a top level space. * @throws Throws if this is a top level space.
*/ */
public async setOrder(index: number): Promise<void> { 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. * 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(). * The file contents are in a type that is compatible with MatrixClient.uploadContent().
* @param {string} name The name of the file. * @param name - The name of the file.
* @param {File | String | Buffer | ReadStream | Blob} encryptedContents The encrypted contents. * @param encryptedContents - The encrypted contents.
* @param {Partial<IEncryptedFile>} info The encrypted file information. * @param info - The encrypted file information.
* @param {IContent} additionalContent Optional event content fields to include in the message. * @param additionalContent - Optional event content fields to include in the message.
* @returns {Promise<ISendEventResponse>} Resolves to the file event's sent response. * @returns Promise which resolves to the file event's sent response.
*/ */
public async createFile( public async createFile(
name: string, name: string,
@ -512,8 +512,8 @@ export class MSC3089TreeSpace {
/** /**
* Retrieves a file from the tree. * Retrieves a file from the tree.
* @param {string} fileEventId The event ID of the file. * @param fileEventId - The event ID of the file.
* @returns {MSC3089Branch | null} The file, or null if not found. * @returns The file, or null if not found.
*/ */
public getFile(fileEventId: string): MSC3089Branch | null { public getFile(fileEventId: string): MSC3089Branch | null {
const branch = this.room.currentState.getStateEvents(UNSTABLE_MSC3089_BRANCH.name, fileEventId); 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. * 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[] { public listFiles(): MSC3089Branch[] {
return this.listAllFiles().filter(b => b.isActive); 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. * 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[] { public listAllFiles(): MSC3089Branch[] {
const branches = this.room.currentState.getStateEvents(UNSTABLE_MSC3089_BRANCH.name) ?? []; const branches = this.room.currentState.getStateEvents(UNSTABLE_MSC3089_BRANCH.name) ?? [];

View File

@ -17,9 +17,6 @@ limitations under the License.
import { MatrixEvent } from "./event"; import { MatrixEvent } from "./event";
import { Direction } from "./event-timeline"; import { Direction } from "./event-timeline";
/**
* @module models/event-context
*/
export class EventContext { export class EventContext {
private timeline: MatrixEvent[]; private timeline: MatrixEvent[];
private ourEventIndex = 0; private ourEventIndex = 0;
@ -38,9 +35,7 @@ export class EventContext {
* It also stores pagination tokens for going backwards and forwards in the * It also stores pagination tokens for going backwards and forwards in the
* timeline. * timeline.
* *
* @param {MatrixEvent} ourEvent the event at the centre of this context * @param ourEvent - the event at the centre of this context
*
* @constructor
*/ */
public constructor(public readonly ourEvent: MatrixEvent) { public constructor(public readonly ourEvent: MatrixEvent) {
this.timeline = [ourEvent]; this.timeline = [ourEvent];
@ -51,7 +46,7 @@ export class EventContext {
* *
* This is a convenience function for getTimeline()[getOurEventIndex()]. * 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 { public getEvent(): MatrixEvent {
return this.timeline[this.ourEventIndex]; return this.timeline[this.ourEventIndex];
@ -60,7 +55,7 @@ export class EventContext {
/** /**
* Get the list of events in this context * Get the list of events in this context
* *
* @return {Array} An array of MatrixEvents * @returns An array of MatrixEvents
*/ */
public getTimeline(): MatrixEvent[] { public getTimeline(): MatrixEvent[] {
return this.timeline; return this.timeline;
@ -68,8 +63,6 @@ export class EventContext {
/** /**
* Get the index in the timeline of our event * Get the index in the timeline of our event
*
* @return {Number}
*/ */
public getOurEventIndex(): number { public getOurEventIndex(): number {
return this.ourEventIndex; return this.ourEventIndex;
@ -78,9 +71,7 @@ export class EventContext {
/** /**
* Get a pagination token. * Get a pagination token.
* *
* @param {boolean} backwards true to get the pagination token for going * @param backwards - true to get the pagination token for going
* backwards in time
* @return {string}
*/ */
public getPaginateToken(backwards = false): string | null { public getPaginateToken(backwards = false): string | null {
return this.paginateTokens[backwards ? Direction.Backward : Direction.Forward]; 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. * Generally this will be used only by the matrix js sdk.
* *
* @param {string} token pagination token * @param token - pagination token
* @param {boolean} backwards true to set the pagination token for going * @param backwards - true to set the pagination token for going
* backwards in time * backwards in time
*/ */
public setPaginateToken(token?: string, backwards = false): void { public setPaginateToken(token?: string, backwards = false): void {
@ -102,8 +93,8 @@ export class EventContext {
/** /**
* Add more events to the timeline * Add more events to the timeline
* *
* @param {Array} events new events, in timeline order * @param events - new events, in timeline order
* @param {boolean} atStart true to insert new events at the start * @param atStart - true to insert new events at the start
*/ */
public addEvents(events: MatrixEvent[], atStart = false): void { public addEvents(events: MatrixEvent[], atStart = false): void {
// TODO: should we share logic with Room.addEventsToTimeline? // TODO: should we share logic with Room.addEventsToTimeline?

View File

@ -17,7 +17,6 @@ limitations under the License.
/** /**
* Enum for event statuses. * Enum for event statuses.
* @readonly * @readonly
* @enum {string}
*/ */
export enum EventStatus { export enum EventStatus {
/** The event was not sent and will no longer be retried. */ /** The event was not sent and will no longer be retried. */

View File

@ -14,10 +14,6 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/**
* @module models/event-timeline-set
*/
import { EventTimeline, IAddEventOptions } from "./event-timeline"; import { EventTimeline, IAddEventOptions } from "./event-timeline";
import { MatrixEvent } from "./event"; import { MatrixEvent } from "./event";
import { logger } from '../logger'; import { logger } from '../logger';
@ -31,16 +27,20 @@ import { Thread, ThreadFilterType } from "./thread";
const DEBUG = true; const DEBUG = true;
/* istanbul ignore next */
let debuglog: (...args: any[]) => void; let debuglog: (...args: any[]) => void;
if (DEBUG) { if (DEBUG) {
// using bind means that we get to keep useful line numbers in the console // using bind means that we get to keep useful line numbers in the console
debuglog = logger.log.bind(logger); debuglog = logger.log.bind(logger);
} else { } else {
/* istanbul ignore next */
debuglog = function(): void {}; debuglog = function(): void {};
} }
interface IOpts { interface IOpts {
// Set to true to enable improved timeline support.
timelineSupport?: boolean; timelineSupport?: boolean;
// The filter object, if any, for this timelineSet.
filter?: Filter; filter?: Filter;
pendingEvents?: boolean; pendingEvents?: boolean;
} }
@ -51,7 +51,9 @@ export enum DuplicateStrategy {
} }
export interface IRoomTimelineData { export interface IRoomTimelineData {
// the timeline the event was added to/removed from
timeline: EventTimeline; timeline: EventTimeline;
// true if the event was a real-time event added to the end of the live timeline
liveEvent?: boolean; liveEvent?: boolean;
} }
@ -75,6 +77,26 @@ export interface IAddLiveEventOptions
type EmittedEvents = RoomEvent.Timeline | RoomEvent.TimelineReset; type EmittedEvents = RoomEvent.Timeline | RoomEvent.TimelineReset;
export type EventTimelineSetHandlerMap = { 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]: ( [RoomEvent.Timeline]: (
event: MatrixEvent, event: MatrixEvent,
room: Room | undefined, room: Room | undefined,
@ -82,6 +104,18 @@ export type EventTimelineSetHandlerMap = {
removed: boolean, removed: boolean,
data: IRoomTimelineData, data: IRoomTimelineData,
) => void; ) => 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]: ( [RoomEvent.TimelineReset]: (
room: Room | undefined, room: Room | undefined,
eventTimelineSet: EventTimelineSet, 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 * <p>In order that we can find events from their ids later, we also maintain a
* map from event_id to timeline and index. * map from event_id to timeline and index.
* *
* @constructor * @param room - Room for this timelineSet. May be null for non-room cases, such as the
* @param {Room=} room
* Room for this timelineSet. May be null for non-room cases, such as the
* notification timeline. * notification timeline.
* @param {Object} opts Options inherited from Room. * @param opts - Options inherited from Room.
* * @param client - the Matrix client which owns this EventTimelineSet,
* @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,
* can be omitted if room is specified. * can be omitted if room is specified.
* @param {Thread=} thread the thread to which this timeline set relates. * @param thread - the thread to which this timeline set relates.
* @param {boolean} isThreadTimeline Whether this timeline set relates to a thread list timeline * @param isThreadTimeline - Whether this timeline set relates to a thread list timeline
* (e.g., All threads or My threads) * (e.g., All threads or My threads)
*/ */
public constructor( public constructor(
@ -159,7 +186,7 @@ export class EventTimelineSet extends TypedEventEmitter<EmittedEvents, EventTime
/** /**
* Get all the timelines in this set * 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[] { public getTimelines(): EventTimeline[] {
return this.timelines; 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 * 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 { public getFilter(): Filter | undefined {
return this.filter; return this.filter;
@ -176,7 +203,7 @@ export class EventTimelineSet extends TypedEventEmitter<EmittedEvents, EventTime
/** /**
* Set the filter object this timeline set is filtered on * Set the filter object this timeline set is filtered on
* (passed to the server when paginating via /messages). * (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 { public setFilter(filter?: Filter): void {
this.filter = filter; 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 * Get the list of pending sent events for this timelineSet's room, filtered
* by the timelineSet's filter if appropriate. * 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. * waiting for remote echo.
* *
* @throws If <code>opts.pendingEventOrdering</code> was not 'detached' * @throws If `opts.pendingEventOrdering` was not 'detached'
*/ */
public getPendingEvents(): MatrixEvent[] { public getPendingEvents(): MatrixEvent[] {
if (!this.room || !this.displayPendingEvents) { if (!this.room || !this.displayPendingEvents) {
@ -201,7 +228,7 @@ export class EventTimelineSet extends TypedEventEmitter<EmittedEvents, EventTime
/** /**
* Get the live timeline for this room. * Get the live timeline for this room.
* *
* @return {module:models/event-timeline~EventTimeline} live timeline * @returns live timeline
*/ */
public getLiveTimeline(): EventTimeline { public getLiveTimeline(): EventTimeline {
return this.liveTimeline; return this.liveTimeline;
@ -210,7 +237,7 @@ export class EventTimelineSet extends TypedEventEmitter<EmittedEvents, EventTime
/** /**
* Set the live timeline for this room. * Set the live timeline for this room.
* *
* @return {module:models/event-timeline~EventTimeline} live timeline * @returns live timeline
*/ */
public setLiveTimeline(timeline: EventTimeline): void { public setLiveTimeline(timeline: EventTimeline): void {
this.liveTimeline = timeline; this.liveTimeline = timeline;
@ -218,8 +245,8 @@ export class EventTimelineSet extends TypedEventEmitter<EmittedEvents, EventTime
/** /**
* Return the timeline (if any) this event is in. * Return the timeline (if any) this event is in.
* @param {String} eventId the eventId being sought * @param eventId - the eventId being sought
* @return {module:models/event-timeline~EventTimeline} timeline * @returns timeline
*/ */
public eventIdToTimeline(eventId: string): EventTimeline | undefined { public eventIdToTimeline(eventId: string): EventTimeline | undefined {
return this._eventIdToTimeline.get(eventId); 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, * Track a new event as if it were in the same timeline as an old event,
* replacing it. * replacing it.
* @param {String} oldEventId event ID of the original event * @param oldEventId - event ID of the original event
* @param {String} newEventId event ID of the replacement event * @param newEventId - event ID of the replacement event
*/ */
public replaceEventId(oldEventId: string, newEventId: string): void { public replaceEventId(oldEventId: string, newEventId: string): void {
const existingTimeline = this._eventIdToTimeline.get(oldEventId); 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. * <p>This is used when /sync returns a 'limited' timeline.
* *
* @param {string=} backPaginationToken token for back-paginating the new timeline * @param backPaginationToken - token for back-paginating the new timeline
* @param {string=} forwardPaginationToken token for forward-paginating the old live timeline, * @param forwardPaginationToken - token for forward-paginating the old live timeline,
* if absent or null, all timelines are reset. * 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 { public resetLiveTimeline(backPaginationToken?: string, forwardPaginationToken?: string): void {
// Each EventTimeline has RoomState objects tracking the state at the start // 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 * Get the timeline which contains the given event, if any
* *
* @param {string} eventId event ID to look for * @param eventId - event ID to look for
* @return {?module:models/event-timeline~EventTimeline} timeline containing * @returns timeline containing
* the given event, or null if unknown * the given event, or null if unknown
*/ */
public getTimelineForEvent(eventId?: string): EventTimeline | null { 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 * Get an event which is stored in our timelines
* *
* @param {string} eventId event ID to look for * @param eventId - event ID to look for
* @return {?module:models/event~MatrixEvent} the given event, or undefined if unknown * @returns the given event, or undefined if unknown
*/ */
public findEventById(eventId: string): MatrixEvent | undefined { public findEventById(eventId: string): MatrixEvent | undefined {
const tl = this.getTimelineForEvent(eventId); const tl = this.getTimelineForEvent(eventId);
@ -322,7 +350,7 @@ export class EventTimelineSet extends TypedEventEmitter<EmittedEvents, EventTime
/** /**
* Add a new timeline to this timeline list * Add a new timeline to this timeline list
* *
* @return {module:models/event-timeline~EventTimeline} newly-created timeline * @returns newly-created timeline
*/ */
public addTimeline(): EventTimeline { public addTimeline(): EventTimeline {
if (!this.timelineSupport) { if (!this.timelineSupport) {
@ -341,18 +369,19 @@ export class EventTimelineSet extends TypedEventEmitter<EmittedEvents, EventTime
* *
* <p>Will fire "Room.timeline" for each event added. * <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 * (oldest) instead of the end (newest) of the timeline. If true, the oldest
* event will be the <b>last</b> element of 'events'. * 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. * 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( public addEventsToTimeline(
@ -557,8 +586,8 @@ export class EventTimelineSet extends TypedEventEmitter<EmittedEvents, EventTime
/** /**
* Add an event to the end of this live timeline. * Add an event to the end of this live timeline.
* *
* @param {MatrixEvent} event Event to be added * @param event - Event to be added
* @param {IAddLiveEventOptions} options addLiveEvent options * @param options - addLiveEvent options
*/ */
public addLiveEvent( public addLiveEvent(
event: MatrixEvent, event: MatrixEvent,
@ -653,11 +682,10 @@ export class EventTimelineSet extends TypedEventEmitter<EmittedEvents, EventTime
* *
* Will fire "Room.timeline" for each event added. * Will fire "Room.timeline" for each event added.
* *
* @param {MatrixEvent} event * @param options - addEventToTimeline options
* @param {EventTimeline} timeline
* @param {IAddEventToTimelineOptions} options addEventToTimeline options
* *
* @fires module:client~MatrixClient#event:"Room.timeline" * @remarks
* Fires {@link RoomEvent.Timeline}
*/ */
public addEventToTimeline( public addEventToTimeline(
event: MatrixEvent, 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 * Replaces event with ID oldEventId with one with newEventId, if oldEventId is
* recognised. Otherwise, add to the live timeline. Used to handle remote echos. * 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 localEvent - the new event to be added to the timeline
* @param {String} oldEventId the ID of the original event * @param oldEventId - the ID of the original event
* @param {boolean} newEventId the ID of the replacement event * @param newEventId - the ID of the replacement event
* *
* @fires module:client~MatrixClient#event:"Room.timeline" * @remarks
* Fires {@link RoomEvent.Timeline}
*/ */
public handleRemoteEcho( public handleRemoteEcho(
localEvent: MatrixEvent, localEvent: MatrixEvent,
@ -771,9 +800,9 @@ export class EventTimelineSet extends TypedEventEmitter<EmittedEvents, EventTime
/** /**
* Removes a single event from this room. * 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. * in this room.
*/ */
public removeEvent(eventId: string): MatrixEvent | null { 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 * Determine where two events appear in the timeline relative to one another
* *
* @param {string} eventId1 The id of the first event * @param eventId1 - The id of the first event
* @param {string} eventId2 The id of the second 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 * 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 * 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 * 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. * for events which should be shown in the main room timeline.
* Requires the `room` property to have been set at EventTimelineSet construction time. * 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. * @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. * @throws Error if `room` was not set when constructing this timeline set.
* @return {boolean} whether the event belongs to this timeline set. * @returns whether the event belongs to this timeline set.
*/ */
public canContain(event: MatrixEvent): boolean { public canContain(event: MatrixEvent): boolean {
if (!this.room) { if (!this.room) {
@ -891,43 +920,3 @@ export class EventTimelineSet extends TypedEventEmitter<EmittedEvents, EventTime
return shouldLiveInRoom; 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.
*/

View File

@ -14,10 +14,6 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/**
* @module models/event-timeline
*/
import { logger } from '../logger'; import { logger } from '../logger';
import { IMarkerFoundOptions, RoomState } from "./room-state"; import { IMarkerFoundOptions, RoomState } from "./room-state";
import { EventTimelineSet } from "./event-timeline-set"; import { EventTimelineSet } from "./event-timeline-set";
@ -63,9 +59,9 @@ export class EventTimeline {
/** /**
* Static helper method to set sender and target properties * Static helper method to set sender and target properties
* *
* @param {MatrixEvent} event the event whose metadata is to be set * @param event - the event whose metadata is to be set
* @param {RoomState} stateContext the room state to be queried * @param stateContext - the room state to be queried
* @param {boolean} toStartOfTimeline if true the event's forwardLooking flag is set false * @param toStartOfTimeline - if true the event's forwardLooking flag is set false
*/ */
public static setEventMetadata(event: MatrixEvent, stateContext: RoomState, toStartOfTimeline: boolean): void { public static setEventMetadata(event: MatrixEvent, stateContext: RoomState, toStartOfTimeline: boolean): void {
// When we try to generate a sentinel member before we have that member // 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 * <p>Once a timeline joins up with its neighbour, they are linked together into a
* doubly-linked list. * doubly-linked list.
* *
* @param {EventTimelineSet} eventTimelineSet the set of timelines this is part of * @param eventTimelineSet - the set of timelines this is part of
* @constructor
*/ */
public constructor(private readonly eventTimelineSet: EventTimelineSet) { public constructor(private readonly eventTimelineSet: EventTimelineSet) {
this.roomId = eventTimelineSet.room?.roomId ?? null; this.roomId = eventTimelineSet.room?.roomId ?? null;
@ -148,9 +143,9 @@ export class EventTimeline {
* *
* <p>This can only be called before any events are added. * <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. * 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 { public initialiseState(stateEvents: MatrixEvent[], { timelineWasEmpty }: IInitialiseStateOptions = {}): void {
if (this.events.length > 0) { 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, * 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. * 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 * start of the timeline; EventTimeline.FORWARDS to get the state at the end
* of the timeline. * of the timeline.
* *
* @return {EventTimeline} the new timeline * @returns the new timeline
*/ */
public forkLive(direction: Direction): EventTimeline { public forkLive(direction: Direction): EventTimeline {
const forkState = this.getState(direction); const forkState = this.getState(direction);
@ -191,11 +186,11 @@ export class EventTimeline {
/** /**
* Creates an independent timeline, inheriting the directional state from this timeline. * 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 * start of the timeline; EventTimeline.FORWARDS to get the state at the end
* of the timeline. * of the timeline.
* *
* @return {EventTimeline} the new timeline * @returns the new timeline
*/ */
public fork(direction: Direction): EventTimeline { public fork(direction: Direction): EventTimeline {
const forkState = this.getState(direction); const forkState = this.getState(direction);
@ -207,7 +202,7 @@ export class EventTimeline {
/** /**
* Get the ID of the room for this timeline * Get the ID of the room for this timeline
* @return {string} room ID * @returns room ID
*/ */
public getRoomId(): string | null { public getRoomId(): string | null {
return this.roomId; return this.roomId;
@ -215,7 +210,7 @@ export class EventTimeline {
/** /**
* Get the filter for this timeline's timelineSet (if any) * Get the filter for this timeline's timelineSet (if any)
* @return {Filter} filter * @returns filter
*/ */
public getFilter(): Filter | undefined { public getFilter(): Filter | undefined {
return this.eventTimelineSet.getFilter(); return this.eventTimelineSet.getFilter();
@ -223,7 +218,7 @@ export class EventTimeline {
/** /**
* Get the timelineSet for this timeline * Get the timelineSet for this timeline
* @return {EventTimelineSet} timelineSet * @returns timelineSet
*/ */
public getTimelineSet(): EventTimelineSet { public getTimelineSet(): EventTimelineSet {
return this.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 * 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 * well be less than the base index, thus giving that event a negative relative
* index). * index).
*
* @return {number}
*/ */
public getBaseIndex(): number { public getBaseIndex(): number {
return this.baseIndex; return this.baseIndex;
@ -247,7 +240,7 @@ export class EventTimeline {
/** /**
* Get the list of events in this context * Get the list of events in this context
* *
* @return {MatrixEvent[]} An array of MatrixEvents * @returns An array of MatrixEvents
*/ */
public getEvents(): MatrixEvent[] { public getEvents(): MatrixEvent[] {
return this.events; return this.events;
@ -256,11 +249,11 @@ export class EventTimeline {
/** /**
* Get the room state at the start/end of the timeline * 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 * start of the timeline; EventTimeline.FORWARDS to get the state at the end
* of the timeline. * 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 { public getState(direction: Direction): RoomState | undefined {
if (direction == EventTimeline.BACKWARDS) { if (direction == EventTimeline.BACKWARDS) {
@ -275,11 +268,11 @@ export class EventTimeline {
/** /**
* Get a pagination token * 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 * token for going backwards in time; EventTimeline.FORWARDS to get the
* pagination token for going forwards in time. * pagination token for going forwards in time.
* *
* @return {?string} pagination token * @returns pagination token
*/ */
public getPaginationToken(direction: Direction): string | null { public getPaginationToken(direction: Direction): string | null {
if (this.roomId) { if (this.roomId) {
@ -294,9 +287,9 @@ export class EventTimeline {
/** /**
* Set a pagination token * 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 * token for going backwards in time; EventTimeline.FORWARDS to set the
* pagination token for going forwards in time. * pagination token for going forwards in time.
*/ */
@ -313,10 +306,10 @@ export class EventTimeline {
/** /**
* Get the next timeline in the series * 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. * 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. * joined up.
*/ */
public getNeighbouringTimeline(direction: Direction): EventTimeline | null { public getNeighbouringTimeline(direction: Direction): EventTimeline | null {
@ -332,12 +325,12 @@ export class EventTimeline {
/** /**
* Set the next timeline in the series * 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. * 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. * it is already set.
*/ */
public setNeighbouringTimeline(neighbour: EventTimeline, direction: Direction): void { 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 * Add a new event to the timeline, and update the state
* *
* @param {MatrixEvent} event new event * @param event - new event
* @param {IAddEventOptions} options addEvent options * @param options - addEvent options
*/ */
public addEvent( public addEvent(
event: MatrixEvent, event: MatrixEvent,
@ -447,8 +440,8 @@ export class EventTimeline {
/** /**
* Remove an event from the timeline * Remove an event from the timeline
* *
* @param {string} eventId ID of event to be removed * @param eventId - ID of event to be removed
* @return {?MatrixEvent} removed event, or null if not found * @returns removed event, or null if not found
*/ */
public removeEvent(eventId: string): MatrixEvent | null { public removeEvent(eventId: string): MatrixEvent | null {
for (let i = this.events.length - 1; i >= 0; i--) { 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 a string to identify this timeline, for debugging
* *
* @return {string} name for this timeline * @returns name for this timeline
*/ */
public toString(): string { public toString(): string {
return this.name; return this.name;

View File

@ -17,7 +17,6 @@ limitations under the License.
/** /**
* This is an internal module. See {@link MatrixEvent} and {@link RoomEvent} for * This is an internal module. See {@link MatrixEvent} and {@link RoomEvent} for
* the public classes. * the public classes.
* @module models/event
*/ */
import { ExtensibleEvent, ExtensibleEvents, Optional } from "matrix-events-sdk"; import { ExtensibleEvent, ExtensibleEvents, Optional } from "matrix-events-sdk";
@ -80,15 +79,15 @@ export interface IEvent {
redacts?: string; redacts?: string;
/** /**
* @deprecated * @deprecated in favour of `sender`
*/ */
user_id?: string; user_id?: string;
/** /**
* @deprecated * @deprecated in favour of `unsigned.prev_content`
*/ */
prev_content?: IContent; prev_content?: IContent;
/** /**
* @deprecated * @deprecated in favour of `origin_server_ts`
*/ */
age?: number; age?: number;
} }
@ -150,8 +149,11 @@ interface IKeyRequestRecipient {
} }
export interface IDecryptOptions { export interface IDecryptOptions {
// Emits "event.decrypted" if set to true
emit?: boolean; emit?: boolean;
// True if this is a retry (enables more logging)
isRetry?: boolean; isRetry?: boolean;
// whether the message should be re-decrypted if it was previously successfully decrypted with an untrusted key
forceRedecryptIfUntrusted?: boolean; forceRedecryptIfUntrusted?: boolean;
} }
@ -192,6 +194,12 @@ export enum MatrixEventEvent {
export type MatrixEventEmittedEvents = MatrixEventEvent | ThreadEvent.Update; export type MatrixEventEmittedEvents = MatrixEventEvent | ThreadEvent.Update;
export type MatrixEventHandlerMap = { 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.Decrypted]: (event: MatrixEvent, err?: Error) => void;
[MatrixEventEvent.BeforeRedaction]: (event: MatrixEvent, redactionEvent: MatrixEvent) => void; [MatrixEventEvent.BeforeRedaction]: (event: MatrixEvent, redactionEvent: MatrixEvent) => void;
[MatrixEventEvent.VisibilityChange]: (event: MatrixEvent, visible: boolean) => void; [MatrixEventEvent.VisibilityChange]: (event: MatrixEvent, visible: boolean) => void;
@ -271,12 +279,43 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
*/ */
public localTimestamp: number; 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; 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; public target: RoomMember | null = null;
/**
* The sending status of the event.
* @privateRemarks
* Should be read-only
*/
public status: EventStatus | null = null; 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 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, /* 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 * `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 * Construct a Matrix Event object
* @constructor
* *
* @param {Object} event The raw event to be wrapped in this DAO * @param event - The raw (possibly encrypted) event. <b>Do not access
*
* @prop {Object} event The raw (possibly encrypted) event. <b>Do not access
* this property</b> directly unless you absolutely have to. Prefer the getter * this property</b> directly unless you absolutely have to. Prefer the getter
* methods defined on this class. Using the getter methods shields your app * methods defined on this class. Using the getter methods shields your app
* from changes to event JSON between Matrix versions. * 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> = {}) { public constructor(public event: Partial<IEvent> = {}) {
super(); 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 * Gets the event as though it would appear unencrypted. If the event is already not
* encrypted, it is simply returned as-is. * encrypted, it is simply returned as-is.
* @returns {IEvent} The event in wire format. * @returns The event in wire format.
*/ */
public getEffectiveEvent(): IEvent { public getEffectiveEvent(): IEvent {
const content = Object.assign({}, this.getContent()); // clone for mutation 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. * 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> * </code>
*/ */
public getId(): string | undefined { public getId(): string | undefined {
@ -398,7 +422,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
/** /**
* Get the user_id for this event. * 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 { public getSender(): string | undefined {
return this.event.sender || this.event.user_id; // v2 / v1 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. * 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 { public getType(): EventType | string {
if (this.clearEvent) { 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 * Get the (possibly encrypted) type of the event that will be sent to the
* homeserver. * homeserver.
* *
* @return {string} The event type. * @returns The event type.
*/ */
public getWireType(): EventType | string { public getWireType(): EventType | string {
return this.event.type!; return this.event.type!;
} }
/** /**
* Get the room_id for this event. This will return <code>undefined</code> * Get the room_id for this event. This will return `undefined`
* for <code>m.presence</code> events. * for `m.presence` events.
* @return {string?} The room ID, e.g. <code>!cURbafjkfsMDVwdRDQ:matrix.org * @returns The room ID, e.g. <code>!cURbafjkfsMDVwdRDQ:matrix.org
* </code> * </code>
*/ */
public getRoomId(): string | undefined { public getRoomId(): string | undefined {
@ -438,7 +462,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
/** /**
* Get the timestamp of this event. * 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 { public getTs(): number {
return this.event.origin_server_ts!; 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. * 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 { public getDate(): Date | null {
return this.event.origin_server_ts ? new Date(this.event.origin_server_ts) : 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: * 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 { public getDetails(): string {
let details = `id=${this.getId()} type=${this.getWireType()} sender=${this.getSender()}`; 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 * Get the (decrypted, if necessary) event content JSON, even if the event
* was replaced by another 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 { public getOriginalContent<T = IContent>(): T {
if (this._localRedactionEvent) { if (this._localRedactionEvent) {
@ -493,7 +521,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
* or the content from the replacing event, if any. * or the content from the replacing event, if any.
* See `makeReplaced`. * 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 { public getContent<T extends IContent = IContent>(): T {
if (this._localRedactionEvent) { 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 * Get the (possibly encrypted) event content JSON that will be sent to the
* homeserver. * homeserver.
* *
* @return {Object} The event content JSON, or an empty object. * @returns The event content JSON, or an empty object.
*/ */
public getWireContent(): IContent { public getWireContent(): IContent {
return this.event.content || {}; 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 * Get the previous event content JSON. This will only return something for
* state events which exist in the timeline. * 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 { public getPrevContent(): IContent {
// v2 then v1 then default // 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 * In practice, this means we get the chronologically earlier content value
* for this event (this method should surely be called getEarlierContent) * for this event (this method should surely be called getEarlierContent)
* <strong>This method is experimental and may change.</strong> * <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. * event.prev_content.
*/ */
public getDirectionalContent(): IContent { 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 * event arrived at the device, and not the age of the event when this
* function was called. * function was called.
* Can only be returned once the server has echo'ed back * 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 { public getAge(): number | undefined {
return this.getUnsigned().age || this.event.age; // v2 / v1 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. * Get the age of the event when this function was called.
* This is the 'age' field adjusted according to how long this client has * This is the 'age' field adjusted according to how long this client has
* had the event. * had the event.
* @return {Number} The age of this event in milliseconds. * @returns The age of this event in milliseconds.
*/ */
public getLocalAge(): number { public getLocalAge(): number {
return Date.now() - this.localTimestamp; 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 * Get the event state_key if it has one. This will return <code>undefined
* </code> for message events. * </code> for message events.
* @return {string} The event's <code>state_key</code>. * @returns The event's `state_key`.
*/ */
public getStateKey(): string | undefined { public getStateKey(): string | undefined {
return this.event.state_key; return this.event.state_key;
@ -612,7 +640,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
/** /**
* Check if this event is a state event. * 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 { public isState(): boolean {
return this.event.state_key !== undefined; return this.event.state_key !== undefined;
@ -624,18 +652,18 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
* *
* @internal * @internal
* *
* @param {string} cryptoType type of the encrypted event - typically * @param cryptoType - type of the encrypted event - typically
* <tt>"m.room.encrypted"</tt> * <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. * 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. * sender if this event.
* See {@link module:models/event.MatrixEvent#getClaimedEd25519Key} * See {@link MatrixEvent#getClaimedEd25519Key}
*/ */
public makeEncrypted( public makeEncrypted(
cryptoType: string, cryptoType: string,
@ -657,7 +685,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
/** /**
* Check if this event is currently being decrypted. * 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 { public isBeingDecrypted(): boolean {
return this.decryptionPromise != null; 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) * (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. * couldn't decrypt.
*/ */
public isDecryptionFailure(): boolean { public isDecryptionFailure(): boolean {
@ -695,14 +723,9 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
* *
* @internal * @internal
* *
* @param {module:crypto} crypto crypto module * @param 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
* *
* @returns {Promise} promise which resolves (to undefined) when the decryption * @returns promise which resolves (to undefined) when the decryption
* attempt is completed. * attempt is completed.
*/ */
public async attemptDecryption(crypto: Crypto, options: IDecryptOptions = {}): Promise<void> { 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. * Cancel any room key request for this event and resend another.
* *
* @param {module:crypto} crypto crypto module * @param crypto - crypto module
* @param {string} userId the user who received this event * @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> { public cancelAndResendKeyRequest(crypto: Crypto, userId: string): Promise<void> {
const wireContent = this.getWireContent(); const wireContent = this.getWireContent();
@ -759,9 +782,9 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
/** /**
* Calculate the recipients for keyshare requests. * 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[] { public getKeyRequestRecipients(userId: string): IKeyRequestRecipient[] {
// send the request to all of our own devices, and the // send the request to all of our own devices, and the
@ -903,10 +926,10 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
* *
* @internal * @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 * @remarks
* the decryption result, including the plaintext and some key info * Fires {@link MatrixEventEvent.Decrypted}
*/ */
private setClearData(decryptionResult: IEventDecryptionResult): void { private setClearData(decryptionResult: IEventDecryptionResult): void {
this.clearEvent = decryptionResult.clearEvent; 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, * Gets the cleartext content for this event. If the event is not encrypted,
* or encryption has not been completed, this will return null. * 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 { public getClearContent(): IContent | null {
return this.clearEvent ? this.clearEvent.content : 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. * Check if the event is encrypted.
* @return {boolean} True if this event is encrypted. * @returns True if this event is encrypted.
*/ */
public isEncrypted(): boolean { public isEncrypted(): boolean {
return !this.isState() && this.event.type === EventType.RoomMessageEncrypted; 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 * For a megolm-encrypted event, it is inferred from the Olm message which
* established the megolm session * established the megolm session
*
* @return {string}
*/ */
public getSenderKey(): string | null { public getSenderKey(): string | null {
return this.senderCurve25519Key; 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. * The additional keys the sender of this encrypted event claims to possess.
* *
* Just a wrapper for #getClaimedEd25519Key (q.v.) * Just a wrapper for #getClaimedEd25519Key (q.v.)
*
* @return {Object<string, string>}
*/ */
public getKeysClaimed(): Partial<Record<"ed25519", string>> { public getKeysClaimed(): Partial<Record<"ed25519", string>> {
if (!this.claimedEd25519Key) return {}; 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 * In general, applications should not use this method directly, but should
* instead use MatrixClient.getEventSenderDeviceInfo. * instead use MatrixClient.getEventSenderDeviceInfo.
*
* @return {string}
*/ */
public getClaimedEd25519Key(): string | null { public getClaimedEd25519Key(): string | null {
return this.claimedEd25519Key; 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 * 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. * 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[] { public getForwardingCurve25519KeyChain(): string[] {
return this.forwardingCurve25519KeyChain; 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, * Whether the decryption key was obtained from an untrusted source. If so,
* we cannot verify the authenticity of the message. * we cannot verify the authenticity of the message.
*
* @return {boolean}
*/ */
public isKeySourceUntrusted(): boolean | undefined { public isKeySourceUntrusted(): boolean | undefined {
return !!this.untrusted; 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 . * 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 * 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 * visible (if it was hidden), by making it hidden (if it was visible) or by
* changing the reason (if it was hidden). * 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 { public applyVisibilityEvent(visibilityChange?: IVisibilityChange): void {
const visible = visibilityChange?.visible ?? true; 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 * 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 * if it were redacted before it was sent to us
* *
* @param {module:models/event.MatrixEvent} redactionEvent * @param redactionEvent - event causing the redaction
* event causing the redaction
*/ */
public makeRedacted(redactionEvent: MatrixEvent): void { public makeRedacted(redactionEvent: MatrixEvent): void {
// quick sanity-check // quick sanity-check
@ -1145,7 +1161,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
/** /**
* Check if this event has been redacted * 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 { public isRedacted(): boolean {
return Boolean(this.getUnsigned().redacted_because); 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 * 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 { public isRedaction(): boolean {
return this.getType() === EventType.RoomRedaction; 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, * Check if this event alters the visibility of another event,
* as per https://github.com/matrix-org/matrix-doc/pull/3531. * 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. * of another event.
*/ */
public isVisibilityEvent(): boolean { public isVisibilityEvent(): boolean {
@ -1212,7 +1228,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
* Get the (decrypted, if necessary) redaction event JSON * Get the (decrypted, if necessary) redaction event JSON
* if event was redacted * 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 { public getRedactionEvent(): IEvent | {} | null {
if (!this.isRedacted()) return 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 * Get the push actions, if known, for this event
* *
* @return {?Object} push actions * @returns push actions
*/ */
public getPushActions(): IActionsObject | null { public getPushActions(): IActionsObject | null {
return this.pushActions; return this.pushActions;
@ -1238,7 +1254,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
/** /**
* Set the push actions for this event. * Set the push actions for this event.
* *
* @param {Object} pushActions push actions * @param pushActions - push actions
*/ */
public setPushActions(pushActions: IActionsObject | null): void { public setPushActions(pushActions: IActionsObject | null): void {
this.pushActions = pushActions; 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. * 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 { public handleRemoteEcho(event: object): void {
const oldUnsigned = this.getUnsigned(); 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 * Whether the event is in any phase of sending, send failure, waiting for
* remote echo, etc. * remote echo, etc.
*
* @return {boolean}
*/ */
public isSending(): boolean { public isSending(): boolean {
return !!this.status; 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. * 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 { public setStatus(status: EventStatus | null): void {
this.status = status; 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 * Get whether the event is a relation event, and of a given type if
* `relType` is passed in. State events cannot be relation events * `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 * given type
* @return {boolean}
*/ */
public isRelation(relType?: string): boolean { public isRelation(relType?: string): boolean {
// Relation info is lifted out of the encrypted content when sent to // 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. * Get relation info for the event, if any.
*
* @return {Object}
*/ */
public getRelation(): IEventRelation | null { public getRelation(): IEventRelation | null {
if (!this.isRelation()) { 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. * 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 { public makeReplaced(newEvent?: MatrixEvent): void {
// don't allow redacted events to be replaced. // 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 * Returns the status of any associated edit or redaction
* (not for reactions/annotations as their local echo doesn't affect the original event), * (not for reactions/annotations as their local echo doesn't affect the original event),
* or else the status of the event. * or else the status of the event.
*
* @return {EventStatus}
*/ */
public getAssociatedStatus(): EventStatus | null { public getAssociatedStatus(): EventStatus | null {
if (this._replacingEvent) { 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. * Returns the event ID of the event replacing the content of this event, if any.
*
* @return {string?}
*/ */
public replacingEventId(): string | undefined { public replacingEventId(): string | undefined {
const replaceRelation = this.getServerAggregatedRelation<IAggregatedRelation>(RelationType.Replace); 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. * Returns the event replacing the content of this event, if any.
* Replacements are aggregated on the server, so this would only * 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 an event in case it came down the sync, or for local echo of edits.
*
* @return {MatrixEvent?}
*/ */
public replacingEvent(): MatrixEvent | null { public replacingEvent(): MatrixEvent | null {
return this._replacingEvent; 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. * Returns the origin_server_ts of the event replacing the content of this event, if any.
*
* @return {Date?}
*/ */
public replacingEventDate(): Date | undefined { public replacingEventDate(): Date | undefined {
const replaceRelation = this.getServerAggregatedRelation<IAggregatedRelation>(RelationType.Replace); 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. * 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 { public localRedactionEvent(): MatrixEvent | null {
return this._localRedactionEvent; 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. * For relations and redactions, returns the event_id this event is referring to.
*
* @return {string?}
*/ */
public getAssociatedId(): string | undefined { public getAssociatedId(): string | undefined {
const relation = this.getRelation(); 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`. * Checks if this event is associated with another event. See `getAssociatedId`.
*
* @return {boolean}
* @deprecated use hasAssociation instead. * @deprecated use hasAssociation instead.
*/ */
public hasAssocation(): boolean { 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`. * Checks if this event is associated with another event. See `getAssociatedId`.
*
* @return {boolean}
*/ */
public hasAssociation(): boolean { public hasAssociation(): boolean {
return !!this.getAssociatedId(); 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 * Used to replace a local id with remote one before sending
* an event with a related id. * an event with a related id.
* *
* @param {string} eventId the new event id * @param eventId - the new event id
*/ */
public updateAssociatedId(eventId: string): void { public updateAssociatedId(eventId: string): void {
const relation = this.getRelation(); 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 * 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 * 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. * 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 { public flagCancelled(cancelled = true): void {
this._isCancelled = cancelled; 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 * Gets whether or not the event is flagged as cancelled. See flagCancelled() for
* more information. * more information.
* @returns {boolean} True if the event is cancelled, false otherwise. * @returns True if the event is cancelled, false otherwise.
*/ */
public isCancelled(): boolean { public isCancelled(): boolean {
return this._isCancelled; 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 * This is meant to be used to snapshot the event details themselves, not the
* features (such as sender) surrounding the event. * features (such as sender) surrounding the event.
* @returns {MatrixEvent} A snapshot of this event. * @returns A snapshot of this event.
*/ */
public toSnapshot(): MatrixEvent { public toSnapshot(): MatrixEvent {
const ev = new MatrixEvent(JSON.parse(JSON.stringify(this.event))); 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 * 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 * the event object itself, not the other properties of the event. Intended for
* use with toSnapshot() to identify events changing. * use with toSnapshot() to identify events changing.
* @param {MatrixEvent} otherEvent The other event to check against. * @param otherEvent - The other event to check against.
* @returns {boolean} True if the events are the same, false otherwise. * @returns True if the events are the same, false otherwise.
*/ */
public isEquivalentTo(otherEvent: MatrixEvent): boolean { public isEquivalentTo(otherEvent: MatrixEvent): boolean {
if (!otherEvent) return false; 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 * This is named `toJSON` for use with `JSON.stringify` which checks objects
* for functions named `toJSON` and will call them to customise the output * for functions named `toJSON` and will call them to customise the output
* if they are defined. * if they are defined.
*
* @return {Object}
*/ */
public toJSON(): object { public toJSON(): object {
const event = this.getEffectiveEvent(); const event = this.getEffectiveEvent();
@ -1625,15 +1621,3 @@ const REDACT_KEEP_CONTENT_MAP: Record<string, Record<string, 1>> = {
'users': 1, 'users_default': 1, 'users': 1, 'users_default': 1,
}, },
} as const; } 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.
*/

View File

@ -81,10 +81,10 @@ export class IgnoredInvites {
/** /**
* Add a new rule. * Add a new rule.
* *
* @param scope The scope for this rule. * @param scope - The scope for this rule.
* @param entity The entity covered by this rule. Globs are supported. * @param entity - The entity covered by this rule. Globs are supported.
* @param reason A human-readable reason for introducing this new rule. * @param reason - A human-readable reason for introducing this new rule.
* @return The event id for the new rule. * @returns The event id for the new rule.
*/ */
public async addRule(scope: PolicyScope, entity: string, reason: string): Promise<string> { public async addRule(scope: PolicyScope, entity: string, reason: string): Promise<string> {
const target = await this.getOrCreateTargetRoom(); 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 * Add a new room to the list of sources. If the user isn't a member of the
* room, attempt to join it. * 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. * 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 * @throws If `roomId` isn't the id of a room that the current user is already
* member of or can join. * member of or can join.
* *
@ -142,8 +142,8 @@ export class IgnoredInvites {
/** /**
* Find out whether an invite should be ignored. * Find out whether an invite should be ignored.
* *
* @param sender The user id for the user who issued the invite. * @param sender - The user id for the user who issued the invite.
* @param roomId The room to which the user is invited. * @param roomId - The room to which the user is invited.
* @returns A rule matching the entity, if any was found, `null` otherwise. * @returns A rule matching the entity, if any was found, `null` otherwise.
*/ */
public async getRuleForInvite({ sender, roomId }: { public async getRuleForInvite({ sender, roomId }: {

View File

@ -63,9 +63,9 @@ export abstract class ReadReceipt<
/** /**
* Gets the latest receipt for a given user in the room * 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 userId - The id of the user for which we want the receipt
* @param ignoreSynthesized Whether to ignore synthesized receipts or not * @param ignoreSynthesized - Whether to ignore synthesized receipts or not
* @param receiptType Optional. The type of the receipt we want to get * @param receiptType - Optional. The type of the receipt we want to get
* @returns the latest receipts of the chosen type for the chosen user * @returns the latest receipts of the chosen type for the chosen user
*/ */
public getReadReceiptForUserId( 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 * 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. * have received no read receipts from them.
* @param {String} userId The user ID to get read receipt event ID for * @param userId - The user ID to get read receipt event ID for
* @param {Boolean} ignoreSynthesized If true, return only receipts that have been * @param ignoreSynthesized - If true, return only receipts that have been
* sent by the server, not implicit ones generated * sent by the server, not implicit ones generated
* by the JS SDK. * 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 { 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 // 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. * Get a list of receipts for the given event.
* @param {MatrixEvent} event the event to get receipts for * @param event - the event to get receipts for
* @return {Object[]} A list of receipts with a userId, type and data keys or * @returns A list of receipts with a userId, type and data keys or
* an empty list. * an empty list.
*/ */
public getReceiptsForEvent(event: MatrixEvent): CachedReceipt[] { 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 * Add a temporary local-echo receipt to the room to reflect in the
* client the fact that we've sent one. * client the fact that we've sent one.
* @param {string} userId The user ID if the receipt sender * @param userId - The user ID if the receipt sender
* @param {MatrixEvent} e The event that is to be acknowledged * @param e - The event that is to be acknowledged
* @param {ReceiptType} receiptType The type of receipt * @param receiptType - The type of receipt
*/ */
public addLocalEchoReceipt(userId: string, e: MatrixEvent, receiptType: ReceiptType): void { public addLocalEchoReceipt(userId: string, e: MatrixEvent, receiptType: ReceiptType): void {
this.addReceipt(synthesizeReceipt(userId, e, receiptType), true); 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. * 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. * @param event - the event to get read receipts for.
* @return {String[]} A list of user IDs. * @returns A list of user IDs.
*/ */
public getUsersReadUpTo(event: MatrixEvent): string[] { public getUsersReadUpTo(event: MatrixEvent): string[] {
return this.getReceiptsForEvent(event).filter(function(receipt) { 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 * 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 * 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. * what is available to the room at the time of execution.
* @param {String} userId The user ID to check the read state of. * @param userId - The user ID to check the read state of.
* @param {String} eventId The event ID to check if the user read. * @param eventId - The event ID to check if the user read.
* @returns {Boolean} True if the user has read the event, false otherwise. * @returns True if the user has read the event, false otherwise.
*/ */
public hasUserReadEvent(userId: string, eventId: string): boolean { public hasUserReadEvent(userId: string, eventId: string): boolean {
const readUpToId = this.getEventReadUpTo(userId, false); const readUpToId = this.getEventReadUpTo(userId, false);

View File

@ -32,17 +32,14 @@ export class RelationsContainer {
/** /**
* Get a collection of child events to a given event in this timeline set. * Get a collection of child events to a given event in this timeline set.
* *
* @param {String} eventId * @param eventId - The ID of the event that you'd like to access child events for.
* 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. * For example, with annotations, this would be the ID of the event being annotated.
* @param {String} relationType * @param relationType - The type of relationship involved, such as "m.annotation", "m.reference", "m.replace", etc.
* 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.
* @param {String} eventType * @throws If `eventId</code>, <code>relationType</code> or <code>eventType`
* The relation event's type, such as "m.reaction", etc.
* @throws If <code>eventId</code>, <code>relationType</code> or <code>eventType</code>
* are not valid. * are not valid.
* *
* @returns {?Relations} * @returns
* A container for relation events or undefined if there are no relation events for * A container for relation events or undefined if there are no relation events for
* the relationType. * 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 * 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. * 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 { public aggregateParentEvent(event: MatrixEvent): void {
const relationsForEvent = this.relations.get(event.getId()!); const relationsForEvent = this.relations.get(event.getId()!);
@ -87,8 +84,8 @@ export class RelationsContainer {
/** /**
* Add relation events to the relevant relation collection. * Add relation events to the relevant relation collection.
* *
* @param {MatrixEvent} event The new child event to be aggregated. * @param 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 timelineSet - The event timeline set within which to search for the related event if any.
*/ */
public aggregateChildEvent(event: MatrixEvent, timelineSet?: EventTimelineSet): void { public aggregateChildEvent(event: MatrixEvent, timelineSet?: EventTimelineSet): void {
if (event.isRedacted() || event.status === EventStatus.CANCELLED) { if (event.isRedacted() || event.status === EventStatus.CANCELLED) {

View File

@ -52,13 +52,9 @@ export class Relations extends TypedEventEmitter<RelationsEvent, EventHandlerMap
private readonly client: MatrixClient; private readonly client: MatrixClient;
/** /**
* @param {RelationType} relationType * @param relationType - The type of relation involved, such as "m.annotation", "m.reference", "m.replace", etc.
* The type of relation involved, such as "m.annotation", "m.reference", * @param eventType - The relation event's type, such as "m.reaction", etc.
* "m.replace", etc. * @param client - The client which created this instance. For backwards compatibility also accepts a Room.
* @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.
*/ */
public constructor( public constructor(
public readonly relationType: RelationType | string, public readonly relationType: RelationType | string,
@ -72,8 +68,7 @@ export class Relations extends TypedEventEmitter<RelationsEvent, EventHandlerMap
/** /**
* Add relation events to this collection. * Add relation events to this collection.
* *
* @param {MatrixEvent} event * @param event - The new relation event to be added.
* The new relation event to be added.
*/ */
public async addEvent(event: MatrixEvent): Promise<void> { public async addEvent(event: MatrixEvent): Promise<void> {
if (this.relationEventIds.has(event.getId()!)) { if (this.relationEventIds.has(event.getId()!)) {
@ -120,8 +115,7 @@ export class Relations extends TypedEventEmitter<RelationsEvent, EventHandlerMap
/** /**
* Remove relation event from this collection. * Remove relation event from this collection.
* *
* @param {MatrixEvent} event * @param event - The relation event to remove.
* The relation event to remove.
*/ */
private async removeEvent(event: MatrixEvent): Promise<void> { private async removeEvent(event: MatrixEvent): Promise<void> {
if (!this.relations.has(event)) { 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. * Listens for event status changes to remove cancelled events.
* *
* @param {MatrixEvent} event The event whose status has changed * @param event - The event whose status has changed
* @param {EventStatus} status The new status * @param status - The new status
*/ */
private onEventStatus = (event: MatrixEvent, status: EventStatus | null): void => { private onEventStatus = (event: MatrixEvent, status: EventStatus | null): void => {
if (!event.isSending()) { if (!event.isSending()) {
@ -181,7 +175,6 @@ export class Relations extends TypedEventEmitter<RelationsEvent, EventHandlerMap
* won't match timeline order in the case of scrollback. * won't match timeline order in the case of scrollback.
* TODO: Tweak `addEvent` to insert correctly for scrollback. * TODO: Tweak `addEvent` to insert correctly for scrollback.
* *
* @return {Array}
* Relation events in insertion order. * Relation events in insertion order.
*/ */
public getRelations(): MatrixEvent[] { 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 * - after the server accepted the redaction and remote echoed back to us
* - before the original event has been marked redacted in the client * - before the original event has been marked redacted in the client
* *
* @param {MatrixEvent} redactedEvent * @param redactedEvent - The original relation event that is about to be redacted.
* The original relation event that is about to be redacted.
*/ */
private onBeforeRedaction = async (redactedEvent: MatrixEvent): Promise<void> => { private onBeforeRedaction = async (redactedEvent: MatrixEvent): Promise<void> => {
if (!this.relations.has(redactedEvent)) { 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. * This is currently only supported for the annotation relation type.
* *
* @return {Array}
* An array of [key, events] pairs sorted by descending event count. * An array of [key, events] pairs sorted by descending event count.
* The events are stored in a Set (which preserves insertion order). * 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. * 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 * An object with each relation sender as a key and the matching Set of
* events for that sender as a value. * 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, * This is currently only supported for the m.replace relation type,
* once the target event is known, see `addEvent`. * once the target event is known, see `addEvent`.
*
* @return {MatrixEvent?}
*/ */
public async getLastReplacement(): Promise<MatrixEvent | null> { public async getLastReplacement(): Promise<MatrixEvent | null> {
if (this.relationType !== RelationType.Replace) { 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> { public async setTargetEvent(event: MatrixEvent): Promise<void> {
if (this.targetEvent) { if (this.targetEvent) {

View File

@ -14,10 +14,6 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/**
* @module models/room-member
*/
import { getHttpUriForMxc } from "../content-repo"; import { getHttpUriForMxc } from "../content-repo";
import * as utils from "../utils"; import * as utils from "../utils";
import { User } from "./user"; import { User } from "./user";
@ -35,9 +31,56 @@ export enum RoomMemberEvent {
} }
export type RoomMemberEventHandlerMap = { 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; [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; [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; [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; [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 public requestedProfileInfo = false; // used by sync.ts
// XXX these should be read-only // XXX these should be read-only
/**
* True if the room member is currently typing.
*/
public typing = false; 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; public name: string;
/**
* The ambiguous displayname of this room member.
*/
public rawDisplayName: string; public rawDisplayName: string;
/**
* The power level for this room member.
*/
public powerLevel = 0; public powerLevel = 0;
/**
* The normalised power level (0-100) for this room member.
*/
public powerLevelNorm = 0; public powerLevelNorm = 0;
/**
* The User object for this room member, if one exists.
*/
public user?: User; public user?: User;
/**
* The membership state for this room member e.g. 'join'.
*/
public membership?: string; public membership?: string;
/**
* True if the member's name is disambiguated.
*/
public disambiguate = false; public disambiguate = false;
/**
* The events describing this RoomMember.
*/
public events: { public events: {
/**
* The m.room.member event for this RoomMember.
*/
member?: MatrixEvent; member?: MatrixEvent;
} = {}; } = {};
/** /**
* Construct a new room member. * Construct a new room member.
* *
* @constructor * @param roomId - The room ID of the member.
* @alias module:models/room-member * @param userId - The user ID of the 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.
*/ */
public constructor(public readonly roomId: string, public readonly userId: string) { public constructor(public readonly roomId: string, public readonly userId: string) {
super(); 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 * This is used to store the member seperately
* from the sync state so it available across browser sessions. * 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 * Update this room member's membership event. May fire "RoomMember.name" if
* this event updates this member's name. * this event updates this member's name.
* @param {MatrixEvent} event The <code>m.room.member</code> event * @param event - The `m.room.member` event
* @param {RoomState} roomState Optional. The room state to take into account * @param roomState - Optional. The room state to take into account
* when calculating (e.g. for disambiguating users with the same name). * 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 { public setMembershipEvent(event: MatrixEvent, roomState?: RoomState): void {
const displayName = event.getDirectionalContent().displayname ?? ""; 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 * Update this room member's power level event. May fire
* "RoomMember.powerLevel" if this event updates this member's power levels. * "RoomMember.powerLevel" if this event updates this member's power levels.
* @param {MatrixEvent} powerLevelEvent The <code>m.room.power_levels</code> * @param powerLevelEvent - The `m.room.power_levels` event
* event *
* @fires module:client~MatrixClient#event:"RoomMember.powerLevel" * @remarks
* Fires {@link RoomMemberEvent.PowerLevel}
*/ */
public setPowerLevelEvent(powerLevelEvent: MatrixEvent): void { public setPowerLevelEvent(powerLevelEvent: MatrixEvent): void {
if (powerLevelEvent.getType() !== EventType.RoomPowerLevels || powerLevelEvent.getStateKey() !== "") { 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 * Update this room member's typing event. May fire "RoomMember.typing" if
* this event changes this member's typing state. * this event changes this member's typing state.
* @param {MatrixEvent} event The typing event * @param event - The typing event
* @fires module:client~MatrixClient#event:"RoomMember.typing" *
* @remarks
* Fires {@link RoomMemberEvent.Typing}
*/ */
public setTypingEvent(event: MatrixEvent): void { public setTypingEvent(event: MatrixEvent): void {
if (event.getType() !== "m.typing") { 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 * Get the timestamp when this RoomMember was last updated. This timestamp is
* updated when properties on this RoomMember are updated. * updated when properties on this RoomMember are updated.
* It is updated <i>before</i> firing events. * It is updated <i>before</i> firing events.
* @return {number} The timestamp * @returns The timestamp
*/ */
public getLastModifiedTime(): number { public getLastModifiedTime(): number {
return this.modified; 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 * If this member was invited with the is_direct flag set, return
* the user that invited this member * the user that invited this member
* @return {string} user id of the inviter * @returns user id of the inviter
*/ */
public getDMInviter(): string | undefined { public getDMInviter(): string | undefined {
// when not available because that room state hasn't been loaded in, // 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. * Get the avatar URL for a room member.
* @param {string} baseUrl The base homeserver URL See * @param baseUrl - The base homeserver URL See
* {@link module:client~MatrixClient#getHomeserverUrl}. * {@link MatrixClient#getHomeserverUrl}.
* @param {Number} width The desired width of the thumbnail. * @param width - The desired width of the thumbnail.
* @param {Number} height The desired height of the thumbnail. * @param height - The desired height of the thumbnail.
* @param {string} resizeMethod The thumbnail resize method to use, either * @param resizeMethod - The thumbnail resize method to use, either
* "crop" or "scale". * "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 * return null if the user has no avatar image. Otherwise, a default image URL
* will be returned. Default: true. (Deprecated) * 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. * 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 * 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 * true will expose URLs that, if fetched, will leak information about the user
* to anyone who they share a room with. * to anyone who they share a room with.
* @return {?string} the avatar URL or null. * @returns the avatar URL or null.
*/ */
public getAvatarUrl( public getAvatarUrl(
baseUrl: string, 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 * 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 { public getMxcAvatarUrl(): string | undefined {
if (this.events.member) { if (this.events.member) {
@ -390,52 +452,3 @@ function calculateDisplayName(
// with the embed chars or marker chars. // with the embed chars or marker chars.
return utils.removeDirectionOverrideChars(displayName); 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;
* });
*/

View File

@ -14,10 +14,6 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/**
* @module models/room-state
*/
import { RoomMember } from "./room-member"; import { RoomMember } from "./room-member";
import { logger } from '../logger'; import { logger } from '../logger';
import * as utils from "../utils"; import * as utils from "../utils";
@ -77,8 +73,52 @@ export enum RoomStateEvent {
} }
export type RoomStateEventHandlerMap = { 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; [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; [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.NewMember]: (event: MatrixEvent, state: RoomState, member: RoomMember) => void;
[RoomStateEvent.Update]: (state: RoomState) => void; [RoomStateEvent.Update]: (state: RoomState) => void;
[RoomStateEvent.BeaconLiveness]: (state: RoomState, hasLiveBeacons: boolean) => void; [RoomStateEvent.BeaconLiveness]: (state: RoomState, hasLiveBeacons: boolean) => void;
@ -109,8 +149,11 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
private modified = -1; private modified = -1;
// XXX: Should be read-only // XXX: Should be read-only
// The room member dictionary, keyed on the user's ID.
public members: Record<string, RoomMember> = {}; // userId: RoomMember 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>> 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 paginationToken: string | null = null;
public readonly beacons = new Map<BeaconIdentifier, Beacon>(); 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. * It can be mutated by adding state events to it.
* There are two types of room member associated with a state event: * There are two types of room member associated with a state event:
* normal member objects (accessed via getMember/getMembers) which mutate * normal member objects (accessed via getMember/getMembers) which mutate
* with the state to represent the current state of that room/user, eg. * 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 * the object returned by `getMember('@bob:example.com')` will mutate to
* get a different display name if Bob later changes his display name * get a different display name if Bob later changes his display name
* in the room. * in the room.
* There are also 'sentinel' members (accessed via getSentinelMember). * 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 * after the display name change will return a new RoomMember object
* with Bob's new display name. * with Bob's new display name.
* *
* @constructor * @param roomId - Optional. The ID of the room which has this state.
* @param {?string} roomId Optional. The ID of the room which has this state.
* If none is specified it just tracks paginationTokens, useful for notifTimelineSet * 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 * 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. * and shared when the room state is cloned for the new timeline.
* This should only be passed from clone. * 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 }) { public constructor(public readonly roomId: string, private oobMemberFlags = { status: OobStatus.NotStarted }) {
super(); super();
@ -158,7 +195,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
/** /**
* Returns the number of joined members in this room * Returns the number of joined members in this room
* This method caches the result. * 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 { public getJoinedMemberCount(): number {
if (this.summaryJoinedMemberCount !== null) { 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) * 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 { public setJoinedMemberCount(count: number): void {
this.summaryJoinedMemberCount = count; this.summaryJoinedMemberCount = count;
@ -182,7 +219,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
/** /**
* Returns the number of invited members in this room * 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 { public getInvitedMemberCount(): number {
if (this.summaryInvitedMemberCount !== null) { if (this.summaryInvitedMemberCount !== null) {
@ -198,7 +235,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
/** /**
* Set the amount of invited members in this room * 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 { public setInvitedMemberCount(count: number): void {
this.summaryInvitedMemberCount = count; this.summaryInvitedMemberCount = count;
@ -206,7 +243,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
/** /**
* Get all RoomMembers in this room. * Get all RoomMembers in this room.
* @return {Array<RoomMember>} A list of RoomMembers. * @returns A list of RoomMembers.
*/ */
public getMembers(): RoomMember[] { public getMembers(): RoomMember[] {
return Object.values(this.members); 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. * Get all RoomMembers in this room, excluding the user IDs provided.
* @param {Array<string>} excludedIds The user IDs to exclude. * @param excludedIds - The user IDs to exclude.
* @return {Array<RoomMember>} A list of RoomMembers. * @returns A list of RoomMembers.
*/ */
public getMembersExcept(excludedIds: string[]): RoomMember[] { public getMembersExcept(excludedIds: string[]): RoomMember[] {
return this.getMembers().filter((m) => !excludedIds.includes(m.userId)); 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. * Get a room member by their user ID.
* @param {string} userId The room member's user ID. * @param userId - The room member's user ID.
* @return {RoomMember} The member or null if they do not exist. * @returns The member or null if they do not exist.
*/ */
public getMember(userId: string): RoomMember | null { public getMember(userId: string): RoomMember | null {
return this.members[userId] || 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. * 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 * The term 'sentinel' refers to the fact that this RoomMember is an unchanging
* guardian for state at this particular point in time. * guardian for state at this particular point in time.
* @param {string} userId The room member's user ID. * @param userId - The room member's user ID.
* @return {RoomMember} The member or null if they do not exist. * @returns The member or null if they do not exist.
*/ */
public getSentinelMember(userId: string): RoomMember | null { public getSentinelMember(userId: string): RoomMember | null {
if (!userId) return 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. * Get state events from the state of the room.
* @param {string} eventType The event type of the state event. * @param eventType - The event type of the state event.
* @param {string} stateKey Optional. The state_key of the state event. If * @param stateKey - Optional. The state_key of the state event. If
* this is <code>undefined</code> then all matching state events will be * this is `undefined` then all matching state events will be
* returned. * returned.
* @return {MatrixEvent[]|MatrixEvent} A list of events if state_key was * @returns A list of events if state_key was
* <code>undefined</code>, else a single event (or null if no match found). * `undefined`, else a single event (or null if no match found).
*/ */
public getStateEvents(eventType: EventType | string): MatrixEvent[]; public getStateEvents(eventType: EventType | string): MatrixEvent[];
public getStateEvents(eventType: EventType | string, stateKey: string): MatrixEvent | null; 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. * 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 { public clone(): RoomState {
const copy = new RoomState(this.roomId, this.oobMemberFlags); 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, * When lazy loading members while back-paginating,
* the relevant room state for the timeline chunk at the end * the relevant room state for the timeline chunk at the end
* of the chunk can be set with this method. * 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 { public setUnknownStateEvents(events: MatrixEvent[]): void {
const unknownStateEvents = events.filter((event) => { 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 * 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 * for every event added. May fire "RoomState.members" if there are
* <code>m.room.member</code> events. May fire "RoomStateEvent.Marker" if there are * `m.room.member` events. May fire "RoomStateEvent.Marker" if there are
* <code>UNSTABLE_MSC2716_MARKER</code> events. * `UNSTABLE_MSC2716_MARKER` events.
* @param {MatrixEvent[]} stateEvents a list of state events for this room. * @param stateEvents - a list of state events for this room.
* @param {IMarkerFoundOptions} markerFoundOptions *
* @fires module:client~MatrixClient#event:"RoomState.members" * @remarks
* @fires module:client~MatrixClient#event:"RoomState.newMember" * Fires {@link RoomStateEvent.Members}
* @fires module:client~MatrixClient#event:"RoomState.events" * Fires {@link RoomStateEvent.NewMember}
* @fires module:client~MatrixClient#event:"RoomStateEvent.Marker" * Fires {@link RoomStateEvent.Events}
* Fires {@link RoomStateEvent.Marker}
*/ */
public setStateEvents(stateEvents: MatrixEvent[], markerFoundOptions?: IMarkerFoundOptions): void { public setStateEvents(stateEvents: MatrixEvent[], markerFoundOptions?: IMarkerFoundOptions): void {
this.updateModifiedTime(); this.updateModifiedTime();
@ -479,10 +517,12 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
* create it and emit the `RoomState.newMember` event. * create it and emit the `RoomState.newMember` event.
* This method makes sure the member is added to the members dictionary * This method makes sure the member is added to the members dictionary
* before emitting, as this is done from setStateEvents and setOutOfBandMember. * before emitting, as this is done from setStateEvents and setOutOfBandMember.
* @param {string} userId the id of the user to look up * @param userId - the id of the user to look up
* @param {MatrixEvent} event the membership event for the (new) member. Used to emit. * @param event - the membership event for the (new) member. Used to emit.
* @fires module:client~MatrixClient#event:"RoomState.newMember" * @returns the member, existing or newly created.
* @returns {RoomMember} the member, existing or newly created. *
* @remarks
* Fires {@link RoomStateEvent.NewMember}
*/ */
private getOrCreateMember(userId: string, event: MatrixEvent): RoomMember { private getOrCreateMember(userId: string, event: MatrixEvent): RoomMember {
let member = this.members[userId]; 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. * 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. * 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 { public needsOutOfBandMembers(): boolean {
return this.oobMemberFlags.status === OobStatus.NotStarted; return this.oobMemberFlags.status === OobStatus.NotStarted;
@ -624,7 +664,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
/** /**
* Sets the loaded out-of-band members. * 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 { public setOutOfBandMembers(stateEvents: MatrixEvent[]): void {
logger.log(`LL: RoomState about to set ${stateEvents.length} OOB members ...`); 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 * 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 { private setOutOfBandMember(stateEvent: MatrixEvent): void {
if (stateEvent.getType() !== EventType.RoomMember) { if (stateEvent.getType() !== EventType.RoomMember) {
@ -668,7 +708,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
/** /**
* Set the current typing event for this room. * Set the current typing event for this room.
* @param {MatrixEvent} event The typing event * @param event - The typing event
*/ */
public setTypingEvent(event: MatrixEvent): void { public setTypingEvent(event: MatrixEvent): void {
Object.values(this.members).forEach(function(member) { 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. * Get the m.room.member event which has the given third party invite token.
* *
* @param {string} token The token * @param token - The token
* @return {?MatrixEvent} The m.room.member event or null * @returns The m.room.member event or null
*/ */
public getInviteForThreePidToken(token: string): MatrixEvent | null { public getInviteForThreePidToken(token: string): MatrixEvent | null {
return this.tokenToInvite[token] || 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 * Get the timestamp when this room state was last updated. This timestamp is
* updated when this object has received new state events. * updated when this object has received new state events.
* @return {number} The timestamp * @returns The timestamp
*/ */
public getLastModifiedTime(): number { public getLastModifiedTime(): number {
return this.modified; return this.modified;
@ -704,8 +744,8 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
/** /**
* Get user IDs with the specified or similar display names. * Get user IDs with the specified or similar display names.
* @param {string} displayName The display name to get user IDs from. * @param displayName - The display name to get user IDs from.
* @return {string[]} An array of user IDs or an empty array. * @returns An array of user IDs or an empty array.
*/ */
public getUserIdsWithDisplayName(displayName: string): string[] { public getUserIdsWithDisplayName(displayName: string): string[] {
return this.displayNameToUserIds.get(utils.removeHiddenChars(displayName)) ?? []; 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 * 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. * mxEvent or has power level sufficient to redact events other than their own.
* @param {MatrixEvent} mxEvent The event to test permission for * @param mxEvent - The event to test permission for
* @param {string} userId The user ID of the user to test permission for * @param userId - The user ID of the user to test permission for
* @return {boolean} true if the given used ID can redact given event * @returns true if the given used ID can redact given event
*/ */
public maySendRedactionForEvent(mxEvent: MatrixEvent, userId: string): boolean { public maySendRedactionForEvent(mxEvent: MatrixEvent, userId: string): boolean {
const member = this.getMember(userId); 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 * Returns true if the given power level is sufficient for action
* @param {string} action The type of power level to check * @param action - The type of power level to check
* @param {number} powerLevel The power level of the member * @param powerLevel - The power level of the member
* @return {boolean} true if the given power level is sufficient * @returns true if the given power level is sufficient
*/ */
public hasSufficientPowerLevelFor(action: "ban" | "kick" | "redact", powerLevel: number): boolean { public hasSufficientPowerLevelFor(action: "ban" | "kick" | "redact", powerLevel: number): boolean {
const powerLevelsEvent = this.getStateEvents(EventType.RoomPowerLevels, ""); 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) * Short-form for maySendEvent('m.room.message', userId)
* @param {string} userId The user ID of the user to test permission for * @param userId - The user ID of the user to test permission for
* @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
* message events into the given room. * message events into the given room.
*/ */
public maySendMessage(userId: string): boolean { 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 * Returns true if the given user ID has permission to send a normal
* event of type `eventType` into this room. * event of type `eventType` into this room.
* @param {string} eventType The type of event to test * @param eventType - The type of event to test
* @param {string} userId The user ID of the user to test permission for * @param userId - The user ID of the user to test permission for
* @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, * the given type of event into this room,
* according to the room's state. * 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 * Returns true if the given MatrixClient has permission to send a state
* event of type `stateEventType` into this room. * event of type `stateEventType` into this room.
* @param {string} stateEventType The type of state events to test * @param stateEventType - The type of state events to test
* @param {MatrixClient} cli The client to test permission for * @param cli - The client to test permission for
* @return {boolean} true if the given client should be permitted to send * @returns true if the given client should be permitted to send
* the given type of state event into this room, * the given type of state event into this room,
* according to the room's state. * 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 * Returns true if the given user ID has permission to send a state
* event of type `stateEventType` into this room. * event of type `stateEventType` into this room.
* @param {string} stateEventType The type of state events to test * @param stateEventType - The type of state events to test
* @param {string} userId The user ID of the user to test permission for * @param userId - The user ID of the user to test permission for
* @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 state event into this room, * the given type of state event into this room,
* according to the room's state. * 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 * Returns true if the given user ID has permission to send a normal or state
* event of type `eventType` into this room. * event of type `eventType` into this room.
* @param {string} eventType The type of event to test * @param eventType - The type of event to test
* @param {string} userId The user ID of the user to test permission for * @param 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 state - If true, tests if the user may send a state
event of this type. Otherwise tests whether event of this type. Otherwise tests whether
they may send a regular event. 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, * the given type of event into this room,
* according to the room's state. * 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 * Returns true if the given user ID has permission to trigger notification
* of type `notifLevelKey` * of type `notifLevelKey`
* @param {string} notifLevelKey The level of notification to test (eg. 'room') * @param notifLevelKey - The level of notification to test (eg. 'room')
* @param {string} userId The user ID of the user to test permission for * @param userId - The user ID of the user to test permission for
* @return {boolean} true if the given user ID has permission to trigger a * @returns true if the given user ID has permission to trigger a
* notification of this type. * notification of this type.
*/ */
public mayTriggerNotifOfType(notifLevelKey: string, userId: string): boolean { 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 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 { public getJoinRule(): JoinRule {
const joinRuleEvent = this.getStateEvents(EventType.RoomJoinRules, ""); 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 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 { public getHistoryVisibility(): HistoryVisibility {
const historyVisibilityEvent = this.getStateEvents(EventType.RoomHistoryVisibility, ""); 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 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 { public getGuestAccess(): GuestAccess {
const guestAccessEvent = this.getStateEvents(EventType.RoomGuestAccess, ""); 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'
* });
*/

View File

@ -14,10 +14,6 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/**
* @module models/room-summary
*/
export interface IRoomSummary { export interface IRoomSummary {
"m.heroes": string[]; "m.heroes": string[];
"m.joined_member_count"?: number; "m.joined_member_count"?: number;
@ -25,25 +21,23 @@ export interface IRoomSummary {
} }
interface IInfo { interface IInfo {
/** The title of the room (e.g. `m.room.name`) */
title: string; title: string;
/** The description of the room (e.g. `m.room.topic`) */
desc?: string; desc?: string;
/** The number of joined users. */
numMembers?: number; numMembers?: number;
/** The list of aliases for this room. */
aliases?: string[]; aliases?: string[];
/** The timestamp for this room. */
timestamp?: number; timestamp?: number;
} }
/** /**
* Construct a new Room Summary. A summary can be used for display on a recent * 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. * list, without having to load the entire room list into memory.
* @constructor * @param roomId - Required. The ID of this room.
* @param {string} roomId Required. The ID of this room. * @param info - Optional. The summary info. Additional keys are supported.
* @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.
*/ */
export class RoomSummary { export class RoomSummary {
public constructor(public readonly roomId: string, info?: IInfo) {} public constructor(public readonly roomId: string, info?: IInfo) {}

File diff suppressed because it is too large Load Diff

View File

@ -14,10 +14,6 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/**
* @module models/search-result
*/
import { EventContext } from "./event-context"; import { EventContext } from "./event-context";
import { EventMapper } from "../event-mapper"; import { EventMapper } from "../event-mapper";
import { IResultContext, ISearchResult } from "../@types/search"; import { IResultContext, ISearchResult } from "../@types/search";
@ -25,10 +21,6 @@ import { IResultContext, ISearchResult } from "../@types/search";
export class SearchResult { export class SearchResult {
/** /**
* Create a SearchResponse from the response to /search * 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 { public static fromJson(jsonObj: ISearchResult, eventMapper: EventMapper): SearchResult {
@ -54,11 +46,9 @@ export class SearchResult {
/** /**
* Construct a new SearchResult * Construct a new SearchResult
* *
* @param {number} rank where this SearchResult ranks in the results * @param rank - where this SearchResult ranks in the results
* @param {event-context.EventContext} context the matching event and its * @param context - the matching event and its
* context * context
*
* @constructor
*/ */
public constructor(public readonly rank: number, public readonly context: EventContext) {} public constructor(public readonly rank: number, public readonly context: EventContext) {}
} }

View File

@ -247,10 +247,10 @@ export class Thread extends ReadReceipt<EmittedEvents, EventHandlerMap> {
* Add an event to the thread and updates * Add an event to the thread and updates
* the tail/root references if needed * the tail/root references if needed
* Will fire "Thread.update" * Will fire "Thread.update"
* @param event The event to add * @param event - The event to add
* @param {boolean} toStartOfTimeline whether the event is being added * @param toStartOfTimeline - whether the event is being added
* to the start (and not the end) of the timeline. * 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> { public async addEvent(event: MatrixEvent, toStartOfTimeline: boolean, emit = true): Promise<void> {
this.setEventMetadata(event); this.setEventMetadata(event);

View File

@ -69,7 +69,7 @@ export class TypedEventEmitter<
return super.listenerCount(event); return super.listenerCount(event);
} }
public listeners(event: Events | EventEmitterEvents): Function[] { public listeners(event: Events | EventEmitterEvents): ReturnType<EventEmitter["listeners"]> {
return super.listeners(event); return super.listeners(event);
} }
@ -119,7 +119,7 @@ export class TypedEventEmitter<
return super.removeListener(event, listener); return super.removeListener(event, listener);
} }
public rawListeners(event: Events | EventEmitterEvents): Function[] { public rawListeners(event: Events | EventEmitterEvents): ReturnType<EventEmitter["rawListeners"]> {
return super.rawListeners(event); return super.rawListeners(event);
} }
} }

View File

@ -14,10 +14,6 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/**
* @module models/user
*/
import { MatrixEvent } from "./event"; import { MatrixEvent } from "./event";
import { TypedEventEmitter } from "./typed-event-emitter"; import { TypedEventEmitter } from "./typed-event-emitter";
@ -30,51 +26,132 @@ export enum UserEvent {
} }
export type UserEventHandlerMap = { 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; [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; [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; [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; [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; [UserEvent.LastPresenceTs]: (event: MatrixEvent | undefined, user: User) => void;
}; };
export class User extends TypedEventEmitter<UserEvent, UserEventHandlerMap> { export class User extends TypedEventEmitter<UserEvent, UserEventHandlerMap> {
private modified = -1; 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 displayName?: string;
public rawDisplayName?: string; public rawDisplayName?: string;
/**
* The 'avatar_url' of the user if known.
* @privateRemarks
* Should be read-only
*/
public avatarUrl?: string; public avatarUrl?: string;
/**
* The presence status message if known.
* @privateRemarks
* Should be read-only
*/
public presenceStatusMsg?: string; public presenceStatusMsg?: string;
/**
* The presence enum if known.
* @privateRemarks
* Should be read-only
*/
public presence = "offline"; 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; 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; 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; public currentlyActive = false;
/**
* The events describing this user.
* @privateRemarks
* Should be read-only
*/
public events: { public events: {
/** The m.presence event for this user. */
presence?: MatrixEvent; presence?: MatrixEvent;
profile?: MatrixEvent; profile?: MatrixEvent;
} = {}; } = {};
/** /**
* Construct a new User. A User must have an ID and can optionally have extra * Construct a new User. A User must have an ID and can optionally have extra information associated with it.
* information associated with it. * @param userId - Required. The ID of this user.
* @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.
*/ */
public constructor(public readonly userId: string) { public constructor(public readonly userId: string) {
super(); super();
@ -87,10 +164,12 @@ export class User extends TypedEventEmitter<UserEvent, UserEventHandlerMap> {
* Update this User with the given presence event. May fire "User.presence", * 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 * "User.avatarUrl" and/or "User.displayName" if this event updates this user's
* properties. * properties.
* @param {MatrixEvent} event The <code>m.presence</code> event. * @param event - The `m.presence` event.
* @fires module:client~MatrixClient#event:"User.presence" *
* @fires module:client~MatrixClient#event:"User.displayName" * @remarks
* @fires module:client~MatrixClient#event:"User.avatarUrl" * Fires {@link UserEvent.Presence}
* Fires {@link UserEvent.DisplayName}
* Fires {@link UserEvent.AvatarUrl}
*/ */
public setPresenceEvent(event: MatrixEvent): void { public setPresenceEvent(event: MatrixEvent): void {
if (event.getType() !== "m.presence") { 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 * Manually set this user's display name. No event is emitted in response to this
* as there is no underlying MatrixEvent to emit with. * 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 { public setDisplayName(name: string): void {
const oldName = this.displayName; 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 * 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. * 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 { public setRawDisplayName(name?: string): void {
this.rawDisplayName = name; 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 * Manually set this user's avatar URL. No event is emitted in response to this
* as there is no underlying MatrixEvent to emit with. * 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 { public setAvatarUrl(url?: string): void {
const oldUrl = this.avatarUrl; 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 * 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 * 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. * property on this object. It is updated <i>before</i> firing events.
* @return {number} The timestamp * @returns The timestamp
*/ */
public getLastModifiedTime(): number { public getLastModifiedTime(): number {
return this.modified; 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. * Get the absolute timestamp when this User was last known active on the server.
* It is *NOT* accurate if this.currentlyActive is true. * It is *NOT* accurate if this.currentlyActive is true.
* @return {number} The timestamp * @returns The timestamp
*/ */
public getLastActiveTs(): number { public getLastActiveTs(): number {
return this.lastPresenceTs - this.lastActiveAgo; 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;
* });
*/

View File

@ -38,10 +38,6 @@ import {
} from "./@types/PushRules"; } from "./@types/PushRules";
import { EventType } from "./@types/event"; import { EventType } from "./@types/event";
/**
* @module pushprocessor
*/
const RULEKINDS_IN_ORDER = [ const RULEKINDS_IN_ORDER = [
PushRuleKind.Override, PushRuleKind.Override,
PushRuleKind.ContentSpecific, PushRuleKind.ContentSpecific,
@ -116,25 +112,27 @@ const DEFAULT_UNDERRIDE_RULES: IPushRule[] = [
]; ];
export interface IActionsObject { export interface IActionsObject {
/** Whether this event should notify the user or not. */
notify: boolean; notify: boolean;
/** How this event should be notified. */
tweaks: Partial<Record<TweakName, any>>; tweaks: Partial<Record<TweakName, any>>;
} }
export class PushProcessor { export class PushProcessor {
/** /**
* Construct a Push Processor. * Construct a Push Processor.
* @constructor * @param client - The Matrix client object to use
* @param {Object} client The Matrix client object to use
*/ */
public constructor(private readonly client: MatrixClient) {} public constructor(private readonly client: MatrixClient) {}
/** /**
* Convert a list of actions into a object with the actions as keys and their values * Convert a list of actions into a object with the actions as keys and their values
* eg. [ 'notify', { set_tweak: 'sound', value: 'default' } ] * @example
* becomes { notify: true, tweaks: { sound: 'default' } } * eg. `[ 'notify', { set_tweak: 'sound', value: 'default' } ]`
* @param {array} actionList The actions list * 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 { public static actionListToActionsObject(actionList: PushRuleAction[]): IActionsObject {
const actionObj: IActionsObject = { notify: false, tweaks: {} }; 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 * Rewrites conditions on a client's push rules to match the defaults
* where applicable. Useful for upgrading push rules to more strict * where applicable. Useful for upgrading push rules to more strict
* conditions when the server is falling behind on defaults. * conditions when the server is falling behind on defaults.
* @param {object} incomingRules The client's existing push rules * @param incomingRules - The client's existing push rules
* @returns {object} The rewritten rules * @returns The rewritten rules
*/ */
public static rewriteDefaultRules(incomingRules: IPushRules): IPushRules { public static rewriteDefaultRules(incomingRules: IPushRules): IPushRules {
let newRules: IPushRules = JSON.parse(JSON.stringify(incomingRules)); // deep clone 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 * Get the user's push actions for the given event
*
* @param {module:models/event.MatrixEvent} ev
*
* @return {PushAction}
*/ */
public actionsForEvent(ev: MatrixEvent): IActionsObject { public actionsForEvent(ev: MatrixEvent): IActionsObject {
return this.pushActionsForEventAndRulesets(ev, this.client.pushRules); return this.pushActionsForEventAndRulesets(ev, this.client.pushRules);
@ -514,8 +508,8 @@ export class PushProcessor {
/** /**
* Get one of the users push rules by its ID * Get one of the users push rules by its ID
* *
* @param {string} ruleId The ID of the rule to search for * @param ruleId - The ID of the rule to search for
* @return {object} The push rule, or null if no such rule was found * @returns The push rule, or null if no such rule was found
*/ */
public getPushRuleById(ruleId: string): IPushRule | null { public getPushRuleById(ruleId: string): IPushRule | null {
for (const scope of ['global'] as const) { for (const scope of ['global'] as const) {
@ -532,15 +526,3 @@ export class PushProcessor {
return null; 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.
*/

View File

@ -48,16 +48,17 @@ type Callback = {
const callbackList: Callback[] = []; const callbackList: Callback[] = [];
// var debuglog = logger.log.bind(logger); // var debuglog = logger.log.bind(logger);
/* istanbul ignore next */
const debuglog = function(...params: any[]): void {}; const debuglog = function(...params: any[]): void {};
/** /**
* reimplementation of window.setTimeout, which will call the callback if * reimplementation of window.setTimeout, which will call the callback if
* the wallclock time goes past the deadline. * the wallclock time goes past the deadline.
* *
* @param {function} func callback to be called after a delay * @param func - callback to be called after a delay
* @param {Number} delayMs number of milliseconds to delay by * @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. * clearTimeout later.
*/ */
export function setTimeout(func: (...params: any[]) => void, delayMs: number, ...params: any[]): number { 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 * 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 { export function clearTimeout(key: number): void {
if (callbackList.length === 0) { if (callbackList.length === 0) {

View File

@ -67,9 +67,9 @@ export class MSC3906Rendezvous {
private _code?: string; private _code?: string;
/** /**
* @param channel The secure channel used for communication * @param channel - The secure channel used for communication
* @param client The Matrix client in used on the device already logged in * @param client - The Matrix client in used on the device already logged in
* @param onFailure Callback for when the rendezvous fails * @param onFailure - Callback for when the rendezvous fails
*/ */
public constructor( public constructor(
private channel: RendezvousChannel<MSC3906RendezvousPayload>, private channel: RendezvousChannel<MSC3906RendezvousPayload>,
@ -217,7 +217,7 @@ export class MSC3906Rendezvous {
/** /**
* Verify the device and cross-sign it. * 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 * @returns the new device info if the device was verified
*/ */
public async verifyNewDeviceOnExistingDevice( public async verifyNewDeviceOnExistingDevice(

View File

@ -28,7 +28,7 @@ export interface RendezvousChannel<T> {
/** /**
* Send a payload via the channel. * Send a payload via the channel.
* @param data payload to send * @param data - payload to send
*/ */
send(data: T): Promise<void>; send(data: T): Promise<void>;

View File

@ -41,7 +41,7 @@ export interface RendezvousTransport<T> {
/** /**
* Send data via the transport. * Send data via the transport.
* @param data the data itself * @param data - the data itself
*/ */
send(data: T): Promise<void>; send(data: T): Promise<void>;
@ -52,7 +52,7 @@ export interface RendezvousTransport<T> {
/** /**
* Cancel the rendezvous. This will call `onCancelled()` if it is set. * 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>; cancel(reason: RendezvousFailureReason): Promise<void>;
} }

View File

@ -14,10 +14,6 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/**
* @module room-hierarchy
*/
import { Room } from "./models/room"; import { Room } from "./models/room";
import { IHierarchyRoom, IHierarchyRelation } from "./@types/spaces"; import { IHierarchyRoom, IHierarchyRelation } from "./@types/spaces";
import { MatrixClient } from "./client"; 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. * 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 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 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 maxDepth - the maximum depth to traverse the hierarchy to
* @param {boolean} suggestedOnly whether to only return rooms with suggested=true. * @param suggestedOnly - whether to only return rooms with suggested=true.
* @constructor
*/ */
public constructor( public constructor(
public readonly root: Room, public readonly root: Room,

View File

@ -17,7 +17,6 @@ limitations under the License.
/** /**
* This is an internal module which manages queuing, scheduling and retrying * This is an internal module which manages queuing, scheduling and retrying
* of requests. * of requests.
* @module scheduler
*/ */
import * as utils from "./utils"; import * as utils from "./utils";
import { logger } from './logger'; import { logger } from './logger';
@ -35,20 +34,13 @@ interface IQueueEntry<T> {
attempts: number; 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>; 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 // eslint-disable-next-line camelcase
export class MatrixScheduler<T = ISendEventResponse> { 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 * 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 * failure was due to a rate limited request, the time specified in the error is
* waited before being retried. * waited before being retried.
* @param {MatrixEvent} event * @param attempts - Number of attempts that have been made, including the one that just failed (ie. starting at 1)
* @param {Number} attempts Number of attempts that have been made, including the one that just failed (ie. starting at 1) * @see retryAlgorithm
* @param {MatrixError} err
* @return {Number}
* @see module:scheduler~retryAlgorithm
*/ */
// eslint-disable-next-line @typescript-eslint/naming-convention // eslint-disable-next-line @typescript-eslint/naming-convention
public static RETRY_BACKOFF_RATELIMIT(event: MatrixEvent | null, attempts: number, err: MatrixError): number { 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. * concurrently.
* @param {MatrixEvent} event * @see queueAlgorithm
* @return {string}
* @see module:scheduler~queueAlgorithm
*/ */
// eslint-disable-next-line @typescript-eslint/naming-convention // eslint-disable-next-line @typescript-eslint/naming-convention
public static QUEUE_MESSAGES(event: MatrixEvent): string | null { public static QUEUE_MESSAGES(event: MatrixEvent): string | null {
@ -116,16 +103,52 @@ export class MatrixScheduler<T = ISendEventResponse> {
private activeQueues: string[] = []; private activeQueues: string[] = [];
private procFn: ProcessFunction<T> | null = null; 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( 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, 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, public readonly queueAlgorithm = MatrixScheduler.QUEUE_MESSAGES,
) {} ) {}
/** /**
* Retrieve a queue based on an event. The event provided does not need to be in * Retrieve a queue based on an event. The event provided does not need to be in
* the queue. * the queue.
* @param {MatrixEvent} event An event to get the queue for. * @param event - An event to get the queue for.
* @return {?Array<MatrixEvent>} A shallow copy of events in the queue or null. * @returns A shallow copy of events in the queue or null.
* Modifying this array will not modify the list itself. Modifying events in * Modifying this array will not modify the list itself. Modifying events in
* this array <i>will</i> modify the underlying event in the queue. * this array <i>will</i> modify the underlying event in the queue.
* @see MatrixScheduler.removeEventFromQueue To remove an event from 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 * Remove this event from the queue. The event is equal to another event if they
* have the same ID returned from event.getId(). * have the same ID returned from event.getId().
* @param {MatrixEvent} event The event to remove. * @param event - The event to remove.
* @return {boolean} True if this event was removed. * @returns True if this event was removed.
*/ */
public removeEventFromQueue(event: MatrixEvent): boolean { public removeEventFromQueue(event: MatrixEvent): boolean {
const name = this.queueAlgorithm(event); 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. * 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 * If set after events have been added to the queue, this will immediately start
* processing them. * processing them.
* @param {module:scheduler~processFn} fn The function that can process events * @param fn - The function that can process events
* in the queue. * in the queue.
*/ */
public setProcessFunction(fn: ProcessFunction<T>): void { 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. * Queue an event if it is required and start processing queues.
* @param {MatrixEvent} event The event that may be queued. * @param event - The event that may be queued.
* @return {?Promise} A promise if the event was queued, which will be * @returns A promise if the event was queued, which will be
* resolved or rejected in due time, else null. * resolved or rejected in due time, else null.
*/ */
public queueEvent(event: MatrixEvent): Promise<T> | 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 { function debuglog(...args: any[]): void {
if (DEBUG) { if (DEBUG) {
logger.log(...args); 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.
*/

View File

@ -458,7 +458,7 @@ export class SlidingSyncSdk {
/** /**
* Sync rooms the user has left. * 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[]> { public async syncLeftRooms(): Promise<Room[]> {
return []; // TODO 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 * 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. * is accessible via getRooms(). Live updates for the room will be provided.
* @param {string} roomId The room ID to peek into. * @param roomId - The room ID to peek into.
* @return {Promise} A promise which resolves once the room has been added to the * @returns A promise which resolves once the room has been added to the
* store. * store.
*/ */
public async peek(_roomId: string): Promise<Room> { public async peek(_roomId: string): Promise<Room> {
@ -485,8 +485,7 @@ export class SlidingSyncSdk {
/** /**
* Returns the current state of this sync object * Returns the current state of this sync object
* @see module:client~MatrixClient#event:"sync" * @see MatrixClient#event:"sync"
* @return {?String}
*/ */
public getSyncState(): SyncState | null { public getSyncState(): SyncState | null {
return this.syncState; return this.syncState;
@ -498,7 +497,6 @@ export class SlidingSyncSdk {
* such data. * such data.
* Sync errors, if available, are put in the 'error' key of * Sync errors, if available, are put in the 'error' key of
* this object. * this object.
* @return {?Object}
*/ */
public getSyncStateData(): ISyncStateData | null { public getSyncStateData(): ISyncStateData | null {
return this.syncStateData ?? null; return this.syncStateData ?? null;
@ -765,12 +763,11 @@ export class SlidingSyncSdk {
/** /**
* Injects events into a room's model. * Injects events into a room's model.
* @param {Room} room * @param stateEventList - A list of state events. This is the state
* @param {MatrixEvent[]} stateEventList A list of state events. This is the state
* at the *START* of the timeline list if it is supplied. * 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. * 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. * supplied from the server.
*/ */
public injectRoomEvents( public injectRoomEvents(
@ -933,8 +930,8 @@ export class SlidingSyncSdk {
/** /**
* Sets the sync state and emits an event to say so * Sets the sync state and emits an event to say so
* @param {String} newState The new state string * @param newState - The new state string
* @param {Object} data Object of additional data to emit in the event * @param data - Object of additional data to emit in the event
*/ */
private updateSyncState(newState: SyncState, data?: ISyncStateData): void { private updateSyncState(newState: SyncState, data?: ISyncStateData): void {
const old = this.syncState; const old = this.syncState;
@ -948,7 +945,7 @@ export class SlidingSyncSdk {
* as appropriate. * as appropriate.
* This must be called after the room the events belong to has been stored. * 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. * is earlier in time. Higher index is later.
*/ */
private addNotifications(timelineEventList: MatrixEvent[]): void { private addNotifications(timelineEventList: MatrixEvent[]): void {

View File

@ -156,7 +156,7 @@ export enum SlidingSyncState {
/** /**
* Internal Class. SlidingList represents a single list in sliding sync. The list can have filters, * 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 { class SlidingList {
private list!: MSC3575List; private list!: MSC3575List;
@ -168,7 +168,7 @@ class SlidingList {
/** /**
* Construct a new sliding list. * 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) { public constructor(list: MSC3575List) {
this.replaceList(list); 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. * 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. * 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 { public setModified(modified: boolean): void {
this.isModified = modified; 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. * 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 { public updateListRange(newRanges: number[][]): void {
this.list.ranges = JSON.parse(JSON.stringify(newRanges)); 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. * 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 { public replaceList(list: MSC3575List): void {
list.filters = list.filters || {}; list.filters = list.filters || {};
@ -213,7 +213,7 @@ class SlidingList {
/** /**
* Return a copy of the list suitable for a request body. * 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 * hasn't been modified. Callers may want to do this if they are modifying the list prior to calling
* updateList. * updateList.
*/ */
@ -235,7 +235,7 @@ class SlidingList {
* a b c d _ f COMMAND: DELETE 7; * a b c d _ f COMMAND: DELETE 7;
* e a b c d f COMMAND: INSERT 0 e; * 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 * 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 * @returns True if the index is within a sliding window
*/ */
public isIndexInRange(i: number): boolean { 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. * A function which is called when the request JSON is being formed.
* Returns the data to insert under this key. * 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. * @returns The request JSON to send.
*/ */
onRequest(isInitial: boolean): Req | undefined; onRequest(isInitial: boolean): Req | undefined;
/** /**
* A function which is called when there is response JSON under this extension. * 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; onResponse(data: Res): void;
/** /**
@ -368,11 +368,11 @@ export class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, SlidingSync
/** /**
* Create a new sliding sync instance * Create a new sliding sync instance
* @param {string} proxyBaseUrl The base URL of the sliding sync proxy * @param proxyBaseUrl - The base URL of the sliding sync proxy
* @param {MSC3575List[]} lists The lists to use for sliding sync. * @param lists - The lists to use for sliding sync.
* @param {MSC3575RoomSubscription} roomSubscriptionInfo The params to use for room subscriptions. * @param roomSubscriptionInfo - The params to use for room subscriptions.
* @param {MatrixClient} client The client to use for /sync calls. * @param client - The client to use for /sync calls.
* @param {number} timeoutMS The number of milliseconds to wait for a response. * @param timeoutMS - The number of milliseconds to wait for a response.
*/ */
public constructor( public constructor(
private readonly proxyBaseUrl: string, 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 * 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. * 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. * useCustomSubscription.
* @param sub The subscription information. * @param sub - The subscription information.
*/ */
public addCustomSubscription(name: string, sub: MSC3575RoomSubscription): void { public addCustomSubscription(name: string, sub: MSC3575RoomSubscription): void {
this.customSubscriptions.set(name, sub); 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 * Use a custom subscription previously added via addCustomSubscription. No requests are sent
* by calling this method. Use modifyRoomSubscriptions to resend subscription information. * by calling this method. Use modifyRoomSubscriptions to resend subscription information.
* @param roomId The room to use the subscription in. * @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 name - The name of the subscription. If this name is unknown, the default subscription
* will be used. * will be used.
*/ */
public useCustomSubscription(roomId: string, name: string): void { 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. * 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 * @returns The list data which contains the rooms in this list
*/ */
public getListData(index: number): {joinedCount: number, roomIndexToRoomId: Record<number, string>} | null { 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 * 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. * 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. * @returns A copy of the list or undefined.
*/ */
public getList(index: number): MSC3575List | null { 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 * 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, * is more efficient than calling setList(index,list) as this function won't resend sticky params,
* whereas setList always will. * whereas setList always will.
* @param index The list index to modify * @param index - The list index to modify
* @param ranges The new ranges to apply. * @param ranges - The new ranges to apply.
* @return A promise which resolves to the transaction ID when it has been received down sync * @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 * (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) * 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 * Add or replace a list. Calling this function will interrupt the /sync request to resend new
* lists. * lists.
* @param index The index to modify * @param index - The index to modify
* @param list The new list parameters. * @param list - The new list parameters.
* @return A promise which resolves to the transaction ID when it has been received down sync * @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 * (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) * 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 * 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 * /sync request to resend new subscriptions. If the /sync stream has not started, this will
* prepare the room subscriptions for when start() is called. * prepare the room subscriptions for when start() is called.
* @param s The new desired room subscriptions. * @param s - The new desired room subscriptions.
* @return A promise which resolves to the transaction ID when it has been received down sync * @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 * (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) * 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 * Modify which events to retrieve for room subscriptions. Invalidates all room subscriptions
* such that they will be sent up afresh. * such that they will be sent up afresh.
* @param rs The new room subscription fields to fetch. * @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 * @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 * (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) * 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. * 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 { public registerExtension(ext: Extension<any, any>): void {
if (this.extensions[ext.name()]) { if (this.extensions[ext.name()]) {
@ -552,8 +552,8 @@ export class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, SlidingSync
/** /**
* Invoke all attached room data listeners. * Invoke all attached room data listeners.
* @param {string} roomId The room which received some data. * @param roomId - The room which received some data.
* @param {object} roomData The raw sliding sync response JSON. * @param roomData - The raw sliding sync response JSON.
*/ */
private invokeRoomDataListeners(roomId: string, roomData: MSC3575RoomData): void { private invokeRoomDataListeners(roomId: string, roomData: MSC3575RoomData): void {
if (!roomData.required_state) { roomData.required_state = []; } if (!roomData.required_state) { roomData.required_state = []; }
@ -563,9 +563,9 @@ export class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, SlidingSync
/** /**
* Invoke all attached lifecycle listeners. * Invoke all attached lifecycle listeners.
* @param {SlidingSyncState} state The Lifecycle state * @param state - The Lifecycle state
* @param {object} resp The raw sync response JSON * @param resp - The raw sync response JSON
* @param {Error?} err Any error that occurred when making the request e.g. network errors. * @param err - Any error that occurred when making the request e.g. network errors.
*/ */
private invokeLifecycleListeners( private invokeLifecycleListeners(
state: SlidingSyncState, state: SlidingSyncState,

View File

@ -42,141 +42,133 @@ export interface IStore {
// for when it falls back to being a memory store due to errors. // for when it falls back to being a memory store due to errors.
on?: (event: EventEmitterEvents | "degraded", handler: (...args: any[]) => void) => void; 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>; isNewlyCreated(): Promise<boolean>;
/** /**
* Get the sync token. * Get the sync token.
* @return {string}
*/ */
getSyncToken(): string | null; getSyncToken(): string | null;
/** /**
* Set the sync token. * Set the sync token.
* @param {string} token
*/ */
setSyncToken(token: string): void; setSyncToken(token: string): void;
/** /**
* Store the given room. * 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; storeRoom(room: Room): void;
/** /**
* Retrieve a room by its' room ID. * Retrieve a room by its' room ID.
* @param {string} roomId The room ID. * @param roomId - The room ID.
* @return {Room} The room or null. * @returns The room or null.
*/ */
getRoom(roomId: string): Room | null; getRoom(roomId: string): Room | null;
/** /**
* Retrieve all known rooms. * 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[]; getRooms(): Room[];
/** /**
* Permanently delete a room. * Permanently delete a room.
* @param {string} roomId
*/ */
removeRoom(roomId: string): void; removeRoom(roomId: string): void;
/** /**
* Retrieve a summary of all the rooms. * Retrieve a summary of all the rooms.
* @return {RoomSummary[]} A summary of each room. * @returns A summary of each room.
*/ */
getRoomSummaries(): RoomSummary[]; getRoomSummaries(): RoomSummary[];
/** /**
* Store a User. * Store a User.
* @param {User} user The user to store. * @param user - The user to store.
*/ */
storeUser(user: User): void; storeUser(user: User): void;
/** /**
* Retrieve a User by its' user ID. * Retrieve a User by its' user ID.
* @param {string} userId The user ID. * @param userId - The user ID.
* @return {User} The user or null. * @returns The user or null.
*/ */
getUser(userId: string): User | null; getUser(userId: string): User | null;
/** /**
* Retrieve all known users. * 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[]; getUsers(): User[];
/** /**
* Retrieve scrollback for this room. * Retrieve scrollback for this room.
* @param {Room} room The matrix room * @param room - The matrix room
* @param {number} limit The max number of old events to retrieve. * @param limit - The max number of old events to retrieve.
* @return {Array<Object>} An array of objects which will be at most 'limit' * @returns An array of objects which will be at most 'limit'
* length and at least 0. The objects are the raw event JSON. * length and at least 0. The objects are the raw event JSON.
*/ */
scrollback(room: Room, limit: number): MatrixEvent[]; scrollback(room: Room, limit: number): MatrixEvent[];
/** /**
* Store events for a room. * Store events for a room.
* @param {Room} room The room to store events for. * @param room - The room to store events for.
* @param {Array<MatrixEvent>} events The events to store. * @param events - The events to store.
* @param {string} token The token associated with these events. * @param token - The token associated with these events.
* @param {boolean} toStart True if these are paginated results. * @param toStart - True if these are paginated results.
*/ */
storeEvents(room: Room, events: MatrixEvent[], token: string | null, toStart: boolean): void; storeEvents(room: Room, events: MatrixEvent[], token: string | null, toStart: boolean): void;
/** /**
* Store a filter. * Store a filter.
* @param {Filter} filter
*/ */
storeFilter(filter: Filter): void; storeFilter(filter: Filter): void;
/** /**
* Retrieve a filter. * Retrieve a filter.
* @param {string} userId * @returns A filter or null.
* @param {string} filterId
* @return {?Filter} A filter or null.
*/ */
getFilter(userId: string, filterId: string): Filter | null; getFilter(userId: string, filterId: string): Filter | null;
/** /**
* Retrieve a filter ID with the given name. * Retrieve a filter ID with the given name.
* @param {string} filterName The filter name. * @param filterName - The filter name.
* @return {?string} The filter ID or null. * @returns The filter ID or null.
*/ */
getFilterIdByName(filterName: string): string | null; getFilterIdByName(filterName: string): string | null;
/** /**
* Set a filter name to ID mapping. * Set a filter name to ID mapping.
* @param {string} filterName
* @param {string} filterId
*/ */
setFilterIdByName(filterName: string, filterId?: string): void; setFilterIdByName(filterName: string, filterId?: string): void;
/** /**
* Store user-scoped account data events * Store user-scoped account data events
* @param {Array<MatrixEvent>} events The events to store. * @param events - The events to store.
*/ */
storeAccountDataEvents(events: MatrixEvent[]): void; storeAccountDataEvents(events: MatrixEvent[]): void;
/** /**
* Get account data event by event type * 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; getAccountData(eventType: EventType | string): MatrixEvent | undefined;
/** /**
* setSyncData does nothing as there is no backing data store. * setSyncData does nothing as there is no backing data store.
* *
* @param {Object} syncData The sync data * @param syncData - The sync data
* @return {Promise} An immediately resolved promise. * @returns An immediately resolved promise.
*/ */
setSyncData(syncData: ISyncResponse): Promise<void>; setSyncData(syncData: ISyncResponse): Promise<void>;
/** /**
* We never want to save because we have nothing to save to. * 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; wantsSave(): boolean;
@ -187,19 +179,19 @@ export interface IStore {
/** /**
* Startup does nothing. * Startup does nothing.
* @return {Promise} An immediately resolved promise. * @returns An immediately resolved promise.
*/ */
startup(): Promise<void>; 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 * client state to where it was at the last save, or null if there
* is no saved sync data. * is no saved sync data.
*/ */
getSavedSync(): Promise<ISavedSync | null>; 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. * for this sync, otherwise null.
*/ */
getSavedSyncToken(): Promise<string | null>; getSavedSyncToken(): Promise<string | null>;
@ -207,16 +199,15 @@ export interface IStore {
/** /**
* Delete all data from this store. Does nothing since this store * Delete all data from this store. Does nothing since this store
* doesn't store anything. * doesn't store anything.
* @return {Promise} An immediately resolved promise. * @returns An immediately resolved promise.
*/ */
deleteAllData(): Promise<void>; deleteAllData(): Promise<void>;
/** /**
* Returns the out-of-band membership events for this room that * Returns the out-of-band membership events for this room that
* were previously loaded. * were previously loaded.
* @param {string} roomId * @returns the events, potentially an empty array if OOB loading didn't yield any new members
* @returns {event[]} 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
* @returns {null} in case the members for this room haven't been stored yet
*/ */
getOutOfBandMembers(roomId: string): Promise<IStateEventWithRoomId[] | null>; 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 * 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 * 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 * marked as fetched, and getOutOfBandMembers will return an empty array instead of null
* @param {string} roomId * @param membershipEvents - the membership events to store
* @param {event[]} membershipEvents the membership events to store * @returns when all members have been stored
* @returns {Promise} when all members have been stored
*/ */
setOutOfBandMembers(roomId: string, membershipEvents: IStateEventWithRoomId[]): Promise<void>; setOutOfBandMembers(roomId: string, membershipEvents: IStateEventWithRoomId[]): Promise<void>;

View File

@ -51,12 +51,12 @@ const VERSION = DB_MIGRATIONS.length;
/** /**
* Helper method to collect results from a Cursor and promiseify it. * Helper method to collect results from a Cursor and promiseify it.
* @param {ObjectStore|Index} store The store to perform openCursor on. * @param store - The store to perform openCursor on.
* @param {IDBKeyRange=} keyRange Optional key range to apply on the cursor. * @param keyRange - Optional key range to apply on the cursor.
* @param {Function} resultMapper A function which is repeatedly called with a * @param resultMapper - A function which is repeatedly called with a
* Cursor. * Cursor.
* Return the data you want to keep. * 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. * resultMapper.
*/ */
function selectQuery<T>( function selectQuery<T>(
@ -134,11 +134,10 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend {
* Does the actual reading from and writing to the indexeddb * Does the actual reading from and writing to the indexeddb
* *
* Construct a new Indexed Database store backend. This requires a call to * Construct a new Indexed Database store backend. This requires a call to
* <code>connect()</code> before this store can be used. * `connect()` before this store can be used.
* @constructor * @param indexedDB - The Indexed DB interface e.g
* @param {Object} indexedDB The Indexed DB interface e.g * `window.indexedDB`
* <code>window.indexedDB</code> * @param dbName - Optional database name. The same name must be used
* @param {string=} dbName Optional database name. The same name must be used
* to open the same database. * to open the same database.
*/ */
public constructor(private readonly indexedDB: IDBFactory, dbName = "default") { 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 * Attempt to connect to the database. This can fail if the user does not
* grant permission. * grant permission.
* @return {Promise} Resolves if successfully connected. * @returns Promise which resolves if successfully connected.
*/ */
public connect(): Promise<void> { public connect(): Promise<void> {
if (!this.disconnected) { 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> { public isNewlyCreated(): Promise<boolean> {
return Promise.resolve(this._isNewlyCreated); return Promise.resolve(this._isNewlyCreated);
} }
/** /**
* Having connected, load initial data from the database and prepare for use * 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> { private init(): Promise<unknown> {
return Promise.all([ return Promise.all([
@ -223,9 +222,8 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend {
/** /**
* Returns the out-of-band membership events for this room that * Returns the out-of-band membership events for this room that
* were previously loaded. * were previously loaded.
* @param {string} roomId * @returns the events, potentially an empty array if OOB loading didn't yield any new members
* @returns {Promise<event[]>} 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
* @returns {null} in case the members for this room haven't been stored yet
*/ */
public getOutOfBandMembers(roomId: string): Promise<IStateEventWithRoomId[] | null> { public getOutOfBandMembers(roomId: string): Promise<IStateEventWithRoomId[] | null> {
return new Promise<IStateEventWithRoomId[] | null>((resolve, reject) => { 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 * 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 * 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 * marked as fetched, and getOutOfBandMembers will return an empty array instead of null
* @param {string} roomId * @param membershipEvents - the membership events to store
* @param {event[]} membershipEvents the membership events to store
*/ */
public async setOutOfBandMembers(roomId: string, membershipEvents: IStateEventWithRoomId[]): Promise<void> { public async setOutOfBandMembers(roomId: string, membershipEvents: IStateEventWithRoomId[]): Promise<void> {
logger.log(`LL: backend about to store ${membershipEvents.length}` + 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 * Clear the entire database. This should be used when logging out of a client
* to prevent mixing data between accounts. * 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> { public clearDatabase(): Promise<void> {
return new Promise((resolve) => { 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 * buffers and must not be mutated. Otherwise, a copy is made before
* returning such that the data can be safely mutated. Default: true. * 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 * client state to where it was at the last save, or null if there
* is no saved sync data. * is no saved sync data.
*/ */
@ -421,9 +418,9 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend {
/** /**
* Persist rooms /sync data along with the next batch token. * Persist rooms /sync data along with the next batch token.
* @param {string} nextBatch The next_batch /sync value. * @param nextBatch - The next_batch /sync value.
* @param {Object} roomsData The 'rooms' /sync data from a SyncAccumulator * @param roomsData - The 'rooms' /sync data from a SyncAccumulator
* @return {Promise} Resolves if the data was persisted. * @returns Promise which resolves if the data was persisted.
*/ */
private persistSyncData( private persistSyncData(
nextBatch: string, nextBatch: string,
@ -447,8 +444,8 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend {
/** /**
* Persist a list of account data events. Events with the same 'type' will * Persist a list of account data events. Events with the same 'type' will
* be replaced. * be replaced.
* @param {Object[]} accountData An array of raw user-scoped account data events * @param accountData - An array of raw user-scoped account data events
* @return {Promise} Resolves if the events were persisted. * @returns Promise which resolves if the events were persisted.
*/ */
private persistAccountData(accountData: IMinimalEvent[]): Promise<void> { private persistAccountData(accountData: IMinimalEvent[]): Promise<void> {
return utils.promiseTry<void>(() => { return utils.promiseTry<void>(() => {
@ -466,8 +463,8 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend {
* Users with the same 'userId' will be replaced. * Users with the same 'userId' will be replaced.
* Presence events should be the event in its raw form (not the Event * Presence events should be the event in its raw form (not the Event
* object) * object)
* @param {Object[]} tuples An array of [userid, event] tuples * @param tuples - An array of [userid, event] tuples
* @return {Promise} Resolves if the users were persisted. * @returns Promise which resolves if the users were persisted.
*/ */
private persistUserPresenceEvents(tuples: UserTuple[]): Promise<void> { private persistUserPresenceEvents(tuples: UserTuple[]): Promise<void> {
return utils.promiseTry<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. * 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 * FIXME: It would probably be more sensible to store the events in the
* sync. * 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[]> { public getUserPresenceEvents(): Promise<UserTuple[]> {
return utils.promiseTry<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. * 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[]> { private loadAccountData(): Promise<IMinimalEvent[]> {
logger.log(`LocalIndexedDBStoreBackend: loading account data...`); logger.log(`LocalIndexedDBStoreBackend: loading account data...`);
@ -519,7 +516,7 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend {
/** /**
* Load the sync data from the database. * 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> { private loadSyncData(): Promise<ISyncData> {
logger.log(`LocalIndexedDBStoreBackend: loading sync data...`); logger.log(`LocalIndexedDBStoreBackend: loading sync data...`);

View File

@ -36,10 +36,9 @@ export class RemoteIndexedDBStoreBackend implements IIndexedDBBackend {
* worker. * worker.
* *
* Construct a new Indexed Database store backend. This requires a call to * Construct a new Indexed Database store backend. This requires a call to
* <code>connect()</code> before this store can be used. * `connect()` before this store can be used.
* @constructor * @param workerFactory - Factory which produces a Worker
* @param {Function} workerFactory Factory which produces a Worker * @param dbName - Optional database name. The same name must be used
* @param {string=} dbName Optional database name. The same name must be used
* to open the same database. * to open the same database.
*/ */
public constructor( 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 * Attempt to connect to the database. This can fail if the user does not
* grant permission. * grant permission.
* @return {Promise} Resolves if successfully connected. * @returns Promise which resolves if successfully connected.
*/ */
public connect(): Promise<void> { public connect(): Promise<void> {
return this.ensureStarted().then(() => this.doCmd('connect')); 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 * Clear the entire database. This should be used when logging out of a client
* to prevent mixing data between accounts. * 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> { public clearDatabase(): Promise<void> {
return this.ensureStarted().then(() => this.doCmd('clearDatabase')); 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> { public isNewlyCreated(): Promise<boolean> {
return this.doCmd('isNewlyCreated'); 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 * client state to where it was at the last save, or null if there
* is no saved sync data. * 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 * Returns the out-of-band membership events for this room that
* were previously loaded. * were previously loaded.
* @param {string} roomId * @returns the events, potentially an empty array if OOB loading didn't yield any new members
* @returns {event[]} 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
* @returns {null} in case the members for this room haven't been stored yet
*/ */
public getOutOfBandMembers(roomId: string): Promise<IStateEventWithRoomId[] | null> { public getOutOfBandMembers(roomId: string): Promise<IStateEventWithRoomId[] | null> {
return this.doCmd('getOutOfBandMembers', [roomId]); 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 * 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 * 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 * marked as fetched, and getOutOfBandMembers will return an empty array instead of null
* @param {string} roomId * @param membershipEvents - the membership events to store
* @param {event[]} membershipEvents the membership events to store * @returns when all members have been stored
* @returns {Promise} when all members have been stored
*/ */
public setOutOfBandMembers(roomId: string, membershipEvents: IStateEventWithRoomId[]): Promise<void> { public setOutOfBandMembers(roomId: string, membershipEvents: IStateEventWithRoomId[]): Promise<void> {
return this.doCmd('setOutOfBandMembers', [roomId, membershipEvents]); 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. * 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[]> { public getUserPresenceEvents(): Promise<UserTuple[]> {
return this.doCmd('getUserPresenceEvents'); return this.doCmd('getUserPresenceEvents');

View File

@ -27,12 +27,14 @@ interface ICmd {
* This class lives in the webworker and drives a LocalIndexedDBStoreBackend * This class lives in the webworker and drives a LocalIndexedDBStoreBackend
* controlled by messages from the main process. * controlled by messages from the main process.
* *
* @example
* It should be instantiated by a web worker script provided by the application * It should be instantiated by a web worker script provided by the application
* in a script, for example: * in a script, for example:
* * ```
* import {IndexedDBStoreWorker} from 'matrix-js-sdk/lib/indexeddb-worker.js'; * import {IndexedDBStoreWorker} from 'matrix-js-sdk/lib/indexeddb-worker.js';
* const remoteWorker = new IndexedDBStoreWorker(postMessage); * const remoteWorker = new IndexedDBStoreWorker(postMessage);
* onmessage = remoteWorker.onMessage; * onmessage = remoteWorker.onMessage;
* ```
* *
* Note that it is advisable to import this class by referencing the file directly to * Note that it is advisable to import this class by referencing the file directly to
* avoid a dependency on the whole js-sdk. * avoid a dependency on the whole js-sdk.
@ -42,7 +44,7 @@ export class IndexedDBStoreWorker {
private backend?: LocalIndexedDBStoreBackend; 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. * should be used to communicate back to the main script.
*/ */
public constructor(private readonly postMessage: InstanceType<typeof Worker>["postMessage"]) {} 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 * Passes a message event from the main script into the class. This method
* can be directly assigned to the web worker `onmessage` variable. * 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 => { public onMessage = (ev: MessageEvent): void => {
const msg: ICmd = ev.data; const msg: ICmd = ev.data;

View File

@ -32,7 +32,6 @@ import { IStoredClientOpts } from "../client";
/** /**
* This is an internal module. See {@link IndexedDBStore} for the public class. * 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 // 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 const WRITE_DELAY_MS = 1000 * 60 * 5; // once every 5 minutes
interface IOpts extends IBaseOpts { interface IOpts extends IBaseOpts {
/** The Indexed DB interface e.g. `window.indexedDB` */
indexedDB: IDBFactory; indexedDB: IDBFactory;
/** Optional database name. The same name must be used to open the same database. */
dbName?: string; dbName?: string;
/** Optional factory to spin up a Worker to execute the IDB transactions within. */
workerFactory?: () => Worker; workerFactory?: () => Worker;
} }
@ -57,6 +59,10 @@ export class IndexedDBStore extends MemoryStore {
return LocalIndexedDBStoreBackend.exists(indexedDB, dbName); 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; public readonly backend: IIndexedDBBackend;
private startedUp = false; private startedUp = false;
@ -74,10 +80,10 @@ export class IndexedDBStore extends MemoryStore {
* the contents of the store to an IndexedDB backend. * the contents of the store to an IndexedDB backend.
* *
* All data is still kept in-memory but can be loaded from disk by calling * 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 * 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. * the data is eagerly fetched when `startup()` is called.
* <pre> * ```
* let opts = { indexedDB: window.indexedDB, localStorage: window.localStorage }; * let opts = { indexedDB: window.indexedDB, localStorage: window.localStorage };
* let store = new IndexedDBStore(opts); * let store = new IndexedDBStore(opts);
* await store.startup(); // load from indexed db * 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!"); * console.log("Started up, now with go faster stripes!");
* } * }
* }); * });
* </pre> * ```
* *
* @constructor * @param opts - Options object.
* @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.
*/ */
public constructor(opts: IOpts) { public constructor(opts: IOpts) {
super(opts); super(opts);
@ -126,7 +117,7 @@ export class IndexedDBStore extends MemoryStore {
public on = this.emitter.on.bind(this.emitter); 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> { public startup(): Promise<void> {
if (this.startedUp) { 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 * client state to where it was at the last save, or null if there
* is no saved sync data. * is no saved sync data.
*/ */
@ -160,13 +151,13 @@ export class IndexedDBStore extends MemoryStore {
return this.backend.getSavedSync(); return this.backend.getSavedSync();
}, "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> => { public isNewlyCreated = this.degradable((): Promise<boolean> => {
return this.backend.isNewlyCreated(); return this.backend.isNewlyCreated();
}, "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. * for this sync, otherwise null.
*/ */
public getSavedSyncToken = this.degradable((): Promise<string | null> => { public getSavedSyncToken = this.degradable((): Promise<string | null> => {
@ -175,7 +166,7 @@ export class IndexedDBStore extends MemoryStore {
/** /**
* Delete all data from this store. * 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> => { public deleteAllData = this.degradable((): Promise<void> => {
super.deleteAllData(); super.deleteAllData();
@ -193,7 +184,7 @@ export class IndexedDBStore extends MemoryStore {
* not could change between calling this function and calling * not could change between calling this function and calling
* save(). * 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). * (at the time this function is called).
*/ */
public wantsSave(): boolean { public wantsSave(): boolean {
@ -204,8 +195,8 @@ export class IndexedDBStore extends MemoryStore {
/** /**
* Possibly write data to the database. * Possibly write data to the database.
* *
* @param {boolean} force True to force a save to happen * @param force - True to force a save to happen
* @return {Promise} Promise resolves after the write completes * @returns Promise resolves after the write completes
* (or immediately if no write is performed) * (or immediately if no write is performed)
*/ */
public save(force = false): Promise<void> { 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 * Returns the out-of-band membership events for this room that
* were previously loaded. * were previously loaded.
* @param {string} roomId * @returns the events, potentially an empty array if OOB loading didn't yield any new members
* @returns {event[]} 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
* @returns {null} in case the members for this room haven't been stored yet
*/ */
public getOutOfBandMembers = this.degradable((roomId: string): Promise<IStateEventWithRoomId[] | null> => { public getOutOfBandMembers = this.degradable((roomId: string): Promise<IStateEventWithRoomId[] | null> => {
return this.backend.getOutOfBandMembers(roomId); 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 * 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 * 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 * marked as fetched, and getOutOfBandMembers will return an empty array instead of null
* @param {string} roomId * @param membershipEvents - the membership events to store
* @param {event[]} membershipEvents the membership events to store * @returns when all members have been stored
* @returns {Promise} when all members have been stored
*/ */
public setOutOfBandMembers = this.degradable( public setOutOfBandMembers = this.degradable(
(roomId: string, membershipEvents: IStateEventWithRoomId[]): Promise<void> => { (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` * 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. * in place so that the current operation and all future ones are in-memory only.
* *
* @param {Function} func The degradable work to do. * @param func - The degradable work to do.
* @param {String} fallback The method name for fallback. * @param fallback - The method name for fallback.
* @returns {Function} A wrapped member function. * @returns A wrapped member function.
*/ */
private degradable<A extends Array<any>, R = void>( private degradable<A extends Array<any>, R = void>(
func: DegradableFn<A, R>, func: DegradableFn<A, R>,
@ -368,8 +357,8 @@ export class IndexedDBStore extends MemoryStore {
} }
/** /**
* @param {string} roomId ID of the current room * @param roomId - ID of the current room
* @returns {string} Storage key to retrieve pending events * @returns Storage key to retrieve pending events
*/ */
function pendingEventsKey(roomId: string): string { function pendingEventsKey(roomId: string): string {
return `mx_pending_events_${roomId}`; return `mx_pending_events_${roomId}`;

View File

@ -16,7 +16,6 @@ limitations under the License.
/** /**
* This is an internal module. See {@link MemoryStore} for the public class. * This is an internal module. See {@link MemoryStore} for the public class.
* @module store/memory
*/ */
import { EventType } from "../@types/event"; import { EventType } from "../@types/event";
@ -43,16 +42,10 @@ function isValidFilterId(filterId?: string | number | null): boolean {
} }
export interface IOpts { export interface IOpts {
/** The local storage instance to persist some forms of data such as tokens. Rooms will NOT be stored. */
localStorage?: Storage; 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 { export class MemoryStore implements IStore {
private rooms: Record<string, Room> = {}; // roomId: Room private rooms: Record<string, Room> = {}; // roomId: Room
private users: Record<string, User> = {}; // userId: User private users: Record<string, User> = {}; // userId: User
@ -69,26 +62,30 @@ export class MemoryStore implements IStore {
private pendingToDeviceBatches: IndexedToDeviceBatch[] = []; private pendingToDeviceBatches: IndexedToDeviceBatch[] = [];
private nextToDeviceBatchId = 0; private nextToDeviceBatchId = 0;
/**
* Construct a new in-memory data store for the Matrix Client.
* @param opts - Config options
*/
public constructor(opts: IOpts = {}) { public constructor(opts: IOpts = {}) {
this.localStorage = opts.localStorage; this.localStorage = opts.localStorage;
} }
/** /**
* Retrieve the token to stream from. * Retrieve the token to stream from.
* @return {string} The token or null. * @returns The token or null.
*/ */
public getSyncToken(): string | null { public getSyncToken(): string | null {
return this.syncToken; 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> { public isNewlyCreated(): Promise<boolean> {
return Promise.resolve(true); return Promise.resolve(true);
} }
/** /**
* Set the token to stream from. * 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 { public setSyncToken(token: string): void {
this.syncToken = token; this.syncToken = token;
@ -96,7 +93,7 @@ export class MemoryStore implements IStore {
/** /**
* Store the given room. * 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 { public storeRoom(room: Room): void {
this.rooms[room.roomId] = room; 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 * Called when a room member in a room being tracked by this store has been
* updated. * updated.
* @param {MatrixEvent} event
* @param {RoomState} state
* @param {RoomMember} member
*/ */
private onRoomMember = (event: MatrixEvent | null, state: RoomState, member: RoomMember): void => { private onRoomMember = (event: MatrixEvent | null, state: RoomState, member: RoomMember): void => {
if (member.membership === "invite") { if (member.membership === "invite") {
@ -138,8 +132,8 @@ export class MemoryStore implements IStore {
/** /**
* Retrieve a room by its' room ID. * Retrieve a room by its' room ID.
* @param {string} roomId The room ID. * @param roomId - The room ID.
* @return {Room} The room or null. * @returns The room or null.
*/ */
public getRoom(roomId: string): Room | null { public getRoom(roomId: string): Room | null {
return this.rooms[roomId] || null; return this.rooms[roomId] || null;
@ -147,7 +141,7 @@ export class MemoryStore implements IStore {
/** /**
* Retrieve all known rooms. * 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[] { public getRooms(): Room[] {
return Object.values(this.rooms); return Object.values(this.rooms);
@ -155,7 +149,6 @@ export class MemoryStore implements IStore {
/** /**
* Permanently delete a room. * Permanently delete a room.
* @param {string} roomId
*/ */
public removeRoom(roomId: string): void { public removeRoom(roomId: string): void {
if (this.rooms[roomId]) { if (this.rooms[roomId]) {
@ -166,7 +159,7 @@ export class MemoryStore implements IStore {
/** /**
* Retrieve a summary of all the rooms. * Retrieve a summary of all the rooms.
* @return {RoomSummary[]} A summary of each room. * @returns A summary of each room.
*/ */
public getRoomSummaries(): RoomSummary[] { public getRoomSummaries(): RoomSummary[] {
return Object.values(this.rooms).map(function(room) { return Object.values(this.rooms).map(function(room) {
@ -176,7 +169,7 @@ export class MemoryStore implements IStore {
/** /**
* Store a User. * Store a User.
* @param {User} user The user to store. * @param user - The user to store.
*/ */
public storeUser(user: User): void { public storeUser(user: User): void {
this.users[user.userId] = user; this.users[user.userId] = user;
@ -184,8 +177,8 @@ export class MemoryStore implements IStore {
/** /**
* Retrieve a User by its' user ID. * Retrieve a User by its' user ID.
* @param {string} userId The user ID. * @param userId - The user ID.
* @return {User} The user or null. * @returns The user or null.
*/ */
public getUser(userId: string): User | null { public getUser(userId: string): User | null {
return this.users[userId] || null; return this.users[userId] || null;
@ -193,7 +186,7 @@ export class MemoryStore implements IStore {
/** /**
* Retrieve all known users. * 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[] { public getUsers(): User[] {
return Object.values(this.users); return Object.values(this.users);
@ -201,9 +194,9 @@ export class MemoryStore implements IStore {
/** /**
* Retrieve scrollback for this room. * Retrieve scrollback for this room.
* @param {Room} room The matrix room * @param room - The matrix room
* @param {number} limit The max number of old events to retrieve. * @param limit - The max number of old events to retrieve.
* @return {Array<Object>} An array of objects which will be at most 'limit' * @returns An array of objects which will be at most 'limit'
* length and at least 0. The objects are the raw event JSON. * length and at least 0. The objects are the raw event JSON.
*/ */
public scrollback(room: Room, limit: number): MatrixEvent[] { 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 * Store events for a room. The events have already been added to the timeline
* @param {Room} room The room to store events for. * @param room - The room to store events for.
* @param {Array<MatrixEvent>} events The events to store. * @param events - The events to store.
* @param {string} token The token associated with these events. * @param token - The token associated with these events.
* @param {boolean} toStart True if these are paginated results. * @param toStart - True if these are paginated results.
*/ */
public storeEvents(room: Room, events: MatrixEvent[], token: string | null, toStart: boolean): void { public storeEvents(room: Room, events: MatrixEvent[], token: string | null, toStart: boolean): void {
// no-op because they've already been added to the room instance. // no-op because they've already been added to the room instance.
@ -223,7 +216,6 @@ export class MemoryStore implements IStore {
/** /**
* Store a filter. * Store a filter.
* @param {Filter} filter
*/ */
public storeFilter(filter: Filter): void { public storeFilter(filter: Filter): void {
if (!filter?.userId || !filter?.filterId) return; if (!filter?.userId || !filter?.filterId) return;
@ -235,9 +227,7 @@ export class MemoryStore implements IStore {
/** /**
* Retrieve a filter. * Retrieve a filter.
* @param {string} userId * @returns A filter or null.
* @param {string} filterId
* @return {?Filter} A filter or null.
*/ */
public getFilter(userId: string, filterId: string): Filter | null { public getFilter(userId: string, filterId: string): Filter | null {
if (!this.filters[userId] || !this.filters[userId][filterId]) { 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. * Retrieve a filter ID with the given name.
* @param {string} filterName The filter name. * @param filterName - The filter name.
* @return {?string} The filter ID or null. * @returns The filter ID or null.
*/ */
public getFilterIdByName(filterName: string): string | null { public getFilterIdByName(filterName: string): string | null {
if (!this.localStorage) { if (!this.localStorage) {
@ -272,8 +262,6 @@ export class MemoryStore implements IStore {
/** /**
* Set a filter name to ID mapping. * Set a filter name to ID mapping.
* @param {string} filterName
* @param {string} filterId
*/ */
public setFilterIdByName(filterName: string, filterId?: string): void { public setFilterIdByName(filterName: string, filterId?: string): void {
if (!this.localStorage) { if (!this.localStorage) {
@ -293,7 +281,7 @@ export class MemoryStore implements IStore {
* Store user-scoped account data events. * Store user-scoped account data events.
* N.B. that account data only allows a single event per type, so multiple * N.B. that account data only allows a single event per type, so multiple
* events with the same type will replace each other. * 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 { public storeAccountDataEvents(events: MatrixEvent[]): void {
events.forEach((event) => { events.forEach((event) => {
@ -303,8 +291,8 @@ export class MemoryStore implements IStore {
/** /**
* Get account data event by event type * Get account data event by event type
* @param {string} eventType The event type being queried * @param eventType - The event type being queried
* @return {?MatrixEvent} the user account_data event of given type, if any * @returns the user account_data event of given type, if any
*/ */
public getAccountData(eventType: EventType | string): MatrixEvent | undefined { public getAccountData(eventType: EventType | string): MatrixEvent | undefined {
return this.accountData[eventType]; return this.accountData[eventType];
@ -313,8 +301,8 @@ export class MemoryStore implements IStore {
/** /**
* setSyncData does nothing as there is no backing data store. * setSyncData does nothing as there is no backing data store.
* *
* @param {Object} syncData The sync data * @param syncData - The sync data
* @return {Promise} An immediately resolved promise. * @returns An immediately resolved promise.
*/ */
public setSyncData(syncData: ISyncResponse): Promise<void> { public setSyncData(syncData: ISyncResponse): Promise<void> {
return Promise.resolve(); return Promise.resolve();
@ -323,7 +311,7 @@ export class MemoryStore implements IStore {
/** /**
* We never want to save becase we have nothing to save to. * 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 { public wantsSave(): boolean {
return false; return false;
@ -331,21 +319,21 @@ export class MemoryStore implements IStore {
/** /**
* Save does nothing as there is no backing data store. * 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) * store still can't save anything)
*/ */
public save(force: boolean): void {} public save(force: boolean): void {}
/** /**
* Startup does nothing as this store doesn't require starting up. * 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> { public startup(): Promise<void> {
return Promise.resolve(); 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 * client state to where it was at the last save, or null if there
* is no saved sync data. * 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. * for this sync, otherwise null.
*/ */
public getSavedSyncToken(): Promise<string | null> { public getSavedSyncToken(): Promise<string | null> {
@ -363,7 +351,7 @@ export class MemoryStore implements IStore {
/** /**
* Delete all data from this store. * Delete all data from this store.
* @return {Promise} An immediately resolved promise. * @returns An immediately resolved promise.
*/ */
public deleteAllData(): Promise<void> { public deleteAllData(): Promise<void> {
this.rooms = { this.rooms = {
@ -387,9 +375,8 @@ export class MemoryStore implements IStore {
/** /**
* Returns the out-of-band membership events for this room that * Returns the out-of-band membership events for this room that
* were previously loaded. * were previously loaded.
* @param {string} roomId * @returns the events, potentially an empty array if OOB loading didn't yield any new members
* @returns {event[]} 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
* @returns {null} in case the members for this room haven't been stored yet
*/ */
public getOutOfBandMembers(roomId: string): Promise<IStateEventWithRoomId[] | null> { public getOutOfBandMembers(roomId: string): Promise<IStateEventWithRoomId[] | null> {
return Promise.resolve(this.oobMembers[roomId] || 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 * 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 * 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 * marked as fetched, and getOutOfBandMembers will return an empty array instead of null
* @param {string} roomId * @param membershipEvents - the membership events to store
* @param {event[]} membershipEvents the membership events to store * @returns when all members have been stored
* @returns {Promise} when all members have been stored
*/ */
public setOutOfBandMembers(roomId: string, membershipEvents: IStateEventWithRoomId[]): Promise<void> { public setOutOfBandMembers(roomId: string, membershipEvents: IStateEventWithRoomId[]): Promise<void> {
this.oobMembers[roomId] = membershipEvents; this.oobMembers[roomId] = membershipEvents;

View File

@ -16,7 +16,6 @@ limitations under the License.
/** /**
* This is an internal module. * This is an internal module.
* @module store/stub
*/ */
import { EventType } from "../@types/event"; 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. * Construct a stub store. This does no-ops on most store methods.
* @constructor
*/ */
export class StubStore implements IStore { export class StubStore implements IStore {
public readonly accountData = {}; // stub public readonly accountData = {}; // stub
private fromToken: string | null = null; 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> { public isNewlyCreated(): Promise<boolean> {
return Promise.resolve(true); return Promise.resolve(true);
} }
/** /**
* Get the sync token. * Get the sync token.
* @return {string}
*/ */
public getSyncToken(): string | null { public getSyncToken(): string | null {
return this.fromToken; return this.fromToken;
@ -54,7 +51,6 @@ export class StubStore implements IStore {
/** /**
* Set the sync token. * Set the sync token.
* @param {string} token
*/ */
public setSyncToken(token: string): void { public setSyncToken(token: string): void {
this.fromToken = token; this.fromToken = token;
@ -62,14 +58,11 @@ export class StubStore implements IStore {
/** /**
* No-op. * No-op.
* @param {Room} room
*/ */
public storeRoom(room: Room): void {} public storeRoom(room: Room): void {}
/** /**
* No-op. * No-op.
* @param {string} roomId
* @return {null}
*/ */
public getRoom(roomId: string): Room | null { public getRoom(roomId: string): Room | null {
return null; return null;
@ -77,7 +70,7 @@ export class StubStore implements IStore {
/** /**
* No-op. * No-op.
* @return {Array} An empty array. * @returns An empty array.
*/ */
public getRooms(): Room[] { public getRooms(): Room[] {
return []; return [];
@ -85,7 +78,6 @@ export class StubStore implements IStore {
/** /**
* Permanently delete a room. * Permanently delete a room.
* @param {string} roomId
*/ */
public removeRoom(roomId: string): void { public removeRoom(roomId: string): void {
return; return;
@ -93,7 +85,7 @@ export class StubStore implements IStore {
/** /**
* No-op. * No-op.
* @return {Array} An empty array. * @returns An empty array.
*/ */
public getRoomSummaries(): RoomSummary[] { public getRoomSummaries(): RoomSummary[] {
return []; return [];
@ -101,14 +93,11 @@ export class StubStore implements IStore {
/** /**
* No-op. * No-op.
* @param {User} user
*/ */
public storeUser(user: User): void {} public storeUser(user: User): void {}
/** /**
* No-op. * No-op.
* @param {string} userId
* @return {null}
*/ */
public getUser(userId: string): User | null { public getUser(userId: string): User | null {
return null; return null;
@ -116,7 +105,6 @@ export class StubStore implements IStore {
/** /**
* No-op. * No-op.
* @return {User[]}
*/ */
public getUsers(): User[] { public getUsers(): User[] {
return []; return [];
@ -124,9 +112,6 @@ export class StubStore implements IStore {
/** /**
* No-op. * No-op.
* @param {Room} room
* @param {number} limit
* @return {Array}
*/ */
public scrollback(room: Room, limit: number): MatrixEvent[] { public scrollback(room: Room, limit: number): MatrixEvent[] {
return []; return [];
@ -134,24 +119,21 @@ export class StubStore implements IStore {
/** /**
* Store events for a room. * Store events for a room.
* @param {Room} room The room to store events for. * @param room - The room to store events for.
* @param {Array<MatrixEvent>} events The events to store. * @param events - The events to store.
* @param {string} token The token associated with these events. * @param token - The token associated with these events.
* @param {boolean} toStart True if these are paginated results. * @param toStart - True if these are paginated results.
*/ */
public storeEvents(room: Room, events: MatrixEvent[], token: string | null, toStart: boolean): void {} public storeEvents(room: Room, events: MatrixEvent[], token: string | null, toStart: boolean): void {}
/** /**
* Store a filter. * Store a filter.
* @param {Filter} filter
*/ */
public storeFilter(filter: Filter): void {} public storeFilter(filter: Filter): void {}
/** /**
* Retrieve a filter. * Retrieve a filter.
* @param {string} userId * @returns A filter or null.
* @param {string} filterId
* @return {?Filter} A filter or null.
*/ */
public getFilter(userId: string, filterId: string): Filter | null { public getFilter(userId: string, filterId: string): Filter | null {
return null; return null;
@ -159,8 +141,8 @@ export class StubStore implements IStore {
/** /**
* Retrieve a filter ID with the given name. * Retrieve a filter ID with the given name.
* @param {string} filterName The filter name. * @param filterName - The filter name.
* @return {?string} The filter ID or null. * @returns The filter ID or null.
*/ */
public getFilterIdByName(filterName: string): string | null { public getFilterIdByName(filterName: string): string | null {
return null; return null;
@ -168,20 +150,18 @@ export class StubStore implements IStore {
/** /**
* Set a filter name to ID mapping. * Set a filter name to ID mapping.
* @param {string} filterName
* @param {string} filterId
*/ */
public setFilterIdByName(filterName: string, filterId?: string): void {} public setFilterIdByName(filterName: string, filterId?: string): void {}
/** /**
* Store user-scoped account data events * 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 {} public storeAccountDataEvents(events: MatrixEvent[]): void {}
/** /**
* Get account data event by event type * 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 { public getAccountData(eventType: EventType | string): MatrixEvent | undefined {
return undefined; return undefined;
@ -190,8 +170,8 @@ export class StubStore implements IStore {
/** /**
* setSyncData does nothing as there is no backing data store. * setSyncData does nothing as there is no backing data store.
* *
* @param {Object} syncData The sync data * @param syncData - The sync data
* @return {Promise} An immediately resolved promise. * @returns An immediately resolved promise.
*/ */
public setSyncData(syncData: ISyncResponse): Promise<void> { public setSyncData(syncData: ISyncResponse): Promise<void> {
return Promise.resolve(); return Promise.resolve();
@ -200,7 +180,7 @@ export class StubStore implements IStore {
/** /**
* We never want to save because we have nothing to save to. * 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 { public wantsSave(): boolean {
return false; return false;
@ -213,14 +193,14 @@ export class StubStore implements IStore {
/** /**
* Startup does nothing. * Startup does nothing.
* @return {Promise} An immediately resolved promise. * @returns An immediately resolved promise.
*/ */
public startup(): Promise<void> { public startup(): Promise<void> {
return Promise.resolve(); 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 * client state to where it was at the last save, or null if there
* is no saved sync data. * 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. * for this sync, otherwise null.
*/ */
public getSavedSyncToken(): Promise<string | 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 * Delete all data from this store. Does nothing since this store
* doesn't store anything. * doesn't store anything.
* @return {Promise} An immediately resolved promise. * @returns An immediately resolved promise.
*/ */
public deleteAllData(): Promise<void> { public deleteAllData(): Promise<void> {
return Promise.resolve(); return Promise.resolve();

Some files were not shown because too many files have changed in this diff Show More