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

Iterate typing to work towards noImplicitAny (#2061)

This commit is contained in:
Michael Telatynski
2021-12-14 14:32:35 +00:00
committed by GitHub
parent aeec4aa4a8
commit 963c7690b6
16 changed files with 161 additions and 140 deletions

View File

@ -312,7 +312,7 @@ describe("MSC3089Branch", () => {
} as MatrixEvent);
const events = [await branch.getFileEvent(), await branch2.getFileEvent(), {
replacingEventId: () => null,
replacingEventId: (): string => null,
getId: () => "$unknown",
}];
staticRoom.getLiveTimeline = () => ({ getEvents: () => events }) as EventTimeline;

View File

@ -62,12 +62,6 @@ declare global {
};
}
interface HTMLAudioElement {
// sinkId & setSinkId are experimental and typescript doesn't know about them
sinkId: string;
setSinkId(outputId: string);
}
interface DummyInterfaceWeShouldntBeUsingThis {}
interface Navigator {

View File

@ -621,7 +621,7 @@ export interface IMyDevice {
last_seen_ts?: number;
}
interface IDownloadKeyResult {
export interface IDownloadKeyResult {
failures: { [serverName: string]: object };
device_keys: {
[userId: string]: {
@ -632,13 +632,42 @@ interface IDownloadKeyResult {
};
};
};
// the following three fields were added in 1.1
master_keys?: {
[userId: string]: {
keys: { [keyId: string]: string };
usage: string[];
user_id: string;
};
};
self_signing_keys?: {
[userId: string]: {
keys: { [keyId: string]: string };
signatures: ISignatures;
usage: string[];
user_id: string;
};
};
user_signing_keys?: {
[userId: string]: {
keys: { [keyId: string]: string };
signatures: ISignatures;
usage: string[];
user_id: string;
};
};
}
interface IClaimOTKsResult {
export interface IClaimOTKsResult {
failures: { [serverName: string]: object };
one_time_keys: {
[userId: string]: {
[deviceId: string]: string;
[deviceId: string]: {
[keyId: string]: {
key: string;
signatures: ISignatures;
};
};
};
};
}
@ -1421,14 +1450,12 @@ export class MatrixClient extends EventEmitter {
}
}
// We swallow errors because we need a default object anyhow
return this.http.authedRequest(
undefined, "GET", "/capabilities",
).catch((e: Error) => {
).catch((e: Error): void => {
// We swallow errors because we need a default object anyhow
logger.error(e);
return null; // otherwise consume the error
}).then((r) => {
if (!r) r = {};
}).then((r: { capabilities?: ICapabilities } = {}) => {
const capabilities: ICapabilities = r["capabilities"] || {};
// If the capabilities missed the cache, cache it for a shorter amount
@ -2836,7 +2863,7 @@ export class MatrixClient extends EventEmitter {
}
let totalKeyCount = 0;
let keys = [];
let keys: IMegolmSessionData[] = [];
const path = this.makeKeyBackupPath(targetRoomId, targetSessionId, backupInfo.version);
@ -5692,18 +5719,14 @@ export class MatrixClient extends EventEmitter {
searchResults.count = roomEvents.count;
searchResults.next_batch = roomEvents.next_batch;
// combine the highlight list with our existing list; build an object
// to avoid O(N^2) fail
const highlights = {};
roomEvents.highlights.forEach((hl) => {
highlights[hl] = 1;
});
// combine the highlight list with our existing list;
const highlights = new Set<string>(roomEvents.highlights);
searchResults.highlights.forEach((hl) => {
highlights[hl] = 1;
highlights.add(hl);
});
// turn it back into a list.
searchResults.highlights = Object.keys(highlights);
searchResults.highlights = Array.from(highlights);
// append the new results to our existing results
const resultsLength = roomEvents.results ? roomEvents.results.length : 0;
@ -5794,11 +5817,9 @@ export class MatrixClient extends EventEmitter {
return this.http.authedRequest(
undefined, "GET", path, undefined, undefined,
).then((response) => {
).then((response: IFilterDefinition) => {
// persist the filter
const filter = Filter.fromJson(
userId, filterId, response,
);
const filter = Filter.fromJson(userId, filterId, response);
this.store.storeFilter(filter);
return filter;
});
@ -6096,7 +6117,7 @@ export class MatrixClient extends EventEmitter {
{
prefix: '',
},
).catch((e) => {
).catch((e: Error) => {
// Need to unset this if it fails, otherwise we'll never retry
this.serverVersionsPromise = null;
// but rethrow the exception to anything that was waiting
@ -6420,7 +6441,7 @@ export class MatrixClient extends EventEmitter {
public isUsernameAvailable(username: string): Promise<true> {
return this.http.authedRequest(
undefined, "GET", '/register/available', { username: username },
).then((response) => {
).then((response: { available: boolean }) => {
return response.available;
});
}
@ -7741,11 +7762,11 @@ export class MatrixClient extends EventEmitter {
* an error response ({@link module:http-api.MatrixError}).
*/
public claimOneTimeKeys(
devices: string[],
devices: [string, string][],
keyAlgorithm = "signed_curve25519",
timeout?: number,
): Promise<IClaimOTKsResult> {
const queries = {};
const queries: Record<string, Record<string, string>> = {};
if (keyAlgorithm === undefined) {
keyAlgorithm = "signed_curve25519";

View File

@ -33,6 +33,7 @@ import { OlmDevice } from "./OlmDevice";
import { ICryptoCallbacks } from "../matrix";
import { ISignatures } from "../@types/signed";
import { CryptoStore } from "./store/base";
import { ISecretStorageKeyInfo } from "./api";
const KEY_REQUEST_TIMEOUT_MS = 1000 * 60;
@ -175,7 +176,7 @@ export class CrossSigningInfo extends EventEmitter {
// check what SSSS keys have encrypted the master key (if any)
const stored = await secretStorage.isStored("m.cross_signing.master", false) || {};
// then check which of those SSSS keys have also encrypted the SSK and USK
function intersect(s) {
function intersect(s: Record<string, ISecretStorageKeyInfo>) {
for (const k of Object.keys(stored)) {
if (!s[k]) {
delete stored[k];

View File

@ -28,7 +28,7 @@ import { CrossSigningInfo, ICrossSigningInfo } from './CrossSigning';
import * as olmlib from './olmlib';
import { IndexedDBCryptoStore } from './store/indexeddb-crypto-store';
import { chunkPromises, defer, IDeferred, sleep } from '../utils';
import { MatrixClient } from "../client";
import { IDownloadKeyResult, MatrixClient } from "../client";
import { OlmDevice } from "./OlmDevice";
import { CryptoStore } from "./store/base";
@ -756,17 +756,21 @@ class DeviceListUpdateSerialiser {
opts.token = this.syncToken;
}
const factories = [];
const factories: Array<() => Promise<IDownloadKeyResult>> = [];
for (let i = 0; i < downloadUsers.length; i += this.deviceList.keyDownloadChunkSize) {
const userSlice = downloadUsers.slice(i, i + this.deviceList.keyDownloadChunkSize);
factories.push(() => this.baseApis.downloadKeysForUsers(userSlice, opts));
}
chunkPromises(factories, 3).then(async (responses: any[]) => {
const dk = Object.assign({}, ...(responses.map(res => res.device_keys || {})));
const masterKeys = Object.assign({}, ...(responses.map(res => res.master_keys || {})));
const ssks = Object.assign({}, ...(responses.map(res => res.self_signing_keys || {})));
const usks = Object.assign({}, ...(responses.map(res => res.user_signing_keys || {})));
chunkPromises(factories, 3).then(async (responses: IDownloadKeyResult[]) => {
const dk: IDownloadKeyResult["device_keys"]
= Object.assign({}, ...(responses.map(res => res.device_keys || {})));
const masterKeys: IDownloadKeyResult["master_keys"]
= Object.assign({}, ...(responses.map(res => res.master_keys || {})));
const ssks: IDownloadKeyResult["self_signing_keys"]
= Object.assign({}, ...(responses.map(res => res.self_signing_keys || {})));
const usks: IDownloadKeyResult["user_signing_keys"]
= Object.assign({}, ...(responses.map(res => res.user_signing_keys || {})));
// yield to other things that want to execute in between users, to
// avoid wedging the CPU
@ -811,8 +815,12 @@ class DeviceListUpdateSerialiser {
private async processQueryResponseForUser(
userId: string,
dkResponse: object,
crossSigningResponse: any, // TODO types
dkResponse: IDownloadKeyResult["device_keys"]["user_id"],
crossSigningResponse: {
master: IDownloadKeyResult["master_keys"]["user_id"];
self_signing: IDownloadKeyResult["master_keys"]["user_id"]; // eslint-disable-line camelcase
user_signing: IDownloadKeyResult["user_signing_keys"]["user_id"]; // eslint-disable-line camelcase
},
): Promise<void> {
logger.log('got device keys for ' + userId + ':', dkResponse);
logger.log('got cross-signing keys for ' + userId + ':', crossSigningResponse);
@ -869,7 +877,7 @@ async function updateStoredDeviceKeysForUser(
olmDevice: OlmDevice,
userId: string,
userStore: Record<string, DeviceInfo>,
userResult: object,
userResult: IDownloadKeyResult["device_keys"]["user_id"],
localUserId: string,
localDeviceId: string,
): Promise<boolean> {

View File

@ -33,6 +33,7 @@ import { encryptAES, decryptAES, calculateKeyCheck } from './aes';
import { getCrypto } from '../utils';
import { ICurve25519AuthData, IAes256AuthData, IKeyBackupInfo, IKeyBackupSession } from "./keybackup";
import { UnstableValue } from "../NamespacedValue";
import { IMegolmSessionData } from "./index";
const KEY_BACKUP_KEYS_PER_REQUEST = 200;
@ -87,7 +88,7 @@ interface BackupAlgorithmClass {
interface BackupAlgorithm {
untrusted: boolean;
encryptSession(data: Record<string, any>): Promise<any>;
decryptSessions(ciphertexts: Record<string, IKeyBackupSession>): Promise<Record<string, any>[]>;
decryptSessions(ciphertexts: Record<string, IKeyBackupSession>): Promise<IMegolmSessionData[]>;
authData: AuthData;
keyMatches(key: ArrayLike<number>): Promise<boolean>;
free(): void;
@ -300,7 +301,7 @@ export class BackupManager {
const ret = {
usable: false,
trusted_locally: false,
sigs: [],
sigs: [] as SigInfo[],
};
if (
@ -320,7 +321,7 @@ export class BackupManager {
ret.trusted_locally = true;
}
const mySigs = backupInfo.auth_data.signatures[this.baseApis.getUserId()] || [];
const mySigs = backupInfo.auth_data.signatures[this.baseApis.getUserId()] || {};
for (const keyId of Object.keys(mySigs)) {
const keyIdParts = keyId.split(':');
@ -645,9 +646,7 @@ export class Curve25519 implements BackupAlgorithm {
return this.publicKey.encrypt(JSON.stringify(plainText));
}
public async decryptSessions(
sessions: Record<string, IKeyBackupSession>,
): Promise<Record<string, any>[]> {
public async decryptSessions(sessions: Record<string, IKeyBackupSession>): Promise<IMegolmSessionData[]> {
const privKey = await this.getKey();
const decryption = new global.Olm.PkDecryption();
try {
@ -658,7 +657,7 @@ export class Curve25519 implements BackupAlgorithm {
throw { errcode: MatrixClient.RESTORE_BACKUP_ERROR_BAD_KEY };
}
const keys = [];
const keys: IMegolmSessionData[] = [];
for (const [sessionId, sessionData] of Object.entries(sessions)) {
try {
@ -777,8 +776,8 @@ export class Aes256 implements BackupAlgorithm {
return await encryptAES(JSON.stringify(plainText), this.key, data.session_id);
}
async decryptSessions(sessions: Record<string, IKeyBackupSession>): Promise<Record<string, any>[]> {
const keys = [];
async decryptSessions(sessions: Record<string, IKeyBackupSession>): Promise<IMegolmSessionData[]> {
const keys: IMegolmSessionData[] = [];
for (const [sessionId, sessionData] of Object.entries(sessions)) {
try {

View File

@ -22,9 +22,7 @@ import { decryptAES, encryptAES } from './aes';
import { logger } from '../logger';
import { ISecretStorageKeyInfo } from "./api";
import { Crypto } from "./index";
// FIXME: these types should eventually go in a different file
type Signatures = Record<string, Record<string, string>>;
import { ISignatures } from "../@types/signed";
export interface IDehydratedDevice {
device_id: string; // eslint-disable-line camelcase
@ -43,13 +41,13 @@ export interface IDeviceKeys {
device_id: string; // eslint-disable-line camelcase
user_id: string; // eslint-disable-line camelcase
keys: Record<string, string>;
signatures?: Signatures;
signatures?: ISignatures;
}
export interface IOneTimeKey {
key: string;
fallback?: boolean;
signatures?: Signatures;
signatures?: ISignatures;
}
export const DEHYDRATION_ALGORITHM = "org.matrix.msc2697.v1.olm.libolm_pickle";
@ -244,7 +242,7 @@ export class DehydrationManager {
}
logger.log("Preparing one-time keys");
const oneTimeKeys = {};
const oneTimeKeys: Record<string, IOneTimeKey> = {};
for (const [keyId, key] of Object.entries(otks.curve25519)) {
const k: IOneTimeKey = { key };
const signature = account.sign(anotherjson.stringify(k));

View File

@ -179,6 +179,13 @@ export interface IEventDecryptionResult {
untrusted?: boolean;
}
export interface IRequestsMap {
getRequest(event: MatrixEvent): VerificationRequest;
getRequestByChannel(channel: IVerificationChannel): VerificationRequest;
setRequest(event: MatrixEvent, request: VerificationRequest): void;
setRequestByChannel(channel: IVerificationChannel, request: VerificationRequest): void;
}
export class Crypto extends EventEmitter {
/**
* @return {string} The version of Olm.
@ -808,7 +815,7 @@ export class Crypto extends EventEmitter {
}
};
const signKeyBackupWithCrossSigning = async (keyBackupAuthData) => {
const signKeyBackupWithCrossSigning = async (keyBackupAuthData: IKeyBackupInfo["auth_data"]) => {
if (
this.crossSigningInfo.getId() &&
await this.crossSigningInfo.isStoredInKeyCache("master")
@ -1148,7 +1155,7 @@ export class Crypto extends EventEmitter {
const signedDevice = await this.crossSigningInfo.signDevice(this.userId, device);
logger.info(`Starting background key sig upload for ${this.deviceId}`);
const upload = ({ shouldEmit }) => {
const upload = ({ shouldEmit = false }) => {
return this.baseApis.uploadKeySignatures({
[this.userId]: {
[this.deviceId]: signedDevice,
@ -1184,7 +1191,7 @@ export class Crypto extends EventEmitter {
// Check all users for signatures if upgrade callback present
// FIXME: do this in batches
const users = {};
const users: Record<string, IDeviceVerificationUpgrade> = {};
for (const [userId, crossSigningInfo]
of Object.entries(this.deviceList.crossSigningInfo)) {
const upgradeInfo = await this.checkForDeviceVerificationUpgrade(
@ -1482,7 +1489,7 @@ export class Crypto extends EventEmitter {
!crossSigningPrivateKeys.has("user_signing")
);
const keySignatures = {};
const keySignatures: Record<string, ISignedKey> = {};
if (selfSigningChanged) {
logger.info("Got new self-signing key", newCrossSigning.getId("self_signing"));
@ -1537,7 +1544,7 @@ export class Crypto extends EventEmitter {
// We may have existing signatures from deleted devices, which will cause
// the entire upload to fail.
keySignatures[this.crossSigningInfo.getId()] = Object.assign(
{},
{} as ISignedKey,
masterKey,
{
signatures: {
@ -1551,7 +1558,7 @@ export class Crypto extends EventEmitter {
const keysToUpload = Object.keys(keySignatures);
if (keysToUpload.length) {
const upload = ({ shouldEmit }) => {
const upload = ({ shouldEmit = false }) => {
logger.info(`Starting background key sig upload for ${keysToUpload}`);
return this.baseApis.uploadKeySignatures({ [this.userId]: keySignatures })
.then((response) => {
@ -1927,7 +1934,7 @@ export class Crypto extends EventEmitter {
}
const oneTimeKeys = await this.olmDevice.getOneTimeKeys();
const oneTimeJson = {};
const oneTimeJson: Record<string, { key: string }> = {};
for (const keyId in oneTimeKeys.curve25519) {
if (oneTimeKeys.curve25519.hasOwnProperty(keyId)) {
@ -2076,7 +2083,7 @@ export class Crypto extends EventEmitter {
);
const device = await this.crossSigningInfo.signUser(xsk);
if (device) {
const upload = async ({ shouldEmit }) => {
const upload = async ({ shouldEmit = false }) => {
logger.info("Uploading signature for " + userId + "...");
const response = await this.baseApis.uploadKeySignatures({
[userId]: {
@ -2149,7 +2156,7 @@ export class Crypto extends EventEmitter {
logger.info("Own device " + deviceId + " marked verified: signing");
// Signing only needed if other device not already signed
let device;
let device: ISignedKey;
const deviceTrust = this.checkDeviceTrust(userId, deviceId);
if (deviceTrust.isCrossSigningVerified()) {
logger.log(`Own device ${deviceId} already cross-signing verified`);
@ -2160,7 +2167,7 @@ export class Crypto extends EventEmitter {
}
if (device) {
const upload = async ({ shouldEmit }) => {
const upload = async ({ shouldEmit = false }) => {
logger.info("Uploading signature for " + deviceId);
const response = await this.baseApis.uploadKeySignatures({
[userId]: {
@ -2204,11 +2211,7 @@ export class Crypto extends EventEmitter {
return Promise.resolve(existingRequest);
}
const channel = new InRoomChannel(this.baseApis, roomId, userId);
return this.requestVerificationWithChannel(
userId,
channel,
this.inRoomVerificationRequests,
);
return this.requestVerificationWithChannel(userId, channel, this.inRoomVerificationRequests);
}
public requestVerification(userId: string, devices: string[]): Promise<VerificationRequest> {
@ -2220,17 +2223,13 @@ export class Crypto extends EventEmitter {
return Promise.resolve(existingRequest);
}
const channel = new ToDeviceChannel(this.baseApis, userId, devices, ToDeviceChannel.makeTransactionId());
return this.requestVerificationWithChannel(
userId,
channel,
this.toDeviceVerificationRequests,
);
return this.requestVerificationWithChannel(userId, channel, this.toDeviceVerificationRequests);
}
private async requestVerificationWithChannel(
userId: string,
channel: IVerificationChannel,
requestsMap: any, // TODO types
requestsMap: IRequestsMap,
): Promise<VerificationRequest> {
let request = new VerificationRequest(channel, this.verificationMethods, this.baseApis);
// if transaction id is already known, add request
@ -2618,7 +2617,7 @@ export class Crypto extends EventEmitter {
users: string[],
force?: boolean,
): Promise<Record<string, Record<string, olmlib.IOlmSessionResult>>> {
const devicesByUser = {};
const devicesByUser: Record<string, DeviceInfo[]> = {};
for (let i = 0; i < users.length; ++i) {
const userId = users[i];
@ -2651,7 +2650,7 @@ export class Crypto extends EventEmitter {
* @return {module:crypto/OlmDevice.MegolmSessionData[]} a list of session export objects
*/
public async exportRoomKeys(): Promise<IMegolmSessionData[]> {
const exportedSessions = [];
const exportedSessions: IMegolmSessionData[] = [];
await this.cryptoStore.doTxn(
'readonly', [IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS], (txn) => {
this.cryptoStore.getAllEndToEndInboundGroupSessions(txn, (s) => {
@ -2783,8 +2782,7 @@ export class Crypto extends EventEmitter {
delete content['io.element.performance_metrics'];
}
const encryptedContent = await alg.encryptMessage(
room, event.getType(), content);
const encryptedContent = await alg.encryptMessage(room, event.getType(), content);
if (mRelatesTo) {
encryptedContent['m.relates_to'] = mRelatesTo;
@ -3154,7 +3152,7 @@ export class Crypto extends EventEmitter {
if (!ToDeviceChannel.validateEvent(event, this.baseApis)) {
return;
}
const createRequest = event => {
const createRequest = (event: MatrixEvent) => {
if (!ToDeviceChannel.canCreateRequest(ToDeviceChannel.getEventType(event))) {
return;
}
@ -3172,11 +3170,7 @@ export class Crypto extends EventEmitter {
return new VerificationRequest(
channel, this.verificationMethods, this.baseApis);
};
this.handleVerificationEvent(
event,
this.toDeviceVerificationRequests,
createRequest,
);
this.handleVerificationEvent(event, this.toDeviceVerificationRequests, createRequest);
}
/**
@ -3199,7 +3193,7 @@ export class Crypto extends EventEmitter {
if (!InRoomChannel.validateEvent(event, this.baseApis)) {
return;
}
const createRequest = event => {
const createRequest = (event: MatrixEvent) => {
const channel = new InRoomChannel(
this.baseApis,
event.getRoomId(),
@ -3207,18 +3201,13 @@ export class Crypto extends EventEmitter {
return new VerificationRequest(
channel, this.verificationMethods, this.baseApis);
};
this.handleVerificationEvent(
event,
this.inRoomVerificationRequests,
createRequest,
liveEvent,
);
this.handleVerificationEvent(event, this.inRoomVerificationRequests, createRequest, liveEvent);
};
private async handleVerificationEvent(
event: MatrixEvent,
requestsMap: any, // TODO types
createRequest: any, // TODO types
requestsMap: IRequestsMap,
createRequest: (event: MatrixEvent) => VerificationRequest,
isLiveEvent = true,
): Promise<void> {
// Wait for event to get its final ID with pendingEventOrdering: "chronological", since DM channels depend on it.
@ -3332,7 +3321,7 @@ export class Crypto extends EventEmitter {
return;
}
}
const devicesByUser = {};
const devicesByUser: Record<string, DeviceInfo[]> = {};
devicesByUser[sender] = [device];
await olmlib.ensureOlmSessionsForDevices(this.olmDevice, this.baseApis, devicesByUser, true);

View File

@ -28,7 +28,8 @@ import { OlmDevice } from "./OlmDevice";
import { DeviceInfo } from "./deviceinfo";
import { logger } from '../logger';
import { IOneTimeKey } from "./dehydration";
import { MatrixClient } from "../client";
import { IClaimOTKsResult, MatrixClient } from "../client";
import { ISignatures } from "../@types/signed";
enum Algorithm {
Olm = "m.olm.v1.curve25519-aes-sha2",
@ -132,6 +133,11 @@ export async function encryptMessageForDevice(
);
}
interface IExistingOlmSession {
device: DeviceInfo;
sessionId?: string;
}
/**
* Get the existing olm sessions for the given devices, and the devices that
* don't have olm sessions.
@ -152,11 +158,11 @@ export async function getExistingOlmSessions(
olmDevice: OlmDevice,
baseApis: MatrixClient,
devicesByUser: Record<string, DeviceInfo[]>,
) {
const devicesWithoutSession = {};
const sessions = {};
): Promise<[Record<string, DeviceInfo[]>, Record<string, Record<string, IExistingOlmSession>>]> {
const devicesWithoutSession: {[userId: string]: DeviceInfo[]} = {};
const sessions: {[userId: string]: {[deviceId: string]: IExistingOlmSession}} = {};
const promises = [];
const promises: Promise<void>[] = [];
for (const [userId, devices] of Object.entries(devicesByUser)) {
for (const deviceInfo of devices) {
@ -230,10 +236,10 @@ export async function ensureOlmSessionsForDevices(
force = false;
}
const devicesWithoutSession = [
const devicesWithoutSession: [string, string][] = [
// [userId, deviceId], ...
];
const result = {};
const result: {[userId: string]: {[deviceId: string]: IExistingOlmSession}} = {};
const resolveSession: Record<string, (sessionId?: string) => void> = {};
// Mark all sessions this task intends to update as in progress. It is
@ -321,9 +327,7 @@ export async function ensureOlmSessionsForDevices(
let taskDetail = `one-time keys for ${devicesWithoutSession.length} devices`;
try {
log.debug(`Claiming ${taskDetail}`);
res = await baseApis.claimOneTimeKeys(
devicesWithoutSession, oneTimeKeyAlgorithm, otkTimeout,
);
res = await baseApis.claimOneTimeKeys(devicesWithoutSession, oneTimeKeyAlgorithm, otkTimeout);
log.debug(`Claimed ${taskDetail}`);
} catch (e) {
for (const resolver of Object.values(resolveSession)) {
@ -337,8 +341,8 @@ export async function ensureOlmSessionsForDevices(
failedServers.push(...Object.keys(res.failures));
}
const otkResult = res.one_time_keys || {};
const promises = [];
const otkResult = res.one_time_keys || {} as IClaimOTKsResult["one_time_keys"];
const promises: Promise<void>[] = [];
for (const [userId, devices] of Object.entries(devicesByUser)) {
const userRes = otkResult[userId] || {};
for (let j = 0; j < devices.length; j++) {
@ -359,7 +363,7 @@ export async function ensureOlmSessionsForDevices(
}
const deviceRes = userRes[deviceId] || {};
let oneTimeKey = null;
let oneTimeKey: IOneTimeKey = null;
for (const keyId in deviceRes) {
if (keyId.indexOf(oneTimeKeyAlgorithm + ":") === 0) {
oneTimeKey = deviceRes[keyId];
@ -441,7 +445,7 @@ async function _verifyKeyAndStartSession(
export interface IObject {
unsigned?: object;
signatures?: object;
signatures?: ISignatures;
}
/**

View File

@ -200,10 +200,10 @@ export class Backend implements CryptoStore {
// index into the wantedStates array
let stateIndex = 0;
let result;
let result: OutgoingRoomKeyRequest;
function onsuccess(ev) {
const cursor = ev.target.result;
function onsuccess(this: IDBRequest<IDBCursorWithValue>) {
const cursor = this.result;
if (cursor) {
// got a match
result = cursor.value;
@ -218,7 +218,7 @@ export class Backend implements CryptoStore {
}
const wantedState = wantedStates[stateIndex];
const cursorReq = ev.target.source.openCursor(wantedState);
const cursorReq = (this.source as IDBIndex).openCursor(wantedState);
cursorReq.onsuccess = onsuccess;
}
@ -255,10 +255,10 @@ export class Backend implements CryptoStore {
wantedStates: number[],
): Promise<OutgoingRoomKeyRequest[]> {
let stateIndex = 0;
const results = [];
const results: OutgoingRoomKeyRequest[] = [];
function onsuccess(ev) {
const cursor = ev.target.result;
function onsuccess(this: IDBRequest<IDBCursorWithValue>) {
const cursor = this.result;
if (cursor) {
const keyReq = cursor.value;
if (keyReq.recipients.includes({ userId, deviceId })) {
@ -274,7 +274,7 @@ export class Backend implements CryptoStore {
}
const wantedState = wantedStates[stateIndex];
const cursorReq = ev.target.source.openCursor(wantedState);
const cursorReq = (this.source as IDBIndex).openCursor(wantedState);
cursorReq.onsuccess = onsuccess;
}
}
@ -306,10 +306,10 @@ export class Backend implements CryptoStore {
expectedState: number,
updates: Partial<OutgoingRoomKeyRequest>,
): Promise<OutgoingRoomKeyRequest | null> {
let result = null;
let result: OutgoingRoomKeyRequest = null;
function onsuccess(ev) {
const cursor = ev.target.result;
function onsuccess(this: IDBRequest<IDBCursorWithValue>) {
const cursor = this.result;
if (!cursor) {
return;
}
@ -444,7 +444,7 @@ export class Backend implements CryptoStore {
const objectStore = txn.objectStore("sessions");
const idx = objectStore.index("deviceKey");
const getReq = idx.openCursor(deviceKey);
const results = {};
const results: Parameters<Parameters<Backend["getEndToEndSessions"]>[2]>[0] = {};
getReq.onsuccess = function() {
const cursor = getReq.result;
if (cursor) {
@ -734,7 +734,7 @@ export class Backend implements CryptoStore {
}
public getEndToEndRooms(txn: IDBTransaction, func: (rooms: Record<string, IRoomEncryption>) => void): void {
const rooms = {};
const rooms: Parameters<Parameters<Backend["getEndToEndRooms"]>[1]>[0] = {};
const objectStore = txn.objectStore("rooms");
const getReq = objectStore.openCursor();
getReq.onsuccess = function() {
@ -756,7 +756,7 @@ export class Backend implements CryptoStore {
public getSessionsNeedingBackup(limit: number): Promise<ISession[]> {
return new Promise((resolve, reject) => {
const sessions = [];
const sessions: ISession[] = [];
const txn = this.db.transaction(
["sessions_needing_backup", "inbound_group_sessions"],
@ -877,8 +877,8 @@ export class Backend implements CryptoStore {
func: (txn: IDBTransaction) => T,
log: PrefixedLogger = logger,
): Promise<T> {
let startTime;
let description;
let startTime: number;
let description: string;
if (PROFILE_TRANSACTIONS) {
const txnId = this.nextTxnId++;
startTime = Date.now();

View File

@ -175,8 +175,10 @@ export class LocalStorageCryptoStore extends MemoryCryptoStore {
}
public async filterOutNotifiedErrorDevices(devices: IOlmDevice[]): Promise<IOlmDevice[]> {
const notifiedErrorDevices = getJsonItem<string[]>(this.store, KEY_NOTIFIED_ERROR_DEVICES) || {};
const ret = [];
const notifiedErrorDevices = getJsonItem<MemoryCryptoStore["notifiedErrorDevices"]>(
this.store, KEY_NOTIFIED_ERROR_DEVICES,
) || {};
const ret: IOlmDevice[] = [];
for (const device of devices) {
const { userId, deviceInfo } = device;
@ -291,7 +293,7 @@ export class LocalStorageCryptoStore extends MemoryCryptoStore {
}
public getEndToEndRooms(txn: unknown, func: (rooms: Record<string, IRoomEncryption>) => void): void {
const result = {};
const result: Record<string, IRoomEncryption> = {};
const prefix = keyEndToEndRoomsPrefix('');
for (let i = 0; i < this.store.length; ++i) {
@ -306,7 +308,7 @@ export class LocalStorageCryptoStore extends MemoryCryptoStore {
public getSessionsNeedingBackup(limit: number): Promise<ISession[]> {
const sessionsNeedingBackup = getJsonItem<string[]>(this.store, KEY_SESSIONS_NEEDING_BACKUP) || {};
const sessions = [];
const sessions: ISession[] = [];
for (const session in sessionsNeedingBackup) {
if (Object.prototype.hasOwnProperty.call(sessionsNeedingBackup, session)) {

View File

@ -30,4 +30,5 @@ export interface IVerificationChannel {
sendCompleted(type: string, content: Record<string, any>): Promise<void>;
completedContentFromEvent(event: MatrixEvent): Record<string, any>;
canCreateRequest(type: string): boolean;
handleEvent(event: MatrixEvent, request: VerificationRequest, isLiveEvent: boolean): Promise<void>;
}

View File

@ -26,6 +26,7 @@ import { IVerificationChannel } from "./Channel";
import { EventType } from "../../../@types/event";
import { MatrixClient } from "../../../client";
import { MatrixEvent } from "../../../models/event";
import { IRequestsMap } from "../..";
const MESSAGE_TYPE = EventType.RoomMessage;
const M_REFERENCE = "m.reference";
@ -304,7 +305,7 @@ export class InRoomChannel implements IVerificationChannel {
}
}
export class InRoomRequests {
export class InRoomRequests implements IRequestsMap {
private requestsByRoomId = new Map<string, Map<string, VerificationRequest>>();
public getRequest(event: MatrixEvent): VerificationRequest {
@ -328,7 +329,7 @@ export class InRoomRequests {
this.doSetRequest(event.getRoomId(), InRoomChannel.getTransactionId(event), request);
}
public setRequestByChannel(channel: InRoomChannel, request: VerificationRequest): void {
public setRequestByChannel(channel: IVerificationChannel, request: VerificationRequest): void {
this.doSetRequest(channel.roomId, channel.transactionId, request);
}

View File

@ -30,8 +30,9 @@ import { errorFromEvent, newUnexpectedMessageError } from "../Error";
import { MatrixEvent } from "../../../models/event";
import { IVerificationChannel } from "./Channel";
import { MatrixClient } from "../../../client";
import { IRequestsMap } from '../..';
type Request = VerificationRequest<ToDeviceChannel>;
export type Request = VerificationRequest<ToDeviceChannel>;
/**
* A key verification channel that sends verification events over to_device messages.
@ -276,7 +277,7 @@ export class ToDeviceChannel implements IVerificationChannel {
private async sendToDevices(type: string, content: Record<string, any>, devices: string[]): Promise<void> {
if (devices.length) {
const msgMap = {};
const msgMap: Record<string, Record<string, any>> = {};
for (const deviceId of devices) {
msgMap[deviceId] = content;
}
@ -294,7 +295,7 @@ export class ToDeviceChannel implements IVerificationChannel {
}
}
export class ToDeviceRequests {
export class ToDeviceRequests implements IRequestsMap {
private requestsByUserId = new Map<string, Map<string, Request>>();
public getRequest(event: MatrixEvent): Request {

View File

@ -582,7 +582,9 @@ export class VerificationRequest<C extends IVerificationChannel = IVerificationC
// get common methods
if (phase === PHASE_REQUESTED || phase === PHASE_READY) {
if (!this.wasSentByOwnDevice(event)) {
const content = event.getContent();
const content = event.getContent<{
methods: string[];
}>();
this.commonMethods =
content.methods.filter(m => this.verificationMethods.has(m));
}

View File

@ -282,7 +282,7 @@ export class MSC3089TreeSpace {
const members = this.room.currentState.getStateEvents(EventType.RoomMember);
for (const member of members) {
const isNotUs = member.getStateKey() !== this.client.getUserId();
if (isNotUs && kickMemberships.includes(member.getContent<string>()['membership'])) {
if (isNotUs && kickMemberships.includes(member.getContent().membership)) {
const stateKey = member.getStateKey();
if (!stateKey) {
throw new Error("State key not found for branch");