1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-07-30 04:23:07 +03:00

Improve tsdoc types (#2940)

* Install eslint-plugin-jsdoc

* Enable lint rule jsdoc/no-types

* Make tsdoc more valid, add required hyphens and s/return/returns/g

* Stash tsdoc work

* Fix mistypes

* Stash

* Stash

* More tsdoc work

* Remove useless doc params

* Fixup docs

* Apply suggestions from code review

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>

* Update src/crypto/verification/request/ToDeviceChannel.ts

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>

* Update src/client.ts

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>

* Update src/client.ts

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>

* Update src/client.ts

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>

* Iterate

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
This commit is contained in:
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: [
"matrix-org",
"import",
"jsdoc",
],
extends: [
"plugin:matrix-org/babel",
@ -45,7 +46,7 @@ module.exports = {
// restrict EventEmitters to force callers to use TypedEventEmitter
"no-restricted-imports": ["error", {
name: "events",
message: "Please use TypedEventEmitter instead"
message: "Please use TypedEventEmitter instead",
}],
"import/no-restricted-paths": ["error", {
@ -61,6 +62,9 @@ module.exports = {
files: [
"**/*.ts",
],
plugins: [
"eslint-plugin-tsdoc",
],
extends: [
"plugin:matrix-org/typescript",
],
@ -84,6 +88,23 @@ module.exports = {
"quotes": "off",
// We use a `logger` intermediary module
"no-console": "error",
},
}, {
// We don't need amazing docs in our spec files
files: [
"src/**/*.ts",
],
rules: {
"tsdoc/syntax": "error",
// We use some select jsdoc rules as the tsdoc linter has only one rule
"jsdoc/no-types": "error",
"jsdoc/empty-tags": "error",
"jsdoc/check-property-names": "error",
"jsdoc/check-values": "error",
// These need a bit more work before we can enable
// "jsdoc/check-param-names": "error",
// "jsdoc/check-indentation": "error",
},
}, {
files: [

View File

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

View File

@ -105,7 +105,7 @@ export class TestClient {
/**
* stop the client
* @return {Promise} Resolves once the mock http backend has finished all pending flushes
* @returns Promise which resolves once the mock http backend has finished all pending flushes
*/
public async stop(): Promise<void> {
this.client.stopClient();
@ -135,7 +135,7 @@ export class TestClient {
* set up an expectation that the keys will be uploaded, and wait for
* that to happen.
*
* @returns {Promise} for the one-time keys
* @returns Promise for the one-time keys
*/
public awaitOneTimeKeyUpload(): Promise<Record<string, IOneTimeKey>> {
if (Object.keys(this.oneTimeKeys!).length != 0) {
@ -177,7 +177,7 @@ export class TestClient {
*
* We check that the query contains each of the users in `response`.
*
* @param {Object} response response to the query.
* @param response - response to the query.
*/
public expectKeyQuery(response: IDownloadKeyResult) {
this.httpBackend.when('POST', '/keys/query').respond<IDownloadKeyResult>(
@ -202,7 +202,7 @@ export class TestClient {
/**
* get the uploaded curve25519 device key
*
* @return {string} base64 device key
* @returns base64 device key
*/
public getDeviceKey(): string {
const keyId = 'curve25519:' + this.deviceId;
@ -212,7 +212,7 @@ export class TestClient {
/**
* get the uploaded ed25519 device key
*
* @return {string} base64 device key
* @returns base64 device key
*/
public getSigningKey(): string {
const keyId = 'ed25519:' + this.deviceId;

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
* members given
*
* @param {string[]} roomMembers
*
* @return {object} sync response
* @returns sync response
*/
function getSyncResponse(roomMembers: string[]) {
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.
*
* @return {promise} resolves once the http request has completed.
* @returns resolves once the http request has completed.
*/
function expectQueryKeys(querier: TestClient, uploader: TestClient): Promise<number> {
// can't query keys before bob has uploaded them
@ -83,7 +83,7 @@ const expectBobQueryKeys = () => expectQueryKeys(bobTestClient, aliTestClient);
/**
* Set an expectation that ali will claim one of bob's keys; then flush the http request.
*
* @return {promise} resolves once the http request has completed.
* @returns resolves once the http request has completed.
*/
async function expectAliClaimKeys(): Promise<void> {
const keys = await bobTestClient.awaitOneTimeKeyUpload();
@ -151,7 +151,7 @@ const bobEnablesEncryption = () => clientEnablesEncryption(bobTestClient.client)
* Ali sends a message, first claiming e2e keys. Set the expectations and
* check the results.
*
* @return {promise} which resolves to the ciphertext for Bob's device.
* @returns which resolves to the ciphertext for Bob's device.
*/
async function aliSendsFirstMessage(): Promise<OlmPayload> {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
@ -168,7 +168,7 @@ async function aliSendsFirstMessage(): Promise<OlmPayload> {
* Ali sends a message without first claiming e2e keys. Set the expectations
* and check the results.
*
* @return {promise} which resolves to the ciphertext for Bob's device.
* @returns which resolves to the ciphertext for Bob's device.
*/
async function aliSendsMessage(): Promise<OlmPayload> {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
@ -183,7 +183,7 @@ async function aliSendsMessage(): Promise<OlmPayload> {
* Bob sends a message, first querying (but not claiming) e2e keys. Set the
* expectations and check the results.
*
* @return {promise} which resolves to the ciphertext for Ali's device.
* @returns which resolves to the ciphertext for Ali's device.
*/
async function bobSendsReplyMessage(): Promise<OlmPayload> {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
@ -198,7 +198,7 @@ async function bobSendsReplyMessage(): Promise<OlmPayload> {
/**
* Set an expectation that Ali will send a message, and flush the request
*
* @return {promise} which resolves to the ciphertext for Bob's device.
* @returns which resolves to the ciphertext for Bob's device.
*/
async function expectAliSendMessageRequest(): Promise<OlmPayload> {
const content = await expectSendMessageRequest(aliTestClient.httpBackend);
@ -212,7 +212,7 @@ async function expectAliSendMessageRequest(): Promise<OlmPayload> {
/**
* Set an expectation that Bob will send a message, and flush the request
*
* @return {promise} which resolves to the ciphertext for Bob's device.
* @returns which resolves to the ciphertext for Bob's device.
*/
async function expectBobSendMessageRequest(): Promise<OlmPayload> {
const content = await expectSendMessageRequest(bobTestClient.httpBackend);
@ -321,8 +321,7 @@ async function recvMessage(
* Send an initial sync response to the client (which just includes the member
* list for our test room).
*
* @param {TestClient} testClient
* @returns {Promise} which resolves when the sync has been flushed.
* @returns which resolves when the sync has been flushed.
*/
function firstSync(testClient: TestClient): Promise<void> {
// send a sync response including our test room.

View File

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

View File

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

View File

@ -1446,11 +1446,11 @@ function timeout(delayMs: number, reason: string): { promise: Promise<never>, ca
/**
* Listen until a callback returns data.
* @param {EventEmitter} emitter The event emitter
* @param {string} eventName The event to listen for
* @param {function} callback The callback which will be invoked when events fire. Return something truthy from this to resolve the promise.
* @param {number} timeoutMs The number of milliseconds to wait for the callback to return data. Default: 500ms.
* @returns {Promise} A promise which will be resolved when the callback returns data. If the callback throws or the timeout is reached,
* @param emitter - The event emitter
* @param eventName - The event to listen for
* @param callback - The callback which will be invoked when events fire. Return something truthy from this to resolve the promise.
* @param timeoutMs - The number of milliseconds to wait for the callback to return data. Default: 500ms.
* @returns A promise which will be resolved when the callback returns data. If the callback throws or the timeout is reached,
* the promise is rejected.
*/
function listenUntil<T>(

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -54,17 +54,31 @@ export interface ISendEventResponse {
}
export interface IPresenceOpts {
// One of "online", "offline" or "unavailable"
presence: "online" | "offline" | "unavailable";
// The status message to attach.
status_msg?: string;
}
export interface IPaginateOpts {
// true to fill backwards, false to go forwards
backwards?: boolean;
// number of events to request
limit?: number;
}
export interface IGuestAccessOpts {
/**
* True to allow guests to join this room. This
* implicitly gives guests write access. If false or not given, guests are
* explicitly forbidden from joining the room.
*/
allowJoin: boolean;
/**
* True to set history visibility to
* be world_readable. This gives guests read access *from this point forward*.
* If false or not given, history visibility is not modified.
*/
allowRead: boolean;
}
@ -74,7 +88,9 @@ export interface ISearchOpts {
}
export interface IEventSearchOpts {
// a JSON filter object to pass in the request
filter?: IRoomEventFilter;
// the term to search for
term: string;
}
@ -92,9 +108,13 @@ export interface ICreateRoomStateEvent {
}
export interface ICreateRoomOpts {
// The alias localpart to assign to this room.
room_alias_name?: string;
// Either 'public' or 'private'.
visibility?: Visibility;
// The name to give this room.
name?: string;
// The topic to give this room.
topic?: string;
preset?: Preset;
power_level_content_override?: {
@ -111,6 +131,7 @@ export interface ICreateRoomOpts {
};
creation_content?: object;
initial_state?: ICreateRoomStateEvent[];
// A list of user IDs to invite to this room.
invite?: string[];
invite_3pid?: IInvite3PID[];
is_direct?: boolean;
@ -121,7 +142,10 @@ export interface IRoomDirectoryOptions {
server?: string;
limit?: number;
since?: string;
// Filter parameters
filter?: {
// String to search for
generic_search_term?: string;
room_types?: Array<RoomType | null>;
};

View File

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

View File

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

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

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

View File

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

View File

@ -15,8 +15,6 @@ limitations under the License.
*/
/**
* @module crypto/DeviceList
*
* Manages the list of other users' devices
*/
@ -64,9 +62,6 @@ export type DeviceInfoMap = Record<string, Record<string, DeviceInfo>>;
type EmittedEvents = CryptoEvent.WillUpdateDevices | CryptoEvent.DevicesUpdated | CryptoEvent.UserCrossSigningUpdated;
/**
* @alias module:crypto/DeviceList
*/
export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHandlerMap> {
private devices: { [userId: string]: { [deviceId: string]: IDevice } } = {};
@ -163,11 +158,11 @@ export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHand
* The actual save will be delayed by a short amount of time to
* aggregate multiple writes to the database.
*
* @param {number} delay Time in ms before which the save actually happens.
* @param delay - Time in ms before which the save actually happens.
* By default, the save is delayed for a short period in order to batch
* multiple writes, but this behaviour can be disabled by passing 0.
*
* @return {Promise<boolean>} true if the data was saved, false if
* @returns true if the data was saved, false if
* it was not (eg. because no changes were pending). The promise
* will only resolve once the data is saved, so may take some time
* to resolve.
@ -236,7 +231,7 @@ export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHand
/**
* Gets the sync token last set with setSyncToken
*
* @return {string} The sync token
* @returns The sync token
*/
public getSyncToken(): string | null {
return this.syncToken;
@ -250,7 +245,7 @@ export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHand
* those changed will not be synced from the server if a new client starts
* up with that data.
*
* @param {string} st The sync token
* @param st - The sync token
*/
public setSyncToken(st: string | null): void {
this.syncToken = st;
@ -260,11 +255,10 @@ export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHand
* Ensures up to date keys for a list of users are stored in the session store,
* downloading and storing them if they're not (or if forceDownload is
* true).
* @param {Array} userIds The users to fetch.
* @param {boolean} forceDownload Always download the keys even if cached.
* @param userIds - The users to fetch.
* @param forceDownload - Always download the keys even if cached.
*
* @return {Promise} A promise which resolves to a map userId->deviceId->{@link
* module:crypto/deviceinfo|DeviceInfo}.
* @returns A promise which resolves to a map userId-\>deviceId-\>{@link DeviceInfo}.
*/
public downloadKeys(userIds: string[], forceDownload: boolean): Promise<DeviceInfoMap> {
const usersToDownload: string[] = [];
@ -303,9 +297,9 @@ export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHand
/**
* Get the stored device keys for a list of user ids
*
* @param {string[]} userIds the list of users to list keys for.
* @param userIds - the list of users to list keys for.
*
* @return {Object} userId->deviceId->{@link module:crypto/deviceinfo|DeviceInfo}.
* @returns userId-\>deviceId-\>{@link DeviceInfo}.
*/
private getDevicesFromStore(userIds: string[]): DeviceInfoMap {
const stored: DeviceInfoMap = {};
@ -322,7 +316,7 @@ export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHand
/**
* Returns a list of all user IDs the DeviceList knows about
*
* @return {array} All known user IDs
* @returns All known user IDs
*/
public getKnownUserIds(): string[] {
return Object.keys(this.devices);
@ -331,9 +325,9 @@ export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHand
/**
* Get the stored device keys for a user id
*
* @param {string} userId the user to list keys for.
* @param userId - the user to list keys for.
*
* @return {module:crypto/deviceinfo[]|null} list of devices, or null if we haven't
* @returns list of devices, or null if we haven't
* managed to get a list of devices for this user yet.
*/
public getStoredDevicesForUser(userId: string): DeviceInfo[] | null {
@ -353,9 +347,9 @@ export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHand
/**
* Get the stored device data for a user, in raw object form
*
* @param {string} userId the user to get data for
* @param userId - the user to get data for
*
* @return {Object} deviceId->{object} devices, or undefined if
* @returns `deviceId->{object}` devices, or undefined if
* there is no data for this user.
*/
public getRawStoredDevicesForUser(userId: string): Record<string, IDevice> {
@ -376,10 +370,8 @@ export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHand
/**
* Get the stored keys for a single device
*
* @param {string} userId
* @param {string} deviceId
*
* @return {module:crypto/deviceinfo?} device, or undefined
* @returns device, or undefined
* if we don't know about this device
*/
public getStoredDevice(userId: string, deviceId: string): DeviceInfo | undefined {
@ -393,10 +385,10 @@ export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHand
/**
* Get a user ID by one of their device's curve25519 identity key
*
* @param {string} algorithm encryption algorithm
* @param {string} senderKey curve25519 key to match
* @param algorithm - encryption algorithm
* @param senderKey - curve25519 key to match
*
* @return {string} user ID
* @returns user ID
*/
public getUserByIdentityKey(algorithm: string, senderKey: string): string | null {
if (algorithm !== olmlib.OLM_ALGORITHM && algorithm !== olmlib.MEGOLM_ALGORITHM) {
@ -410,10 +402,8 @@ export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHand
/**
* Find a device by curve25519 identity key
*
* @param {string} algorithm encryption algorithm
* @param {string} senderKey curve25519 key to match
*
* @return {module:crypto/deviceinfo?}
* @param algorithm - encryption algorithm
* @param senderKey - curve25519 key to match
*/
public getDeviceByIdentityKey(algorithm: string, senderKey: string): DeviceInfo | null {
const userId = this.getUserByIdentityKey(algorithm, senderKey);
@ -453,8 +443,8 @@ export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHand
/**
* Replaces the list of devices for a user with the given device list
*
* @param {string} userId The user ID
* @param {Object} devices New device info for user
* @param userId - The user ID
* @param devices - New device info for user
*/
public storeDevicesForUser(userId: string, devices: Record<string, IDevice>): void {
this.setRawStoredDevicesForUser(userId, devices);
@ -468,7 +458,6 @@ export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHand
* will download the device list for the user, and that subsequent calls to
* invalidateUserDeviceList will trigger more updates.
*
* @param {String} userId
*/
public startTrackingDeviceList(userId: string): void {
// sanity-check the userId. This is mostly paranoia, but if synapse
@ -497,7 +486,6 @@ export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHand
* complete; it will just mean that we don't think that we have an up-to-date
* list for future calls to downloadKeys.
*
* @param {String} userId
*/
public stopTrackingDeviceList(userId: string): void {
if (this.deviceTrackingStatus[userId]) {
@ -532,7 +520,6 @@ export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHand
* This doesn't actually set off an update, so that several users can be
* batched together. Call refreshOutdatedDeviceLists() for that.
*
* @param {String} userId
*/
public invalidateUserDeviceList(userId: string): void {
if (this.deviceTrackingStatus[userId]) {
@ -548,7 +535,7 @@ export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHand
/**
* If we have users who have outdated device lists, start key downloads for them
*
* @returns {Promise} which completes when the download completes; normally there
* @returns which completes when the download completes; normally there
* is no need to wait for this (it's mostly for the unit tests).
*/
public refreshOutdatedDeviceLists(): Promise<void> {
@ -569,9 +556,9 @@ export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHand
* Set the stored device data for a user, in raw object form
* Used only by internal class DeviceListUpdateSerialiser
*
* @param {string} userId the user to get data for
* @param userId - the user to get data for
*
* @param {Object} devices deviceId->{object} the new devices
* @param devices - `deviceId->{object}` the new devices
*/
public setRawStoredDevicesForUser(userId: string, devices: Record<string, IDevice>): void {
// remove old devices from userByIdentityKey
@ -602,9 +589,9 @@ export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHand
* device list tracking status for them, and the
* keyDownloadsInProgressByUser map for them.
*
* @param {String[]} users list of userIds
* @param users - list of userIds
*
* @return {Promise} resolves when all the users listed have
* @returns resolves when all the users listed have
* been updated. rejects if there was a problem updating any of the
* users.
*/
@ -689,9 +676,9 @@ class DeviceListUpdateSerialiser {
private syncToken?: string; // The sync token we send with the requests
/*
* @param {object} baseApis Base API object
* @param {object} olmDevice The Olm Device
* @param {object} deviceList The device list object, the device list to be updated
* @param baseApis - Base API object
* @param olmDevice - The Olm Device
* @param deviceList - The device list object, the device list to be updated
*/
public constructor(
private readonly baseApis: MatrixClient,
@ -702,12 +689,12 @@ class DeviceListUpdateSerialiser {
/**
* Make a key query request for the given users
*
* @param {String[]} users list of user ids
* @param users - list of user ids
*
* @param {String} syncToken sync token to pass in the query request, to
* @param syncToken - sync token to pass in the query request, to
* help the HS give the most recent results
*
* @return {Promise} resolves when all the users listed have
* @returns resolves when all the users listed have
* been updated. rejects if there was a problem updating any of the
* users.
*/

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -16,8 +16,6 @@ limitations under the License.
/**
* Defines m.olm encryption/decryption
*
* @module crypto/algorithms/megolm
*/
import { v4 as uuidv4 } from "uuid";
@ -123,37 +121,27 @@ interface SharedWithData {
}
/**
* @private
* @constructor
*
* @param {string} sessionId
* @param {boolean} sharedHistory whether the session can be freely shared with
* other group members, according to the room history visibility settings
*
* @property {string} sessionId
* @property {Number} useCount number of times this session has been used
* @property {Number} creationTime when the session was created (ms since the epoch)
*
* @property {object} sharedWithDevices
* devices with which we have shared the session key
* userId -> {deviceId -> SharedWithData}
* @internal
*/
class OutboundSessionInfo {
/** number of times this session has been used */
public useCount = 0;
/** when the session was created (ms since the epoch) */
public creationTime: number;
/** devices with which we have shared the session key `userId -> {deviceId -> SharedWithData}` */
public sharedWithDevices: Record<string, Record<string, SharedWithData>> = {};
public blockedDevicesNotified: Record<string, Record<string, boolean>> = {};
/**
* @param sharedHistory - whether the session can be freely shared with
* other group members, according to the room history visibility settings
*/
public constructor(public readonly sessionId: string, public readonly sharedHistory = false) {
this.creationTime = new Date().getTime();
}
/**
* Check if it's time to rotate the session
*
* @param {Number} rotationPeriodMsgs
* @param {Number} rotationPeriodMs
* @return {Boolean}
*/
public needsRotation(rotationPeriodMsgs: number, rotationPeriodMs: number): boolean {
const sessionLifetime = new Date().getTime() - this.creationTime;
@ -189,10 +177,10 @@ class OutboundSessionInfo {
* Determine if this session has been shared with devices which it shouldn't
* have been.
*
* @param {Object} devicesInRoom userId -> {deviceId -> object}
* @param devicesInRoom - `userId -> {deviceId -> object}`
* devices we should shared the session with.
*
* @return {Boolean} true if we have shared the session with devices which aren't
* @returns true if we have shared the session with devices which aren't
* in devicesInRoom.
*/
public sharedWithTooManyDevices(devicesInRoom: Record<string, Record<string, object>>): boolean {
@ -228,11 +216,7 @@ class OutboundSessionInfo {
/**
* Megolm encryption implementation
*
* @constructor
* @extends {module:crypto/algorithms/EncryptionAlgorithm}
*
* @param {object} params parameters, as per
* {@link module:crypto/algorithms/EncryptionAlgorithm}
* @param params - parameters, as per {@link EncryptionAlgorithm}
*/
export class MegolmEncryption extends EncryptionAlgorithm {
// the most recent attempt to set up a session. This is used to serialise
@ -265,15 +249,14 @@ export class MegolmEncryption extends EncryptionAlgorithm {
}
/**
* @private
* @internal
*
* @param {module:models/room} room
* @param {Object} devicesInRoom The devices in this room, indexed by user ID
* @param {Object} blocked The devices that are blocked, indexed by user ID
* @param {boolean} [singleOlmCreationPhase] Only perform one round of olm
* @param devicesInRoom - The devices in this room, indexed by user ID
* @param blocked - The devices that are blocked, indexed by user ID
* @param singleOlmCreationPhase - Only perform one round of olm
* session creation
*
* @return {Promise} Promise which resolves to the
* @returns Promise which resolves to the
* OutboundSessionInfo when setup is complete.
*/
private async ensureOutboundSession(
@ -488,11 +471,10 @@ export class MegolmEncryption extends EncryptionAlgorithm {
}
/**
* @private
* @internal
*
* @param {boolean} sharedHistory
*
* @return {module:crypto/algorithms/megolm.OutboundSessionInfo} session
* @returns session
*/
private async prepareNewSession(sharedHistory: boolean): Promise<OutboundSessionInfo> {
const sessionId = this.olmDevice.createOutboundGroupSession();
@ -514,15 +496,15 @@ export class MegolmEncryption extends EncryptionAlgorithm {
* Determines what devices in devicesByUser don't have an olm session as given
* in devicemap.
*
* @private
* @internal
*
* @param {object} devicemap the devices that have olm sessions, as returned by
* @param devicemap - the devices that have olm sessions, as returned by
* olmlib.ensureOlmSessionsForDevices.
* @param {object} devicesByUser a map of user IDs to array of deviceInfo
* @param {array} [noOlmDevices] an array to fill with devices that don't have
* @param devicesByUser - a map of user IDs to array of deviceInfo
* @param noOlmDevices - an array to fill with devices that don't have
* olm sessions
*
* @return {array} an array of devices that don't have olm sessions. If
* @returns an array of devices that don't have olm sessions. If
* noOlmDevices is specified, then noOlmDevices will be returned.
*/
private getDevicesWithoutSessions(
@ -558,11 +540,11 @@ export class MegolmEncryption extends EncryptionAlgorithm {
* Splits the user device map into multiple chunks to reduce the number of
* devices we encrypt to per API call.
*
* @private
* @internal
*
* @param {object} devicesByUser map from userid to list of devices
* @param devicesByUser - map from userid to list of devices
*
* @return {array<array<object>>} the blocked devices, split into chunks
* @returns the blocked devices, split into chunks
*/
private splitDevices<T extends DeviceInfo | IBlockedDevice>(
devicesByUser: Record<string, Record<string, { device: T }>>,
@ -599,18 +581,16 @@ export class MegolmEncryption extends EncryptionAlgorithm {
}
/**
* @private
* @internal
*
* @param {module:crypto/algorithms/megolm.OutboundSessionInfo} session
*
* @param {number} chainIndex current chain index
* @param chainIndex - current chain index
*
* @param {object<userId, deviceInfo>} userDeviceMap
* mapping from userId to deviceInfo
* @param userDeviceMap - mapping from userId to deviceInfo
*
* @param {object} payload fields to include in the encrypted payload
* @param payload - fields to include in the encrypted payload
*
* @return {Promise} Promise which resolves once the key sharing
* @returns Promise which resolves once the key sharing
* for the given userDeviceMap is generated and has been sent.
*/
private encryptAndSendKeysToDevices(
@ -639,15 +619,14 @@ export class MegolmEncryption extends EncryptionAlgorithm {
}
/**
* @private
* @internal
*
* @param {module:crypto/algorithms/megolm.OutboundSessionInfo} session
*
* @param {array<object>} userDeviceMap list of blocked devices to notify
* @param userDeviceMap - list of blocked devices to notify
*
* @param {object} payload fields to include in the notification payload
* @param payload - fields to include in the notification payload
*
* @return {Promise} Promise which resolves once the notifications
* @returns Promise which resolves once the notifications
* for the given userDeviceMap is generated and has been sent.
*/
private async sendBlockedNotificationsToDevices(
@ -695,10 +674,10 @@ export class MegolmEncryption extends EncryptionAlgorithm {
* Re-shares a megolm session key with devices if the key has already been
* sent to them.
*
* @param {string} senderKey The key of the originating device for the session
* @param {string} sessionId ID of the outbound session to share
* @param {string} userId ID of the user who owns the target device
* @param {module:crypto/deviceinfo} device The target device
* @param senderKey - The key of the originating device for the session
* @param sessionId - ID of the outbound session to share
* @param userId - ID of the user who owns the target device
* @param device - The target device
*/
public async reshareKeyWithDevice(
senderKey: string,
@ -792,26 +771,23 @@ export class MegolmEncryption extends EncryptionAlgorithm {
}
/**
* @private
* @internal
*
* @param {module:crypto/algorithms/megolm.OutboundSessionInfo} session
*
* @param {object} key the session key as returned by
* @param key - the session key as returned by
* OlmDevice.getOutboundGroupSessionKey
*
* @param {object} payload the base to-device message payload for sharing keys
* @param payload - the base to-device message payload for sharing keys
*
* @param {object<string, module:crypto/deviceinfo[]>} devicesByUser
* map from userid to list of devices
* @param devicesByUser - map from userid to list of devices
*
* @param {array<object>} errorDevices
* array that will be populated with the devices that we can't get an
* @param errorDevices - array that will be populated with the devices that we can't get an
* olm session for
*
* @param {Number} [otkTimeout] The timeout in milliseconds when requesting
* @param otkTimeout - The timeout in milliseconds when requesting
* one-time keys for establishing new olm sessions.
*
* @param {Array} [failedServers] An array to fill with remote servers that
* @param failedServers - An array to fill with remote servers that
* failed to respond to one-time-key requests.
*/
private async shareKeyWithDevices(
@ -866,11 +842,9 @@ export class MegolmEncryption extends EncryptionAlgorithm {
/**
* Notify devices that we weren't able to create olm sessions.
*
* @param {module:crypto/algorithms/megolm.OutboundSessionInfo} session
*
* @param {object} key
*
* @param {Array<object>} failedDevices the devices that we were unable to
* @param failedDevices - the devices that we were unable to
* create olm sessions for, as returned by shareKeyWithDevices
*/
private async notifyFailedOlmDevices(
@ -927,10 +901,8 @@ export class MegolmEncryption extends EncryptionAlgorithm {
/**
* Notify blocked devices that they have been blocked.
*
* @param {module:crypto/algorithms/megolm.OutboundSessionInfo} session
*
* @param {object<string, object>} devicesByUser
* map from userid to device ID to blocked data
* @param devicesByUser - map from userid to device ID to blocked data
*/
private async notifyBlockedDevices(
session: OutboundSessionInfo,
@ -963,7 +935,7 @@ export class MegolmEncryption extends EncryptionAlgorithm {
* Perform any background tasks that can be done before a message is ready to
* send, in order to speed up sending of the message.
*
* @param {module:models/room} room the room the event is in
* @param room - the room the event is in
*/
public prepareToEncrypt(room: Room): void {
if (this.encryptionPreparation != null) {
@ -1008,13 +980,9 @@ export class MegolmEncryption extends EncryptionAlgorithm {
}
/**
* @inheritdoc
* @param content - plaintext event content
*
* @param {module:models/room} room
* @param {string} eventType
* @param {object} content plaintext event content
*
* @return {Promise} Promise which resolves to the new event body
* @returns Promise which resolves to the new event body
*/
public async encryptMessage(room: Room, eventType: string, content: IContent): Promise<IMegolmEncryptedContent> {
logger.log(`Starting to encrypt event for ${this.roomId}`);
@ -1103,7 +1071,7 @@ export class MegolmEncryption extends EncryptionAlgorithm {
* unknown to the user. If so, warn the user, and mark them as known to
* give the user a chance to go verify them before re-sending this message.
*
* @param {Object} devicesInRoom userId -> {deviceId -> object}
* @param devicesInRoom - `userId -> {deviceId -> object}`
* devices we should shared the session with.
*/
private checkForUnknownDevices(devicesInRoom: DeviceInfoMap): void {
@ -1133,7 +1101,7 @@ export class MegolmEncryption extends EncryptionAlgorithm {
* Remove unknown devices from a set of devices. The devicesInRoom parameter
* will be modified.
*
* @param {Object} devicesInRoom userId -> {deviceId -> object}
* @param devicesInRoom - `userId -> {deviceId -> object}`
* devices we should shared the session with.
*/
private removeUnknownDevices(devicesInRoom: DeviceInfoMap): void {
@ -1153,11 +1121,10 @@ export class MegolmEncryption extends EncryptionAlgorithm {
/**
* Get the list of unblocked devices for all users in the room
*
* @param {module:models/room} room
* @param forceDistributeToUnverified if set to true will include the unverified devices
* @param forceDistributeToUnverified - if set to true will include the unverified devices
* even if setting is set to block them (useful for verification)
*
* @return {Promise} Promise which resolves to an array whose
* @returns Promise which resolves to an array whose
* first element is a map from userId to deviceId to deviceInfo indicating
* the devices that messages should be encrypted to, and whose second
* element is a map from userId to deviceId to data indicating the devices
@ -1225,11 +1192,7 @@ export class MegolmEncryption extends EncryptionAlgorithm {
/**
* Megolm decryption implementation
*
* @constructor
* @extends {module:crypto/algorithms/DecryptionAlgorithm}
*
* @param {object} params parameters, as per
* {@link module:crypto/algorithms/DecryptionAlgorithm}
* @param params - parameters, as per {@link DecryptionAlgorithm}
*/
export class MegolmDecryption extends DecryptionAlgorithm {
// events which we couldn't decrypt due to unknown sessions /
@ -1248,12 +1211,8 @@ export class MegolmDecryption extends DecryptionAlgorithm {
}
/**
* @inheritdoc
*
* @param {MatrixEvent} event
*
* returns a promise which resolves to a
* {@link module:crypto~EventDecryptionResult} once we have finished
* {@link EventDecryptionResult} once we have finished
* decrypting, or rejects with an `algorithms.DecryptionError` if there is a
* problem decrypting the event.
*/
@ -1394,9 +1353,8 @@ export class MegolmDecryption extends DecryptionAlgorithm {
/**
* Add an event to the list of those awaiting their session keys.
*
* @private
* @internal
*
* @param {module:models/event.MatrixEvent} event
*/
private addEventToPendingList(event: MatrixEvent): void {
const content = event.getWireContent();
@ -1415,9 +1373,8 @@ export class MegolmDecryption extends DecryptionAlgorithm {
/**
* Remove an event from the list of those awaiting their session keys.
*
* @private
* @internal
*
* @param {module:models/event.MatrixEvent} event
*/
private removeEventFromPendingList(event: MatrixEvent): void {
const content = event.getWireContent();
@ -1438,11 +1395,6 @@ export class MegolmDecryption extends DecryptionAlgorithm {
}
}
/**
* @inheritdoc
*
* @param {module:models/event.MatrixEvent} event key event
*/
public async onRoomKeyEvent(event: MatrixEvent): Promise<void> {
const content = event.getContent<Partial<IMessage["content"]>>();
let senderKey = event.getSenderKey()!;
@ -1619,9 +1571,7 @@ export class MegolmDecryption extends DecryptionAlgorithm {
}
/**
* @inheritdoc
*
* @param {module:models/event.MatrixEvent} event key event
* @param event - key event
*/
public async onRoomKeyWithheldEvent(event: MatrixEvent): Promise<void> {
const content = event.getContent();
@ -1706,9 +1656,6 @@ export class MegolmDecryption extends DecryptionAlgorithm {
}
}
/**
* @inheritdoc
*/
public hasKeysForKeyRequest(keyRequest: IncomingRoomKeyRequest): Promise<boolean> {
const body = keyRequest.requestBody;
@ -1720,9 +1667,6 @@ export class MegolmDecryption extends DecryptionAlgorithm {
);
}
/**
* @inheritdoc
*/
public shareKeysWithDevice(keyRequest: IncomingRoomKeyRequest): void {
const userId = keyRequest.userId;
const deviceId = keyRequest.deviceId;
@ -1808,19 +1752,15 @@ export class MegolmDecryption extends DecryptionAlgorithm {
}
/**
* @inheritdoc
*
* @param {module:crypto/OlmDevice.MegolmSessionData} session
* @param {object} [opts={}] options for the import
* @param {boolean} [opts.untrusted] whether the key should be considered as untrusted
* @param {string} [opts.source] where the key came from
* @param untrusted - whether the key should be considered as untrusted
* @param source - where the key came from
*/
public importRoomKey(
session: IMegolmSessionData,
opts: { untrusted?: boolean, source?: string } = {},
{ untrusted, source }: { untrusted?: boolean, source?: string } = {},
): Promise<void> {
const extraSessionData: OlmGroupSessionExtraData = {};
if (opts.untrusted || session.untrusted) {
if (untrusted || session.untrusted) {
extraSessionData.untrusted = true;
}
if (session["org.matrix.msc3061.shared_history"]) {
@ -1836,7 +1776,7 @@ export class MegolmDecryption extends DecryptionAlgorithm {
true,
extraSessionData,
).then(() => {
if (opts.source !== "backup") {
if (source !== "backup") {
// don't wait for it to complete
this.crypto.backupManager.backupGroupSession(
session.sender_key, session.session_id,
@ -1855,13 +1795,11 @@ export class MegolmDecryption extends DecryptionAlgorithm {
* Have another go at decrypting events after we receive a key. Resolves once
* decryption has been re-attempted on all events.
*
* @private
* @param {String} senderKey
* @param {String} sessionId
* @param {Boolean} forceRedecryptIfUntrusted whether messages that were already
* @internal
* @param forceRedecryptIfUntrusted - whether messages that were already
* successfully decrypted using untrusted keys should be re-decrypted
*
* @return {Boolean} whether all messages were successfully
* @returns whether all messages were successfully
* decrypted with trusted keys
*/
private async retryDecryption(

View File

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

View File

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

View File

@ -15,8 +15,6 @@ limitations under the License.
*/
/**
* @module crypto/backup
*
* Classes for dealing with key backup.
*/
@ -134,7 +132,7 @@ export class BackupManager {
*
* Throws an error if a problem is detected.
*
* @param {IKeyBackupInfo} info the key backup info
* @param info - the key backup info
*/
public static checkBackupVersion(info: IKeyBackupInfo): void {
const Algorithm = algorithmsByName[info.algorithm];
@ -276,7 +274,7 @@ export class BackupManager {
* Forces a re-check of the key backup and enables/disables it
* as appropriate.
*
* @return {Object} Object with backup info (as returned by
* @returns Object with backup info (as returned by
* getKeyBackupVersion) in backupInfo and
* trust information (as returned by isKeyBackupTrusted)
* in trustInfo.
@ -309,15 +307,7 @@ export class BackupManager {
/**
* Check if the given backup info is trusted.
*
* @param {IKeyBackupInfo} backupInfo key backup info dict from /room_keys/version
* @return {object} {
* usable: [bool], // is the backup trusted, true iff there is a sig that is valid & from a trusted device
* sigs: [
* valid: [bool || null], // true: valid, false: invalid, null: cannot attempt validation
* deviceId: [string],
* device: [DeviceInfo || null],
* ]
* }
* @param backupInfo - key backup info dict from /room_keys/version
*/
public async isKeyBackupTrusted(backupInfo?: IKeyBackupInfo): Promise<TrustInfo> {
const ret = {
@ -432,7 +422,7 @@ export class BackupManager {
* Schedules sending all keys waiting to be sent to the backup, if not already
* scheduled. Retries if necessary.
*
* @param maxDelay Maximum delay to wait in ms. 0 means no delay.
* @param maxDelay - Maximum delay to wait in ms. 0 means no delay.
*/
public async scheduleKeyBackupSend(maxDelay = 10000): Promise<void> {
if (this.sendingBackups) return;
@ -490,8 +480,8 @@ export class BackupManager {
* Take some e2e keys waiting to be backed up and send them
* to the backup.
*
* @param {number} limit Maximum number of keys to back up
* @returns {number} Number of sessions backed up
* @param limit - Maximum number of keys to back up
* @returns Number of sessions backed up
*/
public async backupPendingKeys(limit: number): Promise<number> {
const sessions = await this.baseApis.crypto!.cryptoStore.getSessionsNeedingBackup(limit);
@ -573,7 +563,7 @@ export class BackupManager {
/**
* Marks all group sessions as needing to be backed up without scheduling
* them to upload in the background.
* @returns {Promise<int>} Resolves to the number of sessions now requiring a backup
* @returns Promise which resolves to the number of sessions now requiring a backup
* (which will be equal to the number of sessions in the store).
*/
public async flagAllGroupSessionsForBackup(): Promise<number> {
@ -599,7 +589,7 @@ export class BackupManager {
/**
* Counts the number of end to end session keys that are waiting to be backed up
* @returns {Promise<int>} Resolves to the number of sessions requiring backup
* @returns Promise which resolves to the number of sessions requiring backup
*/
public countSessionsNeedingBackup(): Promise<number> {
return this.baseApis.crypto!.cryptoStore.countSessionsNeedingBackup();

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -15,8 +15,6 @@ limitations under the License.
*/
/**
* @module olmlib
*
* Utilities common to olm encryption algorithms
*/
@ -55,22 +53,20 @@ export const MEGOLM_ALGORITHM = Algorithm.Megolm;
export const MEGOLM_BACKUP_ALGORITHM = Algorithm.MegolmBackup;
export interface IOlmSessionResult {
/** device info */
device: DeviceInfo;
/** base64 olm session id; null if no session could be established */
sessionId: string | null;
}
/**
* Encrypt an event payload for an Olm device
*
* @param {Object<string, string>} resultsObject The `ciphertext` property
* @param resultsObject - The `ciphertext` property
* of the m.room.encrypted event to which to add our result
*
* @param {string} ourUserId
* @param {string} ourDeviceId
* @param {module:crypto/OlmDevice} olmDevice olm.js wrapper
* @param {string} recipientUserId
* @param {module:crypto/deviceinfo} recipientDevice
* @param {object} payloadFields fields to include in the encrypted payload
* @param olmDevice - olm.js wrapper
* @param payloadFields - fields to include in the encrypted payload
*
* Returns a promise which resolves (to undefined) when the payload
* has been encrypted into `resultsObject`
@ -145,17 +141,14 @@ interface IExistingOlmSession {
* Get the existing olm sessions for the given devices, and the devices that
* don't have olm sessions.
*
* @param {module:crypto/OlmDevice} olmDevice
*
* @param {MatrixClient} baseApis
*
* @param {object<string, module:crypto/deviceinfo[]>} devicesByUser
* map from userid to list of devices to ensure sessions for
* @param devicesByUser - map from userid to list of devices to ensure sessions for
*
* @return {Promise} resolves to an array. The first element of the array is a
* @returns resolves to an array. The first element of the array is a
* a map of user IDs to arrays of deviceInfo, representing the devices that
* don't have established olm sessions. The second element of the array is
* a map from userId to deviceId to {@link module:crypto~OlmSessionResult}
* a map from userId to deviceId to {@link OlmSessionResult}
*/
export async function getExistingOlmSessions(
olmDevice: OlmDevice,
@ -197,27 +190,22 @@ export async function getExistingOlmSessions(
/**
* Try to make sure we have established olm sessions for the given devices.
*
* @param {module:crypto/OlmDevice} olmDevice
* @param devicesByUser - map from userid to list of devices to ensure sessions for
*
* @param {MatrixClient} baseApis
*
* @param {object<string, module:crypto/deviceinfo[]>} devicesByUser
* map from userid to list of devices to ensure sessions for
*
* @param {boolean} [force=false] If true, establish a new session even if one
* @param force - If true, establish a new session even if one
* already exists.
*
* @param {Number} [otkTimeout] The timeout in milliseconds when requesting
* @param otkTimeout - The timeout in milliseconds when requesting
* one-time keys for establishing new olm sessions.
*
* @param {Array} [failedServers] An array to fill with remote servers that
* @param failedServers - An array to fill with remote servers that
* failed to respond to one-time-key requests.
*
* @param {Logger} [log] A possibly customised log
* @param log - A possibly customised log
*
* @return {Promise} resolves once the sessions are complete, to
* @returns resolves once the sessions are complete, to
* an Object mapping from userId to deviceId to
* {@link module:crypto~OlmSessionResult}
* {@link OlmSessionResult}
*/
export async function ensureOlmSessionsForDevices(
olmDevice: OlmDevice,
@ -442,15 +430,15 @@ export interface IObject {
/**
* Verify the signature on an object
*
* @param {module:crypto/OlmDevice} olmDevice olm wrapper to use for verify op
* @param olmDevice - olm wrapper to use for verify op
*
* @param {Object} obj object to check signature on.
* @param obj - object to check signature on.
*
* @param {string} signingUserId ID of the user whose signature should be checked
* @param signingUserId - ID of the user whose signature should be checked
*
* @param {string} signingDeviceId ID of the device whose signature should be checked
* @param signingDeviceId - ID of the device whose signature should be checked
*
* @param {string} signingKey base64-ed ed25519 public key
* @param signingKey - base64-ed ed25519 public key
*
* Returns a promise which resolves (to undefined) if the the signature is good,
* or rejects with an Error if it is bad.
@ -485,13 +473,13 @@ export async function verifySignature(
/**
* Sign a JSON object using public key cryptography
* @param {Object} obj Object to sign. The object will be modified to include
* @param obj - Object to sign. The object will be modified to include
* the new signature
* @param {Olm.PkSigning|Uint8Array} key the signing object or the private key
* @param key - the signing object or the private key
* seed
* @param {string} userId The user ID who owns the signing key
* @param {string} pubKey The public key (ignored if key is a seed)
* @returns {string} the signature for the object
* @param userId - The user ID who owns the signing key
* @param pubKey - The public key (ignored if key is a seed)
* @returns the signature for the object
*/
export function pkSign(obj: object & IObject, key: Uint8Array | PkSigning, userId: string, pubKey: string): string {
let createdKey = false;
@ -521,9 +509,9 @@ export function pkSign(obj: object & IObject, key: Uint8Array | PkSigning, userI
/**
* Verify a signed JSON object
* @param {Object} obj Object to verify
* @param {string} pubKey The public key to use to verify
* @param {string} userId The user ID who signed the object
* @param obj - Object to verify
* @param pubKey - The public key to use to verify
* @param userId - The user ID who signed the object
*/
export function pkVerify(obj: IObject, pubKey: string, userId: string): void {
const keyId = "ed25519:" + pubKey;
@ -563,8 +551,8 @@ export function isOlmEncrypted(event: MatrixEvent): boolean {
/**
* Encode a typed array of uint8 as base64.
* @param {Uint8Array} uint8Array The data to encode.
* @return {string} The base64.
* @param uint8Array - The data to encode.
* @returns The base64.
*/
export function encodeBase64(uint8Array: ArrayBuffer | Uint8Array): string {
return Buffer.from(uint8Array).toString("base64");
@ -572,8 +560,8 @@ export function encodeBase64(uint8Array: ArrayBuffer | Uint8Array): string {
/**
* Encode a typed array of uint8 as unpadded base64.
* @param {Uint8Array} uint8Array The data to encode.
* @return {string} The unpadded base64.
* @param uint8Array - The data to encode.
* @returns The unpadded base64.
*/
export function encodeUnpaddedBase64(uint8Array: ArrayBuffer | Uint8Array): string {
return encodeBase64(uint8Array).replace(/=+$/g, '');
@ -581,8 +569,8 @@ export function encodeUnpaddedBase64(uint8Array: ArrayBuffer | Uint8Array): stri
/**
* Decode a base64 string to a typed array of uint8.
* @param {string} base64 The base64 to decode.
* @return {Uint8Array} The decoded data.
* @param base64 - The base64 to decode.
* @returns The decoded data.
*/
export function decodeBase64(base64: string): Uint8Array {
return Buffer.from(base64, "base64");

View File

@ -30,8 +30,6 @@ import { IEncryptedPayload } from "../aes";
/**
* Internal module. Definitions for storage for the crypto module
*
* @module
*/
export interface SecretStorePrivateKeys {
@ -46,8 +44,6 @@ export interface SecretStorePrivateKeys {
/**
* Abstraction of things that can store data required for end-to-end encryption
*
* @interface CryptoStore
*/
export interface CryptoStore {
startup(): Promise<CryptoStore>;
@ -197,32 +193,29 @@ export interface IWithheld {
/**
* Represents an outgoing room key request
*
* @typedef {Object} OutgoingRoomKeyRequest
*
* @property {string} requestId unique id for this request. Used for both
* an id within the request for later pairing with a cancellation, and for
* the transaction id when sending the to_device messages to our local
* server.
*
* @property {string?} cancellationTxnId
* transaction id for the cancellation, if any
*
* @property {Array<{userId: string, deviceId: string}>} recipients
* list of recipients for the request
*
* @property {module:crypto~RoomKeyRequestBody} requestBody
* parameters for the request.
*
* @property {Number} state current state of this request (states are defined
* in {@link module:crypto/OutgoingRoomKeyRequestManager~ROOM_KEY_REQUEST_STATES})
*/
export interface OutgoingRoomKeyRequest {
/**
* Unique id for this request. Used for both an id within the request for later pairing with a cancellation,
* and for the transaction id when sending the to_device messages to our local server.
*/
requestId: string;
requestTxnId?: string;
/**
* Transaction id for the cancellation, if any
*/
cancellationTxnId?: string;
/**
* List of recipients for the request
*/
recipients: IRoomKeyRequestRecipient[];
/**
* Parameters for the request
*/
requestBody: IRoomKeyRequestBody;
/**
* current state of this request (states are defined in {@link OutgoingRoomKeyRequestManager})
*/
state: RoomKeyRequestState;
}

View File

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

View File

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

View File

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

View File

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

View File

@ -17,7 +17,6 @@ limitations under the License.
/**
* Base class for verification methods.
* @module crypto/verification/Base
*/
import { MatrixEvent } from '../../models/event';
@ -74,21 +73,19 @@ export class VerificationBase<
*
* <p>Subclasses must have a NAME class property.</p>
*
* @class
*
* @param {Object} channel the verification channel to send verification messages over.
* @param channel - the verification channel to send verification messages over.
* TODO: Channel types
*
* @param {MatrixClient} baseApis base matrix api interface
* @param baseApis - base matrix api interface
*
* @param {string} userId the user ID that is being verified
* @param userId - the user ID that is being verified
*
* @param {string} deviceId the device ID that is being verified
* @param deviceId - the device ID that is being verified
*
* @param {object} [startEvent] the m.key.verification.start event that
* @param startEvent - the m.key.verification.start event that
* initiated this verification, if any
*
* @param {object} [request] the key verification request object related to
* @param request - the key verification request object related to
* this verification, if any
*/
public constructor(
@ -279,7 +276,7 @@ export class VerificationBase<
/**
* Begin the key verification
*
* @returns {Promise} Promise which resolves when the verification has
* @returns Promise which resolves when the verification has
* completed.
*/
public verify(): Promise<void> {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -81,6 +81,9 @@ export enum VerificationRequestEvent {
}
type EventHandlerMap = {
/**
* Fires whenever the state of the request object has changed.
*/
[VerificationRequestEvent.Change]: () => void;
};
@ -88,7 +91,6 @@ type EventHandlerMap = {
* State machine for verification requests.
* Things that differ based on what channel is used to
* send and receive verification events are put in `InRoomChannel` or `ToDeviceChannel`.
* @event "change" whenever the state of the request object has changed.
*/
export class VerificationRequest<
C extends IVerificationChannel = IVerificationChannel,
@ -129,10 +131,10 @@ export class VerificationRequest<
/**
* Stateless validation logic not specific to the channel.
* Invoked by the same static method in either channel.
* @param {string} type the "symbolic" event type, as returned by the `getEventType` function on the channel.
* @param {MatrixEvent} event the event to validate. Don't call getType() on it but use the `type` parameter instead.
* @param {MatrixClient} client the client to get the current user and device id from
* @returns {boolean} whether the event is valid and should be passed to handleEvent
* @param type - the "symbolic" event type, as returned by the `getEventType` function on the channel.
* @param event - the event to validate. Don't call getType() on it but use the `type` parameter instead.
* @param client - the client to get the current user and device id from
* @returns whether the event is valid and should be passed to handleEvent
*/
public static validateEvent(type: string, event: MatrixEvent, client: MatrixClient): boolean {
const content = event.getContent();
@ -234,7 +236,7 @@ export class VerificationRequest<
/**
* The key verification request event.
* @returns {MatrixEvent} The request event, or falsey if not found.
* @returns The request event, or falsey if not found.
*/
public get requestEvent(): MatrixEvent | undefined {
return this.getEventByEither(REQUEST_TYPE);
@ -278,9 +280,9 @@ export class VerificationRequest<
* This is useful when setting up the QR code UI, as it is somewhat asymmetrical:
* if the other party supports SCAN_QR, we should show a QR code in the UI, and vice versa.
* For methods that need to be supported by both ends, use the `methods` property.
* @param {string} method the method to check
* @param {boolean} force to check even if the phase is not ready or started yet, internal usage
* @return {boolean} whether or not the other party said the supported the method */
* @param method - the method to check
* @param force - to check even if the phase is not ready or started yet, internal usage
* @returns whether or not the other party said the supported the method */
public otherPartySupportsMethod(method: string, force = false): boolean {
if (!force && !this.ready && !this.started) {
return false;
@ -398,7 +400,7 @@ export class VerificationRequest<
* given the events sent so far in the verification. This is the
* same algorithm used to determine which device to send the
* verification to when no specific device is specified.
* @returns {{userId: *, deviceId: *}} The device information
* @returns The device information
*/
public get targetDevice(): ITargetDevice {
const theirFirstEvent =
@ -415,10 +417,10 @@ export class VerificationRequest<
/* Start the key verification, creating a verifier and sending a .start event.
* If no previous events have been sent, pass in `targetDevice` to set who to direct this request to.
* @param {string} method the name of the verification method to use.
* @param {string?} targetDevice.userId the id of the user to direct this request to
* @param {string?} targetDevice.deviceId the id of the device to direct this request to
* @returns {VerifierBase} the verifier of the given method
* @param method - the name of the verification method to use.
* @param targetDevice.userId the id of the user to direct this request to
* @param targetDevice.deviceId the id of the device to direct this request to
* @returns the verifier of the given method
*/
public beginKeyVerification(
method: VerificationMethod,
@ -448,7 +450,7 @@ export class VerificationRequest<
/**
* sends the initial .request event.
* @returns {Promise} resolves when the event has been sent.
* @returns resolves when the event has been sent.
*/
public async sendRequest(): Promise<void> {
if (!this.observeOnly && this._phase === PHASE_UNSENT) {
@ -459,9 +461,9 @@ export class VerificationRequest<
/**
* Cancels the request, sending a cancellation to the other party
* @param {string?} error.reason the error reason to send the cancellation with
* @param {string?} error.code the error code to send the cancellation with
* @returns {Promise} resolves when the event has been sent.
* @param reason - the error reason to send the cancellation with
* @param code - the error code to send the cancellation with
* @returns resolves when the event has been sent.
*/
public async cancel({ reason = "User declined", code = "m.user" } = {}): Promise<void> {
if (!this.observeOnly && this._phase !== PHASE_CANCELLED) {
@ -478,7 +480,7 @@ export class VerificationRequest<
/**
* Accepts the request, sending a .ready event to the other party
* @returns {Promise} resolves when the event has been sent.
* @returns resolves when the event has been sent.
*/
public async accept(): Promise<void> {
if (!this.observeOnly && this.phase === PHASE_REQUESTED && !this.initiatedByMe) {
@ -491,10 +493,10 @@ export class VerificationRequest<
/**
* Can be used to listen for state changes until the callback returns true.
* @param {Function} fn callback to evaluate whether the request is in the desired state.
* @param fn - callback to evaluate whether the request is in the desired state.
* Takes the request as an argument.
* @returns {Promise} that resolves once the callback returns true
* @throws {Error} when the request is cancelled
* @returns that resolves once the callback returns true
* @throws Error when the request is cancelled
*/
public waitFor(fn: (request: VerificationRequest) => boolean): Promise<VerificationRequest> {
return new Promise((resolve, reject) => {
@ -701,13 +703,13 @@ export class VerificationRequest<
/**
* Changes the state of the request and verifier in response to a key verification event.
* @param {string} type the "symbolic" event type, as returned by the `getEventType` function on the channel.
* @param {MatrixEvent} event the event to handle. Don't call getType() on it but use the `type` parameter instead.
* @param {boolean} isLiveEvent whether this is an even received through sync or not
* @param {boolean} isRemoteEcho whether this is the remote echo of an event sent by the same device
* @param {boolean} isSentByUs whether this event is sent by a party that can accept and/or observe the request like one of our peers.
* @param type - the "symbolic" event type, as returned by the `getEventType` function on the channel.
* @param event - the event to handle. Don't call getType() on it but use the `type` parameter instead.
* @param isLiveEvent - whether this is an even received through sync or not
* @param isRemoteEcho - whether this is the remote echo of an event sent by the same device
* @param isSentByUs - whether this event is sent by a party that can accept and/or observe the request like one of our peers.
* For InRoomChannel this means any device for the syncing user. For ToDeviceChannel, just the syncing device.
* @returns {Promise} a promise that resolves when any requests as an answer to the passed-in event are sent.
* @returns a promise that resolves when any requests as an answer to the passed-in event are sent.
*/
public async handleEvent(
type: string,

View File

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

View File

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

View File

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

View File

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

View File

@ -26,9 +26,8 @@ interface IErrorJson extends Partial<IUsageLimit> {
/**
* Construct a generic HTTP error. This is a JavaScript Error with additional information
* specific to HTTP responses.
* @constructor
* @param {string} msg The error message to include.
* @param {number} httpStatus The HTTP response status code.
* @param msg - The error message to include.
* @param httpStatus - The HTTP response status code.
*/
export class HTTPError extends Error {
public constructor(msg: string, public readonly httpStatus?: number) {
@ -36,21 +35,18 @@ export class HTTPError extends Error {
}
}
/**
* Construct a Matrix error. This is a JavaScript Error with additional
* information specific to the standard Matrix error response.
* @constructor
* @param {Object} errorJson The Matrix error JSON returned from the homeserver.
* @prop {string} errcode The Matrix 'errcode' value, e.g. "M_FORBIDDEN".
* @prop {string} name Same as MatrixError.errcode but with a default unknown string.
* @prop {string} message The Matrix 'error' value, e.g. "Missing token."
* @prop {Object} data The raw Matrix error JSON used to construct this object.
* @prop {number} httpStatus The numeric HTTP status code given
*/
export class MatrixError extends HTTPError {
// The Matrix 'errcode' value, e.g. "M_FORBIDDEN".
public readonly errcode?: string;
// The raw Matrix error JSON used to construct this object.
public data: IErrorJson;
/**
* Construct a Matrix error. This is a JavaScript Error with additional
* information specific to the standard Matrix error response.
* @param errorJson - The Matrix error JSON returned from the homeserver.
* @param httpStatus - The numeric HTTP status code given
*/
public constructor(
errorJson: IErrorJson = {},
public readonly httpStatus?: number,
@ -76,7 +72,6 @@ export class MatrixError extends HTTPError {
* that a request failed because of some error with the connection, either
* CORS was not correctly configured on the server, the server didn't response,
* the request timed out, or the internet connection on the client side went down.
* @constructor
*/
export class ConnectionError extends Error {
public constructor(message: string, cause?: Error) {

View File

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

View File

@ -35,27 +35,13 @@ export class MatrixHttpApi<O extends IHttpOpts> extends FetchHttpApi<O> {
/**
* Upload content to the homeserver
*
* @param {object} file The object to upload. On a browser, something that
* @param file - The object to upload. On a browser, something that
* can be sent to XMLHttpRequest.send (typically a File). Under node.js,
* a Buffer, String or ReadStream.
*
* @param {object} opts options object
* @param opts - options object
*
* @param {string=} opts.name Name to give the file on the server. Defaults
* to <tt>file.name</tt>.
*
* @param {boolean=} opts.includeFilename if false will not send the filename,
* e.g for encrypted file uploads where filename leaks are undesirable.
* Defaults to true.
*
* @param {string=} opts.type Content-type for the upload. Defaults to
* <tt>file.type</tt>, or <tt>application/octet-stream</tt>.
*
* @param {Function=} opts.progressHandler Optional. Called when a chunk of
* data has been uploaded, with an object containing the fields `loaded`
* (number of bytes transferred) and `total` (total size, if known).
*
* @return {Promise} Resolves to response object, as
* @returns Promise which resolves to response object, as
* determined by this.opts.onlyData, opts.rawResponse, and
* opts.onlyContentUri. Rejects with an error (usually a MatrixError).
*/
@ -190,7 +176,7 @@ export class MatrixHttpApi<O extends IHttpOpts> extends FetchHttpApi<O> {
/**
* Get the content repository url with query parameters.
* @return {Object} An object with a 'base', 'path' and 'params' for base URL,
* @returns An object with a 'base', 'path' and 'params' for base URL,
* path and query parameters respectively.
*/
public getContentUri(): IContentUri {

View File

@ -32,11 +32,25 @@ export interface IHttpOpts {
}
export interface IRequestOpts {
/**
* The alternative base url to use.
* If not specified, uses this.opts.baseUrl
*/
baseUrl?: string;
/**
* The full prefix to use e.g.
* "/_matrix/client/v2_alpha". If not specified, uses this.opts.prefix.
*/
prefix?: string;
/**
* map of additional request headers
*/
headers?: Record<string, string>;
abortSignal?: AbortSignal;
/**
* The maximum amount of time to wait before
* timing out the request. If not specified, there is no timeout.
*/
localTimeoutMs?: number;
keepAlive?: boolean; // defaults to false
json?: boolean; // defaults to true
@ -62,7 +76,29 @@ export enum HttpApiEvent {
}
export type HttpApiEventHandlerMap = {
/**
* Fires whenever the login session the JS SDK is using is no
* longer valid and the user must log in again.
* NB. This only fires when action is required from the user, not
* when then login session can be renewed by using a refresh token.
* @example
* ```
* matrixClient.on("Session.logged_out", function(errorObj){
* // show the login screen
* });
* ```
*/
[HttpApiEvent.SessionLoggedOut]: (err: MatrixError) => void;
/**
* Fires when the JS SDK receives a M_CONSENT_NOT_GIVEN error in response
* to a HTTP request.
* @example
* ```
* matrixClient.on("no_consent", function(message, contentUri) {
* console.info(message + ' Go to ' + contentUri);
* });
* ```
*/
[HttpApiEvent.NoConsent]: (message: string, consentUri: string) => void;
};
@ -72,9 +108,26 @@ export interface UploadProgress {
}
export interface UploadOpts {
/**
* Name to give the file on the server. Defaults to <tt>file.name</tt>.
*/
name?: string;
/**
* Content-type for the upload. Defaults to
* <tt>file.type</tt>, or <tt>applicaton/octet-stream</tt>.
*/
type?: string;
/**
* if false will not send the filename,
* e.g for encrypted file uploads where filename leaks are undesirable.
* Defaults to true.
*/
includeFilename?: boolean;
/**
* Optional. Called when a chunk of
* data has been uploaded, with an object containing the fields `loaded`
* (number of bytes transferred) and `total` (total size, if known).
*/
progressHandler?(progress: UploadProgress): void;
abortController?: AbortController;
}

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
* we return a generic Error.
*
* @param {XMLHttpRequest|Response} response response object
* @param {String} body raw body of the response
* @returns {Error}
* @param response - response object
* @param body - raw body of the response
* @returns
*/
export function parseErrorResponse(response: XMLHttpRequest | Response, body?: string): Error {
let contentType: ParsedMediaType | null;
@ -102,8 +102,8 @@ function isXhr(response: XMLHttpRequest | Response): response is XMLHttpRequest
*
* returns null if no content-type header could be found.
*
* @param {XMLHttpRequest|Response} response response object
* @returns {{type: String, parameters: Object}?} parsed content-type header, or null if not found
* @param response - response object
* @returns parsed content-type header, or null if not found
*/
function getResponseContentType(response: XMLHttpRequest | Response): ParsedMediaType | null {
let contentType: string | null;
@ -124,10 +124,10 @@ function getResponseContentType(response: XMLHttpRequest | Response): ParsedMedi
/**
* Retries a network operation run in a callback.
* @param {number} maxAttempts maximum attempts to try
* @param {Function} callback callback that returns a promise of the network operation. If rejected with ConnectionError, it will be retried by calling the callback again.
* @return {any} the result of the network operation
* @throws {ConnectionError} If after maxAttempts the callback still throws ConnectionError
* @param maxAttempts - maximum attempts to try
* @param callback - callback that returns a promise of the network operation. If rejected with ConnectionError, it will be retried by calling the callback again.
* @returns the result of the network operation
* @throws {@link ConnectionError} If after maxAttempts the callback still throws ConnectionError
*/
export async function retryNetworkOperation<T>(maxAttempts: number, callback: () => Promise<T>): Promise<T> {
let attempts = 0;

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

View File

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

View File

@ -16,8 +16,6 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
/** @module interactive-auth */
import { logger } from './logger';
import { MatrixClient } from "./client";
import { defer, IDeferred } from "./utils";
@ -31,8 +29,11 @@ interface IFlow {
}
export interface IInputs {
// An email address. If supplied, a flow using email verification will be chosen.
emailAddress?: string;
// An ISO two letter country code. Gives the country that opts.phoneNumber should be resolved relative to.
phoneCountry?: string;
// A phone number. If supplied, a flow using phone number validation will be chosen.
phoneNumber?: string;
registrationToken?: string;
}
@ -106,15 +107,66 @@ class NoAuthFlowFoundError extends Error {
}
interface IOpts {
/**
* A matrix client to use for the auth process
*/
matrixClient: MatrixClient;
/**
* Error response from the last request. If null, a request will be made with no auth before starting.
*/
authData?: IAuthData;
/**
* Inputs provided by the user and used by different stages of the auto process.
* The inputs provided will affect what flow is chosen.
*/
inputs?: IInputs;
/**
* If resuming an existing interactive auth session, the sessionId of that session.
*/
sessionId?: string;
/**
* If resuming an existing interactive auth session, the client secret for that session
*/
clientSecret?: string;
/**
* If returning from having completed m.login.email.identity auth, the sid for the email verification session.
*/
emailSid?: string;
/**
* Called with the new auth dict to submit the request.
* Also passes a second deprecated arg which is a flag set to true if this request is a background request.
* The busyChanged callback should be used instead of the background flag.
* Should return a promise which resolves to the successful response or rejects with a MatrixError.
*/
doRequest(auth: IAuthData | null, background: boolean): Promise<IAuthData>;
/**
* Called when the status of the UI auth changes,
* ie. when the state of an auth stage changes of when the auth flow moves to a new stage.
* The arguments are: the login type (eg m.login.password); and an object which is either an error or an
* informational object specific to the login type.
* If the 'errcode' key is defined, the object is an error, and has keys:
* errcode: string, the textual error code, eg. M_UNKNOWN
* error: string, human readable string describing the error
*
* The login type specific objects are as follows:
* m.login.email.identity:
* * emailSid: string, the sid of the active email auth session
*/
stateUpdated(nextStage: AuthType, status: IStageStatus): void;
/**
* A function that takes the email address (string), clientSecret (string), attempt number (int) and
* sessionId (string) and calls the relevant requestToken function and returns the promise returned by that
* function.
* If the resulting promise rejects, the rejection will propagate through to the attemptAuth promise.
*/
requestEmailToken(email: string, secret: string, attempt: number, session: string): Promise<{ sid: string }>;
/**
* Called whenever the interactive auth logic becomes busy submitting information provided by the user or finishes.
* After this has been called with true the UI should indicate that a request is in progress
* until it is called again with false.
*/
busyChanged?(busy: boolean): void;
startAuthStage?(nextStage: string): Promise<void>; // LEGACY
}
@ -131,70 +183,7 @@ interface IOpts {
* callbacks, and information gathered from the user can be submitted with
* submitAuthDict.
*
* @constructor
* @alias module:interactive-auth
*
* @param {object} opts options object
*
* @param {object} opts.matrixClient A matrix client to use for the auth process
*
* @param {object?} opts.authData error response from the last request. If
* null, a request will be made with no auth before starting.
*
* @param {function(object?): Promise} opts.doRequest
* called with the new auth dict to submit the request. Also passes a
* second deprecated arg which is a flag set to true if this request
* is a background request. The busyChanged callback should be used
* instead of the background flag. Should return a promise which resolves
* to the successful response or rejects with a MatrixError.
*
* @param {function(boolean): Promise} opts.busyChanged
* called whenever the interactive auth logic becomes busy submitting
* information provided by the user or finishes. After this has been
* called with true the UI should indicate that a request is in progress
* until it is called again with false.
*
* @param {function(string, object?)} opts.stateUpdated
* called when the status of the UI auth changes, ie. when the state of
* an auth stage changes of when the auth flow moves to a new stage.
* The arguments are: the login type (eg m.login.password); and an object
* which is either an error or an informational object specific to the
* login type. If the 'errcode' key is defined, the object is an error,
* and has keys:
* errcode: string, the textual error code, eg. M_UNKNOWN
* error: string, human readable string describing the error
*
* The login type specific objects are as follows:
* m.login.email.identity:
* * emailSid: string, the sid of the active email auth session
*
* @param {object?} opts.inputs Inputs provided by the user and used by different
* stages of the auto process. The inputs provided will affect what flow is chosen.
*
* @param {string?} opts.inputs.emailAddress An email address. If supplied, a flow
* using email verification will be chosen.
*
* @param {string?} opts.inputs.phoneCountry An ISO two letter country code. Gives
* the country that opts.phoneNumber should be resolved relative to.
*
* @param {string?} opts.inputs.phoneNumber A phone number. If supplied, a flow
* using phone number validation will be chosen.
*
* @param {string?} opts.sessionId If resuming an existing interactive auth session,
* the sessionId of that session.
*
* @param {string?} opts.clientSecret If resuming an existing interactive auth session,
* the client secret for that session
*
* @param {string?} opts.emailSid If returning from having completed m.login.email.identity
* auth, the sid for the email verification session.
*
* @param {function?} opts.requestEmailToken A function that takes the email address (string),
* clientSecret (string), attempt number (int) and sessionId (string) and calls the
* relevant requestToken function and returns the promise returned by that function.
* If the resulting promise rejects, the rejection will propagate through to the
* attemptAuth promise.
*
* @param opts - options object
*/
export class InteractiveAuth {
private readonly matrixClient: MatrixClient;
@ -236,7 +225,7 @@ export class InteractiveAuth {
/**
* begin the authentication process.
*
* @return {Promise} which resolves to the response on success,
* @returns which resolves to the response on success,
* or rejects with the error on failure. Rejects with NoAuthFlowFoundError if
* no suitable authentication flow can be found
*/
@ -307,7 +296,7 @@ export class InteractiveAuth {
/**
* get the auth session ID
*
* @return {string} session id
* @returns session id
*/
public getSessionId(): string | undefined {
return this.data?.session;
@ -317,7 +306,7 @@ export class InteractiveAuth {
* get the client secret used for validation sessions
* with the identity server.
*
* @return {string} client secret
* @returns client secret
*/
public getClientSecret(): string {
return this.clientSecret;
@ -326,8 +315,8 @@ export class InteractiveAuth {
/**
* get the server params for a given stage
*
* @param {string} loginType login type for the stage
* @return {object?} any parameters from the server for this stage
* @param loginType - login type for the stage
* @returns any parameters from the server for this stage
*/
public getStageParams(loginType: string): Record<string, any> | undefined {
return this.data.params?.[loginType];
@ -342,10 +331,10 @@ export class InteractiveAuth {
* make attemptAuth resolve/reject, or cause the startAuthStage callback
* to be called for a new stage.
*
* @param {object} authData new auth dict to send to the server. Should
* @param authData - new auth dict to send to the server. Should
* include a `type` property denoting the login type, as well as any
* other params for that stage.
* @param {boolean} background If true, this request failing will not result
* @param background - If true, this request failing will not result
* in the attemptAuth promise being rejected. This can be set to true
* for requests that just poll to see if auth has been completed elsewhere.
*/
@ -398,7 +387,7 @@ export class InteractiveAuth {
* Gets the sid for the email validation session
* Specific to m.login.email.identity
*
* @returns {string} The sid of the email auth session
* @returns The sid of the email auth session
*/
public getEmailSid(): string | undefined {
return this.emailSid;
@ -410,7 +399,7 @@ export class InteractiveAuth {
* of the email validation.
* Specific to m.login.email.identity
*
* @param {string} sid The sid for the email validation session
* @param sid - The sid for the email validation session
*/
public setEmailSid(sid: string): void {
this.emailSid = sid;
@ -448,9 +437,9 @@ export class InteractiveAuth {
* Fire off a request, and either resolve the promise, or call
* startAuthStage.
*
* @private
* @param {object?} auth new auth dict, including session id
* @param {boolean?} background If true, this request is a background poll, so it
* @internal
* @param auth - new auth dict, including session id
* @param background - If true, this request is a background poll, so it
* failing will not result in the attemptAuth promise being rejected.
* This can be set to true for requests that just poll to see if auth has
* been completed elsewhere.
@ -526,8 +515,8 @@ export class InteractiveAuth {
/**
* Pick the next stage and call the callback
*
* @private
* @throws {NoAuthFlowFoundError} If no suitable authentication flow can be found
* @internal
* @throws {@link NoAuthFlowFoundError} If no suitable authentication flow can be found
*/
private startNextAuthStage(): void {
const nextStage = this.chooseStage();
@ -559,9 +548,9 @@ export class InteractiveAuth {
/**
* Pick the next auth stage
*
* @private
* @return {string?} login type
* @throws {NoAuthFlowFoundError} If no suitable authentication flow can be found
* @internal
* @returns login type
* @throws {@link NoAuthFlowFoundError} If no suitable authentication flow can be found
*/
private chooseStage(): AuthType | undefined {
if (this.chosenFlow === null) {
@ -584,9 +573,9 @@ export class InteractiveAuth {
* this could result in the email not being used which would leave
* the account with no means to reset a password.
*
* @private
* @return {object} flow
* @throws {NoAuthFlowFoundError} If no suitable authentication flow can be found
* @internal
* @returns flow
* @throws {@link NoAuthFlowFoundError} If no suitable authentication flow can be found
*/
private chooseFlow(): IFlow {
const flows = this.data.flows || [];
@ -625,9 +614,8 @@ export class InteractiveAuth {
/**
* Get the first uncompleted stage in the given flow
*
* @private
* @param {object} flow
* @return {string} login type
* @internal
* @returns login type
*/
private firstUncompletedStage(flow: IFlow): AuthType | undefined {
const completed = this.data.completed || [];

View File

@ -15,10 +15,6 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @module logger
*/
import log, { Logger } from "loglevel";
// This is to demonstrate, that you can use any namespace you want.
@ -56,7 +52,7 @@ log.methodFactory = function(methodName, logLevel, loggerName) {
};
/**
* Drop-in replacement for <code>console</code> using {@link https://www.npmjs.com/package/loglevel|loglevel}.
* Drop-in replacement for `console` using {@link https://www.npmjs.com/package/loglevel|loglevel}.
* Can be tailored down to specific use cases if needed.
*/
export const logger = log.getLogger(DEFAULT_NAMESPACE) as PrefixedLogger;

View File

@ -70,8 +70,7 @@ let cryptoStoreFactory = (): CryptoStore => new MemoryCryptoStore;
/**
* Configure a different factory to be used for creating crypto stores
*
* @param {Function} fac a function which will return a new
* {@link module:crypto.store.base~CryptoStore}.
* @param fac - a function which will return a new {@link CryptoStore}
*/
export function setCryptoStoreFactory(fac: () => CryptoStore): void {
cryptoStoreFactory = fac;
@ -88,24 +87,14 @@ function amendClientOpts(opts: ICreateClientOpts): ICreateClientOpts {
}
/**
* Construct a Matrix Client. Similar to {@link module:client.MatrixClient}
* Construct a Matrix Client. Similar to {@link MatrixClient}
* except that the 'request', 'store' and 'scheduler' dependencies are satisfied.
* @param {Object} opts The configuration options for this client. These configuration
* options will be passed directly to {@link module:client.MatrixClient}.
* @param {Object} opts.store If not set, defaults to
* {@link module:store/memory.MemoryStore}.
* @param {Object} opts.scheduler If not set, defaults to
* {@link module:scheduler~MatrixScheduler}.
* @param opts - The configuration options for this client. These configuration
* options will be passed directly to {@link MatrixClient}.
*
* @param {module:crypto.store.base~CryptoStore=} opts.cryptoStore
* crypto store implementation. Calls the factory supplied to
* {@link setCryptoStoreFactory} if unspecified; or if no factory has been
* specified, uses a default implementation (indexeddb in the browser,
* in-memory otherwise).
*
* @return {MatrixClient} A new matrix client.
* @see {@link module:client.MatrixClient} for the full list of options for
* <code>opts</code>.
* @returns A new matrix client.
* @see {@link MatrixClient} for the full list of options for
* `opts`.
*/
export function createClient(opts: ICreateClientOpts): MatrixClient {
return new MatrixClient(amendClientOpts(opts));

View File

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

View File

@ -111,8 +111,8 @@ export class MSC3089TreeSpace {
/**
* Sets the name of the tree space.
* @param {string} name The new name for the space.
* @returns {Promise<void>} Resolves when complete.
* @param name - The new name for the space.
* @returns Promise which resolves when complete.
*/
public async setName(name: string): Promise<void> {
await this.client.sendStateEvent(this.roomId, EventType.RoomName, { name }, "");
@ -121,15 +121,15 @@ export class MSC3089TreeSpace {
/**
* Invites a user to the tree space. They will be given the default Viewer
* permission level unless specified elsewhere.
* @param {string} userId The user ID to invite.
* @param {boolean} andSubspaces True (default) to invite the user to all
* @param userId - The user ID to invite.
* @param andSubspaces - True (default) to invite the user to all
* directories/subspaces too, recursively.
* @param {boolean} shareHistoryKeys True (default) to share encryption keys
* @param shareHistoryKeys - True (default) to share encryption keys
* with the invited user. This will allow them to decrypt the events (files)
* in the tree. Keys will not be shared if the room is lacking appropriate
* history visibility (by default, history visibility is "shared" in trees,
* which is an appropriate visibility for these purposes).
* @returns {Promise<void>} Resolves when complete.
* @returns Promise which resolves when complete.
*/
public async invite(userId: string, andSubspaces = true, shareHistoryKeys = true): Promise<void> {
const promises: Promise<void>[] = [this.retryInvite(userId)];
@ -164,9 +164,9 @@ export class MSC3089TreeSpace {
* Sets the permissions of a user to the given role. Note that if setting a user
* to Owner then they will NOT be able to be demoted. If the user does not have
* permission to change the power level of the target, an error will be thrown.
* @param {string} userId The user ID to change the role of.
* @param {TreePermissions} role The role to assign.
* @returns {Promise<void>} Resolves when complete.
* @param userId - The user ID to change the role of.
* @param role - The role to assign.
* @returns Promise which resolves when complete.
*/
public async setPermissions(userId: string, role: TreePermissions): Promise<void> {
const currentPls = this.room.currentState.getStateEvents(EventType.RoomPowerLevels, "");
@ -200,8 +200,8 @@ export class MSC3089TreeSpace {
* Gets the current permissions of a user. Note that any users missing explicit permissions (or not
* in the space) will be considered Viewers. Appropriate membership checks need to be performed
* elsewhere.
* @param {string} userId The user ID to check permissions of.
* @returns {TreePermissions} The permissions for the user, defaulting to Viewer.
* @param userId - The user ID to check permissions of.
* @returns The permissions for the user, defaulting to Viewer.
*/
public getPermissions(userId: string): TreePermissions {
const currentPls = this.room.currentState.getStateEvents(EventType.RoomPowerLevels, "");
@ -220,8 +220,8 @@ export class MSC3089TreeSpace {
/**
* Creates a directory under this tree space, represented as another tree space.
* @param {string} name The name for the directory.
* @returns {Promise<MSC3089TreeSpace>} Resolves to the created directory.
* @param name - The name for the directory.
* @returns Promise which resolves to the created directory.
*/
public async createDirectory(name: string): Promise<MSC3089TreeSpace> {
const directory = await this.client.unstableCreateFileTree(name);
@ -239,7 +239,7 @@ export class MSC3089TreeSpace {
/**
* Gets a list of all known immediate subdirectories to this tree space.
* @returns {MSC3089TreeSpace[]} The tree spaces (directories). May be empty, but not null.
* @returns The tree spaces (directories). May be empty, but not null.
*/
public getDirectories(): MSC3089TreeSpace[] {
const trees: MSC3089TreeSpace[] = [];
@ -261,8 +261,8 @@ export class MSC3089TreeSpace {
/**
* Gets a subdirectory of a given ID under this tree space. Note that this will not recurse
* into children and instead only look one level deep.
* @param {string} roomId The room ID (directory ID) to find.
* @returns {MSC3089TreeSpace | undefined} The directory, or undefined if not found.
* @param roomId - The room ID (directory ID) to find.
* @returns The directory, or undefined if not found.
*/
public getDirectory(roomId: string): MSC3089TreeSpace | undefined {
return this.getDirectories().find(r => r.roomId === roomId);
@ -270,7 +270,7 @@ export class MSC3089TreeSpace {
/**
* Deletes the tree, kicking all members and deleting **all subdirectories**.
* @returns {Promise<void>} Resolves when complete.
* @returns Promise which resolves when complete.
*/
public async delete(): Promise<void> {
const subdirectories = this.getDirectories();
@ -341,7 +341,7 @@ export class MSC3089TreeSpace {
/**
* Gets the current order index for this directory. Note that if this is the top level space
* then -1 will be returned.
* @returns {number} The order index of this space.
* @returns The order index of this space.
*/
public getOrder(): number {
if (this.isTopLevel) return -1;
@ -357,8 +357,8 @@ export class MSC3089TreeSpace {
* Sets the order index for this directory within its parent. Note that if this is a top level
* space then an error will be thrown. -1 can be used to move the child to the start, and numbers
* larger than the number of children can be used to move the child to the end.
* @param {number} index The new order index for this space.
* @returns {Promise<void>} Resolves when complete.
* @param index - The new order index for this space.
* @returns Promise which resolves when complete.
* @throws Throws if this is a top level space.
*/
public async setOrder(index: number): Promise<void> {
@ -464,11 +464,11 @@ export class MSC3089TreeSpace {
/**
* Creates (uploads) a new file to this tree. The file must have already been encrypted for the room.
* The file contents are in a type that is compatible with MatrixClient.uploadContent().
* @param {string} name The name of the file.
* @param {File | String | Buffer | ReadStream | Blob} encryptedContents The encrypted contents.
* @param {Partial<IEncryptedFile>} info The encrypted file information.
* @param {IContent} additionalContent Optional event content fields to include in the message.
* @returns {Promise<ISendEventResponse>} Resolves to the file event's sent response.
* @param name - The name of the file.
* @param encryptedContents - The encrypted contents.
* @param info - The encrypted file information.
* @param additionalContent - Optional event content fields to include in the message.
* @returns Promise which resolves to the file event's sent response.
*/
public async createFile(
name: string,
@ -512,8 +512,8 @@ export class MSC3089TreeSpace {
/**
* Retrieves a file from the tree.
* @param {string} fileEventId The event ID of the file.
* @returns {MSC3089Branch | null} The file, or null if not found.
* @param fileEventId - The event ID of the file.
* @returns The file, or null if not found.
*/
public getFile(fileEventId: string): MSC3089Branch | null {
const branch = this.room.currentState.getStateEvents(UNSTABLE_MSC3089_BRANCH.name, fileEventId);
@ -522,7 +522,7 @@ export class MSC3089TreeSpace {
/**
* Gets an array of all known files for the tree.
* @returns {MSC3089Branch[]} The known files. May be empty, but not null.
* @returns The known files. May be empty, but not null.
*/
public listFiles(): MSC3089Branch[] {
return this.listAllFiles().filter(b => b.isActive);
@ -530,7 +530,7 @@ export class MSC3089TreeSpace {
/**
* Gets an array of all known files for the tree, including inactive/invalid ones.
* @returns {MSC3089Branch[]} The known files. May be empty, but not null.
* @returns The known files. May be empty, but not null.
*/
public listAllFiles(): MSC3089Branch[] {
const branches = this.room.currentState.getStateEvents(UNSTABLE_MSC3089_BRANCH.name) ?? [];

View File

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

View File

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

View File

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

View File

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

View File

@ -17,7 +17,6 @@ limitations under the License.
/**
* This is an internal module. See {@link MatrixEvent} and {@link RoomEvent} for
* the public classes.
* @module models/event
*/
import { ExtensibleEvent, ExtensibleEvents, Optional } from "matrix-events-sdk";
@ -80,15 +79,15 @@ export interface IEvent {
redacts?: string;
/**
* @deprecated
* @deprecated in favour of `sender`
*/
user_id?: string;
/**
* @deprecated
* @deprecated in favour of `unsigned.prev_content`
*/
prev_content?: IContent;
/**
* @deprecated
* @deprecated in favour of `origin_server_ts`
*/
age?: number;
}
@ -150,8 +149,11 @@ interface IKeyRequestRecipient {
}
export interface IDecryptOptions {
// Emits "event.decrypted" if set to true
emit?: boolean;
// True if this is a retry (enables more logging)
isRetry?: boolean;
// whether the message should be re-decrypted if it was previously successfully decrypted with an untrusted key
forceRedecryptIfUntrusted?: boolean;
}
@ -192,6 +194,12 @@ export enum MatrixEventEvent {
export type MatrixEventEmittedEvents = MatrixEventEvent | ThreadEvent.Update;
export type MatrixEventHandlerMap = {
/**
* Fires when an event is decrypted
*
* @param event - The matrix event which has been decrypted
* @param err - The error that occurred during decryption, or `undefined` if no error occurred.
*/
[MatrixEventEvent.Decrypted]: (event: MatrixEvent, err?: Error) => void;
[MatrixEventEvent.BeforeRedaction]: (event: MatrixEvent, redactionEvent: MatrixEvent) => void;
[MatrixEventEvent.VisibilityChange]: (event: MatrixEvent, visible: boolean) => void;
@ -271,12 +279,43 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
*/
public localTimestamp: number;
// XXX: these should be read-only
/**
* The room member who sent this event, or null e.g.
* this is a presence event. This is only guaranteed to be set for events that
* appear in a timeline, ie. do not guarantee that it will be set on state
* events.
* @privateRemarks
* Should be read-only
*/
public sender: RoomMember | null = null;
/**
* The room member who is the target of this event, e.g.
* the invitee, the person being banned, etc.
* @privateRemarks
* Should be read-only
*/
public target: RoomMember | null = null;
/**
* The sending status of the event.
* @privateRemarks
* Should be read-only
*/
public status: EventStatus | null = null;
/**
* most recent error associated with sending the event, if any
* @privateRemarks
* Should be read-only
*/
public error: MatrixError | null = null;
public forwardLooking = true; // only state events may be backwards looking
/**
* True if this event is 'forward looking', meaning
* that getDirectionalContent() will return event.content and not event.prev_content.
* Only state events may be backwards looking
* Default: true. <strong>This property is experimental and may change.</strong>
* @privateRemarks
* Should be read-only
*/
public forwardLooking = true;
/* If the event is a `m.key.verification.request` (or to_device `m.key.verification.start`) event,
* `Crypto` will set this the `VerificationRequest` for the event
@ -288,26 +327,11 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
/**
* Construct a Matrix Event object
* @constructor
*
* @param {Object} event The raw event to be wrapped in this DAO
*
* @prop {Object} event The raw (possibly encrypted) event. <b>Do not access
* @param event - The raw (possibly encrypted) event. <b>Do not access
* this property</b> directly unless you absolutely have to. Prefer the getter
* methods defined on this class. Using the getter methods shields your app
* from changes to event JSON between Matrix versions.
*
* @prop {RoomMember} sender The room member who sent this event, or null e.g.
* this is a presence event. This is only guaranteed to be set for events that
* appear in a timeline, ie. do not guarantee that it will be set on state
* events.
* @prop {RoomMember} target The room member who is the target of this event, e.g.
* the invitee, the person being banned, etc.
* @prop {EventStatus} status The sending status of the event.
* @prop {Error} error most recent error associated with sending the event, if any
* @prop {boolean} forwardLooking True if this event is 'forward looking', meaning
* that getDirectionalContent() will return event.content and not event.prev_content.
* Default: true. <strong>This property is experimental and may change.</strong>
*/
public constructor(public event: Partial<IEvent> = {}) {
super();
@ -360,7 +384,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
/**
* Gets the event as though it would appear unencrypted. If the event is already not
* encrypted, it is simply returned as-is.
* @returns {IEvent} The event in wire format.
* @returns The event in wire format.
*/
public getEffectiveEvent(): IEvent {
const content = Object.assign({}, this.getContent()); // clone for mutation
@ -389,7 +413,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
/**
* Get the event_id for this event.
* @return {string} The event ID, e.g. <code>$143350589368169JsLZx:localhost
* @returns The event ID, e.g. <code>$143350589368169JsLZx:localhost
* </code>
*/
public getId(): string | undefined {
@ -398,7 +422,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
/**
* Get the user_id for this event.
* @return {string} The user ID, e.g. <code>@alice:matrix.org</code>
* @returns The user ID, e.g. `@alice:matrix.org`
*/
public getSender(): string | undefined {
return this.event.sender || this.event.user_id; // v2 / v1
@ -407,7 +431,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
/**
* Get the (decrypted, if necessary) type of event.
*
* @return {string} The event type, e.g. <code>m.room.message</code>
* @returns The event type, e.g. `m.room.message`
*/
public getType(): EventType | string {
if (this.clearEvent) {
@ -420,16 +444,16 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
* Get the (possibly encrypted) type of the event that will be sent to the
* homeserver.
*
* @return {string} The event type.
* @returns The event type.
*/
public getWireType(): EventType | string {
return this.event.type!;
}
/**
* Get the room_id for this event. This will return <code>undefined</code>
* for <code>m.presence</code> events.
* @return {string?} The room ID, e.g. <code>!cURbafjkfsMDVwdRDQ:matrix.org
* Get the room_id for this event. This will return `undefined`
* for `m.presence` events.
* @returns The room ID, e.g. <code>!cURbafjkfsMDVwdRDQ:matrix.org
* </code>
*/
public getRoomId(): string | undefined {
@ -438,7 +462,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
/**
* Get the timestamp of this event.
* @return {Number} The event timestamp, e.g. <code>1433502692297</code>
* @returns The event timestamp, e.g. `1433502692297`
*/
public getTs(): number {
return this.event.origin_server_ts!;
@ -446,7 +470,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
/**
* Get the timestamp of this event, as a Date object.
* @return {Date} The event date, e.g. <code>new Date(1433502692297)</code>
* @returns The event date, e.g. `new Date(1433502692297)`
*/
public getDate(): Date | null {
return this.event.origin_server_ts ? new Date(this.event.origin_server_ts) : null;
@ -457,7 +481,11 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
*
* This is intended for logging, to help trace errors. Example output:
*
* id=$HjnOHV646n0SjLDAqFrgIjim7RCpB7cdMXFrekWYAn type=m.room.encrypted sender=@user:example.com room=!room:example.com ts=2022-10-25T17:30:28.404Z
* @example
* ```
* id=$HjnOHV646n0SjLDAqFrgIjim7RCpB7cdMXFrekWYAn type=m.room.encrypted
* sender=@user:example.com room=!room:example.com ts=2022-10-25T17:30:28.404Z
* ```
*/
public getDetails(): string {
let details = `id=${this.getId()} type=${this.getWireType()} sender=${this.getSender()}`;
@ -476,7 +504,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
* Get the (decrypted, if necessary) event content JSON, even if the event
* was replaced by another event.
*
* @return {Object} The event content JSON, or an empty object.
* @returns The event content JSON, or an empty object.
*/
public getOriginalContent<T = IContent>(): T {
if (this._localRedactionEvent) {
@ -493,7 +521,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
* or the content from the replacing event, if any.
* See `makeReplaced`.
*
* @return {Object} The event content JSON, or an empty object.
* @returns The event content JSON, or an empty object.
*/
public getContent<T extends IContent = IContent>(): T {
if (this._localRedactionEvent) {
@ -509,7 +537,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
* Get the (possibly encrypted) event content JSON that will be sent to the
* homeserver.
*
* @return {Object} The event content JSON, or an empty object.
* @returns The event content JSON, or an empty object.
*/
public getWireContent(): IContent {
return this.event.content || {};
@ -560,7 +588,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
/**
* Get the previous event content JSON. This will only return something for
* state events which exist in the timeline.
* @return {Object} The previous event content JSON, or an empty object.
* @returns The previous event content JSON, or an empty object.
*/
public getPrevContent(): IContent {
// v2 then v1 then default
@ -573,7 +601,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
* In practice, this means we get the chronologically earlier content value
* for this event (this method should surely be called getEarlierContent)
* <strong>This method is experimental and may change.</strong>
* @return {Object} event.content if this event is forward-looking, else
* @returns event.content if this event is forward-looking, else
* event.prev_content.
*/
public getDirectionalContent(): IContent {
@ -585,7 +613,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
* event arrived at the device, and not the age of the event when this
* function was called.
* Can only be returned once the server has echo'ed back
* @return {Number|undefined} The age of this event in milliseconds.
* @returns The age of this event in milliseconds.
*/
public getAge(): number | undefined {
return this.getUnsigned().age || this.event.age; // v2 / v1
@ -595,7 +623,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
* Get the age of the event when this function was called.
* This is the 'age' field adjusted according to how long this client has
* had the event.
* @return {Number} The age of this event in milliseconds.
* @returns The age of this event in milliseconds.
*/
public getLocalAge(): number {
return Date.now() - this.localTimestamp;
@ -604,7 +632,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
/**
* Get the event state_key if it has one. This will return <code>undefined
* </code> for message events.
* @return {string} The event's <code>state_key</code>.
* @returns The event's `state_key`.
*/
public getStateKey(): string | undefined {
return this.event.state_key;
@ -612,7 +640,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
/**
* Check if this event is a state event.
* @return {boolean} True if this is a state event.
* @returns True if this is a state event.
*/
public isState(): boolean {
return this.event.state_key !== undefined;
@ -624,18 +652,18 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
*
* @internal
*
* @param {string} cryptoType type of the encrypted event - typically
* @param cryptoType - type of the encrypted event - typically
* <tt>"m.room.encrypted"</tt>
*
* @param {object} cryptoContent raw 'content' for the encrypted event.
* @param cryptoContent - raw 'content' for the encrypted event.
*
* @param {string} senderCurve25519Key curve25519 key to record for the
* @param senderCurve25519Key - curve25519 key to record for the
* sender of this event.
* See {@link module:models/event.MatrixEvent#getSenderKey}.
* See {@link MatrixEvent#getSenderKey}.
*
* @param {string} claimedEd25519Key claimed ed25519 key to record for the
* @param claimedEd25519Key - claimed ed25519 key to record for the
* sender if this event.
* See {@link module:models/event.MatrixEvent#getClaimedEd25519Key}
* See {@link MatrixEvent#getClaimedEd25519Key}
*/
public makeEncrypted(
cryptoType: string,
@ -657,7 +685,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
/**
* Check if this event is currently being decrypted.
*
* @return {boolean} True if this event is currently being decrypted, else false.
* @returns True if this event is currently being decrypted, else false.
*/
public isBeingDecrypted(): boolean {
return this.decryptionPromise != null;
@ -672,7 +700,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
*
* (This implies that we might retry decryption at some point in the future)
*
* @return {boolean} True if this event is an encrypted event which we
* @returns True if this event is an encrypted event which we
* couldn't decrypt.
*/
public isDecryptionFailure(): boolean {
@ -695,14 +723,9 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
*
* @internal
*
* @param {module:crypto} crypto crypto module
* @param {object} options
* @param {boolean} options.isRetry True if this is a retry (enables more logging)
* @param {boolean} options.emit Emits "event.decrypted" if set to true
* @param {boolean} options.forceRedecryptIfUntrusted whether the message should be
* re-decrypted if it was previously successfully decrypted with an untrusted key
* @param crypto - crypto module
*
* @returns {Promise} promise which resolves (to undefined) when the decryption
* @returns promise which resolves (to undefined) when the decryption
* attempt is completed.
*/
public async attemptDecryption(crypto: Crypto, options: IDecryptOptions = {}): Promise<void> {
@ -741,10 +764,10 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
/**
* Cancel any room key request for this event and resend another.
*
* @param {module:crypto} crypto crypto module
* @param {string} userId the user who received this event
* @param crypto - crypto module
* @param userId - the user who received this event
*
* @returns {Promise} a promise that resolves when the request is queued
* @returns a promise that resolves when the request is queued
*/
public cancelAndResendKeyRequest(crypto: Crypto, userId: string): Promise<void> {
const wireContent = this.getWireContent();
@ -759,9 +782,9 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
/**
* Calculate the recipients for keyshare requests.
*
* @param {string} userId the user who received this event.
* @param userId - the user who received this event.
*
* @returns {Array} array of recipients
* @returns array of recipients
*/
public getKeyRequestRecipients(userId: string): IKeyRequestRecipient[] {
// send the request to all of our own devices, and the
@ -903,10 +926,10 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
*
* @internal
*
* @fires module:models/event.MatrixEvent#"Event.decrypted"
* @param decryptionResult - the decryption result, including the plaintext and some key info
*
* @param {module:crypto~EventDecryptionResult} decryptionResult
* the decryption result, including the plaintext and some key info
* @remarks
* Fires {@link MatrixEventEvent.Decrypted}
*/
private setClearData(decryptionResult: IEventDecryptionResult): void {
this.clearEvent = decryptionResult.clearEvent;
@ -922,7 +945,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
* Gets the cleartext content for this event. If the event is not encrypted,
* or encryption has not been completed, this will return null.
*
* @returns {Object} The cleartext (decrypted) content for the event
* @returns The cleartext (decrypted) content for the event
*/
public getClearContent(): IContent | null {
return this.clearEvent ? this.clearEvent.content : null;
@ -930,7 +953,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
/**
* Check if the event is encrypted.
* @return {boolean} True if this event is encrypted.
* @returns True if this event is encrypted.
*/
public isEncrypted(): boolean {
return !this.isState() && this.event.type === EventType.RoomMessageEncrypted;
@ -946,8 +969,6 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
*
* For a megolm-encrypted event, it is inferred from the Olm message which
* established the megolm session
*
* @return {string}
*/
public getSenderKey(): string | null {
return this.senderCurve25519Key;
@ -957,8 +978,6 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
* The additional keys the sender of this encrypted event claims to possess.
*
* Just a wrapper for #getClaimedEd25519Key (q.v.)
*
* @return {Object<string, string>}
*/
public getKeysClaimed(): Partial<Record<"ed25519", string>> {
if (!this.claimedEd25519Key) return {};
@ -982,8 +1001,6 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
*
* In general, applications should not use this method directly, but should
* instead use MatrixClient.getEventSenderDeviceInfo.
*
* @return {string}
*/
public getClaimedEd25519Key(): string | null {
return this.claimedEd25519Key;
@ -1001,7 +1018,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
* If the device that sent us the key (A) got it from another device which
* it wasn't prepared to vouch for (B), the result will be [A, B]. And so on.
*
* @return {string[]} base64-encoded curve25519 keys, from oldest to newest.
* @returns base64-encoded curve25519 keys, from oldest to newest.
*/
public getForwardingCurve25519KeyChain(): string[] {
return this.forwardingCurve25519KeyChain;
@ -1010,8 +1027,6 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
/**
* Whether the decryption key was obtained from an untrusted source. If so,
* we cannot verify the authenticity of the message.
*
* @return {boolean}
*/
public isKeySourceUntrusted(): boolean | undefined {
return !!this.untrusted;
@ -1047,13 +1062,15 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
/**
* Change the visibility of an event, as per https://github.com/matrix-org/matrix-doc/pull/3531 .
*
* @fires module:models/event.MatrixEvent#"Event.visibilityChange" if `visibilityEvent`
* @param visibilityChange - event holding a hide/unhide payload, or nothing
* if the event is being reset to its original visibility (presumably
* by a visibility event being redacted).
*
* @remarks
* Fires {@link MatrixEventEvent.VisibilityChange} if `visibilityEvent`
* caused a change in the actual visibility of this event, either by making it
* visible (if it was hidden), by making it hidden (if it was visible) or by
* changing the reason (if it was hidden).
* @param visibilityChange event holding a hide/unhide payload, or nothing
* if the event is being reset to its original visibility (presumably
* by a visibility event being redacted).
*/
public applyVisibilityEvent(visibilityChange?: IVisibilityChange): void {
const visible = visibilityChange?.visible ?? true;
@ -1093,8 +1110,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
* Update the content of an event in the same way it would be by the server
* if it were redacted before it was sent to us
*
* @param {module:models/event.MatrixEvent} redactionEvent
* event causing the redaction
* @param redactionEvent - event causing the redaction
*/
public makeRedacted(redactionEvent: MatrixEvent): void {
// quick sanity-check
@ -1145,7 +1161,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
/**
* Check if this event has been redacted
*
* @return {boolean} True if this event has been redacted
* @returns True if this event has been redacted
*/
public isRedacted(): boolean {
return Boolean(this.getUnsigned().redacted_because);
@ -1154,7 +1170,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
/**
* Check if this event is a redaction of another event
*
* @return {boolean} True if this event is a redaction
* @returns True if this event is a redaction
*/
public isRedaction(): boolean {
return this.getType() === EventType.RoomRedaction;
@ -1201,7 +1217,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
* Check if this event alters the visibility of another event,
* as per https://github.com/matrix-org/matrix-doc/pull/3531.
*
* @returns {boolean} True if this event alters the visibility
* @returns True if this event alters the visibility
* of another event.
*/
public isVisibilityEvent(): boolean {
@ -1212,7 +1228,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
* Get the (decrypted, if necessary) redaction event JSON
* if event was redacted
*
* @returns {object} The redaction event JSON, or an empty object
* @returns The redaction event JSON, or an empty object
*/
public getRedactionEvent(): IEvent | {} | null {
if (!this.isRedacted()) return null;
@ -1229,7 +1245,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
/**
* Get the push actions, if known, for this event
*
* @return {?Object} push actions
* @returns push actions
*/
public getPushActions(): IActionsObject | null {
return this.pushActions;
@ -1238,7 +1254,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
/**
* Set the push actions for this event.
*
* @param {Object} pushActions push actions
* @param pushActions - push actions
*/
public setPushActions(pushActions: IActionsObject | null): void {
this.pushActions = pushActions;
@ -1246,7 +1262,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
/**
* Replace the `event` property and recalculate any properties based on it.
* @param {Object} event the object to assign to the `event` property
* @param event - the object to assign to the `event` property
*/
public handleRemoteEcho(event: object): void {
const oldUnsigned = this.getUnsigned();
@ -1276,8 +1292,6 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
/**
* Whether the event is in any phase of sending, send failure, waiting for
* remote echo, etc.
*
* @return {boolean}
*/
public isSending(): boolean {
return !!this.status;
@ -1286,7 +1300,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
/**
* Update the event's sending status and emit an event as well.
*
* @param {String} status The new status
* @param status - The new status
*/
public setStatus(status: EventStatus | null): void {
this.status = status;
@ -1302,9 +1316,8 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
* Get whether the event is a relation event, and of a given type if
* `relType` is passed in. State events cannot be relation events
*
* @param {string?} relType if given, checks that the relation is of the
* @param relType - if given, checks that the relation is of the
* given type
* @return {boolean}
*/
public isRelation(relType?: string): boolean {
// Relation info is lifted out of the encrypted content when sent to
@ -1319,8 +1332,6 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
/**
* Get relation info for the event, if any.
*
* @return {Object}
*/
public getRelation(): IEventRelation | null {
if (!this.isRelation()) {
@ -1332,9 +1343,10 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
/**
* Set an event that replaces the content of this event, through an m.replace relation.
*
* @fires module:models/event.MatrixEvent#"Event.replaced"
* @param newEvent - the event with the replacing content, if any.
*
* @param {MatrixEvent?} newEvent the event with the replacing content, if any.
* @remarks
* Fires {@link MatrixEventEvent.Replaced}
*/
public makeReplaced(newEvent?: MatrixEvent): void {
// don't allow redacted events to be replaced.
@ -1359,8 +1371,6 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
* Returns the status of any associated edit or redaction
* (not for reactions/annotations as their local echo doesn't affect the original event),
* or else the status of the event.
*
* @return {EventStatus}
*/
public getAssociatedStatus(): EventStatus | null {
if (this._replacingEvent) {
@ -1377,8 +1387,6 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
/**
* Returns the event ID of the event replacing the content of this event, if any.
*
* @return {string?}
*/
public replacingEventId(): string | undefined {
const replaceRelation = this.getServerAggregatedRelation<IAggregatedRelation>(RelationType.Replace);
@ -1393,8 +1401,6 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
* Returns the event replacing the content of this event, if any.
* Replacements are aggregated on the server, so this would only
* return an event in case it came down the sync, or for local echo of edits.
*
* @return {MatrixEvent?}
*/
public replacingEvent(): MatrixEvent | null {
return this._replacingEvent;
@ -1402,8 +1408,6 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
/**
* Returns the origin_server_ts of the event replacing the content of this event, if any.
*
* @return {Date?}
*/
public replacingEventDate(): Date | undefined {
const replaceRelation = this.getServerAggregatedRelation<IAggregatedRelation>(RelationType.Replace);
@ -1419,7 +1423,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
/**
* Returns the event that wants to redact this event, but hasn't been sent yet.
* @return {MatrixEvent} the event
* @returns the event
*/
public localRedactionEvent(): MatrixEvent | null {
return this._localRedactionEvent;
@ -1427,8 +1431,6 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
/**
* For relations and redactions, returns the event_id this event is referring to.
*
* @return {string?}
*/
public getAssociatedId(): string | undefined {
const relation = this.getRelation();
@ -1443,8 +1445,6 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
/**
* Checks if this event is associated with another event. See `getAssociatedId`.
*
* @return {boolean}
* @deprecated use hasAssociation instead.
*/
public hasAssocation(): boolean {
@ -1453,8 +1453,6 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
/**
* Checks if this event is associated with another event. See `getAssociatedId`.
*
* @return {boolean}
*/
public hasAssociation(): boolean {
return !!this.getAssociatedId();
@ -1466,7 +1464,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
* Used to replace a local id with remote one before sending
* an event with a related id.
*
* @param {string} eventId the new event id
* @param eventId - the new event id
*/
public updateAssociatedId(eventId: string): void {
const relation = this.getRelation();
@ -1481,7 +1479,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
* Flags an event as cancelled due to future conditions. For example, a verification
* request event in the same sync transaction may be flagged as cancelled to warn
* listeners that a cancellation event is coming down the same pipe shortly.
* @param {boolean} cancelled Whether the event is to be cancelled or not.
* @param cancelled - Whether the event is to be cancelled or not.
*/
public flagCancelled(cancelled = true): void {
this._isCancelled = cancelled;
@ -1490,7 +1488,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
/**
* Gets whether or not the event is flagged as cancelled. See flagCancelled() for
* more information.
* @returns {boolean} True if the event is cancelled, false otherwise.
* @returns True if the event is cancelled, false otherwise.
*/
public isCancelled(): boolean {
return this._isCancelled;
@ -1508,7 +1506,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
*
* This is meant to be used to snapshot the event details themselves, not the
* features (such as sender) surrounding the event.
* @returns {MatrixEvent} A snapshot of this event.
* @returns A snapshot of this event.
*/
public toSnapshot(): MatrixEvent {
const ev = new MatrixEvent(JSON.parse(JSON.stringify(this.event)));
@ -1525,8 +1523,8 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
* Determines if this event is equivalent to the given event. This only checks
* the event object itself, not the other properties of the event. Intended for
* use with toSnapshot() to identify events changing.
* @param {MatrixEvent} otherEvent The other event to check against.
* @returns {boolean} True if the events are the same, false otherwise.
* @param otherEvent - The other event to check against.
* @returns True if the events are the same, false otherwise.
*/
public isEquivalentTo(otherEvent: MatrixEvent): boolean {
if (!otherEvent) return false;
@ -1546,8 +1544,6 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
* This is named `toJSON` for use with `JSON.stringify` which checks objects
* for functions named `toJSON` and will call them to customise the output
* if they are defined.
*
* @return {Object}
*/
public toJSON(): object {
const event = this.getEffectiveEvent();
@ -1625,15 +1621,3 @@ const REDACT_KEEP_CONTENT_MAP: Record<string, Record<string, 1>> = {
'users': 1, 'users_default': 1,
},
} as const;
/**
* Fires when an event is decrypted
*
* @event module:models/event.MatrixEvent#"Event.decrypted"
*
* @param {module:models/event.MatrixEvent} event
* The matrix event which has been decrypted
* @param {module:crypto/algorithms/base.DecryptionError?} err
* The error that occurred during decryption, or `undefined` if no
* error occurred.
*/

View File

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

View File

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

View File

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

View File

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

View File

@ -14,10 +14,6 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @module models/room-member
*/
import { getHttpUriForMxc } from "../content-repo";
import * as utils from "../utils";
import { User } from "./user";
@ -35,9 +31,56 @@ export enum RoomMemberEvent {
}
export type RoomMemberEventHandlerMap = {
/**
* Fires whenever any room member's membership state changes.
* @param event - The matrix event which caused this event to fire.
* @param member - The member whose RoomMember.membership changed.
* @param oldMembership - The previous membership state. Null if it's a new member.
* @example
* ```
* matrixClient.on("RoomMember.membership", function(event, member, oldMembership){
* var newState = member.membership;
* });
* ```
*/
[RoomMemberEvent.Membership]: (event: MatrixEvent, member: RoomMember, oldMembership?: string) => void;
/**
* Fires whenever any room member's name changes.
* @param event - The matrix event which caused this event to fire.
* @param member - The member whose RoomMember.name changed.
* @param oldName - The previous name. Null if the member didn't have a name previously.
* @example
* ```
* matrixClient.on("RoomMember.name", function(event, member){
* var newName = member.name;
* });
* ```
*/
[RoomMemberEvent.Name]: (event: MatrixEvent, member: RoomMember, oldName: string | null) => void;
/**
* Fires whenever any room member's power level changes.
* @param event - The matrix event which caused this event to fire.
* @param member - The member whose RoomMember.powerLevel changed.
* @example
* ```
* matrixClient.on("RoomMember.powerLevel", function(event, member){
* var newPowerLevel = member.powerLevel;
* var newNormPowerLevel = member.powerLevelNorm;
* });
* ```
*/
[RoomMemberEvent.PowerLevel]: (event: MatrixEvent, member: RoomMember) => void;
/**
* Fires whenever any room member's typing state changes.
* @param event - The matrix event which caused this event to fire.
* @param member - The member whose RoomMember.typing changed.
* @example
* ```
* matrixClient.on("RoomMember.typing", function(event, member){
* var isTyping = member.typing;
* });
* ```
*/
[RoomMemberEvent.Typing]: (event: MatrixEvent, member: RoomMember) => void;
};
@ -47,41 +90,55 @@ export class RoomMember extends TypedEventEmitter<RoomMemberEvent, RoomMemberEve
public requestedProfileInfo = false; // used by sync.ts
// XXX these should be read-only
/**
* True if the room member is currently typing.
*/
public typing = false;
/**
* The human-readable name for this room member. This will be
* disambiguated with a suffix of " (\@user_id:matrix.org)" if another member shares the
* same displayname.
*/
public name: string;
/**
* The ambiguous displayname of this room member.
*/
public rawDisplayName: string;
/**
* The power level for this room member.
*/
public powerLevel = 0;
/**
* The normalised power level (0-100) for this room member.
*/
public powerLevelNorm = 0;
/**
* The User object for this room member, if one exists.
*/
public user?: User;
/**
* The membership state for this room member e.g. 'join'.
*/
public membership?: string;
/**
* True if the member's name is disambiguated.
*/
public disambiguate = false;
/**
* The events describing this RoomMember.
*/
public events: {
/**
* The m.room.member event for this RoomMember.
*/
member?: MatrixEvent;
} = {};
/**
* Construct a new room member.
*
* @constructor
* @alias module:models/room-member
*
* @param {string} roomId The room ID of the member.
* @param {string} userId The user ID of the member.
* @prop {string} roomId The room ID for this member.
* @prop {string} userId The user ID of this member.
* @prop {boolean} typing True if the room member is currently typing.
* @prop {string} name The human-readable name for this room member. This will be
* disambiguated with a suffix of " (@user_id:matrix.org)" if another member shares the
* same displayname.
* @prop {string} rawDisplayName The ambiguous displayname of this room member.
* @prop {Number} powerLevel The power level for this room member.
* @prop {Number} powerLevelNorm The normalised power level (0-100) for this
* room member.
* @prop {User} user The User object for this room member, if one exists.
* @prop {string} membership The membership state for this room member e.g. 'join'.
* @prop {Object} events The events describing this RoomMember.
* @prop {MatrixEvent} events.member The m.room.member event for this RoomMember.
* @prop {boolean} disambiguate True if the member's name is disambiguated.
* @param roomId - The room ID of the member.
* @param userId - The user ID of the member.
*/
public constructor(public readonly roomId: string, public readonly userId: string) {
super();
@ -99,7 +156,7 @@ export class RoomMember extends TypedEventEmitter<RoomMemberEvent, RoomMemberEve
}
/**
* @return {boolean} does the member come from a channel that is not sync?
* @returns does the member come from a channel that is not sync?
* This is used to store the member seperately
* from the sync state so it available across browser sessions.
*/
@ -110,11 +167,13 @@ export class RoomMember extends TypedEventEmitter<RoomMemberEvent, RoomMemberEve
/**
* Update this room member's membership event. May fire "RoomMember.name" if
* this event updates this member's name.
* @param {MatrixEvent} event The <code>m.room.member</code> event
* @param {RoomState} roomState Optional. The room state to take into account
* @param event - The `m.room.member` event
* @param roomState - Optional. The room state to take into account
* when calculating (e.g. for disambiguating users with the same name).
* @fires module:client~MatrixClient#event:"RoomMember.name"
* @fires module:client~MatrixClient#event:"RoomMember.membership"
*
* @remarks
* Fires {@link RoomMemberEvent.Name}
* Fires {@link RoomMemberEvent.Membership}
*/
public setMembershipEvent(event: MatrixEvent, roomState?: RoomState): void {
const displayName = event.getDirectionalContent().displayname ?? "";
@ -164,9 +223,10 @@ export class RoomMember extends TypedEventEmitter<RoomMemberEvent, RoomMemberEve
/**
* Update this room member's power level event. May fire
* "RoomMember.powerLevel" if this event updates this member's power levels.
* @param {MatrixEvent} powerLevelEvent The <code>m.room.power_levels</code>
* event
* @fires module:client~MatrixClient#event:"RoomMember.powerLevel"
* @param powerLevelEvent - The `m.room.power_levels` event
*
* @remarks
* Fires {@link RoomMemberEvent.PowerLevel}
*/
public setPowerLevelEvent(powerLevelEvent: MatrixEvent): void {
if (powerLevelEvent.getType() !== EventType.RoomPowerLevels || powerLevelEvent.getStateKey() !== "") {
@ -206,8 +266,10 @@ export class RoomMember extends TypedEventEmitter<RoomMemberEvent, RoomMemberEve
/**
* Update this room member's typing event. May fire "RoomMember.typing" if
* this event changes this member's typing state.
* @param {MatrixEvent} event The typing event
* @fires module:client~MatrixClient#event:"RoomMember.typing"
* @param event - The typing event
*
* @remarks
* Fires {@link RoomMemberEvent.Typing}
*/
public setTypingEvent(event: MatrixEvent): void {
if (event.getType() !== "m.typing") {
@ -240,7 +302,7 @@ export class RoomMember extends TypedEventEmitter<RoomMemberEvent, RoomMemberEve
* Get the timestamp when this RoomMember was last updated. This timestamp is
* updated when properties on this RoomMember are updated.
* It is updated <i>before</i> firing events.
* @return {number} The timestamp
* @returns The timestamp
*/
public getLastModifiedTime(): number {
return this.modified;
@ -255,7 +317,7 @@ export class RoomMember extends TypedEventEmitter<RoomMemberEvent, RoomMemberEve
/**
* If this member was invited with the is_direct flag set, return
* the user that invited this member
* @return {string} user id of the inviter
* @returns user id of the inviter
*/
public getDMInviter(): string | undefined {
// when not available because that room state hasn't been loaded in,
@ -285,21 +347,21 @@ export class RoomMember extends TypedEventEmitter<RoomMemberEvent, RoomMemberEve
/**
* Get the avatar URL for a room member.
* @param {string} baseUrl The base homeserver URL See
* {@link module:client~MatrixClient#getHomeserverUrl}.
* @param {Number} width The desired width of the thumbnail.
* @param {Number} height The desired height of the thumbnail.
* @param {string} resizeMethod The thumbnail resize method to use, either
* @param baseUrl - The base homeserver URL See
* {@link MatrixClient#getHomeserverUrl}.
* @param width - The desired width of the thumbnail.
* @param height - The desired height of the thumbnail.
* @param resizeMethod - The thumbnail resize method to use, either
* "crop" or "scale".
* @param {Boolean} allowDefault (optional) Passing false causes this method to
* @param allowDefault - (optional) Passing false causes this method to
* return null if the user has no avatar image. Otherwise, a default image URL
* will be returned. Default: true. (Deprecated)
* @param {Boolean} allowDirectLinks (optional) If true, the avatar URL will be
* @param allowDirectLinks - (optional) If true, the avatar URL will be
* returned even if it is a direct hyperlink rather than a matrix content URL.
* If false, any non-matrix content URLs will be ignored. Setting this option to
* true will expose URLs that, if fetched, will leak information about the user
* to anyone who they share a room with.
* @return {?string} the avatar URL or null.
* @returns the avatar URL or null.
*/
public getAvatarUrl(
baseUrl: string,
@ -323,7 +385,7 @@ export class RoomMember extends TypedEventEmitter<RoomMemberEvent, RoomMemberEve
/**
* get the mxc avatar url, either from a state event, or from a lazily loaded member
* @return {string} the mxc avatar url
* @returns the mxc avatar url
*/
public getMxcAvatarUrl(): string | undefined {
if (this.events.member) {
@ -390,52 +452,3 @@ function calculateDisplayName(
// with the embed chars or marker chars.
return utils.removeDirectionOverrideChars(displayName);
}
/**
* Fires whenever any room member's name changes.
* @event module:client~MatrixClient#"RoomMember.name"
* @param {MatrixEvent} event The matrix event which caused this event to fire.
* @param {RoomMember} member The member whose RoomMember.name changed.
* @param {string?} oldName The previous name. Null if the member didn't have a
* name previously.
* @example
* matrixClient.on("RoomMember.name", function(event, member){
* var newName = member.name;
* });
*/
/**
* Fires whenever any room member's membership state changes.
* @event module:client~MatrixClient#"RoomMember.membership"
* @param {MatrixEvent} event The matrix event which caused this event to fire.
* @param {RoomMember} member The member whose RoomMember.membership changed.
* @param {string?} oldMembership The previous membership state. Null if it's a
* new member.
* @example
* matrixClient.on("RoomMember.membership", function(event, member, oldMembership){
* var newState = member.membership;
* });
*/
/**
* Fires whenever any room member's typing state changes.
* @event module:client~MatrixClient#"RoomMember.typing"
* @param {MatrixEvent} event The matrix event which caused this event to fire.
* @param {RoomMember} member The member whose RoomMember.typing changed.
* @example
* matrixClient.on("RoomMember.typing", function(event, member){
* var isTyping = member.typing;
* });
*/
/**
* Fires whenever any room member's power level changes.
* @event module:client~MatrixClient#"RoomMember.powerLevel"
* @param {MatrixEvent} event The matrix event which caused this event to fire.
* @param {RoomMember} member The member whose RoomMember.powerLevel changed.
* @example
* matrixClient.on("RoomMember.powerLevel", function(event, member){
* var newPowerLevel = member.powerLevel;
* var newNormPowerLevel = member.powerLevelNorm;
* });
*/

View File

@ -14,10 +14,6 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @module models/room-state
*/
import { RoomMember } from "./room-member";
import { logger } from '../logger';
import * as utils from "../utils";
@ -77,8 +73,52 @@ export enum RoomStateEvent {
}
export type RoomStateEventHandlerMap = {
/**
* Fires whenever the event dictionary in room state is updated.
* @param event - The matrix event which caused this event to fire.
* @param state - The room state whose RoomState.events dictionary
* was updated.
* @param prevEvent - The event being replaced by the new state, if
* known. Note that this can differ from `getPrevContent()` on the new state event
* as this is the store's view of the last state, not the previous state provided
* by the server.
* @example
* ```
* matrixClient.on("RoomState.events", function(event, state, prevEvent){
* var newStateEvent = event;
* });
* ```
*/
[RoomStateEvent.Events]: (event: MatrixEvent, state: RoomState, lastStateEvent: MatrixEvent | null) => void;
/**
* Fires whenever a member in the members dictionary is updated in any way.
* @param event - The matrix event which caused this event to fire.
* @param state - The room state whose RoomState.members dictionary
* was updated.
* @param member - The room member that was updated.
* @example
* ```
* matrixClient.on("RoomState.members", function(event, state, member){
* var newMembershipState = member.membership;
* });
* ```
*/
[RoomStateEvent.Members]: (event: MatrixEvent, state: RoomState, member: RoomMember) => void;
/**
* Fires whenever a member is added to the members dictionary. The RoomMember
* will not be fully populated yet (e.g. no membership state) but will already
* be available in the members dictionary.
* @param event - The matrix event which caused this event to fire.
* @param state - The room state whose RoomState.members dictionary
* was updated with a new entry.
* @param member - The room member that was added.
* @example
* ```
* matrixClient.on("RoomState.newMember", function(event, state, member){
* // add event listeners on 'member'
* });
* ```
*/
[RoomStateEvent.NewMember]: (event: MatrixEvent, state: RoomState, member: RoomMember) => void;
[RoomStateEvent.Update]: (state: RoomState) => void;
[RoomStateEvent.BeaconLiveness]: (state: RoomState, hasLiveBeacons: boolean) => void;
@ -109,8 +149,11 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
private modified = -1;
// XXX: Should be read-only
// The room member dictionary, keyed on the user's ID.
public members: Record<string, RoomMember> = {}; // userId: RoomMember
// The state events dictionary, keyed on the event type and then the state_key value.
public events = new Map<string, Map<string, MatrixEvent>>(); // Map<eventType, Map<stateKey, MatrixEvent>>
// The pagination token for this state.
public paginationToken: string | null = null;
public readonly beacons = new Map<BeaconIdentifier, Beacon>();
@ -123,8 +166,8 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
* It can be mutated by adding state events to it.
* There are two types of room member associated with a state event:
* normal member objects (accessed via getMember/getMembers) which mutate
* with the state to represent the current state of that room/user, eg.
* the object returned by getMember('@bob:example.com') will mutate to
* with the state to represent the current state of that room/user, e.g.
* the object returned by `getMember('@bob:example.com')` will mutate to
* get a different display name if Bob later changes his display name
* in the room.
* There are also 'sentinel' members (accessed via getSentinelMember).
@ -137,18 +180,12 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
* after the display name change will return a new RoomMember object
* with Bob's new display name.
*
* @constructor
* @param {?string} roomId Optional. The ID of the room which has this state.
* @param roomId - Optional. The ID of the room which has this state.
* If none is specified it just tracks paginationTokens, useful for notifTimelineSet
* @param {?object} oobMemberFlags Optional. The state of loading out of bound members.
* @param oobMemberFlags - Optional. The state of loading out of bound members.
* As the timeline might get reset while they are loading, this state needs to be inherited
* and shared when the room state is cloned for the new timeline.
* This should only be passed from clone.
* @prop {Object.<string, RoomMember>} members The room member dictionary, keyed
* on the user's ID.
* @prop {Object.<string, Object.<string, MatrixEvent>>} events The state
* events dictionary, keyed on the event type and then the state_key value.
* @prop {string} paginationToken The pagination token for this state.
*/
public constructor(public readonly roomId: string, private oobMemberFlags = { status: OobStatus.NotStarted }) {
super();
@ -158,7 +195,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
/**
* Returns the number of joined members in this room
* This method caches the result.
* @return {number} The number of members in this room whose membership is 'join'
* @returns The number of members in this room whose membership is 'join'
*/
public getJoinedMemberCount(): number {
if (this.summaryJoinedMemberCount !== null) {
@ -174,7 +211,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
/**
* Set the joined member count explicitly (like from summary part of the sync response)
* @param {number} count the amount of joined members
* @param count - the amount of joined members
*/
public setJoinedMemberCount(count: number): void {
this.summaryJoinedMemberCount = count;
@ -182,7 +219,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
/**
* Returns the number of invited members in this room
* @return {number} The number of members in this room whose membership is 'invite'
* @returns The number of members in this room whose membership is 'invite'
*/
public getInvitedMemberCount(): number {
if (this.summaryInvitedMemberCount !== null) {
@ -198,7 +235,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
/**
* Set the amount of invited members in this room
* @param {number} count the amount of invited members
* @param count - the amount of invited members
*/
public setInvitedMemberCount(count: number): void {
this.summaryInvitedMemberCount = count;
@ -206,7 +243,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
/**
* Get all RoomMembers in this room.
* @return {Array<RoomMember>} A list of RoomMembers.
* @returns A list of RoomMembers.
*/
public getMembers(): RoomMember[] {
return Object.values(this.members);
@ -214,8 +251,8 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
/**
* Get all RoomMembers in this room, excluding the user IDs provided.
* @param {Array<string>} excludedIds The user IDs to exclude.
* @return {Array<RoomMember>} A list of RoomMembers.
* @param excludedIds - The user IDs to exclude.
* @returns A list of RoomMembers.
*/
public getMembersExcept(excludedIds: string[]): RoomMember[] {
return this.getMembers().filter((m) => !excludedIds.includes(m.userId));
@ -223,8 +260,8 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
/**
* Get a room member by their user ID.
* @param {string} userId The room member's user ID.
* @return {RoomMember} The member or null if they do not exist.
* @param userId - The room member's user ID.
* @returns The member or null if they do not exist.
*/
public getMember(userId: string): RoomMember | null {
return this.members[userId] || null;
@ -236,8 +273,8 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
* may no longer be represented correctly by Room.currentState or Room.oldState.
* The term 'sentinel' refers to the fact that this RoomMember is an unchanging
* guardian for state at this particular point in time.
* @param {string} userId The room member's user ID.
* @return {RoomMember} The member or null if they do not exist.
* @param userId - The room member's user ID.
* @returns The member or null if they do not exist.
*/
public getSentinelMember(userId: string): RoomMember | null {
if (!userId) return null;
@ -256,12 +293,12 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
/**
* Get state events from the state of the room.
* @param {string} eventType The event type of the state event.
* @param {string} stateKey Optional. The state_key of the state event. If
* this is <code>undefined</code> then all matching state events will be
* @param eventType - The event type of the state event.
* @param stateKey - Optional. The state_key of the state event. If
* this is `undefined` then all matching state events will be
* returned.
* @return {MatrixEvent[]|MatrixEvent} A list of events if state_key was
* <code>undefined</code>, else a single event (or null if no match found).
* @returns A list of events if state_key was
* `undefined`, else a single event (or null if no match found).
*/
public getStateEvents(eventType: EventType | string): MatrixEvent[];
public getStateEvents(eventType: EventType | string, stateKey: string): MatrixEvent | null;
@ -287,7 +324,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
/**
* Creates a copy of this room state so that mutations to either won't affect the other.
* @return {RoomState} the copy of the room state
* @returns the copy of the room state
*/
public clone(): RoomState {
const copy = new RoomState(this.roomId, this.oobMemberFlags);
@ -333,7 +370,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
* When lazy loading members while back-paginating,
* the relevant room state for the timeline chunk at the end
* of the chunk can be set with this method.
* @param {MatrixEvent[]} events state events to prepend
* @param events - state events to prepend
*/
public setUnknownStateEvents(events: MatrixEvent[]): void {
const unknownStateEvents = events.filter((event) => {
@ -345,16 +382,17 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
/**
* Add an array of one or more state MatrixEvents, overwriting any existing
* state with the same {type, stateKey} tuple. Will fire "RoomState.events"
* state with the same `{type, stateKey}` tuple. Will fire "RoomState.events"
* for every event added. May fire "RoomState.members" if there are
* <code>m.room.member</code> events. May fire "RoomStateEvent.Marker" if there are
* <code>UNSTABLE_MSC2716_MARKER</code> events.
* @param {MatrixEvent[]} stateEvents a list of state events for this room.
* @param {IMarkerFoundOptions} markerFoundOptions
* @fires module:client~MatrixClient#event:"RoomState.members"
* @fires module:client~MatrixClient#event:"RoomState.newMember"
* @fires module:client~MatrixClient#event:"RoomState.events"
* @fires module:client~MatrixClient#event:"RoomStateEvent.Marker"
* `m.room.member` events. May fire "RoomStateEvent.Marker" if there are
* `UNSTABLE_MSC2716_MARKER` events.
* @param stateEvents - a list of state events for this room.
*
* @remarks
* Fires {@link RoomStateEvent.Members}
* Fires {@link RoomStateEvent.NewMember}
* Fires {@link RoomStateEvent.Events}
* Fires {@link RoomStateEvent.Marker}
*/
public setStateEvents(stateEvents: MatrixEvent[], markerFoundOptions?: IMarkerFoundOptions): void {
this.updateModifiedTime();
@ -479,10 +517,12 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
* create it and emit the `RoomState.newMember` event.
* This method makes sure the member is added to the members dictionary
* before emitting, as this is done from setStateEvents and setOutOfBandMember.
* @param {string} userId the id of the user to look up
* @param {MatrixEvent} event the membership event for the (new) member. Used to emit.
* @fires module:client~MatrixClient#event:"RoomState.newMember"
* @returns {RoomMember} the member, existing or newly created.
* @param userId - the id of the user to look up
* @param event - the membership event for the (new) member. Used to emit.
* @returns the member, existing or newly created.
*
* @remarks
* Fires {@link RoomStateEvent.NewMember}
*/
private getOrCreateMember(userId: string, event: MatrixEvent): RoomMember {
let member = this.members[userId];
@ -578,7 +618,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
/**
* Get the out-of-band members loading state, whether loading is needed or not.
* Note that loading might be in progress and hence isn't needed.
* @return {boolean} whether or not the members of this room need to be loaded
* @returns whether or not the members of this room need to be loaded
*/
public needsOutOfBandMembers(): boolean {
return this.oobMemberFlags.status === OobStatus.NotStarted;
@ -624,7 +664,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
/**
* Sets the loaded out-of-band members.
* @param {MatrixEvent[]} stateEvents array of membership state events
* @param stateEvents - array of membership state events
*/
public setOutOfBandMembers(stateEvents: MatrixEvent[]): void {
logger.log(`LL: RoomState about to set ${stateEvents.length} OOB members ...`);
@ -639,7 +679,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
/**
* Sets a single out of band member, used by both setOutOfBandMembers and clone
* @param {MatrixEvent} stateEvent membership state event
* @param stateEvent - membership state event
*/
private setOutOfBandMember(stateEvent: MatrixEvent): void {
if (stateEvent.getType() !== EventType.RoomMember) {
@ -668,7 +708,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
/**
* Set the current typing event for this room.
* @param {MatrixEvent} event The typing event
* @param event - The typing event
*/
public setTypingEvent(event: MatrixEvent): void {
Object.values(this.members).forEach(function(member) {
@ -679,8 +719,8 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
/**
* Get the m.room.member event which has the given third party invite token.
*
* @param {string} token The token
* @return {?MatrixEvent} The m.room.member event or null
* @param token - The token
* @returns The m.room.member event or null
*/
public getInviteForThreePidToken(token: string): MatrixEvent | null {
return this.tokenToInvite[token] || null;
@ -696,7 +736,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
/**
* Get the timestamp when this room state was last updated. This timestamp is
* updated when this object has received new state events.
* @return {number} The timestamp
* @returns The timestamp
*/
public getLastModifiedTime(): number {
return this.modified;
@ -704,8 +744,8 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
/**
* Get user IDs with the specified or similar display names.
* @param {string} displayName The display name to get user IDs from.
* @return {string[]} An array of user IDs or an empty array.
* @param displayName - The display name to get user IDs from.
* @returns An array of user IDs or an empty array.
*/
public getUserIdsWithDisplayName(displayName: string): string[] {
return this.displayNameToUserIds.get(utils.removeHiddenChars(displayName)) ?? [];
@ -714,9 +754,9 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
/**
* Returns true if userId is in room, event is not redacted and either sender of
* mxEvent or has power level sufficient to redact events other than their own.
* @param {MatrixEvent} mxEvent The event to test permission for
* @param {string} userId The user ID of the user to test permission for
* @return {boolean} true if the given used ID can redact given event
* @param mxEvent - The event to test permission for
* @param userId - The user ID of the user to test permission for
* @returns true if the given used ID can redact given event
*/
public maySendRedactionForEvent(mxEvent: MatrixEvent, userId: string): boolean {
const member = this.getMember(userId);
@ -734,9 +774,9 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
/**
* Returns true if the given power level is sufficient for action
* @param {string} action The type of power level to check
* @param {number} powerLevel The power level of the member
* @return {boolean} true if the given power level is sufficient
* @param action - The type of power level to check
* @param powerLevel - The power level of the member
* @returns true if the given power level is sufficient
*/
public hasSufficientPowerLevelFor(action: "ban" | "kick" | "redact", powerLevel: number): boolean {
const powerLevelsEvent = this.getStateEvents(EventType.RoomPowerLevels, "");
@ -756,8 +796,8 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
/**
* Short-form for maySendEvent('m.room.message', userId)
* @param {string} userId The user ID of the user to test permission for
* @return {boolean} true if the given user ID should be permitted to send
* @param userId - The user ID of the user to test permission for
* @returns true if the given user ID should be permitted to send
* message events into the given room.
*/
public maySendMessage(userId: string): boolean {
@ -767,9 +807,9 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
/**
* Returns true if the given user ID has permission to send a normal
* event of type `eventType` into this room.
* @param {string} eventType The type of event to test
* @param {string} userId The user ID of the user to test permission for
* @return {boolean} true if the given user ID should be permitted to send
* @param eventType - The type of event to test
* @param userId - The user ID of the user to test permission for
* @returns true if the given user ID should be permitted to send
* the given type of event into this room,
* according to the room's state.
*/
@ -780,9 +820,9 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
/**
* Returns true if the given MatrixClient has permission to send a state
* event of type `stateEventType` into this room.
* @param {string} stateEventType The type of state events to test
* @param {MatrixClient} cli The client to test permission for
* @return {boolean} true if the given client should be permitted to send
* @param stateEventType - The type of state events to test
* @param cli - The client to test permission for
* @returns true if the given client should be permitted to send
* the given type of state event into this room,
* according to the room's state.
*/
@ -796,9 +836,9 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
/**
* Returns true if the given user ID has permission to send a state
* event of type `stateEventType` into this room.
* @param {string} stateEventType The type of state events to test
* @param {string} userId The user ID of the user to test permission for
* @return {boolean} true if the given user ID should be permitted to send
* @param stateEventType - The type of state events to test
* @param userId - The user ID of the user to test permission for
* @returns true if the given user ID should be permitted to send
* the given type of state event into this room,
* according to the room's state.
*/
@ -809,12 +849,12 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
/**
* Returns true if the given user ID has permission to send a normal or state
* event of type `eventType` into this room.
* @param {string} eventType The type of event to test
* @param {string} userId The user ID of the user to test permission for
* @param {boolean} state If true, tests if the user may send a state
* @param eventType - The type of event to test
* @param userId - The user ID of the user to test permission for
* @param state - If true, tests if the user may send a state
event of this type. Otherwise tests whether
they may send a regular event.
* @return {boolean} true if the given user ID should be permitted to send
* @returns true if the given user ID should be permitted to send
* the given type of event into this room,
* according to the room's state.
*/
@ -859,9 +899,9 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
/**
* Returns true if the given user ID has permission to trigger notification
* of type `notifLevelKey`
* @param {string} notifLevelKey The level of notification to test (eg. 'room')
* @param {string} userId The user ID of the user to test permission for
* @return {boolean} true if the given user ID has permission to trigger a
* @param notifLevelKey - The level of notification to test (eg. 'room')
* @param userId - The user ID of the user to test permission for
* @returns true if the given user ID has permission to trigger a
* notification of this type.
*/
public mayTriggerNotifOfType(notifLevelKey: string, userId: string): boolean {
@ -887,7 +927,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
/**
* Returns the join rule based on the m.room.join_rule state event, defaulting to `invite`.
* @returns {string} the join_rule applied to this room
* @returns the join_rule applied to this room
*/
public getJoinRule(): JoinRule {
const joinRuleEvent = this.getStateEvents(EventType.RoomJoinRules, "");
@ -897,7 +937,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
/**
* Returns the history visibility based on the m.room.history_visibility state event, defaulting to `shared`.
* @returns {HistoryVisibility} the history_visibility applied to this room
* @returns the history_visibility applied to this room
*/
public getHistoryVisibility(): HistoryVisibility {
const historyVisibilityEvent = this.getStateEvents(EventType.RoomHistoryVisibility, "");
@ -907,7 +947,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
/**
* Returns the guest access based on the m.room.guest_access state event, defaulting to `shared`.
* @returns {GuestAccess} the guest_access applied to this room
* @returns the guest_access applied to this room
*/
public getGuestAccess(): GuestAccess {
const guestAccessEvent = this.getStateEvents(EventType.RoomGuestAccess, "");
@ -959,47 +999,3 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
}
}
}
/**
* Fires whenever the event dictionary in room state is updated.
* @event module:client~MatrixClient#"RoomState.events"
* @param {MatrixEvent} event The matrix event which caused this event to fire.
* @param {RoomState} state The room state whose RoomState.events dictionary
* was updated.
* @param {MatrixEvent} prevEvent The event being replaced by the new state, if
* known. Note that this can differ from `getPrevContent()` on the new state event
* as this is the store's view of the last state, not the previous state provided
* by the server.
* @example
* matrixClient.on("RoomState.events", function(event, state, prevEvent){
* var newStateEvent = event;
* });
*/
/**
* Fires whenever a member in the members dictionary is updated in any way.
* @event module:client~MatrixClient#"RoomState.members"
* @param {MatrixEvent} event The matrix event which caused this event to fire.
* @param {RoomState} state The room state whose RoomState.members dictionary
* was updated.
* @param {RoomMember} member The room member that was updated.
* @example
* matrixClient.on("RoomState.members", function(event, state, member){
* var newMembershipState = member.membership;
* });
*/
/**
* Fires whenever a member is added to the members dictionary. The RoomMember
* will not be fully populated yet (e.g. no membership state) but will already
* be available in the members dictionary.
* @event module:client~MatrixClient#"RoomState.newMember"
* @param {MatrixEvent} event The matrix event which caused this event to fire.
* @param {RoomState} state The room state whose RoomState.members dictionary
* was updated with a new entry.
* @param {RoomMember} member The room member that was added.
* @example
* matrixClient.on("RoomState.newMember", function(event, state, member){
* // add event listeners on 'member'
* });
*/

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

@ -14,10 +14,6 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @module models/user
*/
import { MatrixEvent } from "./event";
import { TypedEventEmitter } from "./typed-event-emitter";
@ -30,51 +26,132 @@ export enum UserEvent {
}
export type UserEventHandlerMap = {
/**
* Fires whenever any user's display name changes.
* @param event - The matrix event which caused this event to fire.
* @param user - The user whose User.displayName changed.
* @example
* ```
* matrixClient.on("User.displayName", function(event, user){
* var newName = user.displayName;
* });
* ```
*/
[UserEvent.DisplayName]: (event: MatrixEvent | undefined, user: User) => void;
/**
* Fires whenever any user's avatar URL changes.
* @param event - The matrix event which caused this event to fire.
* @param user - The user whose User.avatarUrl changed.
* @example
* ```
* matrixClient.on("User.avatarUrl", function(event, user){
* var newUrl = user.avatarUrl;
* });
* ```
*/
[UserEvent.AvatarUrl]: (event: MatrixEvent | undefined, user: User) => void;
/**
* Fires whenever any user's presence changes.
* @param event - The matrix event which caused this event to fire.
* @param user - The user whose User.presence changed.
* @example
* ```
* matrixClient.on("User.presence", function(event, user){
* var newPresence = user.presence;
* });
* ```
*/
[UserEvent.Presence]: (event: MatrixEvent | undefined, user: User) => void;
/**
* Fires whenever any user's currentlyActive changes.
* @param event - The matrix event which caused this event to fire.
* @param user - The user whose User.currentlyActive changed.
* @example
* ```
* matrixClient.on("User.currentlyActive", function(event, user){
* var newCurrentlyActive = user.currentlyActive;
* });
* ```
*/
[UserEvent.CurrentlyActive]: (event: MatrixEvent | undefined, user: User) => void;
/**
* Fires whenever any user's lastPresenceTs changes,
* ie. whenever any presence event is received for a user.
* @param event - The matrix event which caused this event to fire.
* @param user - The user whose User.lastPresenceTs changed.
* @example
* ```
* matrixClient.on("User.lastPresenceTs", function(event, user){
* var newlastPresenceTs = user.lastPresenceTs;
* });
* ```
*/
[UserEvent.LastPresenceTs]: (event: MatrixEvent | undefined, user: User) => void;
};
export class User extends TypedEventEmitter<UserEvent, UserEventHandlerMap> {
private modified = -1;
// XXX these should be read-only
/**
* The 'displayname' of the user if known.
* @privateRemarks
* Should be read-only
*/
public displayName?: string;
public rawDisplayName?: string;
/**
* The 'avatar_url' of the user if known.
* @privateRemarks
* Should be read-only
*/
public avatarUrl?: string;
/**
* The presence status message if known.
* @privateRemarks
* Should be read-only
*/
public presenceStatusMsg?: string;
/**
* The presence enum if known.
* @privateRemarks
* Should be read-only
*/
public presence = "offline";
/**
* Timestamp (ms since the epoch) for when we last received presence data for this user.
* We can subtract lastActiveAgo from this to approximate an absolute value for when a user was last active.
* @privateRemarks
* Should be read-only
*/
public lastActiveAgo = 0;
/**
* The time elapsed in ms since the user interacted proactively with the server,
* or we saw a message from the user
* @privateRemarks
* Should be read-only
*/
public lastPresenceTs = 0;
/**
* Whether we should consider lastActiveAgo to be an approximation
* and that the user should be seen as active 'now'
* @privateRemarks
* Should be read-only
*/
public currentlyActive = false;
/**
* The events describing this user.
* @privateRemarks
* Should be read-only
*/
public events: {
/** The m.presence event for this user. */
presence?: MatrixEvent;
profile?: MatrixEvent;
} = {};
/**
* Construct a new User. A User must have an ID and can optionally have extra
* information associated with it.
* @constructor
* @param {string} userId Required. The ID of this user.
* @prop {string} userId The ID of the user.
* @prop {Object} info The info object supplied in the constructor.
* @prop {string} displayName The 'displayname' of the user if known.
* @prop {string} avatarUrl The 'avatar_url' of the user if known.
* @prop {string} presence The presence enum if known.
* @prop {string} presenceStatusMsg The presence status message if known.
* @prop {Number} lastActiveAgo The time elapsed in ms since the user interacted
* proactively with the server, or we saw a message from the user
* @prop {Number} lastPresenceTs Timestamp (ms since the epoch) for when we last
* received presence data for this user. We can subtract
* lastActiveAgo from this to approximate an absolute value for
* when a user was last active.
* @prop {Boolean} currentlyActive Whether we should consider lastActiveAgo to be
* an approximation and that the user should be seen as active 'now'
* @prop {Object} events The events describing this user.
* @prop {MatrixEvent} events.presence The m.presence event for this user.
* Construct a new User. A User must have an ID and can optionally have extra information associated with it.
* @param userId - Required. The ID of this user.
*/
public constructor(public readonly userId: string) {
super();
@ -87,10 +164,12 @@ export class User extends TypedEventEmitter<UserEvent, UserEventHandlerMap> {
* Update this User with the given presence event. May fire "User.presence",
* "User.avatarUrl" and/or "User.displayName" if this event updates this user's
* properties.
* @param {MatrixEvent} event The <code>m.presence</code> event.
* @fires module:client~MatrixClient#event:"User.presence"
* @fires module:client~MatrixClient#event:"User.displayName"
* @fires module:client~MatrixClient#event:"User.avatarUrl"
* @param event - The `m.presence` event.
*
* @remarks
* Fires {@link UserEvent.Presence}
* Fires {@link UserEvent.DisplayName}
* Fires {@link UserEvent.AvatarUrl}
*/
public setPresenceEvent(event: MatrixEvent): void {
if (event.getType() !== "m.presence") {
@ -142,7 +221,7 @@ export class User extends TypedEventEmitter<UserEvent, UserEventHandlerMap> {
/**
* Manually set this user's display name. No event is emitted in response to this
* as there is no underlying MatrixEvent to emit with.
* @param {string} name The new display name.
* @param name - The new display name.
*/
public setDisplayName(name: string): void {
const oldName = this.displayName;
@ -155,7 +234,7 @@ export class User extends TypedEventEmitter<UserEvent, UserEventHandlerMap> {
/**
* Manually set this user's non-disambiguated display name. No event is emitted
* in response to this as there is no underlying MatrixEvent to emit with.
* @param {string} name The new display name.
* @param name - The new display name.
*/
public setRawDisplayName(name?: string): void {
this.rawDisplayName = name;
@ -164,7 +243,7 @@ export class User extends TypedEventEmitter<UserEvent, UserEventHandlerMap> {
/**
* Manually set this user's avatar URL. No event is emitted in response to this
* as there is no underlying MatrixEvent to emit with.
* @param {string} url The new avatar URL.
* @param url - The new avatar URL.
*/
public setAvatarUrl(url?: string): void {
const oldUrl = this.avatarUrl;
@ -185,7 +264,7 @@ export class User extends TypedEventEmitter<UserEvent, UserEventHandlerMap> {
* Get the timestamp when this User was last updated. This timestamp is
* updated when this User receives a new Presence event which has updated a
* property on this object. It is updated <i>before</i> firing events.
* @return {number} The timestamp
* @returns The timestamp
*/
public getLastModifiedTime(): number {
return this.modified;
@ -194,65 +273,9 @@ export class User extends TypedEventEmitter<UserEvent, UserEventHandlerMap> {
/**
* Get the absolute timestamp when this User was last known active on the server.
* It is *NOT* accurate if this.currentlyActive is true.
* @return {number} The timestamp
* @returns The timestamp
*/
public getLastActiveTs(): number {
return this.lastPresenceTs - this.lastActiveAgo;
}
}
/**
* Fires whenever any user's lastPresenceTs changes,
* ie. whenever any presence event is received for a user.
* @event module:client~MatrixClient#"User.lastPresenceTs"
* @param {MatrixEvent} event The matrix event which caused this event to fire.
* @param {User} user The user whose User.lastPresenceTs changed.
* @example
* matrixClient.on("User.lastPresenceTs", function(event, user){
* var newlastPresenceTs = user.lastPresenceTs;
* });
*/
/**
* Fires whenever any user's presence changes.
* @event module:client~MatrixClient#"User.presence"
* @param {MatrixEvent} event The matrix event which caused this event to fire.
* @param {User} user The user whose User.presence changed.
* @example
* matrixClient.on("User.presence", function(event, user){
* var newPresence = user.presence;
* });
*/
/**
* Fires whenever any user's currentlyActive changes.
* @event module:client~MatrixClient#"User.currentlyActive"
* @param {MatrixEvent} event The matrix event which caused this event to fire.
* @param {User} user The user whose User.currentlyActive changed.
* @example
* matrixClient.on("User.currentlyActive", function(event, user){
* var newCurrentlyActive = user.currentlyActive;
* });
*/
/**
* Fires whenever any user's display name changes.
* @event module:client~MatrixClient#"User.displayName"
* @param {MatrixEvent} event The matrix event which caused this event to fire.
* @param {User} user The user whose User.displayName changed.
* @example
* matrixClient.on("User.displayName", function(event, user){
* var newName = user.displayName;
* });
*/
/**
* Fires whenever any user's avatar URL changes.
* @event module:client~MatrixClient#"User.avatarUrl"
* @param {MatrixEvent} event The matrix event which caused this event to fire.
* @param {User} user The user whose User.avatarUrl changed.
* @example
* matrixClient.on("User.avatarUrl", function(event, user){
* var newUrl = user.avatarUrl;
* });
*/

View File

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

View File

@ -48,16 +48,17 @@ type Callback = {
const callbackList: Callback[] = [];
// var debuglog = logger.log.bind(logger);
/* istanbul ignore next */
const debuglog = function(...params: any[]): void {};
/**
* reimplementation of window.setTimeout, which will call the callback if
* the wallclock time goes past the deadline.
*
* @param {function} func callback to be called after a delay
* @param {Number} delayMs number of milliseconds to delay by
* @param func - callback to be called after a delay
* @param delayMs - number of milliseconds to delay by
*
* @return {Number} an identifier for this callback, which may be passed into
* @returns an identifier for this callback, which may be passed into
* clearTimeout later.
*/
export function setTimeout(func: (...params: any[]) => void, delayMs: number, ...params: any[]): number {
@ -93,7 +94,7 @@ export function setTimeout(func: (...params: any[]) => void, delayMs: number, ..
/**
* reimplementation of window.clearTimeout, which mirrors setTimeout
*
* @param {Number} key result from an earlier setTimeout call
* @param key - result from an earlier setTimeout call
*/
export function clearTimeout(key: number): void {
if (callbackList.length === 0) {

View File

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

View File

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

View File

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

View File

@ -14,10 +14,6 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @module room-hierarchy
*/
import { Room } from "./models/room";
import { IHierarchyRoom, IHierarchyRelation } from "./@types/spaces";
import { MatrixClient } from "./client";
@ -41,11 +37,10 @@ export class RoomHierarchy {
*
* A RoomHierarchy instance allows you to easily make use of the /hierarchy API and paginate it.
*
* @param {Room} root the root of this hierarchy
* @param {number} pageSize the maximum number of rooms to return per page, can be overridden per load request.
* @param {number} maxDepth the maximum depth to traverse the hierarchy to
* @param {boolean} suggestedOnly whether to only return rooms with suggested=true.
* @constructor
* @param root - the root of this hierarchy
* @param pageSize - the maximum number of rooms to return per page, can be overridden per load request.
* @param maxDepth - the maximum depth to traverse the hierarchy to
* @param suggestedOnly - whether to only return rooms with suggested=true.
*/
public constructor(
public readonly root: Room,

View File

@ -17,7 +17,6 @@ limitations under the License.
/**
* This is an internal module which manages queuing, scheduling and retrying
* of requests.
* @module scheduler
*/
import * as utils from "./utils";
import { logger } from './logger';
@ -35,20 +34,13 @@ interface IQueueEntry<T> {
attempts: number;
}
/**
* The function to invoke to process (send) events in the queue.
* @param event - The event to send.
* @returns Resolved/rejected depending on the outcome of the request.
*/
type ProcessFunction<T> = (event: MatrixEvent) => Promise<T>;
/**
* Construct a scheduler for Matrix. Requires
* {@link module:scheduler~MatrixScheduler#setProcessFunction} to be provided
* with a way of processing events.
* @constructor
* @param {module:scheduler~retryAlgorithm} retryAlgorithm Optional. The retry
* algorithm to apply when determining when to try to send an event again.
* Defaults to {@link module:scheduler~MatrixScheduler.RETRY_BACKOFF_RATELIMIT}.
* @param {module:scheduler~queueAlgorithm} queueAlgorithm Optional. The queuing
* algorithm to apply when determining which events should be sent before the
* given event. Defaults to {@link module:scheduler~MatrixScheduler.QUEUE_MESSAGES}.
*/
// eslint-disable-next-line camelcase
export class MatrixScheduler<T = ISendEventResponse> {
/**
@ -56,11 +48,8 @@ export class MatrixScheduler<T = ISendEventResponse> {
* times of 2, 4, 8, and 16 seconds (30s total) after which we give up. If the
* failure was due to a rate limited request, the time specified in the error is
* waited before being retried.
* @param {MatrixEvent} event
* @param {Number} attempts Number of attempts that have been made, including the one that just failed (ie. starting at 1)
* @param {MatrixError} err
* @return {Number}
* @see module:scheduler~retryAlgorithm
* @param attempts - Number of attempts that have been made, including the one that just failed (ie. starting at 1)
* @see retryAlgorithm
*/
// eslint-disable-next-line @typescript-eslint/naming-convention
public static RETRY_BACKOFF_RATELIMIT(event: MatrixEvent | null, attempts: number, err: MatrixError): number {
@ -90,11 +79,9 @@ export class MatrixScheduler<T = ISendEventResponse> {
}
/**
* Queues <code>m.room.message</code> events and lets other events continue
* Queues `m.room.message` events and lets other events continue
* concurrently.
* @param {MatrixEvent} event
* @return {string}
* @see module:scheduler~queueAlgorithm
* @see queueAlgorithm
*/
// eslint-disable-next-line @typescript-eslint/naming-convention
public static QUEUE_MESSAGES(event: MatrixEvent): string | null {
@ -116,16 +103,52 @@ export class MatrixScheduler<T = ISendEventResponse> {
private activeQueues: string[] = [];
private procFn: ProcessFunction<T> | null = null;
/**
* Construct a scheduler for Matrix. Requires
* {@link MatrixScheduler#setProcessFunction} to be provided
* with a way of processing events.
* @param retryAlgorithm - Optional. The retry
* algorithm to apply when determining when to try to send an event again.
* Defaults to {@link MatrixScheduler.RETRY_BACKOFF_RATELIMIT}.
* @param queueAlgorithm - Optional. The queuing
* algorithm to apply when determining which events should be sent before the
* given event. Defaults to {@link MatrixScheduler.QUEUE_MESSAGES}.
*/
public constructor(
/**
* The retry algorithm to apply when retrying events. To stop retrying, return
* `-1`. If this event was part of a queue, it will be removed from
* the queue.
* @param event - The event being retried.
* @param attempts - The number of failed attempts. This will always be \>= 1.
* @param err - The most recent error message received when trying
* to send this event.
* @returns The number of milliseconds to wait before trying again. If
* this is 0, the request will be immediately retried. If this is
* `-1`, the event will be marked as
* {@link EventStatus.NOT_SENT} and will not be retried.
*/
public readonly retryAlgorithm = MatrixScheduler.RETRY_BACKOFF_RATELIMIT,
/**
* The queuing algorithm to apply to events. This function must be idempotent as
* it may be called multiple times with the same event. All queues created are
* serviced in a FIFO manner. To send the event ASAP, return `null`
* which will not put this event in a queue. Events that fail to send that form
* part of a queue will be removed from the queue and the next event in the
* queue will be sent.
* @param event - The event to be sent.
* @returns The name of the queue to put the event into. If a queue with
* this name does not exist, it will be created. If this is `null`,
* the event is not put into a queue and will be sent concurrently.
*/
public readonly queueAlgorithm = MatrixScheduler.QUEUE_MESSAGES,
) {}
/**
* Retrieve a queue based on an event. The event provided does not need to be in
* the queue.
* @param {MatrixEvent} event An event to get the queue for.
* @return {?Array<MatrixEvent>} A shallow copy of events in the queue or null.
* @param event - An event to get the queue for.
* @returns A shallow copy of events in the queue or null.
* Modifying this array will not modify the list itself. Modifying events in
* this array <i>will</i> modify the underlying event in the queue.
* @see MatrixScheduler.removeEventFromQueue To remove an event from the queue.
@ -143,8 +166,8 @@ export class MatrixScheduler<T = ISendEventResponse> {
/**
* Remove this event from the queue. The event is equal to another event if they
* have the same ID returned from event.getId().
* @param {MatrixEvent} event The event to remove.
* @return {boolean} True if this event was removed.
* @param event - The event to remove.
* @returns True if this event was removed.
*/
public removeEventFromQueue(event: MatrixEvent): boolean {
const name = this.queueAlgorithm(event);
@ -168,7 +191,7 @@ export class MatrixScheduler<T = ISendEventResponse> {
* Set the process function. Required for events in the queue to be processed.
* If set after events have been added to the queue, this will immediately start
* processing them.
* @param {module:scheduler~processFn} fn The function that can process events
* @param fn - The function that can process events
* in the queue.
*/
public setProcessFunction(fn: ProcessFunction<T>): void {
@ -178,8 +201,8 @@ export class MatrixScheduler<T = ISendEventResponse> {
/**
* Queue an event if it is required and start processing queues.
* @param {MatrixEvent} event The event that may be queued.
* @return {?Promise} A promise if the event was queued, which will be
* @param event - The event that may be queued.
* @returns A promise if the event was queued, which will be
* resolved or rejected in due time, else null.
*/
public queueEvent(event: MatrixEvent): Promise<T> | null {
@ -283,46 +306,9 @@ export class MatrixScheduler<T = ISendEventResponse> {
}
}
/* istanbul ignore next */
function debuglog(...args: any[]): void {
if (DEBUG) {
logger.log(...args);
}
}
/**
* The retry algorithm to apply when retrying events. To stop retrying, return
* <code>-1</code>. If this event was part of a queue, it will be removed from
* the queue.
* @callback retryAlgorithm
* @param {MatrixEvent} event The event being retried.
* @param {Number} attempts The number of failed attempts. This will always be
* >= 1.
* @param {MatrixError} err The most recent error message received when trying
* to send this event.
* @return {Number} The number of milliseconds to wait before trying again. If
* this is 0, the request will be immediately retried. If this is
* <code>-1</code>, the event will be marked as
* {@link module:models/event.EventStatus.NOT_SENT} and will not be retried.
*/
/**
* The queuing algorithm to apply to events. This function must be idempotent as
* it may be called multiple times with the same event. All queues created are
* serviced in a FIFO manner. To send the event ASAP, return <code>null</code>
* which will not put this event in a queue. Events that fail to send that form
* part of a queue will be removed from the queue and the next event in the
* queue will be sent.
* @callback queueAlgorithm
* @param {MatrixEvent} event The event to be sent.
* @return {string} The name of the queue to put the event into. If a queue with
* this name does not exist, it will be created. If this is <code>null</code>,
* the event is not put into a queue and will be sent concurrently.
*/
/**
* The function to invoke to process (send) events in the queue.
* @callback processFn
* @param {MatrixEvent} event The event to send.
* @return {Promise} Resolved/rejected depending on the outcome of the request.
*/

View File

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

View File

@ -156,7 +156,7 @@ export enum SlidingSyncState {
/**
* Internal Class. SlidingList represents a single list in sliding sync. The list can have filters,
* multiple sliding windows, and maintains the index->room_id mapping.
* multiple sliding windows, and maintains the index-\>room_id mapping.
*/
class SlidingList {
private list!: MSC3575List;
@ -168,7 +168,7 @@ class SlidingList {
/**
* Construct a new sliding list.
* @param {MSC3575List} list The range, sort and filter values to use for this list.
* @param list - The range, sort and filter values to use for this list.
*/
public constructor(list: MSC3575List) {
this.replaceList(list);
@ -177,7 +177,7 @@ class SlidingList {
/**
* Mark this list as modified or not. Modified lists will return sticky params with calls to getList.
* This is useful for the first time the list is sent, or if the list has changed in some way.
* @param modified True to mark this list as modified so all sticky parameters will be re-sent.
* @param modified - True to mark this list as modified so all sticky parameters will be re-sent.
*/
public setModified(modified: boolean): void {
this.isModified = modified;
@ -185,7 +185,7 @@ class SlidingList {
/**
* Update the list range for this list. Does not affect modified status as list ranges are non-sticky.
* @param newRanges The new ranges for the list
* @param newRanges - The new ranges for the list
*/
public updateListRange(newRanges: number[][]): void {
this.list.ranges = JSON.parse(JSON.stringify(newRanges));
@ -193,7 +193,7 @@ class SlidingList {
/**
* Replace list parameters. All fields will be replaced with the new list parameters.
* @param list The new list parameters
* @param list - The new list parameters
*/
public replaceList(list: MSC3575List): void {
list.filters = list.filters || {};
@ -213,7 +213,7 @@ class SlidingList {
/**
* Return a copy of the list suitable for a request body.
* @param {boolean} forceIncludeAllParams True to forcibly include all params even if the list
* @param forceIncludeAllParams - True to forcibly include all params even if the list
* hasn't been modified. Callers may want to do this if they are modifying the list prior to calling
* updateList.
*/
@ -235,7 +235,7 @@ class SlidingList {
* a b c d _ f COMMAND: DELETE 7;
* e a b c d f COMMAND: INSERT 0 e;
* c=3 is wrong as we are not tracking it, ergo we need to see if `i` is in range else drop it
* @param i The index to check
* @param i - The index to check
* @returns True if the index is within a sliding window
*/
public isIndexInRange(i: number): boolean {
@ -274,13 +274,13 @@ export interface Extension<Req extends {}, Res extends {}> {
/**
* A function which is called when the request JSON is being formed.
* Returns the data to insert under this key.
* @param isInitial True when this is part of the initial request (send sticky params)
* @param isInitial - True when this is part of the initial request (send sticky params)
* @returns The request JSON to send.
*/
onRequest(isInitial: boolean): Req | undefined;
/**
* A function which is called when there is response JSON under this extension.
* @param data The response JSON under the extension name.
* @param data - The response JSON under the extension name.
*/
onResponse(data: Res): void;
/**
@ -368,11 +368,11 @@ export class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, SlidingSync
/**
* Create a new sliding sync instance
* @param {string} proxyBaseUrl The base URL of the sliding sync proxy
* @param {MSC3575List[]} lists The lists to use for sliding sync.
* @param {MSC3575RoomSubscription} roomSubscriptionInfo The params to use for room subscriptions.
* @param {MatrixClient} client The client to use for /sync calls.
* @param {number} timeoutMS The number of milliseconds to wait for a response.
* @param proxyBaseUrl - The base URL of the sliding sync proxy
* @param lists - The lists to use for sliding sync.
* @param roomSubscriptionInfo - The params to use for room subscriptions.
* @param client - The client to use for /sync calls.
* @param timeoutMS - The number of milliseconds to wait for a response.
*/
public constructor(
private readonly proxyBaseUrl: string,
@ -388,9 +388,9 @@ export class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, SlidingSync
/**
* Add a custom room subscription, referred to by an arbitrary name. If a subscription with this
* name already exists, it is replaced. No requests are sent by calling this method.
* @param name The name of the subscription. Only used to reference this subscription in
* @param name - The name of the subscription. Only used to reference this subscription in
* useCustomSubscription.
* @param sub The subscription information.
* @param sub - The subscription information.
*/
public addCustomSubscription(name: string, sub: MSC3575RoomSubscription): void {
this.customSubscriptions.set(name, sub);
@ -399,8 +399,8 @@ export class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, SlidingSync
/**
* Use a custom subscription previously added via addCustomSubscription. No requests are sent
* by calling this method. Use modifyRoomSubscriptions to resend subscription information.
* @param roomId The room to use the subscription in.
* @param name The name of the subscription. If this name is unknown, the default subscription
* @param roomId - The room to use the subscription in.
* @param name - The name of the subscription. If this name is unknown, the default subscription
* will be used.
*/
public useCustomSubscription(roomId: string, name: string): void {
@ -419,7 +419,7 @@ export class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, SlidingSync
/**
* Get the room data for a list.
* @param index The list index
* @param index - The list index
* @returns The list data which contains the rooms in this list
*/
public getListData(index: number): {joinedCount: number, roomIndexToRoomId: Record<number, string>} | null {
@ -435,7 +435,7 @@ export class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, SlidingSync
/**
* Get the full list parameters for a list index. This function is provided for callers to use
* in conjunction with setList to update fields on an existing list.
* @param index The list index to get the list for.
* @param index - The list index to get the list for.
* @returns A copy of the list or undefined.
*/
public getList(index: number): MSC3575List | null {
@ -449,9 +449,9 @@ export class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, SlidingSync
* Set new ranges for an existing list. Calling this function when _only_ the ranges have changed
* is more efficient than calling setList(index,list) as this function won't resend sticky params,
* whereas setList always will.
* @param index The list index to modify
* @param ranges The new ranges to apply.
* @return A promise which resolves to the transaction ID when it has been received down sync
* @param index - The list index to modify
* @param ranges - The new ranges to apply.
* @returns A promise which resolves to the transaction ID when it has been received down sync
* (or rejects with the transaction ID if the action was not applied e.g the request was cancelled
* immediately after sending, in which case the action will be applied in the subsequent request)
*/
@ -463,9 +463,9 @@ export class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, SlidingSync
/**
* Add or replace a list. Calling this function will interrupt the /sync request to resend new
* lists.
* @param index The index to modify
* @param list The new list parameters.
* @return A promise which resolves to the transaction ID when it has been received down sync
* @param index - The index to modify
* @param list - The new list parameters.
* @returns A promise which resolves to the transaction ID when it has been received down sync
* (or rejects with the transaction ID if the action was not applied e.g the request was cancelled
* immediately after sending, in which case the action will be applied in the subsequent request)
*/
@ -491,8 +491,8 @@ export class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, SlidingSync
* Modify the room subscriptions for the sync API. Calling this function will interrupt the
* /sync request to resend new subscriptions. If the /sync stream has not started, this will
* prepare the room subscriptions for when start() is called.
* @param s The new desired room subscriptions.
* @return A promise which resolves to the transaction ID when it has been received down sync
* @param s - The new desired room subscriptions.
* @returns A promise which resolves to the transaction ID when it has been received down sync
* (or rejects with the transaction ID if the action was not applied e.g the request was cancelled
* immediately after sending, in which case the action will be applied in the subsequent request)
*/
@ -504,8 +504,8 @@ export class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, SlidingSync
/**
* Modify which events to retrieve for room subscriptions. Invalidates all room subscriptions
* such that they will be sent up afresh.
* @param rs The new room subscription fields to fetch.
* @return A promise which resolves to the transaction ID when it has been received down sync
* @param rs - The new room subscription fields to fetch.
* @returns A promise which resolves to the transaction ID when it has been received down sync
* (or rejects with the transaction ID if the action was not applied e.g the request was cancelled
* immediately after sending, in which case the action will be applied in the subsequent request)
*/
@ -517,7 +517,7 @@ export class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, SlidingSync
/**
* Register an extension to send with the /sync request.
* @param ext The extension to register.
* @param ext - The extension to register.
*/
public registerExtension(ext: Extension<any, any>): void {
if (this.extensions[ext.name()]) {
@ -552,8 +552,8 @@ export class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, SlidingSync
/**
* Invoke all attached room data listeners.
* @param {string} roomId The room which received some data.
* @param {object} roomData The raw sliding sync response JSON.
* @param roomId - The room which received some data.
* @param roomData - The raw sliding sync response JSON.
*/
private invokeRoomDataListeners(roomId: string, roomData: MSC3575RoomData): void {
if (!roomData.required_state) { roomData.required_state = []; }
@ -563,9 +563,9 @@ export class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, SlidingSync
/**
* Invoke all attached lifecycle listeners.
* @param {SlidingSyncState} state The Lifecycle state
* @param {object} resp The raw sync response JSON
* @param {Error?} err Any error that occurred when making the request e.g. network errors.
* @param state - The Lifecycle state
* @param resp - The raw sync response JSON
* @param err - Any error that occurred when making the request e.g. network errors.
*/
private invokeLifecycleListeners(
state: SlidingSyncState,

View File

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

View File

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

View File

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

View File

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

View File

@ -32,7 +32,6 @@ import { IStoredClientOpts } from "../client";
/**
* This is an internal module. See {@link IndexedDBStore} for the public class.
* @module store/indexeddb
*/
// If this value is too small we'll be writing very often which will cause
@ -43,8 +42,11 @@ import { IStoredClientOpts } from "../client";
const WRITE_DELAY_MS = 1000 * 60 * 5; // once every 5 minutes
interface IOpts extends IBaseOpts {
/** The Indexed DB interface e.g. `window.indexedDB` */
indexedDB: IDBFactory;
/** Optional database name. The same name must be used to open the same database. */
dbName?: string;
/** Optional factory to spin up a Worker to execute the IDB transactions within. */
workerFactory?: () => Worker;
}
@ -57,6 +59,10 @@ export class IndexedDBStore extends MemoryStore {
return LocalIndexedDBStoreBackend.exists(indexedDB, dbName);
}
/**
* The backend instance.
* Call through to this API if you need to perform specific indexeddb actions like deleting the database.
*/
public readonly backend: IIndexedDBBackend;
private startedUp = false;
@ -74,10 +80,10 @@ export class IndexedDBStore extends MemoryStore {
* the contents of the store to an IndexedDB backend.
*
* All data is still kept in-memory but can be loaded from disk by calling
* <code>startup()</code>. This can make startup times quicker as a complete
* `startup()`. This can make startup times quicker as a complete
* sync from the server is not required. This does not reduce memory usage as all
* the data is eagerly fetched when <code>startup()</code> is called.
* <pre>
* the data is eagerly fetched when `startup()` is called.
* ```
* let opts = { indexedDB: window.indexedDB, localStorage: window.localStorage };
* let store = new IndexedDBStore(opts);
* await store.startup(); // load from indexed db
@ -90,24 +96,9 @@ export class IndexedDBStore extends MemoryStore {
* console.log("Started up, now with go faster stripes!");
* }
* });
* </pre>
* ```
*
* @constructor
* @extends MemoryStore
* @param {Object} opts Options object.
* @param {Object} opts.indexedDB The Indexed DB interface e.g.
* <code>window.indexedDB</code>
* @param {string=} opts.dbName Optional database name. The same name must be used
* to open the same database.
* @param {string=} opts.workerScript Optional URL to a script to invoke a web
* worker with to run IndexedDB queries on the web worker. The IndexedDbStoreWorker
* class is provided for this purpose and requires the application to provide a
* trivial wrapper script around it.
* @param {Object=} opts.workerApi The webWorker API object. If omitted, the global Worker
* object will be used if it exists.
* @prop {IndexedDBStoreBackend} backend The backend instance. Call through to
* this API if you need to perform specific indexeddb actions like deleting the
* database.
* @param opts - Options object.
*/
public constructor(opts: IOpts) {
super(opts);
@ -126,7 +117,7 @@ export class IndexedDBStore extends MemoryStore {
public on = this.emitter.on.bind(this.emitter);
/**
* @return {Promise} Resolved when loaded from indexed db.
* @returns Resolved when loaded from indexed db.
*/
public startup(): Promise<void> {
if (this.startedUp) {
@ -152,7 +143,7 @@ export class IndexedDBStore extends MemoryStore {
}
/**
* @return {Promise} Resolves with a sync response to restore the
* @returns Promise which resolves with a sync response to restore the
* client state to where it was at the last save, or null if there
* is no saved sync data.
*/
@ -160,13 +151,13 @@ export class IndexedDBStore extends MemoryStore {
return this.backend.getSavedSync();
}, "getSavedSync");
/** @return {Promise<boolean>} whether or not the database was newly created in this session. */
/** @returns whether or not the database was newly created in this session. */
public isNewlyCreated = this.degradable((): Promise<boolean> => {
return this.backend.isNewlyCreated();
}, "isNewlyCreated");
/**
* @return {Promise} If there is a saved sync, the nextBatch token
* @returns If there is a saved sync, the nextBatch token
* for this sync, otherwise null.
*/
public getSavedSyncToken = this.degradable((): Promise<string | null> => {
@ -175,7 +166,7 @@ export class IndexedDBStore extends MemoryStore {
/**
* Delete all data from this store.
* @return {Promise} Resolves if the data was deleted from the database.
* @returns Promise which resolves if the data was deleted from the database.
*/
public deleteAllData = this.degradable((): Promise<void> => {
super.deleteAllData();
@ -193,7 +184,7 @@ export class IndexedDBStore extends MemoryStore {
* not could change between calling this function and calling
* save().
*
* @return {boolean} True if calling save() will actually save
* @returns True if calling save() will actually save
* (at the time this function is called).
*/
public wantsSave(): boolean {
@ -204,8 +195,8 @@ export class IndexedDBStore extends MemoryStore {
/**
* Possibly write data to the database.
*
* @param {boolean} force True to force a save to happen
* @return {Promise} Promise resolves after the write completes
* @param force - True to force a save to happen
* @returns Promise resolves after the write completes
* (or immediately if no write is performed)
*/
public save(force = false): Promise<void> {
@ -241,9 +232,8 @@ export class IndexedDBStore extends MemoryStore {
/**
* Returns the out-of-band membership events for this room that
* were previously loaded.
* @param {string} roomId
* @returns {event[]} the events, potentially an empty array if OOB loading didn't yield any new members
* @returns {null} in case the members for this room haven't been stored yet
* @returns the events, potentially an empty array if OOB loading didn't yield any new members
* @returns in case the members for this room haven't been stored yet
*/
public getOutOfBandMembers = this.degradable((roomId: string): Promise<IStateEventWithRoomId[] | null> => {
return this.backend.getOutOfBandMembers(roomId);
@ -253,9 +243,8 @@ export class IndexedDBStore extends MemoryStore {
* Stores the out-of-band membership events for this room. Note that
* it still makes sense to store an empty array as the OOB status for the room is
* marked as fetched, and getOutOfBandMembers will return an empty array instead of null
* @param {string} roomId
* @param {event[]} membershipEvents the membership events to store
* @returns {Promise} when all members have been stored
* @param membershipEvents - the membership events to store
* @returns when all members have been stored
*/
public setOutOfBandMembers = this.degradable(
(roomId: string, membershipEvents: IStateEventWithRoomId[]): Promise<void> => {
@ -287,9 +276,9 @@ export class IndexedDBStore extends MemoryStore {
* When IndexedDB fails via any of these paths, we degrade this back to a `MemoryStore`
* in place so that the current operation and all future ones are in-memory only.
*
* @param {Function} func The degradable work to do.
* @param {String} fallback The method name for fallback.
* @returns {Function} A wrapped member function.
* @param func - The degradable work to do.
* @param fallback - The method name for fallback.
* @returns A wrapped member function.
*/
private degradable<A extends Array<any>, R = void>(
func: DegradableFn<A, R>,
@ -368,8 +357,8 @@ export class IndexedDBStore extends MemoryStore {
}
/**
* @param {string} roomId ID of the current room
* @returns {string} Storage key to retrieve pending events
* @param roomId - ID of the current room
* @returns Storage key to retrieve pending events
*/
function pendingEventsKey(roomId: string): string {
return `mx_pending_events_${roomId}`;

View File

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

View File

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

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