1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-08-06 12:02:40 +03:00

Update eslint-plugin-matrix-org and improve visibilities & types (#2887)

This commit is contained in:
Michael Telatynski
2022-11-18 09:20:53 +00:00
committed by GitHub
parent e085609572
commit c0f7df8c3b
88 changed files with 486 additions and 456 deletions

View File

@@ -85,5 +85,14 @@ module.exports = {
// We use a `logger` intermediary module // We use a `logger` intermediary module
"no-console": "error", "no-console": "error",
}, },
}, {
files: [
"spec/**/*.ts",
],
rules: {
// We don't need super strict typing in test utilities
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/explicit-member-accessibility": "off",
},
}], }],
}; };

View File

@@ -99,7 +99,7 @@
"eslint-config-google": "^0.14.0", "eslint-config-google": "^0.14.0",
"eslint-import-resolver-typescript": "^3.5.1", "eslint-import-resolver-typescript": "^3.5.1",
"eslint-plugin-import": "^2.26.0", "eslint-plugin-import": "^2.26.0",
"eslint-plugin-matrix-org": "^0.7.0", "eslint-plugin-matrix-org": "^0.8.0",
"eslint-plugin-unicorn": "^44.0.2", "eslint-plugin-unicorn": "^44.0.2",
"exorcist": "^2.0.0", "exorcist": "^2.0.0",
"fake-indexeddb": "^4.0.0", "fake-indexeddb": "^4.0.0",

View File

@@ -709,11 +709,11 @@ describe("MatrixClient syncing", () => {
const room = client!.getRoom(roomOne)!; const room = client!.getRoom(roomOne)!;
const stateAtStart = room.getLiveTimeline().getState(EventTimeline.BACKWARDS)!; const stateAtStart = room.getLiveTimeline().getState(EventTimeline.BACKWARDS)!;
const startRoomNameEvent = stateAtStart.getStateEvents('m.room.name', ''); const startRoomNameEvent = stateAtStart.getStateEvents('m.room.name', '');
expect(startRoomNameEvent.getContent().name).toEqual('Old room name'); expect(startRoomNameEvent!.getContent().name).toEqual('Old room name');
const stateAtEnd = room.getLiveTimeline().getState(EventTimeline.FORWARDS)!; const stateAtEnd = room.getLiveTimeline().getState(EventTimeline.FORWARDS)!;
const endRoomNameEvent = stateAtEnd.getStateEvents('m.room.name', ''); const endRoomNameEvent = stateAtEnd.getStateEvents('m.room.name', '');
expect(endRoomNameEvent.getContent().name).toEqual('A new room name'); expect(endRoomNameEvent!.getContent().name).toEqual('A new room name');
}); });
}); });
@@ -1599,7 +1599,7 @@ describe("MatrixClient syncing", () => {
expect(room.roomId).toBe(roomOne); expect(room.roomId).toBe(roomOne);
expect(room.getMyMembership()).toBe("leave"); expect(room.getMyMembership()).toBe("leave");
expect(room.name).toBe("Room Name"); expect(room.name).toBe("Room Name");
expect(room.currentState.getStateEvents("m.room.name", "").getId()).toBe("$eventId"); expect(room.currentState.getStateEvents("m.room.name", "")?.getId()).toBe("$eventId");
expect(room.timeline[0].getContent().body).toBe("Message 1"); expect(room.timeline[0].getContent().body).toBe("Message 1");
expect(room.timeline[1].getContent().body).toBe("Message 2"); expect(room.timeline[1].getContent().body).toBe("Message 2");
client?.stopPeeking(); client?.stopPeeking();

View File

@@ -179,7 +179,7 @@ describe("RoomWidgetClient", () => {
// It should've also inserted the event into the room object // It should've also inserted the event into the room object
const room = client.getRoom("!1:example.org"); const room = client.getRoom("!1:example.org");
expect(room).not.toBeNull(); expect(room).not.toBeNull();
expect(room!.currentState.getStateEvents("org.example.foo", "bar").getEffectiveEvent()).toEqual(event); expect(room!.currentState.getStateEvents("org.example.foo", "bar")?.getEffectiveEvent()).toEqual(event);
}); });
it("backfills", async () => { it("backfills", async () => {
@@ -195,7 +195,7 @@ describe("RoomWidgetClient", () => {
const room = client.getRoom("!1:example.org"); const room = client.getRoom("!1:example.org");
expect(room).not.toBeNull(); expect(room).not.toBeNull();
expect(room!.currentState.getStateEvents("org.example.foo", "bar").getEffectiveEvent()).toEqual(event); expect(room!.currentState.getStateEvents("org.example.foo", "bar")?.getEffectiveEvent()).toEqual(event);
}); });
}); });

View File

@@ -152,7 +152,7 @@ describe("RoomState", function() {
it("should return a single MatrixEvent if a state_key was specified", it("should return a single MatrixEvent if a state_key was specified",
function() { function() {
const event = state.getStateEvents("m.room.member", userA); const event = state.getStateEvents("m.room.member", userA);
expect(event.getContent()).toMatchObject({ expect(event?.getContent()).toMatchObject({
membership: "join", membership: "join",
}); });
}); });

View File

@@ -22,7 +22,7 @@ import { EventEmitter } from "events";
import { ListenerMap, TypedEventEmitter } from "./models/typed-event-emitter"; import { ListenerMap, TypedEventEmitter } from "./models/typed-event-emitter";
export class ReEmitter { export class ReEmitter {
constructor(private readonly target: EventEmitter) {} public constructor(private readonly target: EventEmitter) {}
// Map from emitter to event name to re-emitter // Map from emitter to event name to re-emitter
private reEmitters = new Map<EventEmitter, Map<string, (...args: any[]) => void>>(); private reEmitters = new Map<EventEmitter, Map<string, (...args: any[]) => void>>();
@@ -38,7 +38,7 @@ export class ReEmitter {
// We include the source as the last argument for event handlers which may need it, // We include the source as the last argument for event handlers which may need it,
// such as read receipt listeners on the client class which won't have the context // such as read receipt listeners on the client class which won't have the context
// of the room. // of the room.
const forSource = (...args: any[]) => { const forSource = (...args: any[]): void => {
// EventEmitter special cases 'error' to make the emit function throw if no // EventEmitter special cases 'error' to make the emit function throw if no
// handler is attached, which sort of makes sense for making sure that something // handler is attached, which sort of makes sense for making sure that something
// handles an error, but for re-emitting, there could be a listener on the original // handles an error, but for re-emitting, there could be a listener on the original
@@ -74,7 +74,7 @@ export class TypedReEmitter<
Events extends string, Events extends string,
Arguments extends ListenerMap<Events>, Arguments extends ListenerMap<Events>,
> extends ReEmitter { > extends ReEmitter {
constructor(target: TypedEventEmitter<Events, Arguments>) { public constructor(target: TypedEventEmitter<Events, Arguments>) {
super(target); super(target);
} }

View File

@@ -31,7 +31,7 @@ export class ToDeviceMessageQueue {
private retryTimeout: ReturnType<typeof setTimeout> | null = null; private retryTimeout: ReturnType<typeof setTimeout> | null = null;
private retryAttempts = 0; private retryAttempts = 0;
constructor(private client: MatrixClient) { public constructor(private client: MatrixClient) {
} }
public start(): void { public start(): void {

View File

@@ -1010,7 +1010,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
// A manager for determining which invites should be ignored. // A manager for determining which invites should be ignored.
public readonly ignoredInvites: IgnoredInvites; public readonly ignoredInvites: IgnoredInvites;
constructor(opts: IMatrixClientCreateOpts) { public constructor(opts: IMatrixClientCreateOpts) {
super(); super();
opts.baseUrl = utils.ensureNoTrailingSlash(opts.baseUrl); opts.baseUrl = utils.ensureNoTrailingSlash(opts.baseUrl);
@@ -1232,7 +1232,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
// shallow-copy the opts dict before modifying and storing it // shallow-copy the opts dict before modifying and storing it
this.clientOpts = Object.assign({}, opts) as IStoredClientOpts; this.clientOpts = Object.assign({}, opts) as IStoredClientOpts;
this.clientOpts.crypto = this.crypto; this.clientOpts.crypto = this.crypto;
this.clientOpts.canResetEntireTimeline = (roomId) => { this.clientOpts.canResetEntireTimeline = (roomId): boolean => {
if (!this.canResetTimelineCallback) { if (!this.canResetTimelineCallback) {
return false; return false;
} }
@@ -1259,7 +1259,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
* High level helper method to stop the client from polling and allow a * High level helper method to stop the client from polling and allow a
* clean shutdown. * clean shutdown.
*/ */
public stopClient() { public stopClient(): void {
this.crypto?.stop(); // crypto might have been initialised even if the client wasn't fully started this.crypto?.stop(); // crypto might have been initialised even if the client wasn't fully started
if (!this.clientRunning) return; // already stopped if (!this.clientRunning) return; // already stopped
@@ -1536,7 +1536,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
* when creating the client. * when creating the client.
* @param {boolean} force True to force use of TURN servers * @param {boolean} force True to force use of TURN servers
*/ */
public setForceTURN(force: boolean) { public setForceTURN(force: boolean): void {
this.forceTURN = force; this.forceTURN = force;
} }
@@ -1544,7 +1544,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
* Set whether to advertise transfer support to other parties on Matrix calls. * Set whether to advertise transfer support to other parties on Matrix calls.
* @param {boolean} support True to advertise the 'm.call.transferee' capability * @param {boolean} support True to advertise the 'm.call.transferee' capability
*/ */
public setSupportsCallTransfer(support: boolean) { public setSupportsCallTransfer(support: boolean): void {
this.supportsCallTransfer = support; this.supportsCallTransfer = support;
} }
@@ -1678,7 +1678,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
* and may change without warning.</b> * and may change without warning.</b>
* @param {boolean} guest True if this is a guest account. * @param {boolean} guest True if this is a guest account.
*/ */
public setGuest(guest: boolean) { public setGuest(guest: boolean): void {
// EXPERIMENTAL: // EXPERIMENTAL:
// If the token is a macaroon, it should be encoded in it that it is a 'guest' // If the token is a macaroon, it should be encoded in it that it is a 'guest'
// access token, which means that the SDK can determine this entirely without // access token, which means that the SDK can determine this entirely without
@@ -1721,7 +1721,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
* *
* @param {EventTimelineSet} set * @param {EventTimelineSet} set
*/ */
public setNotifTimelineSet(set: EventTimelineSet) { public setNotifTimelineSet(set: EventTimelineSet): void {
this.notifTimelineSet = set; this.notifTimelineSet = set;
} }
@@ -2279,11 +2279,11 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
* send, in order to speed up sending of the message. * send, in order to speed up sending of the message.
* @param {module:models/room} room the room the event is in * @param {module:models/room} room the room the event is in
*/ */
public prepareToEncrypt(room: Room) { public prepareToEncrypt(room: Room): void {
if (!this.crypto) { if (!this.crypto) {
throw new Error("End-to-end encryption disabled"); throw new Error("End-to-end encryption disabled");
} }
return this.crypto.prepareToEncrypt(room); this.crypto.prepareToEncrypt(room);
} }
/** /**
@@ -2324,7 +2324,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
* auth data as an object. Can be called multiple times, first with an empty * auth data as an object. Can be called multiple times, first with an empty
* authDict, to obtain the flows. * authDict, to obtain the flows.
*/ */
public bootstrapCrossSigning(opts: IBootstrapCrossSigningOpts) { public bootstrapCrossSigning(opts: IBootstrapCrossSigningOpts): Promise<void> {
if (!this.crypto) { if (!this.crypto) {
throw new Error("End-to-end encryption disabled"); throw new Error("End-to-end encryption disabled");
} }
@@ -2352,11 +2352,11 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
* *
* @param {boolean} val True to trust cross-signed devices * @param {boolean} val True to trust cross-signed devices
*/ */
public setCryptoTrustCrossSignedDevices(val: boolean) { public setCryptoTrustCrossSignedDevices(val: boolean): void {
if (!this.crypto) { if (!this.crypto) {
throw new Error("End-to-end encryption disabled"); throw new Error("End-to-end encryption disabled");
} }
return this.crypto.setCryptoTrustCrossSignedDevices(val); this.crypto.setCryptoTrustCrossSignedDevices(val);
} }
/** /**
@@ -2497,7 +2497,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
* @param {Array} keys The IDs of the keys to use to encrypt the secret or null/undefined * @param {Array} keys The IDs of the keys to use to encrypt the secret or null/undefined
* to use the default (will throw if no default key is set). * to use the default (will throw if no default key is set).
*/ */
public storeSecret(name: string, secret: string, keys?: string[]) { public storeSecret(name: string, secret: string, keys?: string[]): Promise<void> {
if (!this.crypto) { if (!this.crypto) {
throw new Error("End-to-end encryption disabled"); throw new Error("End-to-end encryption disabled");
} }
@@ -2575,7 +2575,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
* *
* @param {string} keyId The new default key ID * @param {string} keyId The new default key ID
*/ */
public setDefaultSecretStorageKeyId(keyId: string) { public setDefaultSecretStorageKeyId(keyId: string): Promise<void> {
if (!this.crypto) { if (!this.crypto) {
throw new Error("End-to-end encryption disabled"); throw new Error("End-to-end encryption disabled");
} }
@@ -2716,7 +2716,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
* *
* This should not normally be necessary. * This should not normally be necessary.
*/ */
public forceDiscardSession(roomId: string) { public forceDiscardSession(roomId: string): void {
if (!this.crypto) { if (!this.crypto) {
throw new Error("End-to-End encryption disabled"); throw new Error("End-to-End encryption disabled");
} }
@@ -2840,7 +2840,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
/** /**
* Disable backing up of keys. * Disable backing up of keys.
*/ */
public disableKeyBackup() { public disableKeyBackup(): void {
if (!this.crypto) { if (!this.crypto) {
throw new Error("End-to-end encryption disabled"); throw new Error("End-to-end encryption disabled");
} }
@@ -3044,7 +3044,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
* Marks all group sessions as needing to be backed up and schedules them to * Marks all group sessions as needing to be backed up and schedules them to
* upload in the background as soon as possible. * upload in the background as soon as possible.
*/ */
public async scheduleAllGroupSessionsForBackup() { public async scheduleAllGroupSessionsForBackup(): Promise<void> {
if (!this.crypto) { if (!this.crypto) {
throw new Error("End-to-end encryption disabled"); throw new Error("End-to-end encryption disabled");
} }
@@ -3401,7 +3401,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
* @param {array} userIds a list of users to share with. The keys will be sent to * @param {array} userIds a list of users to share with. The keys will be sent to
* all of the user's current devices. * all of the user's current devices.
*/ */
public async sendSharedHistoryKeys(roomId: string, userIds: string[]) { public async sendSharedHistoryKeys(roomId: string, userIds: string[]): Promise<void> {
if (!this.crypto) { if (!this.crypto) {
throw new Error("End-to-end encryption disabled"); throw new Error("End-to-end encryption disabled");
} }
@@ -3685,7 +3685,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
* @param {MatrixEvent} event Event to cancel * @param {MatrixEvent} event Event to cancel
* @throws Error if the event is not in QUEUED, NOT_SENT or ENCRYPTING state * @throws Error if the event is not in QUEUED, NOT_SENT or ENCRYPTING state
*/ */
public cancelPendingEvent(event: MatrixEvent) { public cancelPendingEvent(event: MatrixEvent): void {
if (![EventStatus.QUEUED, EventStatus.NOT_SENT, EventStatus.ENCRYPTING].includes(event.status!)) { if (![EventStatus.QUEUED, EventStatus.NOT_SENT, EventStatus.ENCRYPTING].includes(event.status!)) {
throw new Error("cannot cancel an event with status " + event.status); throw new Error("cannot cancel an event with status " + event.status);
} }
@@ -3834,7 +3834,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
public async unstable_createLiveBeacon( public async unstable_createLiveBeacon(
roomId: Room["roomId"], roomId: Room["roomId"],
beaconInfoContent: MBeaconInfoEventContent, beaconInfoContent: MBeaconInfoEventContent,
) { ): Promise<ISendEventResponse> {
return this.unstable_setLiveBeacon(roomId, beaconInfoContent); return this.unstable_setLiveBeacon(roomId, beaconInfoContent);
} }
@@ -3849,7 +3849,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
public async unstable_setLiveBeacon( public async unstable_setLiveBeacon(
roomId: string, roomId: string,
beaconInfoContent: MBeaconInfoEventContent, beaconInfoContent: MBeaconInfoEventContent,
) { ): Promise<ISendEventResponse> {
return this.sendStateEvent(roomId, M_BEACON_INFO.name, beaconInfoContent, this.getUserId()!); return this.sendStateEvent(roomId, M_BEACON_INFO.name, beaconInfoContent, this.getUserId()!);
} }
@@ -4121,7 +4121,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
return this.isRoomEncrypted(roomId) ? EventType.RoomMessageEncrypted : eventType; return this.isRoomEncrypted(roomId) ? EventType.RoomMessageEncrypted : eventType;
} }
protected updatePendingEventStatus(room: Room | null, event: MatrixEvent, newStatus: EventStatus) { protected updatePendingEventStatus(room: Room | null, event: MatrixEvent, newStatus: EventStatus): void {
if (room) { if (room) {
room.updatePendingEvent(event, newStatus); room.updatePendingEvent(event, newStatus);
} else { } else {
@@ -4944,12 +4944,12 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
const populationResults: { [roomId: string]: Error } = {}; const populationResults: { [roomId: string]: Error } = {};
const promises: Promise<any>[] = []; const promises: Promise<any>[] = [];
const doLeave = (roomId: string) => { const doLeave = (roomId: string): Promise<void> => {
return this.leave(roomId).then(() => { return this.leave(roomId).then(() => {
delete populationResults[roomId]; delete populationResults[roomId];
}).catch((err) => { }).catch((err) => {
// suppress error
populationResults[roomId] = err; populationResults[roomId] = err;
return null; // suppress error
}); });
}; };
@@ -5904,7 +5904,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
* Reset the notifTimelineSet entirely, paginating in some historical notifs as * Reset the notifTimelineSet entirely, paginating in some historical notifs as
* a starting point for subsequent pagination. * a starting point for subsequent pagination.
*/ */
public resetNotifTimelineSet() { public resetNotifTimelineSet(): void {
if (!this.notifTimelineSet) { if (!this.notifTimelineSet) {
return; return;
} }
@@ -5949,7 +5949,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
/** /**
* Stop any ongoing room peeking. * Stop any ongoing room peeking.
*/ */
public stopPeeking() { public stopPeeking(): void {
if (this.peekSync) { if (this.peekSync) {
this.peekSync.stopPeeking(); this.peekSync.stopPeeking();
this.peekSync = null; this.peekSync = null;
@@ -6683,7 +6683,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
* *
* @param {boolean} allow * @param {boolean} allow
*/ */
public setFallbackICEServerAllowed(allow: boolean) { public setFallbackICEServerAllowed(allow: boolean): void {
this.fallbackICEServerAllowed = allow; this.fallbackICEServerAllowed = allow;
} }
@@ -7024,7 +7024,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
* Default: returns false. * Default: returns false.
* @param {Function} cb The callback which will be invoked. * @param {Function} cb The callback which will be invoked.
*/ */
public setCanResetTimelineCallback(cb: ResetTimelineCallback) { public setCanResetTimelineCallback(cb: ResetTimelineCallback): void {
this.canResetTimelineCallback = cb; this.canResetTimelineCallback = cb;
} }
@@ -7164,7 +7164,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
* Set the identity server URL of this client * Set the identity server URL of this client
* @param {string} url New identity server URL * @param {string} url New identity server URL
*/ */
public setIdentityServerUrl(url: string) { public setIdentityServerUrl(url: string): void {
this.idBaseUrl = utils.ensureNoTrailingSlash(url); this.idBaseUrl = utils.ensureNoTrailingSlash(url);
this.http.setIdBaseUrl(this.idBaseUrl); this.http.setIdBaseUrl(this.idBaseUrl);
} }
@@ -7181,7 +7181,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
* Set the access token associated with this account. * Set the access token associated with this account.
* @param {string} token The new access token. * @param {string} token The new access token.
*/ */
public setAccessToken(token: string) { public setAccessToken(token: string): void {
this.http.opts.accessToken = token; this.http.opts.accessToken = token;
} }

View File

@@ -33,6 +33,7 @@ import {
LegacyLocationEventContent, LegacyLocationEventContent,
} from "./@types/location"; } from "./@types/location";
import { MRoomTopicEventContent, MTopicContent, M_TOPIC } from "./@types/topic"; import { MRoomTopicEventContent, MTopicContent, M_TOPIC } from "./@types/topic";
import { IContent } from "./models/event";
/** /**
* Generates the content for a HTML Message event * Generates the content for a HTML Message event
@@ -40,7 +41,7 @@ import { MRoomTopicEventContent, MTopicContent, M_TOPIC } from "./@types/topic";
* @param {string} htmlBody the HTML representation of the message * @param {string} htmlBody the HTML representation of the message
* @returns {{msgtype: string, format: string, body: string, formatted_body: string}} * @returns {{msgtype: string, format: string, body: string, formatted_body: string}}
*/ */
export function makeHtmlMessage(body: string, htmlBody: string) { export function makeHtmlMessage(body: string, htmlBody: string): IContent {
return { return {
msgtype: MsgType.Text, msgtype: MsgType.Text,
format: "org.matrix.custom.html", format: "org.matrix.custom.html",
@@ -55,7 +56,7 @@ export function makeHtmlMessage(body: string, htmlBody: string) {
* @param {string} htmlBody the HTML representation of the notice * @param {string} htmlBody the HTML representation of the notice
* @returns {{msgtype: string, format: string, body: string, formatted_body: string}} * @returns {{msgtype: string, format: string, body: string, formatted_body: string}}
*/ */
export function makeHtmlNotice(body: string, htmlBody: string) { export function makeHtmlNotice(body: string, htmlBody: string): IContent {
return { return {
msgtype: MsgType.Notice, msgtype: MsgType.Notice,
format: "org.matrix.custom.html", format: "org.matrix.custom.html",
@@ -70,7 +71,7 @@ export function makeHtmlNotice(body: string, htmlBody: string) {
* @param {string} htmlBody the HTML representation of the emote * @param {string} htmlBody the HTML representation of the emote
* @returns {{msgtype: string, format: string, body: string, formatted_body: string}} * @returns {{msgtype: string, format: string, body: string, formatted_body: string}}
*/ */
export function makeHtmlEmote(body: string, htmlBody: string) { export function makeHtmlEmote(body: string, htmlBody: string): IContent {
return { return {
msgtype: MsgType.Emote, msgtype: MsgType.Emote,
format: "org.matrix.custom.html", format: "org.matrix.custom.html",
@@ -84,7 +85,7 @@ export function makeHtmlEmote(body: string, htmlBody: string) {
* @param {string} body the plaintext body of the emote * @param {string} body the plaintext body of the emote
* @returns {{msgtype: string, body: string}} * @returns {{msgtype: string, body: string}}
*/ */
export function makeTextMessage(body: string) { export function makeTextMessage(body: string): IContent {
return { return {
msgtype: MsgType.Text, msgtype: MsgType.Text,
body: body, body: body,
@@ -96,7 +97,7 @@ export function makeTextMessage(body: string) {
* @param {string} body the plaintext body of the notice * @param {string} body the plaintext body of the notice
* @returns {{msgtype: string, body: string}} * @returns {{msgtype: string, body: string}}
*/ */
export function makeNotice(body: string) { export function makeNotice(body: string): IContent {
return { return {
msgtype: MsgType.Notice, msgtype: MsgType.Notice,
body: body, body: body,
@@ -108,7 +109,7 @@ export function makeNotice(body: string) {
* @param {string} body the plaintext body of the emote * @param {string} body the plaintext body of the emote
* @returns {{msgtype: string, body: string}} * @returns {{msgtype: string, body: string}}
*/ */
export function makeEmoteMessage(body: string) { export function makeEmoteMessage(body: string): IContent {
return { return {
msgtype: MsgType.Emote, msgtype: MsgType.Emote,
body: body, body: body,

View File

@@ -21,7 +21,7 @@ limitations under the License.
import { PkSigning } from "@matrix-org/olm"; import { PkSigning } from "@matrix-org/olm";
import { decodeBase64, encodeBase64, pkSign, pkVerify } from './olmlib'; import { decodeBase64, encodeBase64, IObject, pkSign, pkVerify } from './olmlib';
import { logger } from '../logger'; import { logger } from '../logger';
import { IndexedDBCryptoStore } from '../crypto/store/indexeddb-crypto-store'; import { IndexedDBCryptoStore } from '../crypto/store/indexeddb-crypto-store';
import { decryptAES, encryptAES } from './aes'; import { decryptAES, encryptAES } from './aes';
@@ -74,7 +74,7 @@ export class CrossSigningInfo {
* Requires getCrossSigningKey and saveCrossSigningKeys * Requires getCrossSigningKey and saveCrossSigningKeys
* @param {object} cacheCallbacks Callbacks used to interact with the cache * @param {object} cacheCallbacks Callbacks used to interact with the cache
*/ */
constructor( public constructor(
public readonly userId: string, public readonly userId: string,
private callbacks: ICryptoCallbacks = {}, private callbacks: ICryptoCallbacks = {},
private cacheCallbacks: ICacheCallbacks = {}, private cacheCallbacks: ICacheCallbacks = {},
@@ -175,7 +175,7 @@ export class CrossSigningInfo {
// check what SSSS keys have encrypted the master key (if any) // check what SSSS keys have encrypted the master key (if any)
const stored = await secretStorage.isStored("m.cross_signing.master") || {}; const stored = await secretStorage.isStored("m.cross_signing.master") || {};
// then check which of those SSSS keys have also encrypted the SSK and USK // then check which of those SSSS keys have also encrypted the SSK and USK
function intersect(s: Record<string, ISecretStorageKeyInfo>) { function intersect(s: Record<string, ISecretStorageKeyInfo>): void {
for (const k of Object.keys(stored)) { for (const k of Object.keys(stored)) {
if (!s[k]) { if (!s[k]) {
delete stored[k]; delete stored[k];
@@ -586,7 +586,14 @@ export class CrossSigningInfo {
} }
} }
function deviceToObject(device: DeviceInfo, userId: string) { interface DeviceObject extends IObject {
algorithms: string[];
keys: Record<string, string>;
device_id: string;
user_id: string;
}
function deviceToObject(device: DeviceInfo, userId: string): DeviceObject {
return { return {
algorithms: device.algorithms, algorithms: device.algorithms,
keys: device.keys, keys: device.keys,
@@ -606,7 +613,7 @@ export enum CrossSigningLevel {
* Represents the ways in which we trust a user * Represents the ways in which we trust a user
*/ */
export class UserTrustLevel { export class UserTrustLevel {
constructor( public constructor(
private readonly crossSigningVerified: boolean, private readonly crossSigningVerified: boolean,
private readonly crossSigningVerifiedBefore: boolean, private readonly crossSigningVerifiedBefore: boolean,
private readonly tofu: boolean, private readonly tofu: boolean,
@@ -646,7 +653,7 @@ export class UserTrustLevel {
* Represents the ways in which we trust a device * Represents the ways in which we trust a device
*/ */
export class DeviceTrustLevel { export class DeviceTrustLevel {
constructor( public constructor(
public readonly crossSigningVerified: boolean, public readonly crossSigningVerified: boolean,
public readonly tofu: boolean, public readonly tofu: boolean,
private readonly localVerified: boolean, private readonly localVerified: boolean,
@@ -775,7 +782,7 @@ export async function requestKeysDuringVerification(
// CrossSigningInfo.getCrossSigningKey() to validate/cache // CrossSigningInfo.getCrossSigningKey() to validate/cache
const crossSigning = new CrossSigningInfo( const crossSigning = new CrossSigningInfo(
original.userId, original.userId,
{ getCrossSigningKey: async (type) => { { getCrossSigningKey: async (type): Promise<Uint8Array> => {
logger.debug("Cross-signing: requesting secret", type, deviceId); logger.debug("Cross-signing: requesting secret", type, deviceId);
const { promise } = client.requestSecret( const { promise } = client.requestSecret(
`m.cross_signing.${type}`, [deviceId], `m.cross_signing.${type}`, [deviceId],
@@ -801,7 +808,7 @@ export async function requestKeysDuringVerification(
}); });
// also request and cache the key backup key // also request and cache the key backup key
const backupKeyPromise = (async () => { const backupKeyPromise = (async (): Promise<void> => {
const cachedKey = await client.crypto!.getSessionBackupPrivateKey(); const cachedKey = await client.crypto!.getSessionBackupPrivateKey();
if (!cachedKey) { if (!cachedKey) {
logger.info("No cached backup key found. Requesting..."); logger.info("No cached backup key found. Requesting...");

View File

@@ -102,7 +102,7 @@ export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHand
private readonly serialiser: DeviceListUpdateSerialiser; private readonly serialiser: DeviceListUpdateSerialiser;
constructor( public constructor(
baseApis: MatrixClient, baseApis: MatrixClient,
private readonly cryptoStore: CryptoStore, private readonly cryptoStore: CryptoStore,
olmDevice: OlmDevice, olmDevice: OlmDevice,
@@ -117,7 +117,7 @@ export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHand
/** /**
* Load the device tracking state from storage * Load the device tracking state from storage
*/ */
public async load() { public async load(): Promise<void> {
await this.cryptoStore.doTxn( await this.cryptoStore.doTxn(
'readonly', [IndexedDBCryptoStore.STORE_DEVICE_DATA], (txn) => { 'readonly', [IndexedDBCryptoStore.STORE_DEVICE_DATA], (txn) => {
this.cryptoStore.getEndToEndDeviceData(txn, (deviceData) => { this.cryptoStore.getEndToEndDeviceData(txn, (deviceData) => {
@@ -150,7 +150,7 @@ export class DeviceList extends TypedEventEmitter<EmittedEvents, CryptoEventHand
} }
} }
public stop() { public stop(): void {
if (this.saveTimer !== null) { if (this.saveTimer !== null) {
clearTimeout(this.saveTimer); clearTimeout(this.saveTimer);
} }
@@ -693,7 +693,7 @@ class DeviceListUpdateSerialiser {
* @param {object} olmDevice The Olm Device * @param {object} olmDevice The Olm Device
* @param {object} deviceList The device list object, the device list to be updated * @param {object} deviceList The device list object, the device list to be updated
*/ */
constructor( public constructor(
private readonly baseApis: MatrixClient, private readonly baseApis: MatrixClient,
private readonly olmDevice: OlmDevice, private readonly olmDevice: OlmDevice,
private readonly deviceList: DeviceList, private readonly deviceList: DeviceList,

View File

@@ -61,7 +61,7 @@ export class EncryptionSetupBuilder {
* @param {Object.<String, MatrixEvent>} accountData pre-existing account data, will only be read, not written. * @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 {CryptoCallbacks} delegateCryptoCallbacks crypto callbacks to delegate to if the key isn't in cache yet
*/ */
constructor(accountData: Record<string, MatrixEvent>, delegateCryptoCallbacks?: ICryptoCallbacks) { public constructor(accountData: Record<string, MatrixEvent>, delegateCryptoCallbacks?: ICryptoCallbacks) {
this.accountDataClientAdapter = new AccountDataClientAdapter(accountData); this.accountDataClientAdapter = new AccountDataClientAdapter(accountData);
this.crossSigningCallbacks = new CrossSigningCallbacks(); this.crossSigningCallbacks = new CrossSigningCallbacks();
this.ssssCryptoCallbacks = new SSSSCryptoCallbacks(delegateCryptoCallbacks); this.ssssCryptoCallbacks = new SSSSCryptoCallbacks(delegateCryptoCallbacks);
@@ -192,7 +192,7 @@ export class EncryptionSetupOperation {
* @param {Object} keyBackupInfo * @param {Object} keyBackupInfo
* @param {Object} keySignatures * @param {Object} keySignatures
*/ */
constructor( public constructor(
private readonly accountData: Map<string, object>, private readonly accountData: Map<string, object>,
private readonly crossSigningKeys?: ICrossSigningKeys, private readonly crossSigningKeys?: ICrossSigningKeys,
private readonly keyBackupInfo?: IKeyBackupInfo, private readonly keyBackupInfo?: IKeyBackupInfo,
@@ -272,7 +272,7 @@ class AccountDataClientAdapter
/** /**
* @param {Object.<String, MatrixEvent>} existingValues existing account data * @param {Object.<String, MatrixEvent>} existingValues existing account data
*/ */
constructor(private readonly existingValues: Record<string, MatrixEvent>) { public constructor(private readonly existingValues: Record<string, MatrixEvent>) {
super(); super();
} }
@@ -342,7 +342,7 @@ class CrossSigningCallbacks implements ICryptoCallbacks, ICacheCallbacks {
return Promise.resolve(this.privateKeys.get(type) ?? null); return Promise.resolve(this.privateKeys.get(type) ?? null);
} }
public saveCrossSigningKeys(privateKeys: Record<string, Uint8Array>) { public saveCrossSigningKeys(privateKeys: Record<string, Uint8Array>): void {
for (const [type, privateKey] of Object.entries(privateKeys)) { for (const [type, privateKey] of Object.entries(privateKeys)) {
this.privateKeys.set(type, privateKey); this.privateKeys.set(type, privateKey);
} }
@@ -356,7 +356,7 @@ class CrossSigningCallbacks implements ICryptoCallbacks, ICacheCallbacks {
class SSSSCryptoCallbacks { class SSSSCryptoCallbacks {
private readonly privateKeys = new Map<string, Uint8Array>(); private readonly privateKeys = new Map<string, Uint8Array>();
constructor(private readonly delegateCryptoCallbacks?: ICryptoCallbacks) {} public constructor(private readonly delegateCryptoCallbacks?: ICryptoCallbacks) {}
public async getSecretStorageKey( public async getSecretStorageKey(
{ keys }: { keys: Record<string, ISecretStorageKeyInfo> }, { keys }: { keys: Record<string, ISecretStorageKeyInfo> },

View File

@@ -177,13 +177,13 @@ export class OlmDevice {
// Used by olm to serialise prekey message decryptions // Used by olm to serialise prekey message decryptions
public olmPrekeyPromise: Promise<any> = Promise.resolve(); // set by consumers public olmPrekeyPromise: Promise<any> = Promise.resolve(); // set by consumers
constructor(private readonly cryptoStore: CryptoStore) { public constructor(private readonly cryptoStore: CryptoStore) {
} }
/** /**
* @return {array} The version of Olm. * @return {array} The version of Olm.
*/ */
static getOlmVersion(): [number, number, number] { public static getOlmVersion(): [number, number, number] {
return global.Olm.get_library_version(); return global.Olm.get_library_version();
} }
@@ -1515,7 +1515,9 @@ export class OlmDevice {
}); });
} }
async getSharedHistoryInboundGroupSessions(roomId: string): Promise<[senderKey: string, sessionId: string][]> { public async getSharedHistoryInboundGroupSessions(
roomId: string,
): Promise<[senderKey: string, sessionId: string][]> {
let result: Promise<[senderKey: string, sessionId: string][]>; let result: Promise<[senderKey: string, sessionId: string][]>;
await this.cryptoStore.doTxn( await this.cryptoStore.doTxn(
'readonly', [ 'readonly', [

View File

@@ -102,7 +102,7 @@ export class OutgoingRoomKeyRequestManager {
private clientRunning = true; private clientRunning = true;
constructor( public constructor(
private readonly baseApis: MatrixClient, private readonly baseApis: MatrixClient,
private readonly deviceId: string, private readonly deviceId: string,
private readonly cryptoStore: CryptoStore, private readonly cryptoStore: CryptoStore,
@@ -352,7 +352,7 @@ export class OutgoingRoomKeyRequestManager {
return; return;
} }
const startSendingOutgoingRoomKeyRequests = () => { const startSendingOutgoingRoomKeyRequests = (): void => {
if (this.sendOutgoingRoomKeyRequestsRunning) { if (this.sendOutgoingRoomKeyRequestsRunning) {
throw new Error("RoomKeyRequestSend already in progress!"); throw new Error("RoomKeyRequestSend already in progress!");
} }

View File

@@ -38,7 +38,7 @@ export class RoomList {
// Object of roomId -> room e2e info object (body of the m.room.encryption event) // Object of roomId -> room e2e info object (body of the m.room.encryption event)
private roomEncryption: Record<string, IRoomEncryption> = {}; private roomEncryption: Record<string, IRoomEncryption> = {};
constructor(private readonly cryptoStore?: CryptoStore) {} public constructor(private readonly cryptoStore?: CryptoStore) {}
public async init(): Promise<void> { public async init(): Promise<void> {
await this.cryptoStore!.doTxn( await this.cryptoStore!.doTxn(

View File

@@ -78,7 +78,7 @@ export class SecretStorage<B extends MatrixClient | undefined = MatrixClient> {
// as you don't request any secrets. // as you don't request any secrets.
// A better solution would probably be to split this class up into secret storage and // A better solution would probably be to split this class up into secret storage and
// secret sharing which are really two separate things, even though they share an MSC. // secret sharing which are really two separate things, even though they share an MSC.
constructor( public constructor(
private readonly accountDataAdapter: IAccountDataClient, private readonly accountDataAdapter: IAccountDataClient,
private readonly cryptoCallbacks: ICryptoCallbacks, private readonly cryptoCallbacks: ICryptoCallbacks,
private readonly baseApis: B, private readonly baseApis: B,
@@ -381,7 +381,7 @@ export class SecretStorage<B extends MatrixClient | undefined = MatrixClient> {
const deferred = defer<string>(); const deferred = defer<string>();
this.requests.set(requestId, { name, devices, deferred }); this.requests.set(requestId, { name, devices, deferred });
const cancel = (reason: string) => { const cancel = (reason: string): void => {
// send cancellation event // send cancellation event
const cancelData = { const cancelData = {
action: "request_cancellation", action: "request_cancellation",

View File

@@ -78,7 +78,7 @@ export abstract class EncryptionAlgorithm {
protected readonly baseApis: MatrixClient; protected readonly baseApis: MatrixClient;
protected readonly roomId?: string; protected readonly roomId?: string;
constructor(params: IParams) { public constructor(params: IParams) {
this.userId = params.userId; this.userId = params.userId;
this.deviceId = params.deviceId; this.deviceId = params.deviceId;
this.crypto = params.crypto; this.crypto = params.crypto;
@@ -150,7 +150,7 @@ export abstract class DecryptionAlgorithm {
protected readonly baseApis: MatrixClient; protected readonly baseApis: MatrixClient;
protected readonly roomId?: string; protected readonly roomId?: string;
constructor(params: DecryptionClassParams) { public constructor(params: DecryptionClassParams) {
this.userId = params.userId; this.userId = params.userId;
this.crypto = params.crypto; this.crypto = params.crypto;
this.olmDevice = params.olmDevice; this.olmDevice = params.olmDevice;
@@ -242,7 +242,7 @@ export abstract class DecryptionAlgorithm {
export class DecryptionError extends Error { export class DecryptionError extends Error {
public readonly detailedString: string; public readonly detailedString: string;
constructor(public readonly code: string, msg: string, details?: Record<string, string | Error>) { public constructor(public readonly code: string, msg: string, details?: Record<string, string | Error>) {
super(msg); super(msg);
this.code = code; this.code = code;
this.name = 'DecryptionError'; this.name = 'DecryptionError';
@@ -272,7 +272,7 @@ function detailedStringForDecryptionError(err: DecryptionError, details?: Record
* @extends Error * @extends Error
*/ */
export class UnknownDeviceError extends Error { export class UnknownDeviceError extends Error {
constructor( public constructor(
msg: string, msg: string,
public readonly devices: Record<string, Record<string, object>>, public readonly devices: Record<string, Record<string, object>>,
public event?: MatrixEvent, public event?: MatrixEvent,

View File

@@ -136,7 +136,7 @@ class OutboundSessionInfo {
public sharedWithDevices: Record<string, Record<string, SharedWithData>> = {}; public sharedWithDevices: Record<string, Record<string, SharedWithData>> = {};
public blockedDevicesNotified: Record<string, Record<string, boolean>> = {}; public blockedDevicesNotified: Record<string, Record<string, boolean>> = {};
constructor(public readonly sessionId: string, public readonly sharedHistory = false) { public constructor(public readonly sessionId: string, public readonly sharedHistory = false) {
this.creationTime = new Date().getTime(); this.creationTime = new Date().getTime();
} }
@@ -248,7 +248,7 @@ class MegolmEncryption extends EncryptionAlgorithm {
protected readonly roomId: string; protected readonly roomId: string;
constructor(params: IParams & Required<Pick<IParams, "roomId">>) { public constructor(params: IParams & Required<Pick<IParams, "roomId">>) {
super(params); super(params);
this.roomId = params.roomId; this.roomId = params.roomId;
@@ -347,7 +347,7 @@ class MegolmEncryption extends EncryptionAlgorithm {
singleOlmCreationPhase: boolean, singleOlmCreationPhase: boolean,
blocked: IBlockedMap, blocked: IBlockedMap,
session: OutboundSessionInfo, session: OutboundSessionInfo,
) { ): Promise<void> {
// now check if we need to share with any devices // now check if we need to share with any devices
const shareMap: Record<string, DeviceInfo[]> = {}; const shareMap: Record<string, DeviceInfo[]> = {};
@@ -386,13 +386,13 @@ class MegolmEncryption extends EncryptionAlgorithm {
); );
await Promise.all([ await Promise.all([
(async () => { (async (): Promise<void> => {
// share keys with devices that we already have a session for // share keys with devices that we already have a session for
logger.debug(`Sharing keys with existing Olm sessions in ${this.roomId}`, olmSessions); logger.debug(`Sharing keys with existing Olm sessions in ${this.roomId}`, olmSessions);
await this.shareKeyWithOlmSessions(session, key, payload, olmSessions); await this.shareKeyWithOlmSessions(session, key, payload, olmSessions);
logger.debug(`Shared keys with existing Olm sessions in ${this.roomId}`); logger.debug(`Shared keys with existing Olm sessions in ${this.roomId}`);
})(), })(),
(async () => { (async (): Promise<void> => {
logger.debug( logger.debug(
`Sharing keys (start phase 1) with new Olm sessions in ${this.roomId}`, `Sharing keys (start phase 1) with new Olm sessions in ${this.roomId}`,
devicesWithoutSession, devicesWithoutSession,
@@ -415,7 +415,7 @@ class MegolmEncryption extends EncryptionAlgorithm {
if (!singleOlmCreationPhase && (Date.now() - start < 10000)) { if (!singleOlmCreationPhase && (Date.now() - start < 10000)) {
// perform the second phase of olm session creation if requested, // perform the second phase of olm session creation if requested,
// and if the first phase didn't take too long // and if the first phase didn't take too long
(async () => { (async (): Promise<void> => {
// Retry sending keys to devices that we were unable to establish // Retry sending keys to devices that we were unable to establish
// an olm session for. This time, we use a longer timeout, but we // an olm session for. This time, we use a longer timeout, but we
// do this in the background and don't block anything else while we // do this in the background and don't block anything else while we
@@ -452,7 +452,7 @@ class MegolmEncryption extends EncryptionAlgorithm {
} }
logger.debug(`Shared keys (all phases done) with new Olm sessions in ${this.roomId}`); logger.debug(`Shared keys (all phases done) with new Olm sessions in ${this.roomId}`);
})(), })(),
(async () => { (async (): Promise<void> => {
logger.debug(`There are ${Object.entries(blocked).length} blocked devices in ${this.roomId}`, logger.debug(`There are ${Object.entries(blocked).length} blocked devices in ${this.roomId}`,
Object.entries(blocked)); Object.entries(blocked));
@@ -809,7 +809,7 @@ class MegolmEncryption extends EncryptionAlgorithm {
errorDevices: IOlmDevice[], errorDevices: IOlmDevice[],
otkTimeout: number, otkTimeout: number,
failedServers?: string[], failedServers?: string[],
) { ): Promise<void> {
logger.debug(`Ensuring Olm sessions for devices in ${this.roomId}`); logger.debug(`Ensuring Olm sessions for devices in ${this.roomId}`);
const devicemap = await olmlib.ensureOlmSessionsForDevices( const devicemap = await olmlib.ensureOlmSessionsForDevices(
this.olmDevice, this.baseApis, devicesByUser, false, otkTimeout, failedServers, this.olmDevice, this.baseApis, devicesByUser, false, otkTimeout, failedServers,
@@ -969,7 +969,7 @@ class MegolmEncryption extends EncryptionAlgorithm {
this.encryptionPreparation = { this.encryptionPreparation = {
startTime: Date.now(), startTime: Date.now(),
promise: (async () => { promise: (async (): Promise<void> => {
try { try {
logger.debug(`Getting devices in ${this.roomId}`); logger.debug(`Getting devices in ${this.roomId}`);
const [devicesInRoom, blocked] = await this.getDevicesInRoom(room); const [devicesInRoom, blocked] = await this.getDevicesInRoom(room);
@@ -1231,7 +1231,7 @@ class MegolmDecryption extends DecryptionAlgorithm {
protected readonly roomId: string; protected readonly roomId: string;
constructor(params: DecryptionClassParams<IParams & Required<Pick<IParams, "roomId">>>) { public constructor(params: DecryptionClassParams<IParams & Required<Pick<IParams, "roomId">>>) {
super(params); super(params);
this.roomId = params.roomId; this.roomId = params.roomId;
} }

View File

@@ -120,7 +120,7 @@ export class BackupManager {
private sendingBackups: boolean; // Are we currently sending backups? private sendingBackups: boolean; // Are we currently sending backups?
private sessionLastCheckAttemptedTime: Record<string, number> = {}; // When did we last try to check the server for a given session id? private sessionLastCheckAttemptedTime: Record<string, number> = {}; // When did we last try to check the server for a given session id?
constructor(private readonly baseApis: MatrixClient, public readonly getKey: GetKey) { public constructor(private readonly baseApis: MatrixClient, public readonly getKey: GetKey) {
this.checkedForBackup = false; this.checkedForBackup = false;
this.sendingBackups = false; this.sendingBackups = false;
} }
@@ -609,7 +609,7 @@ export class BackupManager {
export class Curve25519 implements BackupAlgorithm { export class Curve25519 implements BackupAlgorithm {
public static algorithmName = "m.megolm_backup.v1.curve25519-aes-sha2"; public static algorithmName = "m.megolm_backup.v1.curve25519-aes-sha2";
constructor( public constructor(
public authData: ICurve25519AuthData, public authData: ICurve25519AuthData,
private publicKey: any, // FIXME: PkEncryption private publicKey: any, // FIXME: PkEncryption
private getKey: () => Promise<Uint8Array>, private getKey: () => Promise<Uint8Array>,
@@ -661,7 +661,7 @@ export class Curve25519 implements BackupAlgorithm {
} }
} }
public get untrusted() { return true; } public get untrusted(): boolean { return true; }
public async encryptSession(data: Record<string, any>): Promise<any> { public async encryptSession(data: Record<string, any>): Promise<any> {
const plainText: Record<string, any> = Object.assign({}, data); const plainText: Record<string, any> = Object.assign({}, data);
@@ -735,7 +735,7 @@ const UNSTABLE_MSC3270_NAME = new UnstableValue(
export class Aes256 implements BackupAlgorithm { export class Aes256 implements BackupAlgorithm {
public static algorithmName = UNSTABLE_MSC3270_NAME.name; public static algorithmName = UNSTABLE_MSC3270_NAME.name;
constructor( public constructor(
public readonly authData: IAes256AuthData, public readonly authData: IAes256AuthData,
private readonly key: Uint8Array, private readonly key: Uint8Array,
) {} ) {}
@@ -786,7 +786,7 @@ export class Aes256 implements BackupAlgorithm {
} }
} }
public get untrusted() { return false; } public get untrusted(): boolean { return false; }
public encryptSession(data: Record<string, any>): Promise<any> { public encryptSession(data: Record<string, any>): Promise<any> {
const plainText: Record<string, any> = Object.assign({}, data); const plainText: Record<string, any> = Object.assign({}, data);

View File

@@ -62,7 +62,7 @@ export class DehydrationManager {
private keyInfo?: {[props: string]: any}; private keyInfo?: {[props: string]: any};
private deviceDisplayName?: string; private deviceDisplayName?: string;
constructor(private readonly crypto: Crypto) { public constructor(private readonly crypto: Crypto) {
this.getDehydrationKeyFromCache(); this.getDehydrationKeyFromCache();
} }
@@ -294,7 +294,7 @@ export class DehydrationManager {
} }
} }
public stop() { public stop(): void {
if (this.timeoutId) { if (this.timeoutId) {
global.clearTimeout(this.timeoutId); global.clearTimeout(this.timeoutId);
this.timeoutId = undefined; this.timeoutId = undefined;

View File

@@ -94,7 +94,7 @@ export class DeviceInfo {
public unsigned: Record<string, any> = {}; public unsigned: Record<string, any> = {};
public signatures: ISignatures = {}; public signatures: ISignatures = {};
constructor(public readonly deviceId: string) {} public constructor(public readonly deviceId: string) {}
/** /**
* Prepare a DeviceInfo for JSON serialisation in the session store * Prepare a DeviceInfo for JSON serialisation in the session store

View File

@@ -278,7 +278,7 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
/** /**
* @return {string} The version of Olm. * @return {string} The version of Olm.
*/ */
static getOlmVersion(): [number, number, number] { public static getOlmVersion(): [number, number, number] {
return OlmDevice.getOlmVersion(); return OlmDevice.getOlmVersion();
} }
@@ -372,7 +372,7 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
* Each element can either be a string from MatrixClient.verificationMethods * Each element can either be a string from MatrixClient.verificationMethods
* or a class that implements a verification method. * or a class that implements a verification method.
*/ */
constructor( public constructor(
public readonly baseApis: MatrixClient, public readonly baseApis: MatrixClient,
public readonly userId: string, public readonly userId: string,
private readonly deviceId: string, private readonly deviceId: string,
@@ -465,7 +465,7 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
// Assuming no app-supplied callback, default to getting from SSSS. // Assuming no app-supplied callback, default to getting from SSSS.
if (!cryptoCallbacks.getCrossSigningKey && cryptoCallbacks.getSecretStorageKey) { if (!cryptoCallbacks.getCrossSigningKey && cryptoCallbacks.getSecretStorageKey) {
cryptoCallbacks.getCrossSigningKey = async (type) => { cryptoCallbacks.getCrossSigningKey = async (type): Promise<Uint8Array | null> => {
return CrossSigningInfo.getFromSecretStorage(type, this.secretStorage); return CrossSigningInfo.getFromSecretStorage(type, this.secretStorage);
}; };
} }
@@ -709,7 +709,7 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
); );
// Reset the cross-signing keys // Reset the cross-signing keys
const resetCrossSigning = async () => { const resetCrossSigning = async (): Promise<void> => {
crossSigningInfo.resetKeys(); crossSigningInfo.resetKeys();
// Sign master key with device key // Sign master key with device key
await this.signObject(crossSigningInfo.keys.master); await this.signObject(crossSigningInfo.keys.master);
@@ -846,12 +846,12 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
*/ */
// TODO this does not resolve with what it says it does // TODO this does not resolve with what it says it does
public async bootstrapSecretStorage({ public async bootstrapSecretStorage({
createSecretStorageKey = async () => ({} as IRecoveryKey), createSecretStorageKey = async (): Promise<IRecoveryKey> => ({} as IRecoveryKey),
keyBackupInfo, keyBackupInfo,
setupNewKeyBackup, setupNewKeyBackup,
setupNewSecretStorage, setupNewSecretStorage,
getKeyBackupPassphrase, getKeyBackupPassphrase,
}: ICreateSecretStorageOpts = {}) { }: ICreateSecretStorageOpts = {}): Promise<void> {
logger.log("Bootstrapping Secure Secret Storage"); logger.log("Bootstrapping Secure Secret Storage");
const delegateCryptoCallbacks = this.baseApis.cryptoCallbacks; const delegateCryptoCallbacks = this.baseApis.cryptoCallbacks;
const builder = new EncryptionSetupBuilder( const builder = new EncryptionSetupBuilder(
@@ -868,7 +868,7 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
let newKeyId: string | null = null; let newKeyId: string | null = null;
// create a new SSSS key and set it as default // create a new SSSS key and set it as default
const createSSSS = async (opts: IAddSecretStorageKeyOpts, privateKey?: Uint8Array) => { const createSSSS = async (opts: IAddSecretStorageKeyOpts, privateKey?: Uint8Array): Promise<string> => {
if (privateKey) { if (privateKey) {
opts.key = privateKey; opts.key = privateKey;
} }
@@ -884,7 +884,7 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
return keyId; return keyId;
}; };
const ensureCanCheckPassphrase = async (keyId: string, keyInfo: ISecretStorageKeyInfo) => { const ensureCanCheckPassphrase = async (keyId: string, keyInfo: ISecretStorageKeyInfo): Promise<void> => {
if (!keyInfo.mac) { if (!keyInfo.mac) {
const key = await this.baseApis.cryptoCallbacks.getSecretStorageKey?.( const key = await this.baseApis.cryptoCallbacks.getSecretStorageKey?.(
{ keys: { [keyId]: keyInfo } }, "", { keys: { [keyId]: keyInfo } }, "",
@@ -903,7 +903,7 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
} }
}; };
const signKeyBackupWithCrossSigning = async (keyBackupAuthData: IKeyBackupInfo["auth_data"]) => { const signKeyBackupWithCrossSigning = async (keyBackupAuthData: IKeyBackupInfo["auth_data"]): Promise<void> => {
if ( if (
this.crossSigningInfo.getId() && this.crossSigningInfo.getId() &&
await this.crossSigningInfo.isStoredInKeyCache("master") await this.crossSigningInfo.isStoredInKeyCache("master")
@@ -1241,7 +1241,7 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
const signedDevice = await this.crossSigningInfo.signDevice(this.userId, device); const signedDevice = await this.crossSigningInfo.signDevice(this.userId, device);
logger.info(`Starting background key sig upload for ${this.deviceId}`); logger.info(`Starting background key sig upload for ${this.deviceId}`);
const upload = ({ shouldEmit = false }) => { const upload = ({ shouldEmit = false }): Promise<void> => {
return this.baseApis.uploadKeySignatures({ return this.baseApis.uploadKeySignatures({
[this.userId]: { [this.userId]: {
[this.deviceId]: signedDevice!, [this.deviceId]: signedDevice!,
@@ -1475,7 +1475,7 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
/* /*
* Event handler for DeviceList's userNewDevices event * Event handler for DeviceList's userNewDevices event
*/ */
private onDeviceListUserCrossSigningUpdated = async (userId: string) => { private onDeviceListUserCrossSigningUpdated = async (userId: string): Promise<void> => {
if (userId === this.userId) { if (userId === this.userId) {
// An update to our own cross-signing key. // An update to our own cross-signing key.
// Get the new key first: // Get the new key first:
@@ -1657,7 +1657,7 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
const keysToUpload = Object.keys(keySignatures); const keysToUpload = Object.keys(keySignatures);
if (keysToUpload.length) { if (keysToUpload.length) {
const upload = ({ shouldEmit = false }) => { const upload = ({ shouldEmit = false }): Promise<void> => {
logger.info(`Starting background key sig upload for ${keysToUpload}`); logger.info(`Starting background key sig upload for ${keysToUpload}`);
return this.baseApis.uploadKeySignatures({ [this.userId]: keySignatures }) return this.baseApis.uploadKeySignatures({ [this.userId]: keySignatures })
.then((response) => { .then((response) => {
@@ -1864,7 +1864,7 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
} }
} }
public setNeedsNewFallback(needsNewFallback: boolean) { public setNeedsNewFallback(needsNewFallback: boolean): void {
this.needsNewFallback = needsNewFallback; this.needsNewFallback = needsNewFallback;
} }
@@ -1873,7 +1873,7 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
} }
// check if it's time to upload one-time keys, and do so if so. // check if it's time to upload one-time keys, and do so if so.
private maybeUploadOneTimeKeys() { private maybeUploadOneTimeKeys(): void {
// frequency with which to check & upload one-time keys // frequency with which to check & upload one-time keys
const uploadPeriod = 1000 * 60; // one minute const uploadPeriod = 1000 * 60; // one minute
@@ -1919,7 +1919,7 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
// out stale private keys that won't receive a message. // out stale private keys that won't receive a message.
const keyLimit = Math.floor(maxOneTimeKeys / 2); const keyLimit = Math.floor(maxOneTimeKeys / 2);
const uploadLoop = async (keyCount: number) => { const uploadLoop = async (keyCount: number): Promise<void> => {
while (keyLimit > keyCount || this.getNeedsNewFallback()) { while (keyLimit > keyCount || this.getNeedsNewFallback()) {
// Ask olm to generate new one time keys, then upload them to synapse. // Ask olm to generate new one time keys, then upload them to synapse.
if (keyLimit > keyCount) { if (keyLimit > keyCount) {
@@ -2155,7 +2155,7 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
); );
const device = await this.crossSigningInfo.signUser(xsk); const device = await this.crossSigningInfo.signUser(xsk);
if (device) { if (device) {
const upload = async ({ shouldEmit = false }) => { const upload = async ({ shouldEmit = false }): Promise<void> => {
logger.info("Uploading signature for " + userId + "..."); logger.info("Uploading signature for " + userId + "...");
const response = await this.baseApis.uploadKeySignatures({ const response = await this.baseApis.uploadKeySignatures({
[userId]: { [userId]: {
@@ -2246,7 +2246,7 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
} }
if (device) { if (device) {
const upload = async ({ shouldEmit = false }) => { const upload = async ({ shouldEmit = false }): Promise<void> => {
logger.info("Uploading signature for " + deviceId); logger.info("Uploading signature for " + deviceId);
const response = await this.baseApis.uploadKeySignatures({ const response = await this.baseApis.uploadKeySignatures({
[userId]: { [userId]: {
@@ -2645,7 +2645,7 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
* @returns {Promise} when all devices for the room have been fetched and marked to track * @returns {Promise} when all devices for the room have been fetched and marked to track
*/ */
public trackRoomDevices(roomId: string): Promise<void> { public trackRoomDevices(roomId: string): Promise<void> {
const trackMembers = async () => { const trackMembers = async (): Promise<void> => {
// not an encrypted room // not an encrypted room
if (!this.roomEncryptors.has(roomId)) { if (!this.roomEncryptors.has(roomId)) {
return; return;
@@ -2747,7 +2747,7 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
let failures = 0; let failures = 0;
const total = keys.length; const total = keys.length;
function updateProgress() { function updateProgress(): void {
opts.progressCallback?.({ opts.progressCallback?.({
stage: "load_keys", stage: "load_keys",
successes, successes,
@@ -3187,7 +3187,7 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
} }
} }
private onMembership = (event: MatrixEvent, member: RoomMember, oldMembership?: string) => { private onMembership = (event: MatrixEvent, member: RoomMember, oldMembership?: string): void => {
try { try {
this.onRoomMembership(event, member, oldMembership); this.onRoomMembership(event, member, oldMembership);
} catch (e) { } catch (e) {
@@ -3340,7 +3340,7 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
if (!InRoomChannel.validateEvent(event, this.baseApis)) { if (!InRoomChannel.validateEvent(event, this.baseApis)) {
return; return;
} }
const createRequest = (event: MatrixEvent) => { const createRequest = (event: MatrixEvent): VerificationRequest => {
const channel = new InRoomChannel(this.baseApis, event.getRoomId()!); const channel = new InRoomChannel(this.baseApis, event.getRoomId()!);
return new VerificationRequest( return new VerificationRequest(
channel, this.verificationMethods, this.baseApis); channel, this.verificationMethods, this.baseApis);
@@ -3361,7 +3361,7 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
try { try {
await new Promise<void>((resolve, reject) => { await new Promise<void>((resolve, reject) => {
eventIdListener = resolve; eventIdListener = resolve;
statusListener = () => { statusListener = (): void => {
if (event.status == EventStatus.CANCELLED) { if (event.status == EventStatus.CANCELLED) {
reject(new Error("Event status set to CANCELLED.")); reject(new Error("Event status set to CANCELLED."));
} }
@@ -3420,7 +3420,7 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
// retry decryption for all events sent by the sender_key. This will // retry decryption for all events sent by the sender_key. This will
// update the events to show a message indicating that the olm session was // update the events to show a message indicating that the olm session was
// wedged. // wedged.
const retryDecryption = () => { const retryDecryption = (): void => {
const roomDecryptors = this.getRoomDecryptors(olmlib.MEGOLM_ALGORITHM); const roomDecryptors = this.getRoomDecryptors(olmlib.MEGOLM_ALGORITHM);
for (const decryptor of roomDecryptors) { for (const decryptor of roomDecryptors) {
decryptor.retryDecryptionFromSender(deviceKey); decryptor.retryDecryptionFromSender(deviceKey);
@@ -3692,7 +3692,7 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
return; return;
} }
req.share = () => { req.share = (): void => {
decryptor.shareKeysWithDevice(req); decryptor.shareKeysWithDevice(req);
}; };
@@ -3863,14 +3863,14 @@ export class IncomingRoomKeyRequest {
public readonly requestBody: IRoomKeyRequestBody; public readonly requestBody: IRoomKeyRequestBody;
public share: () => void; public share: () => void;
constructor(event: MatrixEvent) { public constructor(event: MatrixEvent) {
const content = event.getContent(); const content = event.getContent();
this.userId = event.getSender()!; this.userId = event.getSender()!;
this.deviceId = content.requesting_device_id; this.deviceId = content.requesting_device_id;
this.requestId = content.request_id; this.requestId = content.request_id;
this.requestBody = content.body || {}; this.requestBody = content.body || {};
this.share = () => { this.share = (): void => {
throw new Error("don't know how to share keys for this request yet"); throw new Error("don't know how to share keys for this request yet");
}; };
} }
@@ -3888,7 +3888,7 @@ class IncomingRoomKeyRequestCancellation {
public readonly deviceId: string; public readonly deviceId: string;
public readonly requestId: string; public readonly requestId: string;
constructor(event: MatrixEvent) { public constructor(event: MatrixEvent) {
const content = event.getContent(); const content = event.getContent();
this.userId = event.getSender()!; this.userId = event.getSender()!;

View File

@@ -82,7 +82,7 @@ export async function encryptMessageForDevice(
recipientUserId: string, recipientUserId: string,
recipientDevice: DeviceInfo, recipientDevice: DeviceInfo,
payloadFields: Record<string, any>, payloadFields: Record<string, any>,
) { ): Promise<void> {
const deviceKey = recipientDevice.getIdentityKey(); const deviceKey = recipientDevice.getIdentityKey();
const sessionId = await olmDevice.getSessionIdForDevice(deviceKey); const sessionId = await olmDevice.getSessionIdForDevice(deviceKey);
if (sessionId === null) { if (sessionId === null) {
@@ -173,7 +173,7 @@ export async function getExistingOlmSessions(
for (const deviceInfo of devices) { for (const deviceInfo of devices) {
const deviceId = deviceInfo.deviceId; const deviceId = deviceInfo.deviceId;
const key = deviceInfo.getIdentityKey(); const key = deviceInfo.getIdentityKey();
promises.push((async () => { promises.push((async (): Promise<void> => {
const sessionId = await olmDevice.getSessionIdForDevice( const sessionId = await olmDevice.getSessionIdForDevice(
key, true, key, true,
); );
@@ -256,7 +256,7 @@ export async function ensureOlmSessionsForDevices(
// conditions. If we find that we already have a session, then // conditions. If we find that we already have a session, then
// we'll resolve // we'll resolve
olmDevice.sessionsInProgress[key] = new Promise(resolve => { olmDevice.sessionsInProgress[key] = new Promise(resolve => {
resolveSession[key] = (v: any) => { resolveSession[key] = (v: any): void => {
delete olmDevice.sessionsInProgress[key]; delete olmDevice.sessionsInProgress[key];
resolve(v); resolve(v);
}; };
@@ -463,7 +463,7 @@ export async function verifySignature(
signingUserId: string, signingUserId: string,
signingDeviceId: string, signingDeviceId: string,
signingKey: string, signingKey: string,
) { ): Promise<void> {
const signKeyId = "ed25519:" + signingDeviceId; const signKeyId = "ed25519:" + signingDeviceId;
const signatures = obj.signatures || {}; const signatures = obj.signatures || {};
const userSigs = signatures[signingUserId] || {}; const userSigs = signatures[signingUserId] || {};
@@ -527,7 +527,7 @@ export function pkSign(obj: IObject, key: PkSigning, userId: string, pubKey: str
* @param {string} pubKey The public key to use to verify * @param {string} pubKey The public key to use to verify
* @param {string} userId The user ID who signed the object * @param {string} userId The user ID who signed the object
*/ */
export function pkVerify(obj: IObject, pubKey: string, userId: string) { export function pkVerify(obj: IObject, pubKey: string, userId: string): void {
const keyId = "ed25519:" + pubKey; const keyId = "ed25519:" + pubKey;
if (!(obj.signatures && obj.signatures[userId] && obj.signatures[userId][keyId])) { if (!(obj.signatures && obj.signatures[userId] && obj.signatures[userId][keyId])) {
throw new Error("No signature"); throw new Error("No signature");

View File

@@ -48,11 +48,11 @@ export class Backend implements CryptoStore {
/** /**
* @param {IDBDatabase} db * @param {IDBDatabase} db
*/ */
constructor(private db: IDBDatabase) { public constructor(private db: IDBDatabase) {
// make sure we close the db on `onversionchange` - otherwise // make sure we close the db on `onversionchange` - otherwise
// attempts to delete the database will block (and subsequent // attempts to delete the database will block (and subsequent
// attempts to re-create it will also block). // attempts to re-create it will also block).
db.onversionchange = () => { db.onversionchange = (): void => {
logger.log(`versionchange for indexeddb ${this.db.name}: closing`); logger.log(`versionchange for indexeddb ${this.db.name}: closing`);
db.close(); db.close();
}; };
@@ -103,7 +103,7 @@ export class Backend implements CryptoStore {
`enqueueing key request for ${requestBody.room_id} / ` + `enqueueing key request for ${requestBody.room_id} / ` +
requestBody.session_id, requestBody.session_id,
); );
txn.oncomplete = () => {resolve(request);}; txn.oncomplete = (): void => {resolve(request);};
const store = txn.objectStore("outgoingRoomKeyRequests"); const store = txn.objectStore("outgoingRoomKeyRequests");
store.add(request); store.add(request);
}); });
@@ -157,7 +157,7 @@ export class Backend implements CryptoStore {
requestBody.session_id, requestBody.session_id,
]); ]);
cursorReq.onsuccess = () => { cursorReq.onsuccess = (): void => {
const cursor = cursorReq.result; const cursor = cursorReq.result;
if (!cursor) { if (!cursor) {
// no match found // no match found
@@ -201,7 +201,7 @@ export class Backend implements CryptoStore {
let stateIndex = 0; let stateIndex = 0;
let result: OutgoingRoomKeyRequest; let result: OutgoingRoomKeyRequest;
function onsuccess(this: IDBRequest<IDBCursorWithValue | null>) { function onsuccess(this: IDBRequest<IDBCursorWithValue | null>): void {
const cursor = this.result; const cursor = this.result;
if (cursor) { if (cursor) {
// got a match // got a match
@@ -243,8 +243,8 @@ export class Backend implements CryptoStore {
const index = store.index("state"); const index = store.index("state");
const request = index.getAll(wantedState); const request = index.getAll(wantedState);
request.onsuccess = () => resolve(request.result); request.onsuccess = (): void => resolve(request.result);
request.onerror = () => reject(request.error); request.onerror = (): void => reject(request.error);
}); });
} }
@@ -256,7 +256,7 @@ export class Backend implements CryptoStore {
let stateIndex = 0; let stateIndex = 0;
const results: OutgoingRoomKeyRequest[] = []; const results: OutgoingRoomKeyRequest[] = [];
function onsuccess(this: IDBRequest<IDBCursorWithValue | null>) { function onsuccess(this: IDBRequest<IDBCursorWithValue | null>): void {
const cursor = this.result; const cursor = this.result;
if (cursor) { if (cursor) {
const keyReq = cursor.value; const keyReq = cursor.value;
@@ -309,7 +309,7 @@ export class Backend implements CryptoStore {
): Promise<OutgoingRoomKeyRequest | null> { ): Promise<OutgoingRoomKeyRequest | null> {
let result: OutgoingRoomKeyRequest | null = null; let result: OutgoingRoomKeyRequest | null = null;
function onsuccess(this: IDBRequest<IDBCursorWithValue | null>) { function onsuccess(this: IDBRequest<IDBCursorWithValue | null>): void {
const cursor = this.result; const cursor = this.result;
if (!cursor) { if (!cursor) {
return; return;
@@ -348,7 +348,7 @@ export class Backend implements CryptoStore {
): Promise<OutgoingRoomKeyRequest | null> { ): Promise<OutgoingRoomKeyRequest | null> {
const txn = this.db.transaction("outgoingRoomKeyRequests", "readwrite"); const txn = this.db.transaction("outgoingRoomKeyRequests", "readwrite");
const cursorReq = txn.objectStore("outgoingRoomKeyRequests").openCursor(requestId); const cursorReq = txn.objectStore("outgoingRoomKeyRequests").openCursor(requestId);
cursorReq.onsuccess = () => { cursorReq.onsuccess = (): void => {
const cursor = cursorReq.result; const cursor = cursorReq.result;
if (!cursor) { if (!cursor) {
return; return;
@@ -371,7 +371,7 @@ export class Backend implements CryptoStore {
public getAccount(txn: IDBTransaction, func: (accountPickle: string | null) => void): void { public getAccount(txn: IDBTransaction, func: (accountPickle: string | null) => void): void {
const objectStore = txn.objectStore("account"); const objectStore = txn.objectStore("account");
const getReq = objectStore.get("-"); const getReq = objectStore.get("-");
getReq.onsuccess = function() { getReq.onsuccess = function(): void {
try { try {
func(getReq.result || null); func(getReq.result || null);
} catch (e) { } catch (e) {
@@ -391,7 +391,7 @@ export class Backend implements CryptoStore {
): void { ): void {
const objectStore = txn.objectStore("account"); const objectStore = txn.objectStore("account");
const getReq = objectStore.get("crossSigningKeys"); const getReq = objectStore.get("crossSigningKeys");
getReq.onsuccess = function() { getReq.onsuccess = function(): void {
try { try {
func(getReq.result || null); func(getReq.result || null);
} catch (e) { } catch (e) {
@@ -407,7 +407,7 @@ export class Backend implements CryptoStore {
): void { ): void {
const objectStore = txn.objectStore("account"); const objectStore = txn.objectStore("account");
const getReq = objectStore.get(`ssss_cache:${type}`); const getReq = objectStore.get(`ssss_cache:${type}`);
getReq.onsuccess = function() { getReq.onsuccess = function(): void {
try { try {
func(getReq.result || null); func(getReq.result || null);
} catch (e) { } catch (e) {
@@ -435,7 +435,7 @@ export class Backend implements CryptoStore {
public countEndToEndSessions(txn: IDBTransaction, func: (count: number) => void): void { public countEndToEndSessions(txn: IDBTransaction, func: (count: number) => void): void {
const objectStore = txn.objectStore("sessions"); const objectStore = txn.objectStore("sessions");
const countReq = objectStore.count(); const countReq = objectStore.count();
countReq.onsuccess = function() { countReq.onsuccess = function(): void {
try { try {
func(countReq.result); func(countReq.result);
} catch (e) { } catch (e) {
@@ -453,7 +453,7 @@ export class Backend implements CryptoStore {
const idx = objectStore.index("deviceKey"); const idx = objectStore.index("deviceKey");
const getReq = idx.openCursor(deviceKey); const getReq = idx.openCursor(deviceKey);
const results: Parameters<Parameters<Backend["getEndToEndSessions"]>[2]>[0] = {}; const results: Parameters<Parameters<Backend["getEndToEndSessions"]>[2]>[0] = {};
getReq.onsuccess = function() { getReq.onsuccess = function(): void {
const cursor = getReq.result; const cursor = getReq.result;
if (cursor) { if (cursor) {
results[cursor.value.sessionId] = { results[cursor.value.sessionId] = {
@@ -479,7 +479,7 @@ export class Backend implements CryptoStore {
): void { ): void {
const objectStore = txn.objectStore("sessions"); const objectStore = txn.objectStore("sessions");
const getReq = objectStore.get([deviceKey, sessionId]); const getReq = objectStore.get([deviceKey, sessionId]);
getReq.onsuccess = function() { getReq.onsuccess = function(): void {
try { try {
if (getReq.result) { if (getReq.result) {
func({ func({
@@ -498,7 +498,7 @@ export class Backend implements CryptoStore {
public getAllEndToEndSessions(txn: IDBTransaction, func: (session: ISessionInfo | null) => void): void { public getAllEndToEndSessions(txn: IDBTransaction, func: (session: ISessionInfo | null) => void): void {
const objectStore = txn.objectStore("sessions"); const objectStore = txn.objectStore("sessions");
const getReq = objectStore.openCursor(); const getReq = objectStore.openCursor();
getReq.onsuccess = function() { getReq.onsuccess = function(): void {
try { try {
const cursor = getReq.result; const cursor = getReq.result;
if (cursor) { if (cursor) {
@@ -546,7 +546,7 @@ export class Backend implements CryptoStore {
const objectStore = txn.objectStore("session_problems"); const objectStore = txn.objectStore("session_problems");
const index = objectStore.index("deviceKey"); const index = objectStore.index("deviceKey");
const req = index.getAll(deviceKey); const req = index.getAll(deviceKey);
req.onsuccess = () => { req.onsuccess = (): void => {
const problems = req.result; const problems = req.result;
if (!problems.length) { if (!problems.length) {
result = null; result = null;
@@ -583,7 +583,7 @@ export class Backend implements CryptoStore {
return new Promise<void>((resolve) => { return new Promise<void>((resolve) => {
const { userId, deviceInfo } = device; const { userId, deviceInfo } = device;
const getReq = objectStore.get([userId, deviceInfo.deviceId]); const getReq = objectStore.get([userId, deviceInfo.deviceId]);
getReq.onsuccess = function() { getReq.onsuccess = function(): void {
if (!getReq.result) { if (!getReq.result) {
objectStore.put({ userId, deviceId: deviceInfo.deviceId }); objectStore.put({ userId, deviceId: deviceInfo.deviceId });
ret.push(device); ret.push(device);
@@ -608,7 +608,7 @@ export class Backend implements CryptoStore {
let withheld: IWithheld | null | boolean = false; let withheld: IWithheld | null | boolean = false;
const objectStore = txn.objectStore("inbound_group_sessions"); const objectStore = txn.objectStore("inbound_group_sessions");
const getReq = objectStore.get([senderCurve25519Key, sessionId]); const getReq = objectStore.get([senderCurve25519Key, sessionId]);
getReq.onsuccess = function() { getReq.onsuccess = function(): void {
try { try {
if (getReq.result) { if (getReq.result) {
session = getReq.result.session; session = getReq.result.session;
@@ -625,7 +625,7 @@ export class Backend implements CryptoStore {
const withheldObjectStore = txn.objectStore("inbound_group_sessions_withheld"); const withheldObjectStore = txn.objectStore("inbound_group_sessions_withheld");
const withheldGetReq = withheldObjectStore.get([senderCurve25519Key, sessionId]); const withheldGetReq = withheldObjectStore.get([senderCurve25519Key, sessionId]);
withheldGetReq.onsuccess = function() { withheldGetReq.onsuccess = function(): void {
try { try {
if (withheldGetReq.result) { if (withheldGetReq.result) {
withheld = withheldGetReq.result.session; withheld = withheldGetReq.result.session;
@@ -644,7 +644,7 @@ export class Backend implements CryptoStore {
public getAllEndToEndInboundGroupSessions(txn: IDBTransaction, func: (session: ISession | null) => void): void { public getAllEndToEndInboundGroupSessions(txn: IDBTransaction, func: (session: ISession | null) => void): void {
const objectStore = txn.objectStore("inbound_group_sessions"); const objectStore = txn.objectStore("inbound_group_sessions");
const getReq = objectStore.openCursor(); const getReq = objectStore.openCursor();
getReq.onsuccess = function() { getReq.onsuccess = function(): void {
const cursor = getReq.result; const cursor = getReq.result;
if (cursor) { if (cursor) {
try { try {
@@ -677,7 +677,7 @@ export class Backend implements CryptoStore {
const addReq = objectStore.add({ const addReq = objectStore.add({
senderCurve25519Key, sessionId, session: sessionData, senderCurve25519Key, sessionId, session: sessionData,
}); });
addReq.onerror = (ev) => { addReq.onerror = (ev): void => {
if (addReq.error?.name === 'ConstraintError') { if (addReq.error?.name === 'ConstraintError') {
// This stops the error from triggering the txn's onerror // This stops the error from triggering the txn's onerror
ev.stopPropagation(); ev.stopPropagation();
@@ -722,7 +722,7 @@ export class Backend implements CryptoStore {
public getEndToEndDeviceData(txn: IDBTransaction, func: (deviceData: IDeviceData | null) => void): void { public getEndToEndDeviceData(txn: IDBTransaction, func: (deviceData: IDeviceData | null) => void): void {
const objectStore = txn.objectStore("device_data"); const objectStore = txn.objectStore("device_data");
const getReq = objectStore.get("-"); const getReq = objectStore.get("-");
getReq.onsuccess = function() { getReq.onsuccess = function(): void {
try { try {
func(getReq.result || null); func(getReq.result || null);
} catch (e) { } catch (e) {
@@ -745,7 +745,7 @@ export class Backend implements CryptoStore {
const rooms: Parameters<Parameters<Backend["getEndToEndRooms"]>[1]>[0] = {}; const rooms: Parameters<Parameters<Backend["getEndToEndRooms"]>[1]>[0] = {};
const objectStore = txn.objectStore("rooms"); const objectStore = txn.objectStore("rooms");
const getReq = objectStore.openCursor(); const getReq = objectStore.openCursor();
getReq.onsuccess = function() { getReq.onsuccess = function(): void {
const cursor = getReq.result; const cursor = getReq.result;
if (cursor) { if (cursor) {
rooms[cursor.key as string] = cursor.value; rooms[cursor.key as string] = cursor.value;
@@ -771,17 +771,17 @@ export class Backend implements CryptoStore {
"readonly", "readonly",
); );
txn.onerror = reject; txn.onerror = reject;
txn.oncomplete = function() { txn.oncomplete = function(): void {
resolve(sessions); resolve(sessions);
}; };
const objectStore = txn.objectStore("sessions_needing_backup"); const objectStore = txn.objectStore("sessions_needing_backup");
const sessionStore = txn.objectStore("inbound_group_sessions"); const sessionStore = txn.objectStore("inbound_group_sessions");
const getReq = objectStore.openCursor(); const getReq = objectStore.openCursor();
getReq.onsuccess = function() { getReq.onsuccess = function(): void {
const cursor = getReq.result; const cursor = getReq.result;
if (cursor) { if (cursor) {
const sessionGetReq = sessionStore.get(cursor.key); const sessionGetReq = sessionStore.get(cursor.key);
sessionGetReq.onsuccess = function() { sessionGetReq.onsuccess = function(): void {
sessions.push({ sessions.push({
senderKey: sessionGetReq.result.senderCurve25519Key, senderKey: sessionGetReq.result.senderCurve25519Key,
sessionId: sessionGetReq.result.sessionId, sessionId: sessionGetReq.result.sessionId,
@@ -804,7 +804,7 @@ export class Backend implements CryptoStore {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const req = objectStore.count(); const req = objectStore.count();
req.onerror = reject; req.onerror = reject;
req.onsuccess = () => resolve(req.result); req.onsuccess = (): void => resolve(req.result);
}); });
} }
@@ -852,7 +852,7 @@ export class Backend implements CryptoStore {
} }
const objectStore = txn.objectStore("shared_history_inbound_group_sessions"); const objectStore = txn.objectStore("shared_history_inbound_group_sessions");
const req = objectStore.get([roomId]); const req = objectStore.get([roomId]);
req.onsuccess = () => { req.onsuccess = (): void => {
const { sessions } = req.result || { sessions: [] }; const { sessions } = req.result || { sessions: [] };
sessions.push([senderKey, sessionId]); sessions.push([senderKey, sessionId]);
objectStore.put({ roomId, sessions }); objectStore.put({ roomId, sessions });
@@ -871,7 +871,7 @@ export class Backend implements CryptoStore {
const objectStore = txn.objectStore("shared_history_inbound_group_sessions"); const objectStore = txn.objectStore("shared_history_inbound_group_sessions");
const req = objectStore.get([roomId]); const req = objectStore.get([roomId]);
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
req.onsuccess = () => { req.onsuccess = (): void => {
const { sessions } = req.result || { sessions: [] }; const { sessions } = req.result || { sessions: [] };
resolve(sessions); resolve(sessions);
}; };
@@ -891,7 +891,7 @@ export class Backend implements CryptoStore {
} }
const objectStore = txn.objectStore("parked_shared_history"); const objectStore = txn.objectStore("parked_shared_history");
const req = objectStore.get([roomId]); const req = objectStore.get([roomId]);
req.onsuccess = () => { req.onsuccess = (): void => {
const { parked } = req.result || { parked: [] }; const { parked } = req.result || { parked: [] };
parked.push(parkedData); parked.push(parkedData);
objectStore.put({ roomId, parked }); objectStore.put({ roomId, parked });
@@ -909,7 +909,7 @@ export class Backend implements CryptoStore {
} }
const cursorReq = txn.objectStore("parked_shared_history").openCursor(roomId); const cursorReq = txn.objectStore("parked_shared_history").openCursor(roomId);
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
cursorReq.onsuccess = () => { cursorReq.onsuccess = (): void => {
const cursor = cursorReq.result; const cursor = cursorReq.result;
if (!cursor) { if (!cursor) {
resolve([]); resolve([]);
@@ -957,32 +957,32 @@ export class Backend implements CryptoStore {
type DbMigration = (db: IDBDatabase) => void; type DbMigration = (db: IDBDatabase) => void;
const DB_MIGRATIONS: DbMigration[] = [ const DB_MIGRATIONS: DbMigration[] = [
(db) => { createDatabase(db); }, (db): void => { createDatabase(db); },
(db) => { db.createObjectStore("account"); }, (db): void => { db.createObjectStore("account"); },
(db) => { (db): void => {
const sessionsStore = db.createObjectStore("sessions", { const sessionsStore = db.createObjectStore("sessions", {
keyPath: ["deviceKey", "sessionId"], keyPath: ["deviceKey", "sessionId"],
}); });
sessionsStore.createIndex("deviceKey", "deviceKey"); sessionsStore.createIndex("deviceKey", "deviceKey");
}, },
(db) => { (db): void => {
db.createObjectStore("inbound_group_sessions", { db.createObjectStore("inbound_group_sessions", {
keyPath: ["senderCurve25519Key", "sessionId"], keyPath: ["senderCurve25519Key", "sessionId"],
}); });
}, },
(db) => { db.createObjectStore("device_data"); }, (db): void => { db.createObjectStore("device_data"); },
(db) => { db.createObjectStore("rooms"); }, (db): void => { db.createObjectStore("rooms"); },
(db) => { (db): void => {
db.createObjectStore("sessions_needing_backup", { db.createObjectStore("sessions_needing_backup", {
keyPath: ["senderCurve25519Key", "sessionId"], keyPath: ["senderCurve25519Key", "sessionId"],
}); });
}, },
(db) => { (db): void => {
db.createObjectStore("inbound_group_sessions_withheld", { db.createObjectStore("inbound_group_sessions_withheld", {
keyPath: ["senderCurve25519Key", "sessionId"], keyPath: ["senderCurve25519Key", "sessionId"],
}); });
}, },
(db) => { (db): void => {
const problemsStore = db.createObjectStore("session_problems", { const problemsStore = db.createObjectStore("session_problems", {
keyPath: ["deviceKey", "time"], keyPath: ["deviceKey", "time"],
}); });
@@ -992,12 +992,12 @@ const DB_MIGRATIONS: DbMigration[] = [
keyPath: ["userId", "deviceId"], keyPath: ["userId", "deviceId"],
}); });
}, },
(db) => { (db): void => {
db.createObjectStore("shared_history_inbound_group_sessions", { db.createObjectStore("shared_history_inbound_group_sessions", {
keyPath: ["roomId"], keyPath: ["roomId"],
}); });
}, },
(db) => { (db): void => {
db.createObjectStore("parked_shared_history", { db.createObjectStore("parked_shared_history", {
keyPath: ["roomId"], keyPath: ["roomId"],
}); });
@@ -1037,7 +1037,7 @@ interface IWrappedIDBTransaction extends IDBTransaction {
* Aborts a transaction with a given exception * Aborts a transaction with a given exception
* The transaction promise will be rejected with this exception. * The transaction promise will be rejected with this exception.
*/ */
function abortWithException(txn: IDBTransaction, e: Error) { function abortWithException(txn: IDBTransaction, e: Error): void {
// We cheekily stick our exception onto the transaction object here // We cheekily stick our exception onto the transaction object here
// We could alternatively make the thing we pass back to the app // We could alternatively make the thing we pass back to the app
// an object containing the transaction and exception. // an object containing the transaction and exception.
@@ -1052,13 +1052,13 @@ function abortWithException(txn: IDBTransaction, e: Error) {
function promiseifyTxn<T>(txn: IDBTransaction): Promise<T | null> { function promiseifyTxn<T>(txn: IDBTransaction): Promise<T | null> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
txn.oncomplete = () => { txn.oncomplete = (): void => {
if ((txn as IWrappedIDBTransaction)._mx_abortexception !== undefined) { if ((txn as IWrappedIDBTransaction)._mx_abortexception !== undefined) {
reject((txn as IWrappedIDBTransaction)._mx_abortexception); reject((txn as IWrappedIDBTransaction)._mx_abortexception);
} }
resolve(null); resolve(null);
}; };
txn.onerror = (event) => { txn.onerror = (event): void => {
if ((txn as IWrappedIDBTransaction)._mx_abortexception !== undefined) { if ((txn as IWrappedIDBTransaction)._mx_abortexception !== undefined) {
reject((txn as IWrappedIDBTransaction)._mx_abortexception); reject((txn as IWrappedIDBTransaction)._mx_abortexception);
} else { } else {
@@ -1066,7 +1066,7 @@ function promiseifyTxn<T>(txn: IDBTransaction): Promise<T | null> {
reject(txn.error); reject(txn.error);
} }
}; };
txn.onabort = (event) => { txn.onabort = (event): void => {
if ((txn as IWrappedIDBTransaction)._mx_abortexception !== undefined) { if ((txn as IWrappedIDBTransaction)._mx_abortexception !== undefined) {
reject((txn as IWrappedIDBTransaction)._mx_abortexception); reject((txn as IWrappedIDBTransaction)._mx_abortexception);
} else { } else {

View File

@@ -73,7 +73,7 @@ export class IndexedDBCryptoStore implements CryptoStore {
* @param {IDBFactory} indexedDB global indexedDB instance * @param {IDBFactory} indexedDB global indexedDB instance
* @param {string} dbName name of db to connect to * @param {string} dbName name of db to connect to
*/ */
constructor(private readonly indexedDB: IDBFactory, private readonly dbName: string) {} public constructor(private readonly indexedDB: IDBFactory, private readonly dbName: string) {}
/** /**
* Ensure the database exists and is up-to-date, or fall back to * Ensure the database exists and is up-to-date, or fall back to
@@ -99,24 +99,24 @@ export class IndexedDBCryptoStore implements CryptoStore {
const req = this.indexedDB.open(this.dbName, IndexedDBCryptoStoreBackend.VERSION); const req = this.indexedDB.open(this.dbName, IndexedDBCryptoStoreBackend.VERSION);
req.onupgradeneeded = (ev) => { req.onupgradeneeded = (ev): void => {
const db = req.result; const db = req.result;
const oldVersion = ev.oldVersion; const oldVersion = ev.oldVersion;
IndexedDBCryptoStoreBackend.upgradeDatabase(db, oldVersion); IndexedDBCryptoStoreBackend.upgradeDatabase(db, oldVersion);
}; };
req.onblocked = () => { req.onblocked = (): void => {
logger.log( logger.log(
`can't yet open IndexedDBCryptoStore because it is open elsewhere`, `can't yet open IndexedDBCryptoStore because it is open elsewhere`,
); );
}; };
req.onerror = (ev) => { req.onerror = (ev): void => {
logger.log("Error connecting to indexeddb", ev); logger.log("Error connecting to indexeddb", ev);
reject(req.error); reject(req.error);
}; };
req.onsuccess = () => { req.onsuccess = (): void => {
const db = req.result; const db = req.result;
logger.log(`connected to indexeddb ${this.dbName}`); logger.log(`connected to indexeddb ${this.dbName}`);
@@ -179,18 +179,18 @@ export class IndexedDBCryptoStore implements CryptoStore {
logger.log(`Removing indexeddb instance: ${this.dbName}`); logger.log(`Removing indexeddb instance: ${this.dbName}`);
const req = this.indexedDB.deleteDatabase(this.dbName); const req = this.indexedDB.deleteDatabase(this.dbName);
req.onblocked = () => { req.onblocked = (): void => {
logger.log( logger.log(
`can't yet delete IndexedDBCryptoStore because it is open elsewhere`, `can't yet delete IndexedDBCryptoStore because it is open elsewhere`,
); );
}; };
req.onerror = (ev) => { req.onerror = (ev): void => {
logger.log("Error deleting data from indexeddb", ev); logger.log("Error deleting data from indexeddb", ev);
reject(req.error); reject(req.error);
}; };
req.onsuccess = () => { req.onsuccess = (): void => {
logger.log(`Removed indexeddb instance: ${this.dbName}`); logger.log(`Removed indexeddb instance: ${this.dbName}`);
resolve(); resolve();
}; };
@@ -322,7 +322,7 @@ export class IndexedDBCryptoStore implements CryptoStore {
* @param {*} txn An active transaction. See doTxn(). * @param {*} txn An active transaction. See doTxn().
* @param {function(string)} func Called with the account pickle * @param {function(string)} func Called with the account pickle
*/ */
public getAccount(txn: IDBTransaction, func: (accountPickle: string | null) => void) { public getAccount(txn: IDBTransaction, func: (accountPickle: string | null) => void): void {
this.backend!.getAccount(txn, func); this.backend!.getAccount(txn, func);
} }

View File

@@ -76,7 +76,7 @@ export class LocalStorageCryptoStore extends MemoryCryptoStore {
return false; return false;
} }
constructor(private readonly store: Storage) { public constructor(private readonly store: Storage) {
super(); super();
} }
@@ -154,7 +154,7 @@ export class LocalStorageCryptoStore extends MemoryCryptoStore {
setJsonItem(this.store, key, problems); setJsonItem(this.store, key, problems);
} }
async getEndToEndSessionProblem(deviceKey: string, timestamp: number): Promise<IProblem | null> { public async getEndToEndSessionProblem(deviceKey: string, timestamp: number): Promise<IProblem | null> {
const key = keyEndToEndSessionProblems(deviceKey); const key = keyEndToEndSessionProblems(deviceKey);
const problems = getJsonItem<IProblem[]>(this.store, key) || []; const problems = getJsonItem<IProblem[]>(this.store, key) || [];
if (!problems.length) { if (!problems.length) {
@@ -408,7 +408,7 @@ export class LocalStorageCryptoStore extends MemoryCryptoStore {
setJsonItem(this.store, E2E_PREFIX + `ssss_cache.${type}`, key); setJsonItem(this.store, E2E_PREFIX + `ssss_cache.${type}`, key);
} }
doTxn<T>(mode: Mode, stores: Iterable<string>, func: (txn: unknown) => T): Promise<T> { public doTxn<T>(mode: Mode, stores: Iterable<string>, func: (txn: unknown) => T): Promise<T> {
return Promise.resolve(func(null)); return Promise.resolve(func(null));
} }
} }

View File

@@ -279,7 +279,7 @@ export class MemoryCryptoStore implements CryptoStore {
// Olm Account // Olm Account
public getAccount(txn: unknown, func: (accountPickle: string | null) => void) { public getAccount(txn: unknown, func: (accountPickle: string | null) => void): void {
func(this.account); func(this.account);
} }

View File

@@ -34,7 +34,7 @@ import { ListenerMap, TypedEventEmitter } from "../../models/typed-event-emitter
const timeoutException = new Error("Verification timed out"); const timeoutException = new Error("Verification timed out");
export class SwitchStartEventError extends Error { export class SwitchStartEventError extends Error {
constructor(public readonly startEvent: MatrixEvent | null) { public constructor(public readonly startEvent: MatrixEvent | null) {
super(); super();
} }
} }
@@ -91,7 +91,7 @@ export class VerificationBase<
* @param {object} [request] the key verification request object related to * @param {object} [request] the key verification request object related to
* this verification, if any * this verification, if any
*/ */
constructor( public constructor(
public readonly channel: IVerificationChannel, public readonly channel: IVerificationChannel,
public readonly baseApis: MatrixClient, public readonly baseApis: MatrixClient,
public readonly userId: string, public readonly userId: string,
@@ -286,12 +286,12 @@ export class VerificationBase<
if (this.promise) return this.promise; if (this.promise) return this.promise;
this.promise = new Promise((resolve, reject) => { this.promise = new Promise((resolve, reject) => {
this.resolve = (...args) => { this.resolve = (...args): void => {
this._done = true; this._done = true;
this.endTimer(); this.endTimer();
resolve(...args); resolve(...args);
}; };
this.reject = (e: Error | MatrixEvent) => { this.reject = (e: Error | MatrixEvent): void => {
this._done = true; this._done = true;
this.endTimer(); this.endTimer();
reject(e); reject(e);

View File

@@ -154,7 +154,7 @@ interface IQrData {
} }
export class QRCodeData { export class QRCodeData {
constructor( public constructor(
public readonly mode: Mode, public readonly mode: Mode,
private readonly sharedSecret: string, private readonly sharedSecret: string,
// only set when mode is MODE_VERIFY_OTHER_USER, master key of other party at time of generating QR code // only set when mode is MODE_VERIFY_OTHER_USER, master key of other party at time of generating QR code
@@ -283,21 +283,21 @@ export class QRCodeData {
private static generateBuffer(qrData: IQrData): Buffer { private static generateBuffer(qrData: IQrData): Buffer {
let buf = Buffer.alloc(0); // we'll concat our way through life let buf = Buffer.alloc(0); // we'll concat our way through life
const appendByte = (b) => { const appendByte = (b): void => {
const tmpBuf = Buffer.from([b]); const tmpBuf = Buffer.from([b]);
buf = Buffer.concat([buf, tmpBuf]); buf = Buffer.concat([buf, tmpBuf]);
}; };
const appendInt = (i) => { const appendInt = (i): void => {
const tmpBuf = Buffer.alloc(2); const tmpBuf = Buffer.alloc(2);
tmpBuf.writeInt16BE(i, 0); tmpBuf.writeInt16BE(i, 0);
buf = Buffer.concat([buf, tmpBuf]); buf = Buffer.concat([buf, tmpBuf]);
}; };
const appendStr = (s, enc, withLengthPrefix = true) => { const appendStr = (s, enc, withLengthPrefix = true): void => {
const tmpBuf = Buffer.from(s, enc); const tmpBuf = Buffer.from(s, enc);
if (withLengthPrefix) appendInt(tmpBuf.byteLength); if (withLengthPrefix) appendInt(tmpBuf.byteLength);
buf = Buffer.concat([buf, tmpBuf]); buf = Buffer.concat([buf, tmpBuf]);
}; };
const appendEncBase64 = (b64) => { const appendEncBase64 = (b64): void => {
const b = decodeBase64(b64); const b = decodeBase64(b64);
const tmpBuf = Buffer.from(b); const tmpBuf = Buffer.from(b);
buf = Buffer.concat([buf, tmpBuf]); buf = Buffer.concat([buf, tmpBuf]);

View File

@@ -170,10 +170,12 @@ const macMethods = {
"hmac-sha256": "calculate_mac_long_kdf", "hmac-sha256": "calculate_mac_long_kdf",
}; };
function calculateMAC(olmSAS: OlmSAS, method: string) { type Method = keyof typeof macMethods;
return function(...args) {
function calculateMAC(olmSAS: OlmSAS, method: Method) {
return function(...args): string {
const macFunction = olmSAS[macMethods[method]]; const macFunction = olmSAS[macMethods[method]];
const mac = macFunction.apply(olmSAS, args); const mac: string = macFunction.apply(olmSAS, args);
logger.log("SAS calculateMAC:", method, args, mac); logger.log("SAS calculateMAC:", method, args, mac);
return mac; return mac;
}; };
@@ -208,7 +210,7 @@ const calculateKeyAgreement = {
*/ */
const KEY_AGREEMENT_LIST = ["curve25519-hkdf-sha256", "curve25519"]; const KEY_AGREEMENT_LIST = ["curve25519-hkdf-sha256", "curve25519"];
const HASHES_LIST = ["sha256"]; const HASHES_LIST = ["sha256"];
const MAC_LIST = ["org.matrix.msc3783.hkdf-hmac-sha256", "hkdf-hmac-sha256", "hmac-sha256"]; const MAC_LIST: Method[] = ["org.matrix.msc3783.hkdf-hmac-sha256", "hkdf-hmac-sha256", "hmac-sha256"];
const SAS_LIST = Object.keys(sasGenerators); const SAS_LIST = Object.keys(sasGenerators);
const KEY_AGREEMENT_SET = new Set(KEY_AGREEMENT_LIST); const KEY_AGREEMENT_SET = new Set(KEY_AGREEMENT_LIST);
@@ -300,13 +302,13 @@ export class SAS extends Base<SasEvent, EventHandlerMap> {
keyAgreement: string, keyAgreement: string,
sasMethods: string[], sasMethods: string[],
olmSAS: OlmSAS, olmSAS: OlmSAS,
macMethod: string, macMethod: Method,
): Promise<void> { ): Promise<void> {
const sasBytes = calculateKeyAgreement[keyAgreement](this, olmSAS, 6); const sasBytes = calculateKeyAgreement[keyAgreement](this, olmSAS, 6);
const verifySAS = new Promise<void>((resolve, reject) => { const verifySAS = new Promise<void>((resolve, reject) => {
this.sasEvent = { this.sasEvent = {
sas: generateSas(sasBytes, sasMethods), sas: generateSas(sasBytes, sasMethods),
confirm: async () => { confirm: async (): Promise<void> => {
try { try {
await this.sendMAC(olmSAS, macMethod); await this.sendMAC(olmSAS, macMethod);
resolve(); resolve();
@@ -443,7 +445,7 @@ export class SAS extends Base<SasEvent, EventHandlerMap> {
} }
} }
private sendMAC(olmSAS: OlmSAS, method: string): Promise<void> { private sendMAC(olmSAS: OlmSAS, method: Method): Promise<void> {
const mac = {}; const mac = {};
const keyList: string[] = []; const keyList: string[] = [];
const baseInfo = "MATRIX_KEY_VERIFICATION_MAC" const baseInfo = "MATRIX_KEY_VERIFICATION_MAC"
@@ -475,7 +477,7 @@ export class SAS extends Base<SasEvent, EventHandlerMap> {
return this.send(EventType.KeyVerificationMac, { mac, keys }); return this.send(EventType.KeyVerificationMac, { mac, keys });
} }
private async checkMAC(olmSAS: OlmSAS, content: IContent, method: string): Promise<void> { private async checkMAC(olmSAS: OlmSAS, content: IContent, method: Method): Promise<void> {
const baseInfo = "MATRIX_KEY_VERIFICATION_MAC" const baseInfo = "MATRIX_KEY_VERIFICATION_MAC"
+ this.userId + this.deviceId + this.userId + this.deviceId
+ this.baseApis.getUserId() + this.baseApis.deviceId + this.baseApis.getUserId() + this.baseApis.deviceId

View File

@@ -44,7 +44,7 @@ export class InRoomChannel implements IVerificationChannel {
* @param {string} roomId id of the room where verification events should be posted in, should be a DM with the given user. * @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 {string} userId id of user that the verification request is directed at, should be present in the room.
*/ */
constructor( public constructor(
private readonly client: MatrixClient, private readonly client: MatrixClient,
public readonly roomId: string, public readonly roomId: string,
public userId?: string, public userId?: string,

View File

@@ -42,7 +42,7 @@ export class ToDeviceChannel implements IVerificationChannel {
public request?: VerificationRequest; public request?: VerificationRequest;
// userId and devices of user we're about to verify // userId and devices of user we're about to verify
constructor( public constructor(
private readonly client: MatrixClient, private readonly client: MatrixClient,
public readonly userId: string, public readonly userId: string,
private readonly devices: string[], private readonly devices: string[],

View File

@@ -116,7 +116,7 @@ export class VerificationRequest<
public _cancellingUserId?: string; // Used in tests only public _cancellingUserId?: string; // Used in tests only
private _verifier?: VerificationBase<any, any>; private _verifier?: VerificationBase<any, any>;
constructor( public constructor(
public readonly channel: C, public readonly channel: C,
private readonly verificationMethods: Map<VerificationMethod, typeof VerificationBase>, private readonly verificationMethods: Map<VerificationMethod, typeof VerificationBase>,
private readonly client: MatrixClient, private readonly client: MatrixClient,
@@ -498,7 +498,7 @@ export class VerificationRequest<
*/ */
public waitFor(fn: (request: VerificationRequest) => boolean): Promise<VerificationRequest> { public waitFor(fn: (request: VerificationRequest) => boolean): Promise<VerificationRequest> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const check = () => { const check = (): boolean => {
let handled = false; let handled = false;
if (fn(this)) { if (fn(this)) {
resolve(this); resolve(this);
@@ -539,7 +539,7 @@ export class VerificationRequest<
private calculatePhaseTransitions(): ITransition[] { private calculatePhaseTransitions(): ITransition[] {
const transitions: ITransition[] = [{ phase: PHASE_UNSENT }]; const transitions: ITransition[] = [{ phase: PHASE_UNSENT }];
const phase = () => transitions[transitions.length - 1].phase; const phase = (): Phase => transitions[transitions.length - 1].phase;
// always pass by .request first to be sure channel.userId has been set // always pass by .request first to be sure channel.userId has been set
const hasRequestByThem = this.eventsByThem.has(REQUEST_TYPE); const hasRequestByThem = this.eventsByThem.has(REQUEST_TYPE);
@@ -816,7 +816,7 @@ export class VerificationRequest<
} }
} }
private cancelOnTimeout = async () => { private cancelOnTimeout = async (): Promise<void> => {
try { try {
if (this.initiatedByMe) { if (this.initiatedByMe) {
await this.cancel({ await this.cancel({

View File

@@ -101,7 +101,7 @@ export class RoomWidgetClient extends MatrixClient {
private lifecycle?: AbortController; private lifecycle?: AbortController;
private syncState: SyncState | null = null; private syncState: SyncState | null = null;
constructor( public constructor(
private readonly widgetApi: WidgetApi, private readonly widgetApi: WidgetApi,
private readonly capabilities: ICapabilities, private readonly capabilities: ICapabilities,
private readonly roomId: string, private readonly roomId: string,
@@ -211,7 +211,7 @@ export class RoomWidgetClient extends MatrixClient {
if (this.capabilities.turnServers) this.watchTurnServers(); if (this.capabilities.turnServers) this.watchTurnServers();
} }
public stopClient() { public stopClient(): void {
this.widgetApi.off(`action:${WidgetApiToWidgetAction.SendEvent}`, this.onEvent); this.widgetApi.off(`action:${WidgetApiToWidgetAction.SendEvent}`, this.onEvent);
this.widgetApi.off(`action:${WidgetApiToWidgetAction.SendToDevice}`, this.onToDevice); this.widgetApi.off(`action:${WidgetApiToWidgetAction.SendToDevice}`, this.onToDevice);
@@ -288,7 +288,7 @@ export class RoomWidgetClient extends MatrixClient {
return this.syncState; return this.syncState;
} }
private setSyncState(state: SyncState) { private setSyncState(state: SyncState): void {
const oldState = this.syncState; const oldState = this.syncState;
this.syncState = state; this.syncState = state;
this.emit(ClientEvent.Sync, state, oldState); this.emit(ClientEvent.Sync, state, oldState);
@@ -298,7 +298,7 @@ export class RoomWidgetClient extends MatrixClient {
await this.widgetApi.transport.reply<IWidgetApiAcknowledgeResponseData>(ev.detail, {}); await this.widgetApi.transport.reply<IWidgetApiAcknowledgeResponseData>(ev.detail, {});
} }
private onEvent = async (ev: CustomEvent<ISendEventToWidgetActionRequest>) => { private onEvent = async (ev: CustomEvent<ISendEventToWidgetActionRequest>): Promise<void> => {
ev.preventDefault(); ev.preventDefault();
// Verify the room ID matches, since it's possible for the client to // Verify the room ID matches, since it's possible for the client to
@@ -317,7 +317,7 @@ export class RoomWidgetClient extends MatrixClient {
await this.ack(ev); await this.ack(ev);
}; };
private onToDevice = async (ev: CustomEvent<ISendToDeviceToWidgetActionRequest>) => { private onToDevice = async (ev: CustomEvent<ISendToDeviceToWidgetActionRequest>): Promise<void> => {
ev.preventDefault(); ev.preventDefault();
const event = new MatrixEvent({ const event = new MatrixEvent({
@@ -333,9 +333,11 @@ export class RoomWidgetClient extends MatrixClient {
await this.ack(ev); await this.ack(ev);
}; };
private async watchTurnServers() { private async watchTurnServers(): Promise<void> {
const servers = this.widgetApi.getTurnServers(); const servers = this.widgetApi.getTurnServers();
const onClientStopped = () => servers.return(undefined); const onClientStopped = (): void => {
servers.return(undefined);
};
this.lifecycle!.signal.addEventListener("abort", onClientStopped); this.lifecycle!.signal.addEventListener("abort", onClientStopped);
try { try {

View File

@@ -29,7 +29,7 @@ export function eventMapperFor(client: MatrixClient, options: MapperOpts): Event
let preventReEmit = Boolean(options.preventReEmit); let preventReEmit = Boolean(options.preventReEmit);
const decrypt = options.decrypt !== false; const decrypt = options.decrypt !== false;
function mapper(plainOldJsObject: Partial<IEvent>) { function mapper(plainOldJsObject: Partial<IEvent>): MatrixEvent {
if (options.toDevice) { if (options.toDevice) {
delete plainOldJsObject.room_id; delete plainOldJsObject.room_id;
} }

View File

@@ -73,7 +73,7 @@ export interface IFilterComponent {
* @param {Object} filterJson the definition of this filter JSON, e.g. { 'contains_url': true } * @param {Object} filterJson the definition of this filter JSON, e.g. { 'contains_url': true }
*/ */
export class FilterComponent { export class FilterComponent {
constructor(private filterJson: IFilterComponent, public readonly userId?: string | undefined | null) {} public constructor(private filterJson: IFilterComponent, public readonly userId?: string | undefined | null) {}
/** /**
* Checks with the filter component matches the given event * Checks with the filter component matches the given event

View File

@@ -31,7 +31,7 @@ import { MatrixEvent } from "./models/event";
* @param {string} keyNesting * @param {string} keyNesting
* @param {*} val * @param {*} val
*/ */
function setProp(obj: object, keyNesting: string, val: any) { function setProp(obj: object, keyNesting: string, val: any): void {
const nestedKeys = keyNesting.split("."); const nestedKeys = keyNesting.split(".");
let currentObj = obj; let currentObj = obj;
for (let i = 0; i < (nestedKeys.length - 1); i++) { for (let i = 0; i < (nestedKeys.length - 1); i++) {
@@ -88,7 +88,7 @@ interface IRoomFilter {
* @prop {?string} filterId The filter ID * @prop {?string} filterId The filter ID
*/ */
export class Filter { export class Filter {
static LAZY_LOADING_MESSAGES_FILTER = { public static LAZY_LOADING_MESSAGES_FILTER = {
lazy_load_members: true, lazy_load_members: true,
}; };
@@ -110,7 +110,7 @@ export class Filter {
private roomFilter?: FilterComponent; private roomFilter?: FilterComponent;
private roomTimelineFilter?: FilterComponent; private roomTimelineFilter?: FilterComponent;
constructor(public readonly userId: string | undefined | null, public filterId?: string) {} public constructor(public readonly userId: string | undefined | null, public filterId?: string) {}
/** /**
* Get the ID of this filter on your homeserver (if known) * Get the ID of this filter on your homeserver (if known)
@@ -132,7 +132,7 @@ export class Filter {
* Set the JSON body of the filter * Set the JSON body of the filter
* @param {Object} definition The filter definition * @param {Object} definition The filter definition
*/ */
public setDefinition(definition: IFilterDefinition) { public setDefinition(definition: IFilterDefinition): void {
this.definition = definition; this.definition = definition;
// This is all ported from synapse's FilterCollection() // This is all ported from synapse's FilterCollection()
@@ -225,7 +225,7 @@ export class Filter {
* Set the max number of events to return for each room's timeline. * Set the max number of events to return for each room's timeline.
* @param {Number} limit The max number of events to return for each room. * @param {Number} limit The max number of events to return for each room.
*/ */
public setTimelineLimit(limit: number) { public setTimelineLimit(limit: number): void {
setProp(this.definition, "room.timeline.limit", limit); setProp(this.definition, "room.timeline.limit", limit);
} }
@@ -255,7 +255,7 @@ export class Filter {
* @param {boolean} includeLeave True to make rooms the user has left appear * @param {boolean} includeLeave True to make rooms the user has left appear
* in responses. * in responses.
*/ */
public setIncludeLeaveRooms(includeLeave: boolean) { public setIncludeLeaveRooms(includeLeave: boolean): void {
setProp(this.definition, "room.include_leave", includeLeave); setProp(this.definition, "room.include_leave", includeLeave);
} }
} }

View File

@@ -31,7 +31,7 @@ interface IErrorJson extends Partial<IUsageLimit> {
* @param {number} httpStatus The HTTP response status code. * @param {number} httpStatus The HTTP response status code.
*/ */
export class HTTPError extends Error { export class HTTPError extends Error {
constructor(msg: string, public readonly httpStatus?: number) { public constructor(msg: string, public readonly httpStatus?: number) {
super(msg); super(msg);
} }
} }
@@ -51,7 +51,7 @@ export class MatrixError extends HTTPError {
public readonly errcode?: string; public readonly errcode?: string;
public data: IErrorJson; public data: IErrorJson;
constructor( public constructor(
errorJson: IErrorJson = {}, errorJson: IErrorJson = {},
public readonly httpStatus?: number, public readonly httpStatus?: number,
public url?: string, public url?: string,
@@ -79,11 +79,11 @@ export class MatrixError extends HTTPError {
* @constructor * @constructor
*/ */
export class ConnectionError extends Error { export class ConnectionError extends Error {
constructor(message: string, cause?: Error) { public constructor(message: string, cause?: Error) {
super(message + (cause ? `: ${cause.message}` : "")); super(message + (cause ? `: ${cause.message}` : ""));
} }
get name() { public get name(): string {
return "ConnectionError"; return "ConnectionError";
} }
} }

View File

@@ -41,7 +41,7 @@ export type ResponseType<T, O extends IHttpOpts> =
export class FetchHttpApi<O extends IHttpOpts> { export class FetchHttpApi<O extends IHttpOpts> {
private abortController = new AbortController(); private abortController = new AbortController();
constructor( public constructor(
private eventEmitter: TypedEventEmitter<HttpApiEvent, HttpApiEventHandlerMap>, private eventEmitter: TypedEventEmitter<HttpApiEvent, HttpApiEventHandlerMap>,
public readonly opts: O, public readonly opts: O,
) { ) {

View File

@@ -77,7 +77,7 @@ export class MatrixHttpApi<O extends IHttpOpts> extends FetchHttpApi<O> {
if (global.XMLHttpRequest) { if (global.XMLHttpRequest) {
const xhr = new global.XMLHttpRequest(); const xhr = new global.XMLHttpRequest();
const timeoutFn = function() { const timeoutFn = function(): void {
xhr.abort(); xhr.abort();
defer.reject(new Error("Timeout")); defer.reject(new Error("Timeout"));
}; };
@@ -85,7 +85,7 @@ export class MatrixHttpApi<O extends IHttpOpts> extends FetchHttpApi<O> {
// set an initial timeout of 30s; we'll advance it each time we get a progress notification // set an initial timeout of 30s; we'll advance it each time we get a progress notification
let timeoutTimer = callbacks.setTimeout(timeoutFn, 30000); let timeoutTimer = callbacks.setTimeout(timeoutFn, 30000);
xhr.onreadystatechange = function() { xhr.onreadystatechange = function(): void {
switch (xhr.readyState) { switch (xhr.readyState) {
case global.XMLHttpRequest.DONE: case global.XMLHttpRequest.DONE:
callbacks.clearTimeout(timeoutTimer); callbacks.clearTimeout(timeoutTimer);
@@ -113,7 +113,7 @@ export class MatrixHttpApi<O extends IHttpOpts> extends FetchHttpApi<O> {
} }
}; };
xhr.upload.onprogress = (ev: ProgressEvent) => { xhr.upload.onprogress = (ev: ProgressEvent): void => {
callbacks.clearTimeout(timeoutTimer); callbacks.clearTimeout(timeoutTimer);
upload.loaded = ev.loaded; upload.loaded = ev.loaded;
upload.total = ev.total; upload.total = ev.total;

View File

@@ -36,13 +36,13 @@ export function anySignal(signals: AbortSignal[]): {
} { } {
const controller = new AbortController(); const controller = new AbortController();
function cleanup() { function cleanup(): void {
for (const signal of signals) { for (const signal of signals) {
signal.removeEventListener("abort", onAbort); signal.removeEventListener("abort", onAbort);
} }
} }
function onAbort() { function onAbort(): void {
controller.abort(); controller.abort();
cleanup(); cleanup();
} }

View File

@@ -26,13 +26,13 @@ export function exists(indexedDB: IDBFactory, dbName: string): Promise<boolean>
return new Promise<boolean>((resolve, reject) => { return new Promise<boolean>((resolve, reject) => {
let exists = true; let exists = true;
const req = indexedDB.open(dbName); const req = indexedDB.open(dbName);
req.onupgradeneeded = () => { req.onupgradeneeded = (): void => {
// Since we did not provide an explicit version when opening, this event // Since we did not provide an explicit version when opening, this event
// should only fire if the DB did not exist before at any version. // should only fire if the DB did not exist before at any version.
exists = false; exists = false;
}; };
req.onblocked = () => reject(req.error); req.onblocked = (): void => reject(req.error);
req.onsuccess = () => { req.onsuccess = (): void => {
const db = req.result; const db = req.result;
db.close(); db.close();
if (!exists) { if (!exists) {
@@ -45,6 +45,6 @@ export function exists(indexedDB: IDBFactory, dbName: string): Promise<boolean>
} }
resolve(exists); resolve(exists);
}; };
req.onerror = ev => reject(req.error); req.onerror = (): void => reject(req.error);
}); });
} }

View File

@@ -100,7 +100,7 @@ class NoAuthFlowFoundError extends Error {
public name = "NoAuthFlowFoundError"; public name = "NoAuthFlowFoundError";
// eslint-disable-next-line @typescript-eslint/naming-convention, camelcase // eslint-disable-next-line @typescript-eslint/naming-convention, camelcase
constructor(m: string, public readonly required_stages: string[], public readonly flows: IFlow[]) { public constructor(m: string, public readonly required_stages: string[], public readonly flows: IFlow[]) {
super(m); super(m);
} }
} }
@@ -218,7 +218,7 @@ export class InteractiveAuth {
// the promise the will resolve/reject when it completes // the promise the will resolve/reject when it completes
private submitPromise: Promise<void> | null = null; private submitPromise: Promise<void> | null = null;
constructor(opts: IOpts) { public constructor(opts: IOpts) {
this.matrixClient = opts.matrixClient; this.matrixClient = opts.matrixClient;
this.data = opts.authData || {}; this.data = opts.authData || {};
this.requestCallback = opts.doRequest; this.requestCallback = opts.doRequest;
@@ -419,7 +419,7 @@ export class InteractiveAuth {
/** /**
* Requests a new email token and sets the email sid for the validation session * Requests a new email token and sets the email sid for the validation session
*/ */
public requestEmailToken = async () => { public requestEmailToken = async (): Promise<void> => {
if (!this.requestingEmailToken) { if (!this.requestingEmailToken) {
logger.trace("Requesting email token. Attempt: " + this.emailAttempt); logger.trace("Requesting email token. Attempt: " + this.emailAttempt);
// If we've picked a flow with email auth, we send the email // If we've picked a flow with email auth, we send the email

View File

@@ -35,7 +35,7 @@ const DEFAULT_NAMESPACE = "matrix";
// console methods at initialization time by a factory that looks up the console methods // console methods at initialization time by a factory that looks up the console methods
// when logging so we always get the current value of console methods. // when logging so we always get the current value of console methods.
log.methodFactory = function(methodName, logLevel, loggerName) { log.methodFactory = function(methodName, logLevel, loggerName) {
return function(this: PrefixedLogger, ...args) { return function(this: PrefixedLogger, ...args): void {
/* eslint-disable @typescript-eslint/no-invalid-this */ /* eslint-disable @typescript-eslint/no-invalid-this */
if (this.prefix) { if (this.prefix) {
args.unshift(this.prefix); args.unshift(this.prefix);
@@ -67,7 +67,7 @@ export interface PrefixedLogger extends Logger {
prefix: string; prefix: string;
} }
function extendLogger(logger: Logger) { function extendLogger(logger: Logger): void {
(<PrefixedLogger>logger).withPrefix = function(prefix: string): PrefixedLogger { (<PrefixedLogger>logger).withPrefix = function(prefix: string): PrefixedLogger {
const existingPrefix = this.prefix || ""; const existingPrefix = this.prefix || "";
return getPrefixedLogger(existingPrefix + prefix); return getPrefixedLogger(existingPrefix + prefix);

View File

@@ -21,6 +21,7 @@ import { MemoryStore } from "./store/memory";
import { MatrixScheduler } from "./scheduler"; import { MatrixScheduler } from "./scheduler";
import { MatrixClient, ICreateClientOpts } from "./client"; import { MatrixClient, ICreateClientOpts } from "./client";
import { RoomWidgetClient, ICapabilities } from "./embedded"; import { RoomWidgetClient, ICapabilities } from "./embedded";
import { CryptoStore } from "./crypto/store/base";
export * from "./client"; export * from "./client";
export * from "./embedded"; export * from "./embedded";
@@ -64,7 +65,7 @@ export {
} from "./webrtc/groupCall"; } from "./webrtc/groupCall";
export type { GroupCall } from "./webrtc/groupCall"; export type { GroupCall } from "./webrtc/groupCall";
let cryptoStoreFactory = () => new MemoryCryptoStore; let cryptoStoreFactory = (): CryptoStore => new MemoryCryptoStore;
/** /**
* Configure a different factory to be used for creating crypto stores * Configure a different factory to be used for creating crypto stores
@@ -72,7 +73,7 @@ let cryptoStoreFactory = () => new MemoryCryptoStore;
* @param {Function} fac a function which will return a new * @param {Function} fac a function which will return a new
* {@link module:crypto.store.base~CryptoStore}. * {@link module:crypto.store.base~CryptoStore}.
*/ */
export function setCryptoStoreFactory(fac) { export function setCryptoStoreFactory(fac: () => CryptoStore): void {
cryptoStoreFactory = fac; cryptoStoreFactory = fac;
} }

View File

@@ -172,7 +172,7 @@ export class MSC3089TreeSpace {
const currentPls = this.room.currentState.getStateEvents(EventType.RoomPowerLevels, ""); const currentPls = this.room.currentState.getStateEvents(EventType.RoomPowerLevels, "");
if (Array.isArray(currentPls)) throw new Error("Unexpected return type for power levels"); if (Array.isArray(currentPls)) throw new Error("Unexpected return type for power levels");
const pls = currentPls.getContent() || {}; const pls = currentPls?.getContent() || {};
const viewLevel = pls['users_default'] || 0; const viewLevel = pls['users_default'] || 0;
const editLevel = pls['events_default'] || 50; const editLevel = pls['events_default'] || 50;
const adminLevel = pls['events']?.[EventType.RoomPowerLevels] || 100; const adminLevel = pls['events']?.[EventType.RoomPowerLevels] || 100;
@@ -207,7 +207,7 @@ export class MSC3089TreeSpace {
const currentPls = this.room.currentState.getStateEvents(EventType.RoomPowerLevels, ""); const currentPls = this.room.currentState.getStateEvents(EventType.RoomPowerLevels, "");
if (Array.isArray(currentPls)) throw new Error("Unexpected return type for power levels"); if (Array.isArray(currentPls)) throw new Error("Unexpected return type for power levels");
const pls = currentPls.getContent() || {}; const pls = currentPls?.getContent() || {};
const viewLevel = pls['users_default'] || 0; const viewLevel = pls['users_default'] || 0;
const editLevel = pls['events_default'] || 50; const editLevel = pls['events_default'] || 50;
const adminLevel = pls['events']?.[EventType.RoomPowerLevels] || 100; const adminLevel = pls['events']?.[EventType.RoomPowerLevels] || 100;

View File

@@ -56,7 +56,7 @@ export class Beacon extends TypedEventEmitter<Exclude<BeaconEvent, BeaconEvent.N
private livenessWatchTimeout?: ReturnType<typeof setTimeout>; private livenessWatchTimeout?: ReturnType<typeof setTimeout>;
private _latestLocationEvent?: MatrixEvent; private _latestLocationEvent?: MatrixEvent;
constructor( public constructor(
private rootEvent: MatrixEvent, private rootEvent: MatrixEvent,
) { ) {
super(); super();
@@ -180,7 +180,7 @@ export class Beacon extends TypedEventEmitter<Exclude<BeaconEvent, BeaconEvent.N
} }
} }
private clearLatestLocation = () => { private clearLatestLocation = (): void => {
this._latestLocationEvent = undefined; this._latestLocationEvent = undefined;
this.emit(BeaconEvent.LocationUpdate, this.latestLocationState!); this.emit(BeaconEvent.LocationUpdate, this.latestLocationState!);
}; };

View File

@@ -42,7 +42,7 @@ export class EventContext {
* *
* @constructor * @constructor
*/ */
constructor(public readonly ourEvent: MatrixEvent) { public constructor(public readonly ourEvent: MatrixEvent) {
this.timeline = [ourEvent]; this.timeline = [ourEvent];
} }

View File

@@ -36,7 +36,7 @@ if (DEBUG) {
// using bind means that we get to keep useful line numbers in the console // using bind means that we get to keep useful line numbers in the console
debuglog = logger.log.bind(logger); debuglog = logger.log.bind(logger);
} else { } else {
debuglog = function() {}; debuglog = function(): void {};
} }
interface IOpts { interface IOpts {
@@ -135,7 +135,7 @@ export class EventTimelineSet extends TypedEventEmitter<EmittedEvents, EventTime
* @param {boolean} isThreadTimeline Whether this timeline set relates to a thread list timeline * @param {boolean} isThreadTimeline Whether this timeline set relates to a thread list timeline
* (e.g., All threads or My threads) * (e.g., All threads or My threads)
*/ */
constructor( public constructor(
public readonly room: Room | undefined, public readonly room: Room | undefined,
opts: IOpts = {}, opts: IOpts = {},
client?: MatrixClient, client?: MatrixClient,

View File

@@ -67,7 +67,7 @@ export class EventTimeline {
* @param {RoomState} stateContext the room state to be queried * @param {RoomState} stateContext the room state to be queried
* @param {boolean} toStartOfTimeline if true the event's forwardLooking flag is set false * @param {boolean} toStartOfTimeline if true the event's forwardLooking flag is set false
*/ */
static setEventMetadata(event: MatrixEvent, stateContext: RoomState, toStartOfTimeline: boolean): void { public static setEventMetadata(event: MatrixEvent, stateContext: RoomState, toStartOfTimeline: boolean): void {
// When we try to generate a sentinel member before we have that member // When we try to generate a sentinel member before we have that member
// in the members object, we still generate a sentinel but it doesn't // in the members object, we still generate a sentinel but it doesn't
// have a membership event, so test to see if events.member is set. We // have a membership event, so test to see if events.member is set. We
@@ -130,7 +130,7 @@ export class EventTimeline {
* @param {EventTimelineSet} eventTimelineSet the set of timelines this is part of * @param {EventTimelineSet} eventTimelineSet the set of timelines this is part of
* @constructor * @constructor
*/ */
constructor(private readonly eventTimelineSet: EventTimelineSet) { public constructor(private readonly eventTimelineSet: EventTimelineSet) {
this.roomId = eventTimelineSet.room?.roomId ?? null; this.roomId = eventTimelineSet.room?.roomId ?? null;
if (this.roomId) { if (this.roomId) {
this.startState = new RoomState(this.roomId); this.startState = new RoomState(this.roomId);

View File

@@ -309,7 +309,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
* that getDirectionalContent() will return event.content and not event.prev_content. * that getDirectionalContent() will return event.content and not event.prev_content.
* Default: true. <strong>This property is experimental and may change.</strong> * Default: true. <strong>This property is experimental and may change.</strong>
*/ */
constructor(public event: Partial<IEvent> = {}) { public constructor(public event: Partial<IEvent> = {}) {
super(); super();
// intern the values of matrix events to force share strings and reduce the // intern the values of matrix events to force share strings and reduce the
@@ -352,7 +352,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
return this._cachedExtEv; return this._cachedExtEv;
} }
private invalidateExtensibleEvent() { private invalidateExtensibleEvent(): void {
// just reset the flag - that'll trick the getter into parsing a new event // just reset the flag - that'll trick the getter into parsing a new event
this._hasCachedExtEv = false; this._hasCachedExtEv = false;
} }
@@ -679,7 +679,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
return this.clearEvent?.content?.msgtype === "m.bad.encrypted"; return this.clearEvent?.content?.msgtype === "m.bad.encrypted";
} }
public shouldAttemptDecryption() { public shouldAttemptDecryption(): boolean {
if (this.isRedacted()) return false; if (this.isRedacted()) return false;
if (this.isBeingDecrypted()) return false; if (this.isBeingDecrypted()) return false;
if (this.clearEvent) return false; if (this.clearEvent) return false;
@@ -1480,7 +1480,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
* more information. * more information.
* @returns {boolean} True if the event is cancelled, false otherwise. * @returns {boolean} True if the event is cancelled, false otherwise.
*/ */
isCancelled(): boolean { public isCancelled(): boolean {
return this._isCancelled; return this._isCancelled;
} }
@@ -1498,7 +1498,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
* features (such as sender) surrounding the event. * features (such as sender) surrounding the event.
* @returns {MatrixEvent} A snapshot of this event. * @returns {MatrixEvent} A snapshot of this event.
*/ */
toSnapshot(): MatrixEvent { public toSnapshot(): MatrixEvent {
const ev = new MatrixEvent(JSON.parse(JSON.stringify(this.event))); const ev = new MatrixEvent(JSON.parse(JSON.stringify(this.event)));
for (const [p, v] of Object.entries(this)) { for (const [p, v] of Object.entries(this)) {
if (p !== "event") { // exclude the thing we just cloned if (p !== "event") { // exclude the thing we just cloned
@@ -1515,7 +1515,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
* @param {MatrixEvent} otherEvent The other event to check against. * @param {MatrixEvent} otherEvent The other event to check against.
* @returns {boolean} True if the events are the same, false otherwise. * @returns {boolean} True if the events are the same, false otherwise.
*/ */
isEquivalentTo(otherEvent: MatrixEvent): boolean { public isEquivalentTo(otherEvent: MatrixEvent): boolean {
if (!otherEvent) return false; if (!otherEvent) return false;
if (otherEvent === this) return true; if (otherEvent === this) return true;
const myProps = deepSortedObjectEntries(this.event); const myProps = deepSortedObjectEntries(this.event);

View File

@@ -73,7 +73,7 @@ export enum PolicyScope {
* our data structures. * our data structures.
*/ */
export class IgnoredInvites { export class IgnoredInvites {
constructor( public constructor(
private readonly client: MatrixClient, private readonly client: MatrixClient,
) { ) {
} }
@@ -99,7 +99,7 @@ export class IgnoredInvites {
/** /**
* Remove a rule. * Remove a rule.
*/ */
public async removeRule(event: MatrixEvent) { public async removeRule(event: MatrixEvent): Promise<void> {
await this.client.redactEvent(event.getRoomId()!, event.getId()!); await this.client.redactEvent(event.getRoomId()!, event.getId()!);
} }
@@ -314,7 +314,7 @@ export class IgnoredInvites {
/** /**
* Modify in place the `IGNORE_INVITES_POLICIES` object from account data. * Modify in place the `IGNORE_INVITES_POLICIES` object from account data.
*/ */
private async withIgnoreInvitesPolicies(cb: (ignoreInvitesPolicies: {[key: string]: any}) => void) { private async withIgnoreInvitesPolicies(cb: (ignoreInvitesPolicies: {[key: string]: any}) => void): Promise<void> {
const { policies, ignoreInvitesPolicies } = this.getPoliciesAndIgnoreInvitesPolicies(); const { policies, ignoreInvitesPolicies } = this.getPoliciesAndIgnoreInvitesPolicies();
cb(ignoreInvitesPolicies); cb(ignoreInvitesPolicies);
policies[IGNORE_INVITES_ACCOUNT_EVENT_KEY.name] = ignoreInvitesPolicies; policies[IGNORE_INVITES_ACCOUNT_EVENT_KEY.name] = ignoreInvitesPolicies;

View File

@@ -29,11 +29,11 @@ export class RelatedRelations {
return this.relations.reduce<MatrixEvent[]>((c, p) => [...c, ...p.getRelations()], []); return this.relations.reduce<MatrixEvent[]>((c, p) => [...c, ...p.getRelations()], []);
} }
public on<T extends RelationsEvent>(ev: T, fn: Listener<RelationsEvent, EventHandlerMap, T>) { public on<T extends RelationsEvent>(ev: T, fn: Listener<RelationsEvent, EventHandlerMap, T>): void {
this.relations.forEach(r => r.on(ev, fn)); this.relations.forEach(r => r.on(ev, fn));
} }
public off<T extends RelationsEvent>(ev: T, fn: Listener<RelationsEvent, EventHandlerMap, T>) { public off<T extends RelationsEvent>(ev: T, fn: Listener<RelationsEvent, EventHandlerMap, T>): void {
this.relations.forEach(r => r.off(ev, fn)); this.relations.forEach(r => r.off(ev, fn));
} }
} }

View File

@@ -26,7 +26,7 @@ export class RelationsContainer {
// this.relations.get(parentEventId).get(relationType).get(relationEventType) // this.relations.get(parentEventId).get(relationType).get(relationEventType)
private relations = new Map<string, Map<RelationType | string, Map<EventType | string, Relations>>>(); private relations = new Map<string, Map<RelationType | string, Map<EventType | string, Relations>>>();
constructor(private readonly client: MatrixClient, private readonly room?: Room) { public constructor(private readonly client: MatrixClient, private readonly room?: Room) {
} }
/** /**
@@ -98,7 +98,7 @@ export class RelationsContainer {
const relation = event.getRelation(); const relation = event.getRelation();
if (!relation) return; if (!relation) return;
const onEventDecrypted = () => { const onEventDecrypted = (): void => {
if (event.isDecryptionFailure()) { if (event.isDecryptionFailure()) {
// This could for example happen if the encryption keys are not yet available. // This could for example happen if the encryption keys are not yet available.
// The event may still be decrypted later. Register the listener again. // The event may still be decrypted later. Register the listener again.

View File

@@ -60,7 +60,7 @@ export class Relations extends TypedEventEmitter<RelationsEvent, EventHandlerMap
* @param {MatrixClient|Room} client * @param {MatrixClient|Room} client
* The client which created this instance. For backwards compatibility also accepts a Room. * The client which created this instance. For backwards compatibility also accepts a Room.
*/ */
constructor( public constructor(
public readonly relationType: RelationType | string, public readonly relationType: RelationType | string,
public readonly eventType: string, public readonly eventType: string,
client: MatrixClient | Room, client: MatrixClient | Room,
@@ -75,7 +75,7 @@ export class Relations extends TypedEventEmitter<RelationsEvent, EventHandlerMap
* @param {MatrixEvent} event * @param {MatrixEvent} event
* The new relation event to be added. * The new relation event to be added.
*/ */
public async addEvent(event: MatrixEvent) { public async addEvent(event: MatrixEvent): Promise<void> {
if (this.relationEventIds.has(event.getId()!)) { if (this.relationEventIds.has(event.getId()!)) {
return; return;
} }
@@ -123,7 +123,7 @@ export class Relations extends TypedEventEmitter<RelationsEvent, EventHandlerMap
* @param {MatrixEvent} event * @param {MatrixEvent} event
* The relation event to remove. * The relation event to remove.
*/ */
private async removeEvent(event: MatrixEvent) { private async removeEvent(event: MatrixEvent): Promise<void> {
if (!this.relations.has(event)) { if (!this.relations.has(event)) {
return; return;
} }
@@ -160,7 +160,7 @@ export class Relations extends TypedEventEmitter<RelationsEvent, EventHandlerMap
* @param {MatrixEvent} event The event whose status has changed * @param {MatrixEvent} event The event whose status has changed
* @param {EventStatus} status The new status * @param {EventStatus} status The new status
*/ */
private onEventStatus = (event: MatrixEvent, status: EventStatus | null) => { private onEventStatus = (event: MatrixEvent, status: EventStatus | null): void => {
if (!event.isSending()) { if (!event.isSending()) {
// Sending is done, so we don't need to listen anymore // Sending is done, so we don't need to listen anymore
event.removeListener(MatrixEventEvent.Status, this.onEventStatus); event.removeListener(MatrixEventEvent.Status, this.onEventStatus);
@@ -356,7 +356,7 @@ export class Relations extends TypedEventEmitter<RelationsEvent, EventHandlerMap
/* /*
* @param {MatrixEvent} targetEvent the event the relations are related to. * @param {MatrixEvent} targetEvent the event the relations are related to.
*/ */
public async setTargetEvent(event: MatrixEvent) { public async setTargetEvent(event: MatrixEvent): Promise<void> {
if (this.targetEvent) { if (this.targetEvent) {
return; return;
} }
@@ -374,7 +374,7 @@ export class Relations extends TypedEventEmitter<RelationsEvent, EventHandlerMap
this.maybeEmitCreated(); this.maybeEmitCreated();
} }
private maybeEmitCreated() { private maybeEmitCreated(): void {
if (this.creationEmitted) { if (this.creationEmitted) {
return; return;
} }

View File

@@ -83,7 +83,7 @@ export class RoomMember extends TypedEventEmitter<RoomMemberEvent, RoomMemberEve
* @prop {MatrixEvent} events.member The m.room.member event for 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. * @prop {boolean} disambiguate True if the member's name is disambiguated.
*/ */
constructor(public readonly roomId: string, public readonly userId: string) { public constructor(public readonly roomId: string, public readonly userId: string) {
super(); super();
this.name = userId; this.name = userId;
@@ -232,7 +232,7 @@ export class RoomMember extends TypedEventEmitter<RoomMemberEvent, RoomMemberEve
/** /**
* Update the last modified time to the current time. * Update the last modified time to the current time.
*/ */
private updateModifiedTime() { private updateModifiedTime(): void {
this.modified = Date.now(); this.modified = Date.now();
} }

View File

@@ -136,7 +136,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
* events dictionary, keyed on the event type and then the state_key value. * events dictionary, keyed on the event type and then the state_key value.
* @prop {string} paginationToken The pagination token for this state. * @prop {string} paginationToken The pagination token for this state.
*/ */
constructor(public readonly roomId: string, private oobMemberFlags = { status: OobStatus.NotStarted }) { public constructor(public readonly roomId: string, private oobMemberFlags = { status: OobStatus.NotStarted }) {
super(); super();
this.updateModifiedTime(); this.updateModifiedTime();
} }
@@ -250,8 +250,8 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
* <code>undefined</code>, else a single event (or null if no match found). * <code>undefined</code>, else a single event (or null if no match found).
*/ */
public getStateEvents(eventType: EventType | string): MatrixEvent[]; public getStateEvents(eventType: EventType | string): MatrixEvent[];
public getStateEvents(eventType: EventType | string, stateKey: string): MatrixEvent; public getStateEvents(eventType: EventType | string, stateKey: string): MatrixEvent | null;
public getStateEvents(eventType: EventType | string, stateKey?: string) { public getStateEvents(eventType: EventType | string, stateKey?: string): MatrixEvent[] | MatrixEvent | null {
if (!this.events.has(eventType)) { if (!this.events.has(eventType)) {
// no match // no match
return stateKey === undefined ? [] : null; return stateKey === undefined ? [] : null;
@@ -342,7 +342,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
* @fires module:client~MatrixClient#event:"RoomState.events" * @fires module:client~MatrixClient#event:"RoomState.events"
* @fires module:client~MatrixClient#event:"RoomStateEvent.Marker" * @fires module:client~MatrixClient#event:"RoomStateEvent.Marker"
*/ */
public setStateEvents(stateEvents: MatrixEvent[], markerFoundOptions?: IMarkerFoundOptions) { public setStateEvents(stateEvents: MatrixEvent[], markerFoundOptions?: IMarkerFoundOptions): void {
this.updateModifiedTime(); this.updateModifiedTime();
// update the core event dict // update the core event dict

View File

@@ -46,6 +46,6 @@ interface IInfo {
* @param {Number} info.timestamp The timestamp for this room. * @param {Number} info.timestamp The timestamp for this room.
*/ */
export class RoomSummary { export class RoomSummary {
constructor(public readonly roomId: string, info?: IInfo) {} public constructor(public readonly roomId: string, info?: IInfo) {}
} }

View File

@@ -317,7 +317,7 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
* @param {boolean} [opts.timelineSupport = false] Set to true to enable improved * @param {boolean} [opts.timelineSupport = false] Set to true to enable improved
* timeline support. * timeline support.
*/ */
constructor( public constructor(
public readonly roomId: string, public readonly roomId: string,
public readonly client: MatrixClient, public readonly client: MatrixClient,
public readonly myUserId: string, public readonly myUserId: string,
@@ -1950,7 +1950,7 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
)); ));
} }
private updateThreadRootEvents = (thread: Thread, toStartOfTimeline: boolean) => { private updateThreadRootEvents = (thread: Thread, toStartOfTimeline: boolean): void => {
if (thread.length) { if (thread.length) {
this.updateThreadRootEvent(this.threadsTimelineSets?.[0], thread, toStartOfTimeline); this.updateThreadRootEvent(this.threadsTimelineSets?.[0], thread, toStartOfTimeline);
if (thread.hasCurrentUserParticipated) { if (thread.hasCurrentUserParticipated) {
@@ -1963,7 +1963,7 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
timelineSet: Optional<EventTimelineSet>, timelineSet: Optional<EventTimelineSet>,
thread: Thread, thread: Thread,
toStartOfTimeline: boolean, toStartOfTimeline: boolean,
) => { ): void => {
if (timelineSet && thread.rootEvent) { if (timelineSet && thread.rootEvent) {
if (Thread.hasServerSideSupport) { if (Thread.hasServerSideSupport) {
timelineSet.addLiveEvent(thread.rootEvent, { timelineSet.addLiveEvent(thread.rootEvent, {
@@ -2050,7 +2050,7 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
redactedEvent.getType(), redactedEvent.getType(),
redactedEvent.getStateKey()!, redactedEvent.getStateKey()!,
); );
if (currentStateEvent.getId() === redactedEvent.getId()) { if (currentStateEvent?.getId() === redactedEvent.getId()) {
this.currentState.setStateEvents([redactedEvent]); this.currentState.setStateEvents([redactedEvent]);
} }
} }
@@ -2913,7 +2913,7 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
let excludedUserIds: string[] = []; let excludedUserIds: string[] = [];
const mFunctionalMembers = this.currentState.getStateEvents(UNSTABLE_ELEMENT_FUNCTIONAL_USERS.name, ""); const mFunctionalMembers = this.currentState.getStateEvents(UNSTABLE_ELEMENT_FUNCTIONAL_USERS.name, "");
if (Array.isArray(mFunctionalMembers?.getContent().service_members)) { if (Array.isArray(mFunctionalMembers?.getContent().service_members)) {
excludedUserIds = mFunctionalMembers.getContent().service_members; excludedUserIds = mFunctionalMembers!.getContent().service_members;
} }
// get members that are NOT ourselves and are actually in the room. // get members that are NOT ourselves and are actually in the room.
@@ -3077,7 +3077,7 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
originalEvent.applyVisibilityEvent(visibilityChange); originalEvent.applyVisibilityEvent(visibilityChange);
} }
private redactVisibilityChangeEvent(event: MatrixEvent) { private redactVisibilityChangeEvent(event: MatrixEvent): void {
// Sanity checks. // Sanity checks.
if (!event.isVisibilityEvent) { if (!event.isVisibilityEvent) {
throw new Error("expected a visibility change event"); throw new Error("expected a visibility change event");

View File

@@ -60,5 +60,5 @@ export class SearchResult {
* *
* @constructor * @constructor
*/ */
constructor(public readonly rank: number, public readonly context: EventContext) {} public constructor(public readonly rank: number, public readonly context: EventContext) {}
} }

View File

@@ -94,7 +94,7 @@ export class Thread extends ReadReceipt<EmittedEvents, EventHandlerMap> {
public initialEventsFetched = !Thread.hasServerSideSupport; public initialEventsFetched = !Thread.hasServerSideSupport;
constructor( public constructor(
public readonly id: string, public readonly id: string,
public rootEvent: MatrixEvent | undefined, public rootEvent: MatrixEvent | undefined,
opts: IThreadOpts, opts: IThreadOpts,
@@ -167,7 +167,7 @@ export class Thread extends ReadReceipt<EmittedEvents, EventHandlerMap> {
Thread.hasServerSideFwdPaginationSupport = status; Thread.hasServerSideFwdPaginationSupport = status;
} }
private onBeforeRedaction = (event: MatrixEvent, redaction: MatrixEvent) => { private onBeforeRedaction = (event: MatrixEvent, redaction: MatrixEvent): void => {
if (event?.isRelation(THREAD_RELATION_TYPE.name) && if (event?.isRelation(THREAD_RELATION_TYPE.name) &&
this.room.eventShouldLiveIn(event).threadId === this.id && this.room.eventShouldLiveIn(event).threadId === this.id &&
event.getId() !== this.id && // the root event isn't counted in the length so ignore this redaction event.getId() !== this.id && // the root event isn't counted in the length so ignore this redaction
@@ -178,7 +178,7 @@ export class Thread extends ReadReceipt<EmittedEvents, EventHandlerMap> {
} }
}; };
private onRedaction = async (event: MatrixEvent) => { private onRedaction = async (event: MatrixEvent): Promise<void> => {
if (event.threadRootId !== this.id) return; // ignore redactions for other timelines if (event.threadRootId !== this.id) return; // ignore redactions for other timelines
if (this.replyCount <= 0) { if (this.replyCount <= 0) {
for (const threadEvent of this.events) { for (const threadEvent of this.events) {
@@ -192,7 +192,7 @@ export class Thread extends ReadReceipt<EmittedEvents, EventHandlerMap> {
} }
}; };
private onEcho = async (event: MatrixEvent) => { private onEcho = async (event: MatrixEvent): Promise<void> => {
if (event.threadRootId !== this.id) return; // ignore echoes for other timelines if (event.threadRootId !== this.id) return; // ignore echoes for other timelines
if (this.lastEvent === event) return; if (this.lastEvent === event) return;
if (!event.isRelation(THREAD_RELATION_TYPE.name)) return; if (!event.isRelation(THREAD_RELATION_TYPE.name)) return;
@@ -349,7 +349,7 @@ export class Thread extends ReadReceipt<EmittedEvents, EventHandlerMap> {
/** /**
* Finds an event by ID in the current thread * Finds an event by ID in the current thread
*/ */
public findEventById(eventId: string) { public findEventById(eventId: string): MatrixEvent | undefined {
// Check the lastEvent as it may have been created based on a bundled relationship and not in a timeline // Check the lastEvent as it may have been created based on a bundled relationship and not in a timeline
if (this.lastEvent?.getId() === eventId) { if (this.lastEvent?.getId() === eventId) {
return this.lastEvent; return this.lastEvent;
@@ -361,7 +361,7 @@ export class Thread extends ReadReceipt<EmittedEvents, EventHandlerMap> {
/** /**
* Return last reply to the thread, if known. * Return last reply to the thread, if known.
*/ */
public lastReply(matches: (ev: MatrixEvent) => boolean = () => true): MatrixEvent | null { public lastReply(matches: (ev: MatrixEvent) => boolean = (): boolean => true): MatrixEvent | null {
for (let i = this.events.length - 1; i >= 0; i--) { for (let i = this.events.length - 1; i >= 0; i--) {
const event = this.events[i]; const event = this.events[i];
if (matches(event)) { if (matches(event)) {

View File

@@ -76,7 +76,7 @@ export class User extends TypedEventEmitter<UserEvent, UserEventHandlerMap> {
* @prop {Object} events The events describing this user. * @prop {Object} events The events describing this user.
* @prop {MatrixEvent} events.presence The m.presence event for this user. * @prop {MatrixEvent} events.presence The m.presence event for this user.
*/ */
constructor(public readonly userId: string) { public constructor(public readonly userId: string) {
super(); super();
this.displayName = userId; this.displayName = userId;
this.rawDisplayName = userId; this.rawDisplayName = userId;

View File

@@ -126,7 +126,7 @@ export class PushProcessor {
* @constructor * @constructor
* @param {Object} client The Matrix client object to use * @param {Object} client The Matrix client object to use
*/ */
constructor(private readonly client: MatrixClient) {} public constructor(private readonly client: MatrixClient) {}
/** /**
* Convert a list of actions into a object with the actions as keys and their values * Convert a list of actions into a object with the actions as keys and their values

View File

@@ -48,7 +48,7 @@ type Callback = {
const callbackList: Callback[] = []; const callbackList: Callback[] = [];
// var debuglog = logger.log.bind(logger); // var debuglog = logger.log.bind(logger);
const debuglog = function(...params: any[]) {}; const debuglog = function(...params: any[]): void {};
/** /**
* reimplementation of window.setTimeout, which will call the callback if * reimplementation of window.setTimeout, which will call the callback if

View File

@@ -143,11 +143,11 @@ export class MSC3906Rendezvous {
return await this.channel.receive() as MSC3906RendezvousPayload; return await this.channel.receive() as MSC3906RendezvousPayload;
} }
private async send(payload: MSC3906RendezvousPayload) { private async send(payload: MSC3906RendezvousPayload): Promise<void> {
await this.channel.send(payload); await this.channel.send(payload);
} }
public async declineLoginOnExistingDevice() { public async declineLoginOnExistingDevice(): Promise<void> {
logger.info('User declined sign in'); logger.info('User declined sign in');
await this.send({ type: PayloadType.Finish, outcome: Outcome.Declined }); await this.send({ type: PayloadType.Finish, outcome: Outcome.Declined });
} }

View File

@@ -17,7 +17,7 @@ limitations under the License.
import { RendezvousFailureReason } from "."; import { RendezvousFailureReason } from ".";
export class RendezvousError extends Error { export class RendezvousError extends Error {
constructor(message: string, public readonly code: RendezvousFailureReason) { public constructor(message: string, public readonly code: RendezvousFailureReason) {
super(message); super(message);
} }
} }

View File

@@ -47,7 +47,7 @@ export class RoomHierarchy {
* @param {boolean} suggestedOnly whether to only return rooms with suggested=true. * @param {boolean} suggestedOnly whether to only return rooms with suggested=true.
* @constructor * @constructor
*/ */
constructor( public constructor(
public readonly root: Room, public readonly root: Room,
private readonly pageSize?: number, private readonly pageSize?: number,
private readonly maxDepth?: number, private readonly maxDepth?: number,

View File

@@ -97,7 +97,7 @@ export class MatrixScheduler<T = ISendEventResponse> {
* @see module:scheduler~queueAlgorithm * @see module:scheduler~queueAlgorithm
*/ */
// eslint-disable-next-line @typescript-eslint/naming-convention // eslint-disable-next-line @typescript-eslint/naming-convention
public static QUEUE_MESSAGES(event: MatrixEvent) { public static QUEUE_MESSAGES(event: MatrixEvent): "message" | null {
// enqueue messages or events that associate with another event (redactions and relations) // enqueue messages or events that associate with another event (redactions and relations)
if (event.getType() === EventType.RoomMessage || event.hasAssocation()) { if (event.getType() === EventType.RoomMessage || event.hasAssocation()) {
// put these events in the 'message' queue. // put these events in the 'message' queue.
@@ -116,7 +116,7 @@ export class MatrixScheduler<T = ISendEventResponse> {
private activeQueues: string[] = []; private activeQueues: string[] = [];
private procFn: ProcessFunction<T> | null = null; private procFn: ProcessFunction<T> | null = null;
constructor( public constructor(
public readonly retryAlgorithm = MatrixScheduler.RETRY_BACKOFF_RATELIMIT, public readonly retryAlgorithm = MatrixScheduler.RETRY_BACKOFF_RATELIMIT,
public readonly queueAlgorithm = MatrixScheduler.QUEUE_MESSAGES, public readonly queueAlgorithm = MatrixScheduler.QUEUE_MESSAGES,
) {} ) {}
@@ -283,7 +283,7 @@ export class MatrixScheduler<T = ISendEventResponse> {
} }
} }
function debuglog(...args: any[]) { function debuglog(...args: any[]): void {
if (DEBUG) { if (DEBUG) {
logger.log(...args); logger.log(...args);
} }

View File

@@ -45,7 +45,7 @@ import { RoomMemberEvent } from "./models/room-member";
const FAILED_SYNC_ERROR_THRESHOLD = 3; const FAILED_SYNC_ERROR_THRESHOLD = 3;
class ExtensionE2EE implements Extension { class ExtensionE2EE implements Extension {
constructor(private readonly crypto: Crypto) {} public constructor(private readonly crypto: Crypto) {}
public name(): string { public name(): string {
return "e2ee"; return "e2ee";
@@ -95,7 +95,7 @@ class ExtensionE2EE implements Extension {
class ExtensionToDevice implements Extension { class ExtensionToDevice implements Extension {
private nextBatch: string | null = null; private nextBatch: string | null = null;
constructor(private readonly client: MatrixClient) {} public constructor(private readonly client: MatrixClient) {}
public name(): string { public name(): string {
return "to_device"; return "to_device";
@@ -170,7 +170,7 @@ class ExtensionToDevice implements Extension {
} }
class ExtensionAccountData implements Extension { class ExtensionAccountData implements Extension {
constructor(private readonly client: MatrixClient) {} public constructor(private readonly client: MatrixClient) {}
public name(): string { public name(): string {
return "account_data"; return "account_data";
@@ -244,7 +244,7 @@ export class SlidingSyncSdk {
private failCount = 0; private failCount = 0;
private notifEvents: MatrixEvent[] = []; // accumulator of sync events in the current sync response private notifEvents: MatrixEvent[] = []; // accumulator of sync events in the current sync response
constructor( public constructor(
private readonly slidingSync: SlidingSync, private readonly slidingSync: SlidingSync,
private readonly client: MatrixClient, private readonly client: MatrixClient,
private readonly opts: Partial<IStoredClientOpts> = {}, private readonly opts: Partial<IStoredClientOpts> = {},
@@ -256,7 +256,7 @@ export class SlidingSyncSdk {
this.opts.experimentalThreadSupport = this.opts.experimentalThreadSupport === true; this.opts.experimentalThreadSupport = this.opts.experimentalThreadSupport === true;
if (!opts.canResetEntireTimeline) { if (!opts.canResetEntireTimeline) {
opts.canResetEntireTimeline = (_roomId: string) => { opts.canResetEntireTimeline = (_roomId: string): boolean => {
return false; return false;
}; };
} }
@@ -348,7 +348,7 @@ export class SlidingSyncSdk {
* Sync rooms the user has left. * Sync rooms the user has left.
* @return {Promise} Resolved when they've been added to the store. * @return {Promise} Resolved when they've been added to the store.
*/ */
public async syncLeftRooms() { public async syncLeftRooms(): Promise<Room[]> {
return []; // TODO return []; // TODO
} }
@@ -457,7 +457,7 @@ export class SlidingSyncSdk {
return false; return false;
} }
private async processRoomData(client: MatrixClient, room: Room, roomData: MSC3575RoomData) { private async processRoomData(client: MatrixClient, room: Room, roomData: MSC3575RoomData): Promise<void> {
roomData = ensureNameEvent(client, room.roomId, roomData); roomData = ensureNameEvent(client, room.roomId, roomData);
const stateEvents = mapEvents(this.client, room.roomId, roomData.required_state); const stateEvents = mapEvents(this.client, room.roomId, roomData.required_state);
// Prevent events from being decrypted ahead of time // Prevent events from being decrypted ahead of time
@@ -632,7 +632,7 @@ export class SlidingSyncSdk {
// we'll purge this once we've fully processed the sync response // we'll purge this once we've fully processed the sync response
this.addNotifications(timelineEvents); this.addNotifications(timelineEvents);
const processRoomEvent = async (e: MatrixEvent) => { const processRoomEvent = async (e: MatrixEvent): Promise<void> => {
client.emit(ClientEvent.Event, e); client.emit(ClientEvent.Event, e);
if (e.isState() && e.getType() == EventType.RoomEncryption && this.opts.crypto) { if (e.isState() && e.getType() == EventType.RoomEncryption && this.opts.crypto) {
await this.opts.crypto.onCryptoEvent(e); await this.opts.crypto.onCryptoEvent(e);
@@ -767,7 +767,7 @@ export class SlidingSyncSdk {
/** /**
* Main entry point. Blocks until stop() is called. * Main entry point. Blocks until stop() is called.
*/ */
public async sync() { public async sync(): Promise<void> {
logger.debug("Sliding sync init loop"); logger.debug("Sliding sync init loop");
// 1) We need to get push rules so we can check if events should bing as we get // 1) We need to get push rules so we can check if events should bing as we get

View File

@@ -169,7 +169,7 @@ class SlidingList {
* Construct a new sliding list. * Construct a new sliding list.
* @param {MSC3575List} list The range, sort and filter values to use for this list. * @param {MSC3575List} list The range, sort and filter values to use for this list.
*/ */
constructor(list: MSC3575List) { public constructor(list: MSC3575List) {
this.replaceList(list); this.replaceList(list);
} }
@@ -373,7 +373,7 @@ export class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, SlidingSync
* @param {MatrixClient} client The client to use for /sync calls. * @param {MatrixClient} client The client to use for /sync calls.
* @param {number} timeoutMS The number of milliseconds to wait for a response. * @param {number} timeoutMS The number of milliseconds to wait for a response.
*/ */
constructor( public constructor(
private readonly proxyBaseUrl: string, private readonly proxyBaseUrl: string,
lists: MSC3575List[], lists: MSC3575List[],
private roomSubscriptionInfo: MSC3575RoomSubscription, private roomSubscriptionInfo: MSC3575RoomSubscription,
@@ -391,7 +391,7 @@ export class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, SlidingSync
* useCustomSubscription. * useCustomSubscription.
* @param sub The subscription information. * @param sub The subscription information.
*/ */
public addCustomSubscription(name: string, sub: MSC3575RoomSubscription) { public addCustomSubscription(name: string, sub: MSC3575RoomSubscription): void {
this.customSubscriptions.set(name, sub); this.customSubscriptions.set(name, sub);
} }
@@ -402,7 +402,7 @@ export class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, SlidingSync
* @param name The name of the subscription. If this name is unknown, the default subscription * @param name The name of the subscription. If this name is unknown, the default subscription
* will be used. * will be used.
*/ */
public useCustomSubscription(roomId: string, name: string) { public useCustomSubscription(roomId: string, name: string): void {
this.roomIdToCustomSubscription.set(roomId, name); this.roomIdToCustomSubscription.set(roomId, name);
// unconfirm this subscription so a resend() will send it up afresh. // unconfirm this subscription so a resend() will send it up afresh.
this.confirmedRoomSubscriptions.delete(roomId); this.confirmedRoomSubscriptions.delete(roomId);
@@ -574,7 +574,7 @@ export class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, SlidingSync
this.emit(SlidingSyncEvent.Lifecycle, state, resp, err); this.emit(SlidingSyncEvent.Lifecycle, state, resp, err);
} }
private shiftRight(listIndex: number, hi: number, low: number) { private shiftRight(listIndex: number, hi: number, low: number): void {
// l h // l h
// 0,1,2,3,4 <- before // 0,1,2,3,4 <- before
// 0,1,2,2,3 <- after, hi is deleted and low is duplicated // 0,1,2,2,3 <- after, hi is deleted and low is duplicated
@@ -588,7 +588,7 @@ export class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, SlidingSync
} }
} }
private shiftLeft(listIndex: number, hi: number, low: number) { private shiftLeft(listIndex: number, hi: number, low: number): void {
// l h // l h
// 0,1,2,3,4 <- before // 0,1,2,3,4 <- before
// 0,1,3,4,4 <- after, low is deleted and hi is duplicated // 0,1,3,4,4 <- after, low is deleted and hi is duplicated
@@ -602,7 +602,7 @@ export class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, SlidingSync
} }
} }
private removeEntry(listIndex: number, index: number) { private removeEntry(listIndex: number, index: number): void {
// work out the max index // work out the max index
let max = -1; let max = -1;
for (const n in this.lists[listIndex].roomIndexToRoomId) { for (const n in this.lists[listIndex].roomIndexToRoomId) {
@@ -618,7 +618,7 @@ export class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, SlidingSync
delete this.lists[listIndex].roomIndexToRoomId[max]; delete this.lists[listIndex].roomIndexToRoomId[max];
} }
private addEntry(listIndex: number, index: number) { private addEntry(listIndex: number, index: number): void {
// work out the max index // work out the max index
let max = -1; let max = -1;
for (const n in this.lists[listIndex].roomIndexToRoomId) { for (const n in this.lists[listIndex].roomIndexToRoomId) {
@@ -747,7 +747,7 @@ export class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, SlidingSync
return d.promise; return d.promise;
} }
private resolveTransactionDefers(txnId?: string) { private resolveTransactionDefers(txnId?: string): void {
if (!txnId) { if (!txnId) {
return; return;
} }
@@ -811,7 +811,7 @@ export class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, SlidingSync
/** /**
* Start syncing with the server. Blocks until stopped. * Start syncing with the server. Blocks until stopped.
*/ */
public async start() { public async start(): Promise<void> {
this.abortController = new AbortController(); this.abortController = new AbortController();
let currentPos: string | undefined; let currentPos: string | undefined;

View File

@@ -25,7 +25,7 @@ import { IndexedToDeviceBatch, ToDeviceBatchWithTxnId } from "../models/ToDevice
type DbMigration = (db: IDBDatabase) => void; type DbMigration = (db: IDBDatabase) => void;
const DB_MIGRATIONS: DbMigration[] = [ const DB_MIGRATIONS: DbMigration[] = [
(db) => { (db): void => {
// Make user store, clobber based on user ID. (userId property of User objects) // Make user store, clobber based on user ID. (userId property of User objects)
db.createObjectStore("users", { keyPath: ["userId"] }); db.createObjectStore("users", { keyPath: ["userId"] });
@@ -36,15 +36,15 @@ const DB_MIGRATIONS: DbMigration[] = [
// Make /sync store (sync tokens, room data, etc), always clobber (const key). // Make /sync store (sync tokens, room data, etc), always clobber (const key).
db.createObjectStore("sync", { keyPath: ["clobber"] }); db.createObjectStore("sync", { keyPath: ["clobber"] });
}, },
(db) => { (db): void => {
const oobMembersStore = db.createObjectStore( const oobMembersStore = db.createObjectStore(
"oob_membership_events", { "oob_membership_events", {
keyPath: ["room_id", "state_key"], keyPath: ["room_id", "state_key"],
}); });
oobMembersStore.createIndex("room", "room_id"); oobMembersStore.createIndex("room", "room_id");
}, },
(db) => { db.createObjectStore("client_options", { keyPath: ["clobber"] }); }, (db): void => { db.createObjectStore("client_options", { keyPath: ["clobber"] }); },
(db) => { db.createObjectStore("to_device_queue", { autoIncrement: true }); }, (db): void => { db.createObjectStore("to_device_queue", { autoIncrement: true }); },
// Expand as needed. // Expand as needed.
]; ];
const VERSION = DB_MIGRATIONS.length; const VERSION = DB_MIGRATIONS.length;
@@ -67,11 +67,11 @@ function selectQuery<T>(
const query = store.openCursor(keyRange); const query = store.openCursor(keyRange);
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const results: T[] = []; const results: T[] = [];
query.onerror = () => { query.onerror = (): void => {
reject(new Error("Query failed: " + query.error)); reject(new Error("Query failed: " + query.error));
}; };
// collect results // collect results
query.onsuccess = () => { query.onsuccess = (): void => {
const cursor = query.result; const cursor = query.result;
if (!cursor) { if (!cursor) {
resolve(results); resolve(results);
@@ -85,10 +85,10 @@ function selectQuery<T>(
function txnAsPromise(txn: IDBTransaction): Promise<Event> { function txnAsPromise(txn: IDBTransaction): Promise<Event> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
txn.oncomplete = function(event) { txn.oncomplete = function(event): void {
resolve(event); resolve(event);
}; };
txn.onerror = function() { txn.onerror = function(): void {
reject(txn.error); reject(txn.error);
}; };
}); });
@@ -96,10 +96,10 @@ function txnAsPromise(txn: IDBTransaction): Promise<Event> {
function reqAsEventPromise(req: IDBRequest): Promise<Event> { function reqAsEventPromise(req: IDBRequest): Promise<Event> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
req.onsuccess = function(event) { req.onsuccess = function(event): void {
resolve(event); resolve(event);
}; };
req.onerror = function() { req.onerror = function(): void {
reject(req.error); reject(req.error);
}; };
}); });
@@ -107,8 +107,8 @@ function reqAsEventPromise(req: IDBRequest): Promise<Event> {
function reqAsPromise(req: IDBRequest): Promise<IDBRequest> { function reqAsPromise(req: IDBRequest): Promise<IDBRequest> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
req.onsuccess = () => resolve(req); req.onsuccess = (): void => resolve(req);
req.onerror = (err) => reject(err); req.onerror = (err): void => reject(err);
}); });
} }
@@ -141,7 +141,7 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend {
* @param {string=} dbName Optional database name. The same name must be used * @param {string=} dbName Optional database name. The same name must be used
* to open the same database. * to open the same database.
*/ */
constructor(private readonly indexedDB: IDBFactory, dbName = "default") { public constructor(private readonly indexedDB: IDBFactory, dbName = "default") {
this.dbName = "matrix-js-sdk:" + dbName; this.dbName = "matrix-js-sdk:" + dbName;
this.syncAccumulator = new SyncAccumulator(); this.syncAccumulator = new SyncAccumulator();
} }
@@ -161,7 +161,7 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend {
logger.log(`LocalIndexedDBStoreBackend.connect: connecting...`); logger.log(`LocalIndexedDBStoreBackend.connect: connecting...`);
const req = this.indexedDB.open(this.dbName, VERSION); const req = this.indexedDB.open(this.dbName, VERSION);
req.onupgradeneeded = (ev) => { req.onupgradeneeded = (ev): void => {
const db = req.result; const db = req.result;
const oldVersion = ev.oldVersion; const oldVersion = ev.oldVersion;
logger.log( logger.log(
@@ -176,22 +176,22 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend {
}); });
}; };
req.onblocked = () => { req.onblocked = (): void => {
logger.log(`can't yet open LocalIndexedDBStoreBackend because it is open elsewhere`); logger.log(`can't yet open LocalIndexedDBStoreBackend because it is open elsewhere`);
}; };
logger.log(`LocalIndexedDBStoreBackend.connect: awaiting connection...`); logger.log(`LocalIndexedDBStoreBackend.connect: awaiting connection...`);
return reqAsEventPromise(req).then(() => { return reqAsEventPromise(req).then(async () => {
logger.log(`LocalIndexedDBStoreBackend.connect: connected`); logger.log(`LocalIndexedDBStoreBackend.connect: connected`);
this.db = req.result; this.db = req.result;
// add a poorly-named listener for when deleteDatabase is called // add a poorly-named listener for when deleteDatabase is called
// so we can close our db connections. // so we can close our db connections.
this.db.onversionchange = () => { this.db.onversionchange = (): void => {
this.db?.close(); this.db?.close();
}; };
return this.init(); await this.init();
}); });
} }
@@ -204,7 +204,7 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend {
* Having connected, load initial data from the database and prepare for use * Having connected, load initial data from the database and prepare for use
* @return {Promise} Resolves on success * @return {Promise} Resolves on success
*/ */
private init() { private init(): Promise<unknown> {
return Promise.all([ return Promise.all([
this.loadAccountData(), this.loadAccountData(),
this.loadSyncData(), this.loadSyncData(),
@@ -243,7 +243,7 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend {
// were all known already // were all known already
let oobWritten = false; let oobWritten = false;
request.onsuccess = () => { request.onsuccess = (): void => {
const cursor = request.result; const cursor = request.result;
if (!cursor) { if (!cursor) {
// Unknown room // Unknown room
@@ -260,7 +260,7 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend {
} }
cursor.continue(); cursor.continue();
}; };
request.onerror = (err) => { request.onerror = (err): void => {
reject(err); reject(err);
}; };
}).then((events) => { }).then((events) => {
@@ -346,11 +346,11 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend {
logger.log(`Removing indexeddb instance: ${this.dbName}`); logger.log(`Removing indexeddb instance: ${this.dbName}`);
const req = this.indexedDB.deleteDatabase(this.dbName); const req = this.indexedDB.deleteDatabase(this.dbName);
req.onblocked = () => { req.onblocked = (): void => {
logger.log(`can't yet delete indexeddb ${this.dbName} because it is open elsewhere`); logger.log(`can't yet delete indexeddb ${this.dbName} because it is open elsewhere`);
}; };
req.onerror = () => { req.onerror = (): void => {
// in firefox, with indexedDB disabled, this fails with a // in firefox, with indexedDB disabled, this fails with a
// DOMError. We treat this as non-fatal, so that we can still // DOMError. We treat this as non-fatal, so that we can still
// use the app. // use the app.
@@ -358,7 +358,7 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend {
resolve(); resolve();
}; };
req.onsuccess = () => { req.onsuccess = (): void => {
logger.log(`Removed indexeddb instance: ${this.dbName}`); logger.log(`Removed indexeddb instance: ${this.dbName}`);
resolve(); resolve();
}; };

View File

@@ -42,7 +42,7 @@ export class RemoteIndexedDBStoreBackend implements IIndexedDBBackend {
* @param {string=} dbName Optional database name. The same name must be used * @param {string=} dbName Optional database name. The same name must be used
* to open the same database. * to open the same database.
*/ */
constructor( public constructor(
private readonly workerFactory: () => Worker, private readonly workerFactory: () => Worker,
private readonly dbName?: string, private readonly dbName?: string,
) {} ) {}

View File

@@ -45,7 +45,7 @@ export class IndexedDBStoreWorker {
* @param {function} postMessage The web worker postMessage function that * @param {function} postMessage The web worker postMessage function that
* should be used to communicate back to the main script. * should be used to communicate back to the main script.
*/ */
constructor(private readonly postMessage: InstanceType<typeof Worker>["postMessage"]) {} public constructor(private readonly postMessage: InstanceType<typeof Worker>["postMessage"]) {}
/** /**
* Passes a message event from the main script into the class. This method * Passes a message event from the main script into the class. This method

View File

@@ -53,7 +53,7 @@ type EventHandlerMap = {
}; };
export class IndexedDBStore extends MemoryStore { export class IndexedDBStore extends MemoryStore {
static exists(indexedDB: IDBFactory, dbName: string): Promise<boolean> { public static exists(indexedDB: IDBFactory, dbName: string): Promise<boolean> {
return LocalIndexedDBStoreBackend.exists(indexedDB, dbName); return LocalIndexedDBStoreBackend.exists(indexedDB, dbName);
} }
@@ -109,7 +109,7 @@ export class IndexedDBStore extends MemoryStore {
* this API if you need to perform specific indexeddb actions like deleting the * this API if you need to perform specific indexeddb actions like deleting the
* database. * database.
*/ */
constructor(opts: IOpts) { public constructor(opts: IOpts) {
super(opts); super(opts);
if (!opts.indexedDB) { if (!opts.indexedDB) {

View File

@@ -69,7 +69,7 @@ export class MemoryStore implements IStore {
private pendingToDeviceBatches: IndexedToDeviceBatch[] = []; private pendingToDeviceBatches: IndexedToDeviceBatch[] = [];
private nextToDeviceBatchId = 0; private nextToDeviceBatchId = 0;
constructor(opts: IOpts = {}) { public constructor(opts: IOpts = {}) {
this.localStorage = opts.localStorage; this.localStorage = opts.localStorage;
} }
@@ -90,7 +90,7 @@ export class MemoryStore implements IStore {
* Set the token to stream from. * Set the token to stream from.
* @param {string} token The token to stream from. * @param {string} token The token to stream from.
*/ */
public setSyncToken(token: string) { public setSyncToken(token: string): void {
this.syncToken = token; this.syncToken = token;
} }
@@ -98,7 +98,7 @@ export class MemoryStore implements IStore {
* Store the given room. * Store the given room.
* @param {Room} room The room to be stored. All properties must be stored. * @param {Room} room The room to be stored. All properties must be stored.
*/ */
public storeRoom(room: Room) { public storeRoom(room: Room): void {
this.rooms[room.roomId] = room; this.rooms[room.roomId] = room;
// add listeners for room member changes so we can keep the room member // add listeners for room member changes so we can keep the room member
// map up-to-date. // map up-to-date.
@@ -116,7 +116,7 @@ export class MemoryStore implements IStore {
* @param {RoomState} state * @param {RoomState} state
* @param {RoomMember} member * @param {RoomMember} member
*/ */
private onRoomMember = (event: MatrixEvent | null, state: RoomState, member: RoomMember) => { private onRoomMember = (event: MatrixEvent | null, state: RoomState, member: RoomMember): void => {
if (member.membership === "invite") { if (member.membership === "invite") {
// We do NOT add invited members because people love to typo user IDs // We do NOT add invited members because people love to typo user IDs
// which would then show up in these lists (!) // which would then show up in these lists (!)
@@ -217,7 +217,7 @@ export class MemoryStore implements IStore {
* @param {string} token The token associated with these events. * @param {string} token The token associated with these events.
* @param {boolean} toStart True if these are paginated results. * @param {boolean} toStart True if these are paginated results.
*/ */
public storeEvents(room: Room, events: MatrixEvent[], token: string, toStart: boolean) { public storeEvents(room: Room, events: MatrixEvent[], token: string, toStart: boolean): void {
// no-op because they've already been added to the room instance. // no-op because they've already been added to the room instance.
} }
@@ -275,7 +275,7 @@ export class MemoryStore implements IStore {
* @param {string} filterName * @param {string} filterName
* @param {string} filterId * @param {string} filterId
*/ */
public setFilterIdByName(filterName: string, filterId?: string) { public setFilterIdByName(filterName: string, filterId?: string): void {
if (!this.localStorage) { if (!this.localStorage) {
return; return;
} }

View File

@@ -56,7 +56,7 @@ export class StubStore implements IStore {
* Set the sync token. * Set the sync token.
* @param {string} token * @param {string} token
*/ */
public setSyncToken(token: string) { public setSyncToken(token: string): void {
this.fromToken = token; this.fromToken = token;
} }
@@ -64,7 +64,7 @@ export class StubStore implements IStore {
* No-op. * No-op.
* @param {Room} room * @param {Room} room
*/ */
public storeRoom(room: Room) {} public storeRoom(room: Room): void {}
/** /**
* No-op. * No-op.
@@ -87,7 +87,7 @@ export class StubStore implements IStore {
* Permanently delete a room. * Permanently delete a room.
* @param {string} roomId * @param {string} roomId
*/ */
public removeRoom(roomId: string) { public removeRoom(roomId: string): void {
return; return;
} }
@@ -103,7 +103,7 @@ export class StubStore implements IStore {
* No-op. * No-op.
* @param {User} user * @param {User} user
*/ */
public storeUser(user: User) {} public storeUser(user: User): void {}
/** /**
* No-op. * No-op.
@@ -139,13 +139,13 @@ export class StubStore implements IStore {
* @param {string} token The token associated with these events. * @param {string} token The token associated with these events.
* @param {boolean} toStart True if these are paginated results. * @param {boolean} toStart True if these are paginated results.
*/ */
public storeEvents(room: Room, events: MatrixEvent[], token: string, toStart: boolean) {} public storeEvents(room: Room, events: MatrixEvent[], token: string, toStart: boolean): void {}
/** /**
* Store a filter. * Store a filter.
* @param {Filter} filter * @param {Filter} filter
*/ */
public storeFilter(filter: Filter) {} public storeFilter(filter: Filter): void {}
/** /**
* Retrieve a filter. * Retrieve a filter.
@@ -171,13 +171,13 @@ export class StubStore implements IStore {
* @param {string} filterName * @param {string} filterName
* @param {string} filterId * @param {string} filterId
*/ */
public setFilterIdByName(filterName: string, filterId?: string) {} public setFilterIdByName(filterName: string, filterId?: string): void {}
/** /**
* Store user-scoped account data events * Store user-scoped account data events
* @param {Array<MatrixEvent>} events The events to store. * @param {Array<MatrixEvent>} events The events to store.
*/ */
public storeAccountDataEvents(events: MatrixEvent[]) {} public storeAccountDataEvents(events: MatrixEvent[]): void {}
/** /**
* Get account data event by event type * Get account data event by event type
@@ -209,7 +209,7 @@ export class StubStore implements IStore {
/** /**
* Save does nothing as there is no backing data store. * Save does nothing as there is no backing data store.
*/ */
public save() {} public save(): void {}
/** /**
* Startup does nothing. * Startup does nothing.

View File

@@ -211,7 +211,7 @@ export class SyncAccumulator {
* never be more. This cannot be 0 or else it makes it impossible to scroll * never be more. This cannot be 0 or else it makes it impossible to scroll
* back in a room. Default: 50. * back in a room. Default: 50.
*/ */
constructor(private readonly opts: IOpts = {}) { public constructor(private readonly opts: IOpts = {}) {
this.opts.maxTimelineEntries = this.opts.maxTimelineEntries || 50; this.opts.maxTimelineEntries = this.opts.maxTimelineEntries || 50;
} }

View File

@@ -106,7 +106,7 @@ function getFilterName(userId: string, suffix?: string): string {
return `FILTER_SYNC_${userId}` + (suffix ? "_" + suffix : ""); return `FILTER_SYNC_${userId}` + (suffix ? "_" + suffix : "");
} }
function debuglog(...params) { function debuglog(...params): void {
if (!DEBUG) return; if (!DEBUG) return;
logger.log(...params); logger.log(...params);
} }
@@ -175,7 +175,7 @@ export class SyncApi {
private failedSyncCount = 0; // Number of consecutive failed /sync requests private failedSyncCount = 0; // Number of consecutive failed /sync requests
private storeIsInvalid = false; // flag set if the store needs to be cleared before we can start private storeIsInvalid = false; // flag set if the store needs to be cleared before we can start
constructor(private readonly client: MatrixClient, private readonly opts: Partial<IStoredClientOpts> = {}) { public constructor(private readonly client: MatrixClient, private readonly opts: Partial<IStoredClientOpts> = {}) {
this.opts.initialSyncLimit = this.opts.initialSyncLimit ?? 8; this.opts.initialSyncLimit = this.opts.initialSyncLimit ?? 8;
this.opts.resolveInvitesToProfiles = this.opts.resolveInvitesToProfiles || false; this.opts.resolveInvitesToProfiles = this.opts.resolveInvitesToProfiles || false;
this.opts.pollTimeout = this.opts.pollTimeout || (30 * 1000); this.opts.pollTimeout = this.opts.pollTimeout || (30 * 1000);
@@ -183,7 +183,7 @@ export class SyncApi {
this.opts.experimentalThreadSupport = this.opts.experimentalThreadSupport === true; this.opts.experimentalThreadSupport = this.opts.experimentalThreadSupport === true;
if (!opts.canResetEntireTimeline) { if (!opts.canResetEntireTimeline) {
opts.canResetEntireTimeline = (roomId: string) => { opts.canResetEntireTimeline = (roomId: string): boolean => {
return false; return false;
}; };
} }
@@ -554,7 +554,7 @@ export class SyncApi {
return false; return false;
} }
private getPushRules = async () => { private getPushRules = async (): Promise<void> => {
try { try {
debuglog("Getting push rules..."); debuglog("Getting push rules...");
const result = await this.client.getPushRules(); const result = await this.client.getPushRules();
@@ -572,7 +572,7 @@ export class SyncApi {
} }
}; };
private buildDefaultFilter = () => { private buildDefaultFilter = (): Filter => {
const filter = new Filter(this.client.credentials.userId); const filter = new Filter(this.client.credentials.userId);
if (this.client.canSupport.get(Feature.ThreadUnreadNotifications) !== ServerSupport.Unsupported) { if (this.client.canSupport.get(Feature.ThreadUnreadNotifications) !== ServerSupport.Unsupported) {
filter.setUnreadThreadNotifications(true); filter.setUnreadThreadNotifications(true);
@@ -580,7 +580,7 @@ export class SyncApi {
return filter; return filter;
}; };
private checkLazyLoadStatus = async () => { private checkLazyLoadStatus = async (): Promise<void> => {
debuglog("Checking lazy load status..."); debuglog("Checking lazy load status...");
if (this.opts.lazyLoadMembers && this.client.isGuest()) { if (this.opts.lazyLoadMembers && this.client.isGuest()) {
this.opts.lazyLoadMembers = false; this.opts.lazyLoadMembers = false;
@@ -1389,7 +1389,7 @@ export class SyncApi {
this.processEventsForNotifs(room, events); this.processEventsForNotifs(room, events);
const processRoomEvent = async (e) => { const processRoomEvent = async (e): Promise<void> => {
client.emit(ClientEvent.Event, e); client.emit(ClientEvent.Event, e);
if (e.isState() && e.getType() == "m.room.encryption" && this.opts.crypto) { if (e.isState() && e.getType() == "m.room.encryption" && this.opts.crypto) {
await this.opts.crypto.onCryptoEvent(e); await this.opts.crypto.onCryptoEvent(e);
@@ -1521,7 +1521,7 @@ export class SyncApi {
* @param {boolean} connDidFail True if a connectivity failure has been detected. Optional. * @param {boolean} connDidFail True if a connectivity failure has been detected. Optional.
*/ */
private pokeKeepAlive(connDidFail = false): void { private pokeKeepAlive(connDidFail = false): void {
const success = () => { const success = (): void => {
clearTimeout(this.keepAliveTimer); clearTimeout(this.keepAliveTimer);
if (this.connectionReturnedDefer) { if (this.connectionReturnedDefer) {
this.connectionReturnedDefer.resolve(connDidFail); this.connectionReturnedDefer.resolve(connDidFail);

View File

@@ -32,7 +32,7 @@ const DEBUG = false;
/** /**
* @private * @private
*/ */
const debuglog = DEBUG ? logger.log.bind(logger) : function() {}; const debuglog = DEBUG ? logger.log.bind(logger) : function(): void {};
/** /**
* the number of times we ask the server for more events before giving up * the number of times we ask the server for more events before giving up
@@ -84,7 +84,7 @@ export class TimelineWindow {
* *
* @constructor * @constructor
*/ */
constructor( public constructor(
private readonly client: MatrixClient, private readonly client: MatrixClient,
private readonly timelineSet: EventTimelineSet, private readonly timelineSet: EventTimelineSet,
opts: IOpts = {}, opts: IOpts = {},
@@ -104,7 +104,7 @@ export class TimelineWindow {
public load(initialEventId?: string, initialWindowSize = 20): Promise<void> { public load(initialEventId?: string, initialWindowSize = 20): Promise<void> {
// given an EventTimeline, find the event we were looking for, and initialise our // given an EventTimeline, find the event we were looking for, and initialise our
// fields so that the event in question is in the middle of the window. // fields so that the event in question is in the middle of the window.
const initFields = (timeline: Optional<EventTimeline>) => { const initFields = (timeline: Optional<EventTimeline>): void => {
if (!timeline) { if (!timeline) {
throw new Error("No timeline given to initFields"); throw new Error("No timeline given to initFields");
} }
@@ -430,7 +430,7 @@ export class TimelineIndex {
public pendingPaginate?: Promise<boolean>; public pendingPaginate?: Promise<boolean>;
// index: the indexes are relative to BaseIndex, so could well be negative. // index: the indexes are relative to BaseIndex, so could well be negative.
constructor(public timeline: EventTimeline, public index: number) {} public constructor(public timeline: EventTimeline, public index: number) {}
/** /**
* @return {number} the minimum possible value for the index in the current * @return {number} the minimum possible value for the index in the current

View File

@@ -178,7 +178,7 @@ export function removeElement<T>(
* @param {*} value The thing to check. * @param {*} value The thing to check.
* @return {boolean} True if it is a function. * @return {boolean} True if it is a function.
*/ */
export function isFunction(value: any) { export function isFunction(value: any): boolean {
return Object.prototype.toString.call(value) === "[object Function]"; return Object.prototype.toString.call(value) === "[object Function]";
} }
@@ -189,7 +189,7 @@ export function isFunction(value: any) {
* @throws If the object is missing keys. * @throws If the object is missing keys.
*/ */
// note using 'keys' here would shadow the 'keys' function defined above // note using 'keys' here would shadow the 'keys' function defined above
export function checkObjectHasKeys(obj: object, keys: string[]) { export function checkObjectHasKeys(obj: object, keys: string[]): void {
for (const key of keys) { for (const key of keys) {
if (!obj.hasOwnProperty(key)) { if (!obj.hasOwnProperty(key)) {
throw new Error("Missing required key: " + key); throw new Error("Missing required key: " + key);
@@ -383,7 +383,7 @@ export function globToRegexp(glob: string, extended = false): string {
if (!extended) { if (!extended) {
replacements.push([ replacements.push([
/\\\[(!|)(.*)\\]/g, /\\\[(!|)(.*)\\]/g,
(_match: string, neg: string, pat: string) => [ (_match: string, neg: string, pat: string): string => [
'[', '[',
neg ? '^' : '', neg ? '^' : '',
pat.replace(/\\-/, '-'), pat.replace(/\\-/, '-'),
@@ -490,7 +490,7 @@ export function simpleRetryOperation<T>(promiseFn: (attempt: number) => Promise<
* The default alphabet used by string averaging in this SDK. This matches * The default alphabet used by string averaging in this SDK. This matches
* all usefully printable ASCII characters (0x20-0x7E, inclusive). * all usefully printable ASCII characters (0x20-0x7E, inclusive).
*/ */
export const DEFAULT_ALPHABET = (() => { export const DEFAULT_ALPHABET = ((): string => {
let str = ""; let str = "";
for (let c = 0x20; c <= 0x7E; c++) { for (let c = 0x20; c <= 0x7E; c++) {
str += String.fromCharCode(c); str += String.fromCharCode(c);

View File

@@ -35,7 +35,7 @@ export const acquireContext = (): AudioContext => {
* released, allowing the context and associated hardware resources to be * released, allowing the context and associated hardware resources to be
* cleaned up if nothing else is using it. * cleaned up if nothing else is using it.
*/ */
export const releaseContext = () => { export const releaseContext = (): void => {
refCount--; refCount--;
if (refCount === 0) { if (refCount === 0) {
audioContext?.close(); audioContext?.close();

View File

@@ -268,7 +268,7 @@ const CALL_TIMEOUT_MS = 60000;
export class CallError extends Error { export class CallError extends Error {
public readonly code: string; public readonly code: string;
constructor(code: CallErrorCode, msg: string, err: Error) { public constructor(code: CallErrorCode, msg: string, err: Error) {
// Still don't think there's any way to have proper nested errors // Still don't think there's any way to have proper nested errors
super(msg + ": " + err); super(msg + ": " + err);
@@ -404,7 +404,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
private opponentSessionId?: string; private opponentSessionId?: string;
public groupCallId?: string; public groupCallId?: string;
constructor(opts: CallOpts) { public constructor(opts: CallOpts) {
super(); super();
this.roomId = opts.roomId; this.roomId = opts.roomId;
@@ -452,7 +452,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
* @param label A human readable label for this datachannel * @param label A human readable label for this datachannel
* @param options An object providing configuration options for the data channel. * @param options An object providing configuration options for the data channel.
*/ */
public createDataChannel(label: string, options: RTCDataChannelInit | undefined) { public createDataChannel(label: string, options: RTCDataChannelInit | undefined): RTCDataChannel {
const dataChannel = this.peerConn!.createDataChannel(label, options); const dataChannel = this.peerConn!.createDataChannel(label, options);
this.emit(CallEvent.DataChannel, dataChannel); this.emit(CallEvent.DataChannel, dataChannel);
return dataChannel; return dataChannel;
@@ -564,7 +564,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
return this.feeds.filter((feed) => !feed.isLocal()); return this.feeds.filter((feed) => !feed.isLocal());
} }
private async initOpponentCrypto() { private async initOpponentCrypto(): Promise<void> {
if (!this.opponentDeviceId) return; if (!this.opponentDeviceId) return;
if (!this.client.getUseE2eForGroupCall()) return; if (!this.client.getUseE2eForGroupCall()) return;
// It's possible to want E2EE and yet not have the means to manage E2EE // It's possible to want E2EE and yet not have the means to manage E2EE
@@ -938,7 +938,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
} }
}, invite.lifetime - event.getLocalAge()); }, invite.lifetime - event.getLocalAge());
const onState = (state: CallState) => { const onState = (state: CallState): void => {
if (state !== CallState.Ringing) { if (state !== CallState.Ringing) {
clearTimeout(ringingTimer); clearTimeout(ringingTimer);
this.off(CallEvent.State, onState); this.off(CallEvent.State, onState);
@@ -2132,7 +2132,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
this.pushRemoteFeed(stream); this.pushRemoteFeed(stream);
if (!this.removeTrackListeners.has(stream)) { if (!this.removeTrackListeners.has(stream)) {
const onRemoveTrack = () => { const onRemoveTrack = (): void => {
if (stream.getTracks().length === 0) { if (stream.getTracks().length === 0) {
logger.info(`Call ${this.callId} removing track streamId: ${stream.id}`); logger.info(`Call ${this.callId} removing track streamId: ${stream.id}`);
this.deleteFeedByStream(stream); this.deleteFeedByStream(stream);

View File

@@ -46,7 +46,7 @@ export class CallEventHandler {
private candidateEventsByCall: Map<string, Array<MatrixEvent>>; private candidateEventsByCall: Map<string, Array<MatrixEvent>>;
private eventBufferPromiseChain?: Promise<void>; private eventBufferPromiseChain?: Promise<void>;
constructor(client: MatrixClient) { public constructor(client: MatrixClient) {
this.client = client; this.client = client;
this.calls = new Map<string, MatrixCall>(); this.calls = new Map<string, MatrixCall>();
// The sync code always emits one event at a time, so it will patiently // The sync code always emits one event at a time, so it will patiently
@@ -61,13 +61,13 @@ export class CallEventHandler {
this.candidateEventsByCall = new Map<string, Array<MatrixEvent>>(); this.candidateEventsByCall = new Map<string, Array<MatrixEvent>>();
} }
public start() { public start(): void {
this.client.on(ClientEvent.Sync, this.onSync); this.client.on(ClientEvent.Sync, this.onSync);
this.client.on(RoomEvent.Timeline, this.onRoomTimeline); this.client.on(RoomEvent.Timeline, this.onRoomTimeline);
this.client.on(ClientEvent.ToDeviceEvent, this.onToDeviceEvent); this.client.on(ClientEvent.ToDeviceEvent, this.onToDeviceEvent);
} }
public stop() { public stop(): void {
this.client.removeListener(ClientEvent.Sync, this.onSync); this.client.removeListener(ClientEvent.Sync, this.onSync);
this.client.removeListener(RoomEvent.Timeline, this.onRoomTimeline); this.client.removeListener(RoomEvent.Timeline, this.onRoomTimeline);
this.client.removeListener(ClientEvent.ToDeviceEvent, this.onToDeviceEvent); this.client.removeListener(ClientEvent.ToDeviceEvent, this.onToDeviceEvent);
@@ -87,7 +87,7 @@ export class CallEventHandler {
} }
}; };
private async evaluateEventBuffer(eventBuffer: MatrixEvent[]) { private async evaluateEventBuffer(eventBuffer: MatrixEvent[]): Promise<void> {
await Promise.all(eventBuffer.map((event) => this.client.decryptEventIfNeeded(event))); await Promise.all(eventBuffer.map((event) => this.client.decryptEventIfNeeded(event)));
const callEvents = eventBuffer.filter((event) => { const callEvents = eventBuffer.filter((event) => {
@@ -125,7 +125,7 @@ export class CallEventHandler {
} }
} }
private onRoomTimeline = (event: MatrixEvent) => { private onRoomTimeline = (event: MatrixEvent): void => {
this.callEventBuffer.push(event); this.callEventBuffer.push(event);
}; };
@@ -178,7 +178,7 @@ export class CallEventHandler {
} }
}; };
private async handleCallEvent(event: MatrixEvent) { private async handleCallEvent(event: MatrixEvent): Promise<void> {
this.client.emit(ClientEvent.ReceivedVoipEvent, event); this.client.emit(ClientEvent.ReceivedVoipEvent, event);
const content = event.getContent(); const content = event.getContent();

View File

@@ -80,7 +80,7 @@ export class CallFeed extends TypedEventEmitter<CallFeedEvent, EventHandlerMap>
private volumeLooperTimeout?: ReturnType<typeof setTimeout>; private volumeLooperTimeout?: ReturnType<typeof setTimeout>;
private _disposed = false; private _disposed = false;
constructor(opts: ICallFeedOpts) { public constructor(opts: ICallFeedOpts) {
super(); super();
this.client = opts.client; this.client = opts.client;
@@ -227,11 +227,11 @@ export class CallFeed extends TypedEventEmitter<CallFeedEvent, EventHandlerMap>
} }
} }
public setSpeakingThreshold(threshold: number) { public setSpeakingThreshold(threshold: number): void {
this.speakingThreshold = threshold; this.speakingThreshold = threshold;
} }
private volumeLooper = () => { private volumeLooper = (): void => {
if (!this.analyser) return; if (!this.analyser) return;
if (!this.measuringVolumeActivity) return; if (!this.measuringVolumeActivity) return;

View File

@@ -73,7 +73,7 @@ export enum GroupCallErrorCode {
export class GroupCallError extends Error { export class GroupCallError extends Error {
public code: string; public code: string;
constructor(code: GroupCallErrorCode, msg: string, err?: Error) { public constructor(code: GroupCallErrorCode, msg: string, err?: Error) {
// Still don't think there's any way to have proper nested errors // Still don't think there's any way to have proper nested errors
if (err) { if (err) {
super(msg + ": " + err); super(msg + ": " + err);
@@ -86,13 +86,13 @@ export class GroupCallError extends Error {
} }
export class GroupCallUnknownDeviceError extends GroupCallError { export class GroupCallUnknownDeviceError extends GroupCallError {
constructor(public userId: string) { public constructor(public userId: string) {
super(GroupCallErrorCode.UnknownDevice, "No device found for " + userId); super(GroupCallErrorCode.UnknownDevice, "No device found for " + userId);
} }
} }
export class OtherUserSpeakingError extends Error { export class OtherUserSpeakingError extends Error {
constructor() { public constructor() {
super("Cannot unmute: another user is speaking"); super("Cannot unmute: another user is speaking");
} }
} }
@@ -187,7 +187,7 @@ export class GroupCall extends TypedEventEmitter<
private initWithAudioMuted = false; private initWithAudioMuted = false;
private initWithVideoMuted = false; private initWithVideoMuted = false;
constructor( public constructor(
private client: MatrixClient, private client: MatrixClient,
public room: Room, public room: Room,
public type: GroupCallType, public type: GroupCallType,
@@ -206,7 +206,7 @@ export class GroupCall extends TypedEventEmitter<
} }
} }
public async create() { public async create(): Promise<GroupCall> {
this.client.groupCallEventHandler!.groupCalls.set(this.room.roomId, this); this.client.groupCallEventHandler!.groupCalls.set(this.room.roomId, this);
await this.client.sendStateEvent( await this.client.sendStateEvent(
@@ -258,7 +258,7 @@ export class GroupCall extends TypedEventEmitter<
let stream: MediaStream; let stream: MediaStream;
let disposed = false; let disposed = false;
const onState = (state: GroupCallState) => { const onState = (state: GroupCallState): void => {
if (state === GroupCallState.LocalCallFeedUninitialized) { if (state === GroupCallState.LocalCallFeedUninitialized) {
disposed = true; disposed = true;
} }
@@ -300,7 +300,7 @@ export class GroupCall extends TypedEventEmitter<
return callFeed; return callFeed;
} }
public async updateLocalUsermediaStream(stream: MediaStream) { public async updateLocalUsermediaStream(stream: MediaStream): Promise<void> {
if (this.localCallFeed) { if (this.localCallFeed) {
const oldStream = this.localCallFeed.stream; const oldStream = this.localCallFeed.stream;
this.localCallFeed.setNewStream(stream); this.localCallFeed.setNewStream(stream);
@@ -315,7 +315,7 @@ export class GroupCall extends TypedEventEmitter<
} }
} }
public async enter() { public async enter(): Promise<void> {
if (!(this.state === GroupCallState.LocalCallFeedUninitialized || if (!(this.state === GroupCallState.LocalCallFeedUninitialized ||
this.state === GroupCallState.LocalCallFeedInitialized)) { this.state === GroupCallState.LocalCallFeedInitialized)) {
throw new Error(`Cannot enter call in the "${this.state}" state`); throw new Error(`Cannot enter call in the "${this.state}" state`);
@@ -354,7 +354,7 @@ export class GroupCall extends TypedEventEmitter<
this.onActiveSpeakerLoop(); this.onActiveSpeakerLoop();
} }
private dispose() { private dispose(): void {
if (this.localCallFeed) { if (this.localCallFeed) {
this.removeUserMediaFeed(this.localCallFeed); this.removeUserMediaFeed(this.localCallFeed);
this.localCallFeed = undefined; this.localCallFeed = undefined;
@@ -400,7 +400,7 @@ export class GroupCall extends TypedEventEmitter<
this.client.removeListener(CallEventHandlerEvent.Incoming, this.onIncomingCall); this.client.removeListener(CallEventHandlerEvent.Incoming, this.onIncomingCall);
} }
public leave() { public leave(): void {
if (this.transmitTimer !== null) { if (this.transmitTimer !== null) {
clearTimeout(this.transmitTimer); clearTimeout(this.transmitTimer);
this.transmitTimer = null; this.transmitTimer = null;
@@ -410,7 +410,7 @@ export class GroupCall extends TypedEventEmitter<
this.setState(GroupCallState.LocalCallFeedUninitialized); this.setState(GroupCallState.LocalCallFeedUninitialized);
} }
public async terminate(emitStateEvent = true) { public async terminate(emitStateEvent = true): Promise<void> {
this.dispose(); this.dispose();
if (this.transmitTimer !== null) { if (this.transmitTimer !== null) {
@@ -430,7 +430,7 @@ export class GroupCall extends TypedEventEmitter<
this.room.roomId, this.room.roomId,
EventType.GroupCallPrefix, EventType.GroupCallPrefix,
{ {
...existingStateEvent.getContent(), ...existingStateEvent!.getContent(),
["m.terminated"]: GroupCallTerminationReason.CallEnded, ["m.terminated"]: GroupCallTerminationReason.CallEnded,
}, },
this.groupCallId, this.groupCallId,
@@ -445,7 +445,7 @@ export class GroupCall extends TypedEventEmitter<
* Local Usermedia * Local Usermedia
*/ */
public isLocalVideoMuted() { public isLocalVideoMuted(): boolean {
if (this.localCallFeed) { if (this.localCallFeed) {
return this.localCallFeed.isVideoMuted(); return this.localCallFeed.isVideoMuted();
} }
@@ -453,7 +453,7 @@ export class GroupCall extends TypedEventEmitter<
return true; return true;
} }
public isMicrophoneMuted() { public isMicrophoneMuted(): boolean {
if (this.localCallFeed) { if (this.localCallFeed) {
return this.localCallFeed.isAudioMuted(); return this.localCallFeed.isAudioMuted();
} }
@@ -576,7 +576,7 @@ export class GroupCall extends TypedEventEmitter<
const stream = await this.client.getMediaHandler().getScreensharingStream(opts); const stream = await this.client.getMediaHandler().getScreensharingStream(opts);
for (const track of stream.getTracks()) { for (const track of stream.getTracks()) {
const onTrackEnded = () => { const onTrackEnded = (): void => {
this.setScreensharingEnabled(false); this.setScreensharingEnabled(false);
track.removeEventListener("ended", onTrackEnded); track.removeEventListener("ended", onTrackEnded);
}; };
@@ -651,7 +651,7 @@ export class GroupCall extends TypedEventEmitter<
* as they are observed by the RoomState.members event. * as they are observed by the RoomState.members event.
*/ */
private onIncomingCall = (newCall: MatrixCall) => { private onIncomingCall = (newCall: MatrixCall): void => {
// The incoming calls may be for another room, which we will ignore. // The incoming calls may be for another room, which we will ignore.
if (newCall.roomId !== this.room.roomId) { if (newCall.roomId !== this.room.roomId) {
return; return;
@@ -700,7 +700,7 @@ export class GroupCall extends TypedEventEmitter<
private getMemberStateEvents(userId?: string): MatrixEvent[] | MatrixEvent | null { private getMemberStateEvents(userId?: string): MatrixEvent[] | MatrixEvent | null {
if (userId != null) { if (userId != null) {
const event = this.room.currentState.getStateEvents(EventType.GroupCallMemberPrefix, userId); const event = this.room.currentState.getStateEvents(EventType.GroupCallMemberPrefix, userId);
return callMemberStateIsExpired(event) ? null : event; return callMemberStateIsExpired(event!) ? null : event;
} else { } else {
return this.room.currentState.getStateEvents(EventType.GroupCallMemberPrefix) return this.room.currentState.getStateEvents(EventType.GroupCallMemberPrefix)
.filter(event => !callMemberStateIsExpired(event)); .filter(event => !callMemberStateIsExpired(event));
@@ -708,7 +708,7 @@ export class GroupCall extends TypedEventEmitter<
} }
private async sendMemberStateEvent(): Promise<ISendEventResponse> { private async sendMemberStateEvent(): Promise<ISendEventResponse> {
const send = () => this.updateMemberCallState({ const send = (): Promise<ISendEventResponse> => this.updateMemberCallState({
"m.call_id": this.groupCallId, "m.call_id": this.groupCallId,
"m.devices": [ "m.devices": [
{ {
@@ -779,7 +779,7 @@ export class GroupCall extends TypedEventEmitter<
); );
} }
public onMemberStateChanged = async (event: MatrixEvent) => { public onMemberStateChanged = async (event: MatrixEvent): Promise<void> => {
// If we haven't entered the call yet, we don't care // If we haven't entered the call yet, we don't care
if (this.state !== GroupCallState.Entered) { if (this.state !== GroupCallState.Entered) {
return; return;
@@ -800,7 +800,7 @@ export class GroupCall extends TypedEventEmitter<
logger.debug(`Processing member state event for ${member.userId}`); logger.debug(`Processing member state event for ${member.userId}`);
const ignore = () => { const ignore = (): void => {
this.removeParticipant(member); this.removeParticipant(member);
clearTimeout(this.memberStateExpirationTimers.get(member.userId)); clearTimeout(this.memberStateExpirationTimers.get(member.userId));
this.memberStateExpirationTimers.delete(member.userId); this.memberStateExpirationTimers.delete(member.userId);
@@ -953,7 +953,7 @@ export class GroupCall extends TypedEventEmitter<
return memberDevices[0]; return memberDevices[0];
} }
private onRetryCallLoop = () => { private onRetryCallLoop = (): void => {
for (const event of this.getMemberStateEvents()) { for (const event of this.getMemberStateEvents()) {
const memberId = event.getStateKey()!; const memberId = event.getStateKey()!;
const existingCall = this.calls.find((call) => getCallUserId(call) === memberId); const existingCall = this.calls.find((call) => getCallUserId(call) === memberId);
@@ -976,13 +976,17 @@ export class GroupCall extends TypedEventEmitter<
return this.calls.find((call) => getCallUserId(call) === userId); return this.calls.find((call) => getCallUserId(call) === userId);
} }
private addCall(call: MatrixCall) { private addCall(call: MatrixCall): void {
this.calls.push(call); this.calls.push(call);
this.initCall(call); this.initCall(call);
this.emit(GroupCallEvent.CallsChanged, this.calls); this.emit(GroupCallEvent.CallsChanged, this.calls);
} }
private replaceCall(existingCall: MatrixCall, replacementCall: MatrixCall, hangupReason = CallErrorCode.Replaced) { private replaceCall(
existingCall: MatrixCall,
replacementCall: MatrixCall,
hangupReason = CallErrorCode.Replaced,
): void {
const existingCallIndex = this.calls.indexOf(existingCall); const existingCallIndex = this.calls.indexOf(existingCall);
if (existingCallIndex === -1) { if (existingCallIndex === -1) {
@@ -997,7 +1001,7 @@ export class GroupCall extends TypedEventEmitter<
this.emit(GroupCallEvent.CallsChanged, this.calls); this.emit(GroupCallEvent.CallsChanged, this.calls);
} }
private removeCall(call: MatrixCall, hangupReason: CallErrorCode) { private removeCall(call: MatrixCall, hangupReason: CallErrorCode): void {
this.disposeCall(call, hangupReason); this.disposeCall(call, hangupReason);
const callIndex = this.calls.indexOf(call); const callIndex = this.calls.indexOf(call);
@@ -1011,18 +1015,20 @@ export class GroupCall extends TypedEventEmitter<
this.emit(GroupCallEvent.CallsChanged, this.calls); this.emit(GroupCallEvent.CallsChanged, this.calls);
} }
private initCall(call: MatrixCall) { private initCall(call: MatrixCall): void {
const opponentMemberId = getCallUserId(call); const opponentMemberId = getCallUserId(call);
if (!opponentMemberId) { if (!opponentMemberId) {
throw new Error("Cannot init call without user id"); throw new Error("Cannot init call without user id");
} }
const onCallFeedsChanged = () => this.onCallFeedsChanged(call); const onCallFeedsChanged = (): void => this.onCallFeedsChanged(call);
const onCallStateChanged = const onCallStateChanged = (
(state: CallState, oldState: CallState | undefined) => this.onCallStateChanged(call, state, oldState); state: CallState,
oldState?: CallState,
): void => this.onCallStateChanged(call, state, oldState);
const onCallHangup = this.onCallHangup; const onCallHangup = this.onCallHangup;
const onCallReplaced = (newCall: MatrixCall) => this.replaceCall(call, newCall); const onCallReplaced = (newCall: MatrixCall): void => this.replaceCall(call, newCall);
this.callHandlers.set(opponentMemberId, { this.callHandlers.set(opponentMemberId, {
onCallFeedsChanged, onCallFeedsChanged,
@@ -1041,7 +1047,7 @@ export class GroupCall extends TypedEventEmitter<
onCallFeedsChanged(); onCallFeedsChanged();
} }
private disposeCall(call: MatrixCall, hangupReason: CallErrorCode) { private disposeCall(call: MatrixCall, hangupReason: CallErrorCode): void {
const opponentMemberId = getCallUserId(call); const opponentMemberId = getCallUserId(call);
if (!opponentMemberId) { if (!opponentMemberId) {
@@ -1083,7 +1089,7 @@ export class GroupCall extends TypedEventEmitter<
} }
} }
private onCallFeedsChanged = (call: MatrixCall) => { private onCallFeedsChanged = (call: MatrixCall): void => {
const opponentMemberId = getCallUserId(call); const opponentMemberId = getCallUserId(call);
if (!opponentMemberId) { if (!opponentMemberId) {
@@ -1119,7 +1125,7 @@ export class GroupCall extends TypedEventEmitter<
} }
}; };
private onCallStateChanged = (call: MatrixCall, state: CallState, _oldState: CallState | undefined) => { private onCallStateChanged = (call: MatrixCall, state: CallState, _oldState: CallState | undefined): void => {
const audioMuted = this.localCallFeed!.isAudioMuted(); const audioMuted = this.localCallFeed!.isAudioMuted();
if ( if (
@@ -1143,7 +1149,7 @@ export class GroupCall extends TypedEventEmitter<
} }
}; };
private onCallHangup = (call: MatrixCall) => { private onCallHangup = (call: MatrixCall): void => {
if (call.hangupReason === CallErrorCode.Replaced) { if (call.hangupReason === CallErrorCode.Replaced) {
return; return;
} }
@@ -1155,17 +1161,17 @@ export class GroupCall extends TypedEventEmitter<
* UserMedia CallFeed Event Handlers * UserMedia CallFeed Event Handlers
*/ */
public getUserMediaFeedByUserId(userId: string) { public getUserMediaFeedByUserId(userId: string): CallFeed | undefined {
return this.userMediaFeeds.find((feed) => feed.userId === userId); return this.userMediaFeeds.find((feed) => feed.userId === userId);
} }
private addUserMediaFeed(callFeed: CallFeed) { private addUserMediaFeed(callFeed: CallFeed): void {
this.userMediaFeeds.push(callFeed); this.userMediaFeeds.push(callFeed);
callFeed.measureVolumeActivity(true); callFeed.measureVolumeActivity(true);
this.emit(GroupCallEvent.UserMediaFeedsChanged, this.userMediaFeeds); this.emit(GroupCallEvent.UserMediaFeedsChanged, this.userMediaFeeds);
} }
private replaceUserMediaFeed(existingFeed: CallFeed, replacementFeed: CallFeed) { private replaceUserMediaFeed(existingFeed: CallFeed, replacementFeed: CallFeed): void {
const feedIndex = this.userMediaFeeds.findIndex((feed) => feed.userId === existingFeed.userId); const feedIndex = this.userMediaFeeds.findIndex((feed) => feed.userId === existingFeed.userId);
if (feedIndex === -1) { if (feedIndex === -1) {
@@ -1179,7 +1185,7 @@ export class GroupCall extends TypedEventEmitter<
this.emit(GroupCallEvent.UserMediaFeedsChanged, this.userMediaFeeds); this.emit(GroupCallEvent.UserMediaFeedsChanged, this.userMediaFeeds);
} }
private removeUserMediaFeed(callFeed: CallFeed) { private removeUserMediaFeed(callFeed: CallFeed): void {
const feedIndex = this.userMediaFeeds.findIndex((feed) => feed.userId === callFeed.userId); const feedIndex = this.userMediaFeeds.findIndex((feed) => feed.userId === callFeed.userId);
if (feedIndex === -1) { if (feedIndex === -1) {
@@ -1200,7 +1206,7 @@ export class GroupCall extends TypedEventEmitter<
} }
} }
private onActiveSpeakerLoop = () => { private onActiveSpeakerLoop = (): void => {
let topAvg: number | undefined = undefined; let topAvg: number | undefined = undefined;
let nextActiveSpeaker: string | undefined = undefined; let nextActiveSpeaker: string | undefined = undefined;
@@ -1239,16 +1245,16 @@ export class GroupCall extends TypedEventEmitter<
* Screenshare Call Feed Event Handlers * Screenshare Call Feed Event Handlers
*/ */
public getScreenshareFeedByUserId(userId: string) { public getScreenshareFeedByUserId(userId: string): CallFeed | undefined {
return this.screenshareFeeds.find((feed) => feed.userId === userId); return this.screenshareFeeds.find((feed) => feed.userId === userId);
} }
private addScreenshareFeed(callFeed: CallFeed) { private addScreenshareFeed(callFeed: CallFeed): void {
this.screenshareFeeds.push(callFeed); this.screenshareFeeds.push(callFeed);
this.emit(GroupCallEvent.ScreenshareFeedsChanged, this.screenshareFeeds); this.emit(GroupCallEvent.ScreenshareFeedsChanged, this.screenshareFeeds);
} }
private replaceScreenshareFeed(existingFeed: CallFeed, replacementFeed: CallFeed) { private replaceScreenshareFeed(existingFeed: CallFeed, replacementFeed: CallFeed): void {
const feedIndex = this.screenshareFeeds.findIndex((feed) => feed.userId === existingFeed.userId); const feedIndex = this.screenshareFeeds.findIndex((feed) => feed.userId === existingFeed.userId);
if (feedIndex === -1) { if (feedIndex === -1) {
@@ -1261,7 +1267,7 @@ export class GroupCall extends TypedEventEmitter<
this.emit(GroupCallEvent.ScreenshareFeedsChanged, this.screenshareFeeds); this.emit(GroupCallEvent.ScreenshareFeedsChanged, this.screenshareFeeds);
} }
private removeScreenshareFeed(callFeed: CallFeed) { private removeScreenshareFeed(callFeed: CallFeed): void {
const feedIndex = this.screenshareFeeds.findIndex((feed) => feed.userId === callFeed.userId); const feedIndex = this.screenshareFeeds.findIndex((feed) => feed.userId === callFeed.userId);
if (feedIndex === -1) { if (feedIndex === -1) {
@@ -1278,7 +1284,7 @@ export class GroupCall extends TypedEventEmitter<
* Participant Management * Participant Management
*/ */
private addParticipant(member: RoomMember) { private addParticipant(member: RoomMember): void {
if (this.participants.find((m) => m.userId === member.userId)) { if (this.participants.find((m) => m.userId === member.userId)) {
return; return;
} }
@@ -1289,7 +1295,7 @@ export class GroupCall extends TypedEventEmitter<
this.client.emit(GroupCallEventHandlerEvent.Participants, this.participants, this); this.client.emit(GroupCallEventHandlerEvent.Participants, this.participants, this);
} }
private removeParticipant(member: RoomMember) { private removeParticipant(member: RoomMember): void {
const index = this.participants.findIndex((m) => m.userId === member.userId); const index = this.participants.findIndex((m) => m.userId === member.userId);
if (index === -1) { if (index === -1) {

View File

@@ -55,7 +55,7 @@ export class GroupCallEventHandler {
// and get // and get
private roomDeferreds = new Map<string, RoomDeferred>(); private roomDeferreds = new Map<string, RoomDeferred>();
constructor(private client: MatrixClient) { } public constructor(private client: MatrixClient) { }
public async start(): Promise<void> { public async start(): Promise<void> {
// We wait until the client has started syncing for real. // We wait until the client has started syncing for real.
@@ -66,7 +66,7 @@ export class GroupCallEventHandler {
if (this.client.getSyncState() !== SyncState.Syncing) { if (this.client.getSyncState() !== SyncState.Syncing) {
logger.debug("Waiting for client to start syncing..."); logger.debug("Waiting for client to start syncing...");
await new Promise<void>(resolve => { await new Promise<void>(resolve => {
const onSync = () => { const onSync = (): void => {
if (this.client.getSyncState() === SyncState.Syncing) { if (this.client.getSyncState() === SyncState.Syncing) {
this.client.off(ClientEvent.Sync, onSync); this.client.off(ClientEvent.Sync, onSync);
return resolve(); return resolve();
@@ -192,7 +192,7 @@ export class GroupCallEventHandler {
return groupCall; return groupCall;
} }
private onRoomsChanged = (room: Room) => { private onRoomsChanged = (room: Room): void => {
this.createGroupCallForRoom(room); this.createGroupCallForRoom(room);
}; };

View File

@@ -56,11 +56,11 @@ export class MediaHandler extends TypedEventEmitter<
public userMediaStreams: MediaStream[] = []; public userMediaStreams: MediaStream[] = [];
public screensharingStreams: MediaStream[] = []; public screensharingStreams: MediaStream[] = [];
constructor(private client: MatrixClient) { public constructor(private client: MatrixClient) {
super(); super();
} }
public restoreMediaSettings(audioInput: string, videoInput: string) { public restoreMediaSettings(audioInput: string, videoInput: string): void {
this.audioInput = audioInput; this.audioInput = audioInput;
this.videoInput = videoInput; this.videoInput = videoInput;
} }
@@ -275,7 +275,7 @@ export class MediaHandler extends TypedEventEmitter<
/** /**
* Stops all tracks on the provided usermedia stream * Stops all tracks on the provided usermedia stream
*/ */
public stopUserMediaStream(mediaStream: MediaStream) { public stopUserMediaStream(mediaStream: MediaStream): void {
logger.log(`mediaHandler stopUserMediaStream stopping stream ${mediaStream.id}`); logger.log(`mediaHandler stopUserMediaStream stopping stream ${mediaStream.id}`);
for (const track of mediaStream.getTracks()) { for (const track of mediaStream.getTracks()) {
track.stop(); track.stop();
@@ -333,7 +333,7 @@ export class MediaHandler extends TypedEventEmitter<
/** /**
* Stops all tracks on the provided screensharing stream * Stops all tracks on the provided screensharing stream
*/ */
public stopScreensharingStream(mediaStream: MediaStream) { public stopScreensharingStream(mediaStream: MediaStream): void {
logger.debug("Stopping screensharing stream", mediaStream.id); logger.debug("Stopping screensharing stream", mediaStream.id);
for (const track of mediaStream.getTracks()) { for (const track of mediaStream.getTracks()) {
track.stop(); track.stop();
@@ -352,7 +352,7 @@ export class MediaHandler extends TypedEventEmitter<
/** /**
* Stops all local media tracks * Stops all local media tracks
*/ */
public stopAllStreams() { public stopAllStreams(): void {
for (const stream of this.userMediaStreams) { for (const stream of this.userMediaStreams) {
logger.log(`mediaHandler stopAllStreams stopping stream ${stream.id}`); logger.log(`mediaHandler stopAllStreams stopping stream ${stream.id}`);
for (const track of stream.getTracks()) { for (const track of stream.getTracks()) {

View File

@@ -3278,10 +3278,10 @@ eslint-plugin-import@^2.26.0:
resolve "^1.22.0" resolve "^1.22.0"
tsconfig-paths "^3.14.1" tsconfig-paths "^3.14.1"
eslint-plugin-matrix-org@^0.7.0: eslint-plugin-matrix-org@^0.8.0:
version "0.7.0" version "0.8.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-matrix-org/-/eslint-plugin-matrix-org-0.7.0.tgz#4b7456b31e30e7575b62c2aada91915478829f88" resolved "https://registry.yarnpkg.com/eslint-plugin-matrix-org/-/eslint-plugin-matrix-org-0.8.0.tgz#daa1396900a8cb1c1d88f1a370e45fc32482cd9e"
integrity sha512-FLmwE4/cRalB7J+J1BBuTccaXvKtRgAoHlbqSCbdsRqhh27xpxEWXe08KlNiET7drEnnz+xMHXdmvW469gch7g== integrity sha512-/Poz/F8lXYDsmQa29iPSt+kO+Jn7ArvRdq10g0CCk8wbRS0sb2zb6fvd9xL1BgR5UDQL771V0l8X32etvY5yKA==
eslint-plugin-unicorn@^44.0.2: eslint-plugin-unicorn@^44.0.2:
version "44.0.2" version "44.0.2"