You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-07-31 15:24:23 +03:00
Improve typing (#2055)
This commit is contained in:
committed by
GitHub
parent
95e7a76ba9
commit
f8097221e6
@ -15,7 +15,7 @@
|
|||||||
"build:minify-browser": "terser dist/browser-matrix.js --compress --mangle --source-map --output dist/browser-matrix.min.js",
|
"build:minify-browser": "terser dist/browser-matrix.js --compress --mangle --source-map --output dist/browser-matrix.min.js",
|
||||||
"gendoc": "jsdoc -c jsdoc.json -P package.json",
|
"gendoc": "jsdoc -c jsdoc.json -P package.json",
|
||||||
"lint": "yarn lint:types && yarn lint:js",
|
"lint": "yarn lint:types && yarn lint:js",
|
||||||
"lint:js": "eslint --max-warnings 7 src spec",
|
"lint:js": "eslint --max-warnings 4 src spec",
|
||||||
"lint:js-fix": "eslint --fix src spec",
|
"lint:js-fix": "eslint --fix src spec",
|
||||||
"lint:types": "tsc --noEmit",
|
"lint:types": "tsc --noEmit",
|
||||||
"test": "jest",
|
"test": "jest",
|
||||||
|
@ -4,13 +4,13 @@ import { Room } from "../../src/models/room";
|
|||||||
import { TestClient } from "../TestClient";
|
import { TestClient } from "../TestClient";
|
||||||
|
|
||||||
describe("MatrixClient retrying", function() {
|
describe("MatrixClient retrying", function() {
|
||||||
let client = null;
|
let client: TestClient = null;
|
||||||
let httpBackend = null;
|
let httpBackend: TestClient["httpBackend"] = null;
|
||||||
let scheduler;
|
let scheduler;
|
||||||
const userId = "@alice:localhost";
|
const userId = "@alice:localhost";
|
||||||
const accessToken = "aseukfgwef";
|
const accessToken = "aseukfgwef";
|
||||||
const roomId = "!room:here";
|
const roomId = "!room:here";
|
||||||
let room;
|
let room: Room;
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
scheduler = new MatrixScheduler();
|
scheduler = new MatrixScheduler();
|
||||||
@ -53,10 +53,10 @@ describe("MatrixClient retrying", function() {
|
|||||||
const p1 = client.sendMessage(roomId, {
|
const p1 = client.sendMessage(roomId, {
|
||||||
"msgtype": "m.text",
|
"msgtype": "m.text",
|
||||||
"body": "m1",
|
"body": "m1",
|
||||||
}).then(function(ev) {
|
}).then(function() {
|
||||||
// we expect the first message to fail
|
// we expect the first message to fail
|
||||||
throw new Error('Message 1 unexpectedly sent successfully');
|
throw new Error('Message 1 unexpectedly sent successfully');
|
||||||
}, (e) => {
|
}, () => {
|
||||||
// this is expected
|
// this is expected
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -78,7 +78,7 @@ describe("MatrixClient retrying", function() {
|
|||||||
expect(ev2.status).toEqual(EventStatus.SENDING);
|
expect(ev2.status).toEqual(EventStatus.SENDING);
|
||||||
|
|
||||||
// the first message should get sent, and the second should get queued
|
// the first message should get sent, and the second should get queued
|
||||||
httpBackend.when("PUT", "/send/m.room.message/").check(function(rq) {
|
httpBackend.when("PUT", "/send/m.room.message/").check(function() {
|
||||||
// ev2 should now have been queued
|
// ev2 should now have been queued
|
||||||
expect(ev2.status).toEqual(EventStatus.QUEUED);
|
expect(ev2.status).toEqual(EventStatus.QUEUED);
|
||||||
|
|
||||||
|
@ -1018,7 +1018,7 @@ describe("MSC3089TreeSpace", () => {
|
|||||||
it('should return falsy for unknown files', () => {
|
it('should return falsy for unknown files', () => {
|
||||||
const fileEventId = "$file";
|
const fileEventId = "$file";
|
||||||
room.currentState = {
|
room.currentState = {
|
||||||
getStateEvents: (eventType: string, stateKey?: string) => {
|
getStateEvents: (eventType: string, stateKey?: string): MatrixEvent[] | MatrixEvent | null => {
|
||||||
expect(eventType).toEqual(UNSTABLE_MSC3089_BRANCH.unstable); // test to ensure we're definitely using unstable
|
expect(eventType).toEqual(UNSTABLE_MSC3089_BRANCH.unstable); // test to ensure we're definitely using unstable
|
||||||
expect(stateKey).toEqual(fileEventId);
|
expect(stateKey).toEqual(fileEventId);
|
||||||
return null;
|
return null;
|
||||||
|
@ -111,10 +111,10 @@ describe("utils", function() {
|
|||||||
|
|
||||||
describe("deepCompare", function() {
|
describe("deepCompare", function() {
|
||||||
const assert = {
|
const assert = {
|
||||||
isTrue: function(x) {
|
isTrue: function(x: any) {
|
||||||
expect(x).toBe(true);
|
expect(x).toBe(true);
|
||||||
},
|
},
|
||||||
isFalse: function(x) {
|
isFalse: function(x: any) {
|
||||||
expect(x).toBe(false);
|
expect(x).toBe(false);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -176,10 +176,10 @@ describe("utils", function() {
|
|||||||
// no two different function is equal really, they capture their
|
// no two different function is equal really, they capture their
|
||||||
// context variables so even if they have same toString(), they
|
// context variables so even if they have same toString(), they
|
||||||
// won't have same functionality
|
// won't have same functionality
|
||||||
const func = function(x) {
|
const func = function() {
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
const func2 = function(x) {
|
const func2 = function() {
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
assert.isTrue(utils.deepCompare(func, func));
|
assert.isTrue(utils.deepCompare(func, func));
|
||||||
@ -189,66 +189,6 @@ describe("utils", function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("extend", function() {
|
|
||||||
const SOURCE = { "prop2": 1, "string2": "x", "newprop": "new" };
|
|
||||||
|
|
||||||
it("should extend", function() {
|
|
||||||
const target = {
|
|
||||||
"prop1": 5, "prop2": 7, "string1": "baz", "string2": "foo",
|
|
||||||
};
|
|
||||||
const merged = {
|
|
||||||
"prop1": 5, "prop2": 1, "string1": "baz", "string2": "x",
|
|
||||||
"newprop": "new",
|
|
||||||
};
|
|
||||||
const sourceOrig = JSON.stringify(SOURCE);
|
|
||||||
|
|
||||||
utils.extend(target, SOURCE);
|
|
||||||
expect(JSON.stringify(target)).toEqual(JSON.stringify(merged));
|
|
||||||
|
|
||||||
// check the originial wasn't modified
|
|
||||||
expect(JSON.stringify(SOURCE)).toEqual(sourceOrig);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should ignore null", function() {
|
|
||||||
const target = {
|
|
||||||
"prop1": 5, "prop2": 7, "string1": "baz", "string2": "foo",
|
|
||||||
};
|
|
||||||
const merged = {
|
|
||||||
"prop1": 5, "prop2": 1, "string1": "baz", "string2": "x",
|
|
||||||
"newprop": "new",
|
|
||||||
};
|
|
||||||
const sourceOrig = JSON.stringify(SOURCE);
|
|
||||||
|
|
||||||
utils.extend(target, null, SOURCE);
|
|
||||||
expect(JSON.stringify(target)).toEqual(JSON.stringify(merged));
|
|
||||||
|
|
||||||
// check the originial wasn't modified
|
|
||||||
expect(JSON.stringify(SOURCE)).toEqual(sourceOrig);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should handle properties created with defineProperties", function() {
|
|
||||||
const source = Object.defineProperties({}, {
|
|
||||||
"enumerableProp": {
|
|
||||||
get: function() {
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
enumerable: true,
|
|
||||||
},
|
|
||||||
"nonenumerableProp": {
|
|
||||||
get: function() {
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// TODO: Fix type
|
|
||||||
const target: any = {};
|
|
||||||
utils.extend(target, source);
|
|
||||||
expect(target.enumerableProp).toBe(true);
|
|
||||||
expect(target.nonenumerableProp).toBe(undefined);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("chunkPromises", function() {
|
describe("chunkPromises", function() {
|
||||||
it("should execute promises in chunks", async function() {
|
it("should execute promises in chunks", async function() {
|
||||||
let promiseCount = 0;
|
let promiseCount = 0;
|
||||||
@ -273,7 +213,7 @@ describe("utils", function() {
|
|||||||
it('should retry', async () => {
|
it('should retry', async () => {
|
||||||
let count = 0;
|
let count = 0;
|
||||||
const val = {};
|
const val = {};
|
||||||
const fn = (attempt) => {
|
const fn = (attempt: any) => {
|
||||||
count++;
|
count++;
|
||||||
|
|
||||||
// If this expectation fails then it can appear as a Jest Timeout due to
|
// If this expectation fails then it can appear as a Jest Timeout due to
|
||||||
@ -480,7 +420,7 @@ describe("utils", function() {
|
|||||||
},
|
},
|
||||||
[72]: "test",
|
[72]: "test",
|
||||||
};
|
};
|
||||||
const output = [
|
const output: any = [
|
||||||
["72", "test"],
|
["72", "test"],
|
||||||
["a", 42],
|
["a", 42],
|
||||||
["b", [
|
["b", [
|
||||||
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||||||
import { TestClient } from '../../TestClient';
|
import { TestClient } from '../../TestClient';
|
||||||
import { MatrixCall, CallErrorCode, CallEvent } from '../../../src/webrtc/call';
|
import { MatrixCall, CallErrorCode, CallEvent } from '../../../src/webrtc/call';
|
||||||
import { SDPStreamMetadataKey, SDPStreamMetadataPurpose } from '../../../src/webrtc/callEventTypes';
|
import { SDPStreamMetadataKey, SDPStreamMetadataPurpose } from '../../../src/webrtc/callEventTypes';
|
||||||
|
import { RoomMember } from "../../../src";
|
||||||
|
|
||||||
const DUMMY_SDP = (
|
const DUMMY_SDP = (
|
||||||
"v=0\r\n" +
|
"v=0\r\n" +
|
||||||
@ -85,7 +86,7 @@ class MockRTCPeerConnection {
|
|||||||
|
|
||||||
class MockMediaStream {
|
class MockMediaStream {
|
||||||
constructor(
|
constructor(
|
||||||
public id,
|
public id: string,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
getTracks() { return []; }
|
getTracks() { return []; }
|
||||||
@ -362,7 +363,7 @@ describe('Call', function() {
|
|||||||
await callPromise;
|
await callPromise;
|
||||||
|
|
||||||
call.getOpponentMember = () => {
|
call.getOpponentMember = () => {
|
||||||
return { userId: "@bob:bar.uk" };
|
return { userId: "@bob:bar.uk" } as RoomMember;
|
||||||
};
|
};
|
||||||
|
|
||||||
await call.onAnswerReceived({
|
await call.onAnswerReceived({
|
||||||
|
@ -30,7 +30,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) => {
|
const forSource = (...args: any[]) => {
|
||||||
// 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
|
||||||
|
@ -1423,7 +1423,7 @@ export class MatrixClient extends EventEmitter {
|
|||||||
// We swallow errors because we need a default object anyhow
|
// We swallow errors because we need a default object anyhow
|
||||||
return this.http.authedRequest(
|
return this.http.authedRequest(
|
||||||
undefined, "GET", "/capabilities",
|
undefined, "GET", "/capabilities",
|
||||||
).catch((e) => {
|
).catch((e: Error) => {
|
||||||
logger.error(e);
|
logger.error(e);
|
||||||
return null; // otherwise consume the error
|
return null; // otherwise consume the error
|
||||||
}).then((r) => {
|
}).then((r) => {
|
||||||
@ -3106,7 +3106,7 @@ export class MatrixClient extends EventEmitter {
|
|||||||
* data event.
|
* data event.
|
||||||
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
||||||
*/
|
*/
|
||||||
public async getAccountDataFromServer(eventType: string): Promise<Record<string, any>> {
|
public async getAccountDataFromServer<T>(eventType: string): Promise<T> {
|
||||||
if (this.isInitialSyncComplete()) {
|
if (this.isInitialSyncComplete()) {
|
||||||
const event = this.store.getAccountData(eventType);
|
const event = this.store.getAccountData(eventType);
|
||||||
if (!event) {
|
if (!event) {
|
||||||
@ -3201,7 +3201,7 @@ export class MatrixClient extends EventEmitter {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const queryString = {};
|
const queryString: Record<string, string | string[]> = {};
|
||||||
if (opts.viaServers) {
|
if (opts.viaServers) {
|
||||||
queryString["server_name"] = opts.viaServers;
|
queryString["server_name"] = opts.viaServers;
|
||||||
}
|
}
|
||||||
@ -3411,7 +3411,7 @@ export class MatrixClient extends EventEmitter {
|
|||||||
content: IContent,
|
content: IContent,
|
||||||
txnId?: string,
|
txnId?: string,
|
||||||
callback?: Callback,
|
callback?: Callback,
|
||||||
);
|
): Promise<ISendEventResponse>;
|
||||||
public sendEvent(
|
public sendEvent(
|
||||||
roomId: string,
|
roomId: string,
|
||||||
threadId: string | null,
|
threadId: string | null,
|
||||||
@ -3419,7 +3419,7 @@ export class MatrixClient extends EventEmitter {
|
|||||||
content: IContent,
|
content: IContent,
|
||||||
txnId?: string,
|
txnId?: string,
|
||||||
callback?: Callback,
|
callback?: Callback,
|
||||||
)
|
): Promise<ISendEventResponse>;
|
||||||
public sendEvent(
|
public sendEvent(
|
||||||
roomId: string,
|
roomId: string,
|
||||||
threadId: string | null,
|
threadId: string | null,
|
||||||
@ -3699,14 +3699,14 @@ export class MatrixClient extends EventEmitter {
|
|||||||
eventId: string,
|
eventId: string,
|
||||||
txnId?: string | undefined,
|
txnId?: string | undefined,
|
||||||
cbOrOpts?: Callback | IRedactOpts,
|
cbOrOpts?: Callback | IRedactOpts,
|
||||||
);
|
): Promise<ISendEventResponse>;
|
||||||
public redactEvent(
|
public redactEvent(
|
||||||
roomId: string,
|
roomId: string,
|
||||||
threadId: string | null,
|
threadId: string | null,
|
||||||
eventId: string,
|
eventId: string,
|
||||||
txnId?: string | undefined,
|
txnId?: string | undefined,
|
||||||
cbOrOpts?: Callback | IRedactOpts,
|
cbOrOpts?: Callback | IRedactOpts,
|
||||||
);
|
): Promise<ISendEventResponse>;
|
||||||
public redactEvent(
|
public redactEvent(
|
||||||
roomId: string,
|
roomId: string,
|
||||||
threadId: string | null,
|
threadId: string | null,
|
||||||
@ -3744,14 +3744,14 @@ export class MatrixClient extends EventEmitter {
|
|||||||
content: IContent,
|
content: IContent,
|
||||||
txnId?: string,
|
txnId?: string,
|
||||||
callback?: Callback,
|
callback?: Callback,
|
||||||
)
|
): Promise<ISendEventResponse>;
|
||||||
public sendMessage(
|
public sendMessage(
|
||||||
roomId: string,
|
roomId: string,
|
||||||
threadId: string | null,
|
threadId: string | null,
|
||||||
content: IContent,
|
content: IContent,
|
||||||
txnId?: string,
|
txnId?: string,
|
||||||
callback?: Callback,
|
callback?: Callback,
|
||||||
)
|
): Promise<ISendEventResponse>;
|
||||||
public sendMessage(
|
public sendMessage(
|
||||||
roomId: string,
|
roomId: string,
|
||||||
threadId: string | null | IContent,
|
threadId: string | null | IContent,
|
||||||
@ -3793,14 +3793,14 @@ export class MatrixClient extends EventEmitter {
|
|||||||
body: string,
|
body: string,
|
||||||
txnId?: string,
|
txnId?: string,
|
||||||
callback?: Callback,
|
callback?: Callback,
|
||||||
)
|
): Promise<ISendEventResponse>;
|
||||||
public sendTextMessage(
|
public sendTextMessage(
|
||||||
roomId: string,
|
roomId: string,
|
||||||
threadId: string | null,
|
threadId: string | null,
|
||||||
body: string,
|
body: string,
|
||||||
txnId?: string,
|
txnId?: string,
|
||||||
callback?: Callback,
|
callback?: Callback,
|
||||||
)
|
): Promise<ISendEventResponse>;
|
||||||
public sendTextMessage(
|
public sendTextMessage(
|
||||||
roomId: string,
|
roomId: string,
|
||||||
threadId: string | null,
|
threadId: string | null,
|
||||||
@ -3832,14 +3832,14 @@ export class MatrixClient extends EventEmitter {
|
|||||||
body: string,
|
body: string,
|
||||||
txnId?: string,
|
txnId?: string,
|
||||||
callback?: Callback,
|
callback?: Callback,
|
||||||
)
|
): Promise<ISendEventResponse>;
|
||||||
public sendNotice(
|
public sendNotice(
|
||||||
roomId: string,
|
roomId: string,
|
||||||
threadId: string | null,
|
threadId: string | null,
|
||||||
body: string,
|
body: string,
|
||||||
txnId?: string,
|
txnId?: string,
|
||||||
callback?: Callback,
|
callback?: Callback,
|
||||||
);
|
): Promise<ISendEventResponse>;
|
||||||
public sendNotice(
|
public sendNotice(
|
||||||
roomId: string,
|
roomId: string,
|
||||||
threadId: string | null,
|
threadId: string | null,
|
||||||
@ -3871,14 +3871,14 @@ export class MatrixClient extends EventEmitter {
|
|||||||
body: string,
|
body: string,
|
||||||
txnId?: string,
|
txnId?: string,
|
||||||
callback?: Callback,
|
callback?: Callback,
|
||||||
)
|
): Promise<ISendEventResponse>;
|
||||||
public sendEmoteMessage(
|
public sendEmoteMessage(
|
||||||
roomId: string,
|
roomId: string,
|
||||||
threadId: string | null,
|
threadId: string | null,
|
||||||
body: string,
|
body: string,
|
||||||
txnId?: string,
|
txnId?: string,
|
||||||
callback?: Callback,
|
callback?: Callback,
|
||||||
);
|
): Promise<ISendEventResponse>;
|
||||||
public sendEmoteMessage(
|
public sendEmoteMessage(
|
||||||
roomId: string,
|
roomId: string,
|
||||||
threadId: string | null,
|
threadId: string | null,
|
||||||
@ -3912,7 +3912,7 @@ export class MatrixClient extends EventEmitter {
|
|||||||
info?: IImageInfo,
|
info?: IImageInfo,
|
||||||
text?: string,
|
text?: string,
|
||||||
callback?: Callback,
|
callback?: Callback,
|
||||||
);
|
): Promise<ISendEventResponse>;
|
||||||
public sendImageMessage(
|
public sendImageMessage(
|
||||||
roomId: string,
|
roomId: string,
|
||||||
threadId: string | null,
|
threadId: string | null,
|
||||||
@ -3920,7 +3920,7 @@ export class MatrixClient extends EventEmitter {
|
|||||||
info?: IImageInfo,
|
info?: IImageInfo,
|
||||||
text?: string,
|
text?: string,
|
||||||
callback?: Callback,
|
callback?: Callback,
|
||||||
);
|
): Promise<ISendEventResponse>;
|
||||||
public sendImageMessage(
|
public sendImageMessage(
|
||||||
roomId: string,
|
roomId: string,
|
||||||
threadId: string | null,
|
threadId: string | null,
|
||||||
@ -3965,7 +3965,7 @@ export class MatrixClient extends EventEmitter {
|
|||||||
info?: IImageInfo,
|
info?: IImageInfo,
|
||||||
text?: string,
|
text?: string,
|
||||||
callback?: Callback,
|
callback?: Callback,
|
||||||
);
|
): Promise<ISendEventResponse>;
|
||||||
public sendStickerMessage(
|
public sendStickerMessage(
|
||||||
roomId: string,
|
roomId: string,
|
||||||
threadId: string | null,
|
threadId: string | null,
|
||||||
@ -3973,7 +3973,7 @@ export class MatrixClient extends EventEmitter {
|
|||||||
info?: IImageInfo,
|
info?: IImageInfo,
|
||||||
text?: string,
|
text?: string,
|
||||||
callback?: Callback,
|
callback?: Callback,
|
||||||
);
|
): Promise<ISendEventResponse>;
|
||||||
public sendStickerMessage(
|
public sendStickerMessage(
|
||||||
roomId: string,
|
roomId: string,
|
||||||
threadId: string | null,
|
threadId: string | null,
|
||||||
@ -4015,14 +4015,14 @@ export class MatrixClient extends EventEmitter {
|
|||||||
body: string,
|
body: string,
|
||||||
htmlBody: string,
|
htmlBody: string,
|
||||||
callback?: Callback,
|
callback?: Callback,
|
||||||
);
|
): Promise<ISendEventResponse>;
|
||||||
public sendHtmlMessage(
|
public sendHtmlMessage(
|
||||||
roomId: string,
|
roomId: string,
|
||||||
threadId: string | null,
|
threadId: string | null,
|
||||||
body: string,
|
body: string,
|
||||||
htmlBody: string,
|
htmlBody: string,
|
||||||
callback?: Callback,
|
callback?: Callback,
|
||||||
)
|
): Promise<ISendEventResponse>;
|
||||||
public sendHtmlMessage(
|
public sendHtmlMessage(
|
||||||
roomId: string,
|
roomId: string,
|
||||||
threadId: string | null,
|
threadId: string | null,
|
||||||
@ -4053,14 +4053,14 @@ export class MatrixClient extends EventEmitter {
|
|||||||
body: string,
|
body: string,
|
||||||
htmlBody: string,
|
htmlBody: string,
|
||||||
callback?: Callback,
|
callback?: Callback,
|
||||||
);
|
): Promise<ISendEventResponse>;
|
||||||
public sendHtmlNotice(
|
public sendHtmlNotice(
|
||||||
roomId: string,
|
roomId: string,
|
||||||
threadId: string | null,
|
threadId: string | null,
|
||||||
body: string,
|
body: string,
|
||||||
htmlBody: string,
|
htmlBody: string,
|
||||||
callback?: Callback,
|
callback?: Callback,
|
||||||
)
|
): Promise<ISendEventResponse>;
|
||||||
public sendHtmlNotice(
|
public sendHtmlNotice(
|
||||||
roomId: string,
|
roomId: string,
|
||||||
threadId: string | null,
|
threadId: string | null,
|
||||||
@ -4092,14 +4092,14 @@ export class MatrixClient extends EventEmitter {
|
|||||||
body: string,
|
body: string,
|
||||||
htmlBody: string,
|
htmlBody: string,
|
||||||
callback?: Callback,
|
callback?: Callback,
|
||||||
);
|
): Promise<ISendEventResponse>;
|
||||||
public sendHtmlEmote(
|
public sendHtmlEmote(
|
||||||
roomId: string,
|
roomId: string,
|
||||||
threadId: string | null,
|
threadId: string | null,
|
||||||
body: string,
|
body: string,
|
||||||
htmlBody: string,
|
htmlBody: string,
|
||||||
callback?: Callback,
|
callback?: Callback,
|
||||||
)
|
): Promise<ISendEventResponse>;
|
||||||
public sendHtmlEmote(
|
public sendHtmlEmote(
|
||||||
roomId: string,
|
roomId: string,
|
||||||
threadId: string | null,
|
threadId: string | null,
|
||||||
@ -4420,7 +4420,7 @@ export class MatrixClient extends EventEmitter {
|
|||||||
errcode: "ORG.MATRIX.JSSDK_MISSING_PARAM",
|
errcode: "ORG.MATRIX.JSSDK_MISSING_PARAM",
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
const params = {
|
const params: Record<string, string> = {
|
||||||
id_server: identityServerUrl,
|
id_server: identityServerUrl,
|
||||||
medium: medium,
|
medium: medium,
|
||||||
address: address,
|
address: address,
|
||||||
@ -4478,10 +4478,10 @@ export class MatrixClient extends EventEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const populationResults = {}; // {roomId: Error}
|
const populationResults: Record<string, Error> = {}; // {roomId: Error}
|
||||||
const promises = [];
|
const promises = [];
|
||||||
|
|
||||||
const doLeave = (roomId) => {
|
const doLeave = (roomId: string) => {
|
||||||
return this.leave(roomId).then(() => {
|
return this.leave(roomId).then(() => {
|
||||||
populationResults[roomId] = null;
|
populationResults[roomId] = null;
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
@ -5065,14 +5065,14 @@ export class MatrixClient extends EventEmitter {
|
|||||||
return pendingRequest;
|
return pendingRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
let path;
|
let path: string;
|
||||||
let params;
|
let params: Record<string, string>;
|
||||||
let promise;
|
let promise;
|
||||||
|
|
||||||
if (isNotifTimeline) {
|
if (isNotifTimeline) {
|
||||||
path = "/notifications";
|
path = "/notifications";
|
||||||
params = {
|
params = {
|
||||||
limit: ('limit' in opts) ? opts.limit : 30,
|
limit: (opts.limit ?? 30).toString(),
|
||||||
only: 'highlight',
|
only: 'highlight',
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -5509,7 +5509,7 @@ export class MatrixClient extends EventEmitter {
|
|||||||
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
||||||
*/
|
*/
|
||||||
public setRoomMutePushRule(scope: string, roomId: string, mute: boolean): Promise<void> | void {
|
public setRoomMutePushRule(scope: string, roomId: string, mute: boolean): Promise<void> | void {
|
||||||
let deferred;
|
let promise: Promise<void>;
|
||||||
let hasDontNotifyRule;
|
let hasDontNotifyRule;
|
||||||
|
|
||||||
// Get the existing room-kind push rule if any
|
// Get the existing room-kind push rule if any
|
||||||
@ -5523,17 +5523,17 @@ export class MatrixClient extends EventEmitter {
|
|||||||
if (!mute) {
|
if (!mute) {
|
||||||
// Remove the rule only if it is a muting rule
|
// Remove the rule only if it is a muting rule
|
||||||
if (hasDontNotifyRule) {
|
if (hasDontNotifyRule) {
|
||||||
deferred = this.deletePushRule(scope, PushRuleKind.RoomSpecific, roomPushRule.rule_id);
|
promise = this.deletePushRule(scope, PushRuleKind.RoomSpecific, roomPushRule.rule_id);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!roomPushRule) {
|
if (!roomPushRule) {
|
||||||
deferred = this.addPushRule(scope, PushRuleKind.RoomSpecific, roomId, {
|
promise = this.addPushRule(scope, PushRuleKind.RoomSpecific, roomId, {
|
||||||
actions: ["dont_notify"],
|
actions: ["dont_notify"],
|
||||||
});
|
});
|
||||||
} else if (!hasDontNotifyRule) {
|
} else if (!hasDontNotifyRule) {
|
||||||
// Remove the existing one before setting the mute push rule
|
// Remove the existing one before setting the mute push rule
|
||||||
// This is a workaround to SYN-590 (Push rule update fails)
|
// This is a workaround to SYN-590 (Push rule update fails)
|
||||||
deferred = utils.defer();
|
const deferred = utils.defer();
|
||||||
this.deletePushRule(scope, PushRuleKind.RoomSpecific, roomPushRule.rule_id)
|
this.deletePushRule(scope, PushRuleKind.RoomSpecific, roomPushRule.rule_id)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.addPushRule(scope, PushRuleKind.RoomSpecific, roomId, {
|
this.addPushRule(scope, PushRuleKind.RoomSpecific, roomId, {
|
||||||
@ -5547,21 +5547,21 @@ export class MatrixClient extends EventEmitter {
|
|||||||
deferred.reject(err);
|
deferred.reject(err);
|
||||||
});
|
});
|
||||||
|
|
||||||
deferred = deferred.promise;
|
promise = deferred.promise;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deferred) {
|
if (promise) {
|
||||||
return new Promise<void>((resolve, reject) => {
|
return new Promise<void>((resolve, reject) => {
|
||||||
// Update this.pushRules when the operation completes
|
// Update this.pushRules when the operation completes
|
||||||
deferred.then(() => {
|
promise.then(() => {
|
||||||
this.getPushRules().then((result) => {
|
this.getPushRules().then((result) => {
|
||||||
this.pushRules = result;
|
this.pushRules = result;
|
||||||
resolve();
|
resolve();
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
reject(err);
|
reject(err);
|
||||||
});
|
});
|
||||||
}).catch((err) => {
|
}).catch((err: Error) => {
|
||||||
// Update it even if the previous operation fails. This can help the
|
// Update it even if the previous operation fails. This can help the
|
||||||
// app to recover when push settings has been modifed from another client
|
// app to recover when push settings has been modifed from another client
|
||||||
this.getPushRules().then((result) => {
|
this.getPushRules().then((result) => {
|
||||||
@ -6281,7 +6281,7 @@ export class MatrixClient extends EventEmitter {
|
|||||||
fetchedEventType,
|
fetchedEventType,
|
||||||
opts);
|
opts);
|
||||||
const mapper = this.getEventMapper();
|
const mapper = this.getEventMapper();
|
||||||
let originalEvent;
|
let originalEvent: MatrixEvent;
|
||||||
if (result.original_event) {
|
if (result.original_event) {
|
||||||
originalEvent = mapper(result.original_event);
|
originalEvent = mapper(result.original_event);
|
||||||
}
|
}
|
||||||
@ -6564,7 +6564,7 @@ export class MatrixClient extends EventEmitter {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// merge data into loginData
|
// merge data into loginData
|
||||||
utils.extend(loginData, data);
|
Object.assign(loginData, data);
|
||||||
|
|
||||||
return this.http.authedRequest(
|
return this.http.authedRequest(
|
||||||
(error, response) => {
|
(error, response) => {
|
||||||
@ -7544,7 +7544,7 @@ export class MatrixClient extends EventEmitter {
|
|||||||
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
||||||
*/
|
*/
|
||||||
public getPushRules(callback?: Callback): Promise<IPushRules> {
|
public getPushRules(callback?: Callback): Promise<IPushRules> {
|
||||||
return this.http.authedRequest(callback, "GET", "/pushrules/").then(rules => {
|
return this.http.authedRequest(callback, "GET", "/pushrules/").then((rules: IPushRules) => {
|
||||||
return PushProcessor.rewriteDefaultRules(rules);
|
return PushProcessor.rewriteDefaultRules(rules);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -8018,7 +8018,7 @@ export class MatrixClient extends EventEmitter {
|
|||||||
addressPairs: [string, string][],
|
addressPairs: [string, string][],
|
||||||
identityAccessToken: string,
|
identityAccessToken: string,
|
||||||
): Promise<{ address: string, mxid: string }[]> {
|
): Promise<{ address: string, mxid: string }[]> {
|
||||||
const params = {
|
const params: Record<string, string | string[]> = {
|
||||||
// addresses: ["email@example.org", "10005550000"],
|
// addresses: ["email@example.org", "10005550000"],
|
||||||
// algorithm: "sha256",
|
// algorithm: "sha256",
|
||||||
// pepper: "abc123"
|
// pepper: "abc123"
|
||||||
@ -8032,7 +8032,7 @@ export class MatrixClient extends EventEmitter {
|
|||||||
|
|
||||||
params['pepper'] = hashes['lookup_pepper'];
|
params['pepper'] = hashes['lookup_pepper'];
|
||||||
|
|
||||||
const localMapping = {
|
const localMapping: Record<string, string> = {
|
||||||
// hashed identifier => plain text address
|
// hashed identifier => plain text address
|
||||||
// For use in this function's return format
|
// For use in this function's return format
|
||||||
};
|
};
|
||||||
|
@ -53,13 +53,13 @@ export function getHttpUriForMxc(
|
|||||||
}
|
}
|
||||||
let serverAndMediaId = mxc.slice(6); // strips mxc://
|
let serverAndMediaId = mxc.slice(6); // strips mxc://
|
||||||
let prefix = "/_matrix/media/r0/download/";
|
let prefix = "/_matrix/media/r0/download/";
|
||||||
const params = {};
|
const params: Record<string, string> = {};
|
||||||
|
|
||||||
if (width) {
|
if (width) {
|
||||||
params["width"] = Math.round(width);
|
params["width"] = Math.round(width).toString();
|
||||||
}
|
}
|
||||||
if (height) {
|
if (height) {
|
||||||
params["height"] = Math.round(height);
|
params["height"] = Math.round(height).toString();
|
||||||
}
|
}
|
||||||
if (resizeMethod) {
|
if (resizeMethod) {
|
||||||
params["method"] = resizeMethod;
|
params["method"] = resizeMethod;
|
||||||
|
@ -265,8 +265,8 @@ export class DeviceList extends EventEmitter {
|
|||||||
* module:crypto/deviceinfo|DeviceInfo}.
|
* module:crypto/deviceinfo|DeviceInfo}.
|
||||||
*/
|
*/
|
||||||
public downloadKeys(userIds: string[], forceDownload: boolean): Promise<DeviceInfoMap> {
|
public downloadKeys(userIds: string[], forceDownload: boolean): Promise<DeviceInfoMap> {
|
||||||
const usersToDownload = [];
|
const usersToDownload: string[] = [];
|
||||||
const promises = [];
|
const promises: Promise<unknown>[] = [];
|
||||||
|
|
||||||
userIds.forEach((u) => {
|
userIds.forEach((u) => {
|
||||||
const trackingStatus = this.deviceTrackingStatus[u];
|
const trackingStatus = this.deviceTrackingStatus[u];
|
||||||
@ -633,7 +633,7 @@ export class DeviceList extends EventEmitter {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const finished = (success) => {
|
const finished = (success: boolean): void => {
|
||||||
this.emit("crypto.willUpdateDevices", users, !this.hasFetched);
|
this.emit("crypto.willUpdateDevices", users, !this.hasFetched);
|
||||||
users.forEach((u) => {
|
users.forEach((u) => {
|
||||||
this.dirty = true;
|
this.dirty = true;
|
||||||
|
@ -37,7 +37,7 @@ export interface ISecretRequest {
|
|||||||
|
|
||||||
export interface IAccountDataClient extends EventEmitter {
|
export interface IAccountDataClient extends EventEmitter {
|
||||||
// Subset of MatrixClient (which also uses any for the event content)
|
// Subset of MatrixClient (which also uses any for the event content)
|
||||||
getAccountDataFromServer: (eventType: string) => Promise<Record<string, any>>;
|
getAccountDataFromServer: <T>(eventType: string) => Promise<T>;
|
||||||
getAccountData: (eventType: string) => MatrixEvent;
|
getAccountData: (eventType: string) => MatrixEvent;
|
||||||
setAccountData: (eventType: string, content: any) => Promise<{}>;
|
setAccountData: (eventType: string, content: any) => Promise<{}>;
|
||||||
}
|
}
|
||||||
@ -76,7 +76,7 @@ export class SecretStorage {
|
|||||||
) {}
|
) {}
|
||||||
|
|
||||||
public async getDefaultKeyId(): Promise<string> {
|
public async getDefaultKeyId(): Promise<string> {
|
||||||
const defaultKey = await this.accountDataAdapter.getAccountDataFromServer(
|
const defaultKey = await this.accountDataAdapter.getAccountDataFromServer<{ key: string }>(
|
||||||
'm.secret_storage.default_key',
|
'm.secret_storage.default_key',
|
||||||
);
|
);
|
||||||
if (!defaultKey) return null;
|
if (!defaultKey) return null;
|
||||||
@ -230,7 +230,7 @@ export class SecretStorage {
|
|||||||
* or null/undefined to use the default key.
|
* or null/undefined to use the default key.
|
||||||
*/
|
*/
|
||||||
public async store(name: string, secret: string, keys?: string[]): Promise<void> {
|
public async store(name: string, secret: string, keys?: string[]): Promise<void> {
|
||||||
const encrypted = {};
|
const encrypted: Record<string, IEncryptedPayload> = {};
|
||||||
|
|
||||||
if (!keys) {
|
if (!keys) {
|
||||||
const defaultKeyId = await this.getDefaultKeyId();
|
const defaultKeyId = await this.getDefaultKeyId();
|
||||||
@ -246,9 +246,9 @@ export class SecretStorage {
|
|||||||
|
|
||||||
for (const keyId of keys) {
|
for (const keyId of keys) {
|
||||||
// get key information from key storage
|
// get key information from key storage
|
||||||
const keyInfo = await this.accountDataAdapter.getAccountDataFromServer(
|
const keyInfo = await this.accountDataAdapter.getAccountDataFromServer<ISecretStorageKeyInfo>(
|
||||||
"m.secret_storage.key." + keyId,
|
"m.secret_storage.key." + keyId,
|
||||||
) as ISecretStorageKeyInfo;
|
);
|
||||||
if (!keyInfo) {
|
if (!keyInfo) {
|
||||||
throw new Error("Unknown key: " + keyId);
|
throw new Error("Unknown key: " + keyId);
|
||||||
}
|
}
|
||||||
@ -277,7 +277,7 @@ export class SecretStorage {
|
|||||||
* @return {string} the contents of the secret
|
* @return {string} the contents of the secret
|
||||||
*/
|
*/
|
||||||
public async get(name: string): Promise<string> {
|
public async get(name: string): Promise<string> {
|
||||||
const secretInfo = await this.accountDataAdapter.getAccountDataFromServer(name);
|
const secretInfo = await this.accountDataAdapter.getAccountDataFromServer<any>(name); // TODO types
|
||||||
if (!secretInfo) {
|
if (!secretInfo) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -286,11 +286,13 @@ export class SecretStorage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get possible keys to decrypt
|
// get possible keys to decrypt
|
||||||
const keys = {};
|
const keys: Record<string, ISecretStorageKeyInfo> = {};
|
||||||
for (const keyId of Object.keys(secretInfo.encrypted)) {
|
for (const keyId of Object.keys(secretInfo.encrypted)) {
|
||||||
// get key information from key storage
|
// get key information from key storage
|
||||||
const keyInfo = await this.accountDataAdapter.getAccountDataFromServer(
|
const keyInfo = (
|
||||||
"m.secret_storage.key." + keyId,
|
await this.accountDataAdapter.getAccountDataFromServer<ISecretStorageKeyInfo>(
|
||||||
|
"m.secret_storage.key." + keyId,
|
||||||
|
)
|
||||||
);
|
);
|
||||||
const encInfo = secretInfo.encrypted[keyId];
|
const encInfo = secretInfo.encrypted[keyId];
|
||||||
// only use keys we understand the encryption algorithm of
|
// only use keys we understand the encryption algorithm of
|
||||||
@ -306,7 +308,7 @@ export class SecretStorage {
|
|||||||
`the keys it is encrypted with are for a supported algorithm`);
|
`the keys it is encrypted with are for a supported algorithm`);
|
||||||
}
|
}
|
||||||
|
|
||||||
let keyId;
|
let keyId: string;
|
||||||
let decryption;
|
let decryption;
|
||||||
try {
|
try {
|
||||||
// fetch private key from app
|
// fetch private key from app
|
||||||
@ -337,7 +339,7 @@ export class SecretStorage {
|
|||||||
*/
|
*/
|
||||||
public async isStored(name: string, checkKey: boolean): Promise<Record<string, ISecretStorageKeyInfo>> {
|
public async isStored(name: string, checkKey: boolean): Promise<Record<string, ISecretStorageKeyInfo>> {
|
||||||
// check if secret exists
|
// check if secret exists
|
||||||
const secretInfo = await this.accountDataAdapter.getAccountDataFromServer(name);
|
const secretInfo = await this.accountDataAdapter.getAccountDataFromServer<any>(name); // TODO types
|
||||||
if (!secretInfo) return null;
|
if (!secretInfo) return null;
|
||||||
if (!secretInfo.encrypted) {
|
if (!secretInfo.encrypted) {
|
||||||
return null;
|
return null;
|
||||||
@ -350,7 +352,7 @@ export class SecretStorage {
|
|||||||
// filter secret encryption keys with supported algorithm
|
// filter secret encryption keys with supported algorithm
|
||||||
for (const keyId of Object.keys(secretInfo.encrypted)) {
|
for (const keyId of Object.keys(secretInfo.encrypted)) {
|
||||||
// get key information from key storage
|
// get key information from key storage
|
||||||
const keyInfo = await this.accountDataAdapter.getAccountDataFromServer(
|
const keyInfo = await this.accountDataAdapter.getAccountDataFromServer<any>( // TODO types
|
||||||
"m.secret_storage.key." + keyId,
|
"m.secret_storage.key." + keyId,
|
||||||
);
|
);
|
||||||
if (!keyInfo) continue;
|
if (!keyInfo) continue;
|
||||||
@ -375,8 +377,8 @@ export class SecretStorage {
|
|||||||
public request(name: string, devices: string[]): ISecretRequest {
|
public request(name: string, devices: string[]): ISecretRequest {
|
||||||
const requestId = this.baseApis.makeTxnId();
|
const requestId = this.baseApis.makeTxnId();
|
||||||
|
|
||||||
let resolve: (string) => void;
|
let resolve: (s: string) => void;
|
||||||
let reject: (Error) => void;
|
let reject: (e: Error) => void;
|
||||||
const promise = new Promise<string>((res, rej) => {
|
const promise = new Promise<string>((res, rej) => {
|
||||||
resolve = res;
|
resolve = res;
|
||||||
reject = rej;
|
reject = rej;
|
||||||
|
@ -46,7 +46,7 @@ type DecryptionClassParams = Omit<IParams, "deviceId" | "config">;
|
|||||||
*/
|
*/
|
||||||
export const DECRYPTION_CLASSES: Record<string, new (params: DecryptionClassParams) => DecryptionAlgorithm> = {};
|
export const DECRYPTION_CLASSES: Record<string, new (params: DecryptionClassParams) => DecryptionAlgorithm> = {};
|
||||||
|
|
||||||
interface IParams {
|
export interface IParams {
|
||||||
userId: string;
|
userId: string;
|
||||||
deviceId: string;
|
deviceId: string;
|
||||||
crypto: Crypto;
|
crypto: Crypto;
|
||||||
|
@ -26,6 +26,7 @@ import {
|
|||||||
DecryptionAlgorithm,
|
DecryptionAlgorithm,
|
||||||
DecryptionError,
|
DecryptionError,
|
||||||
EncryptionAlgorithm,
|
EncryptionAlgorithm,
|
||||||
|
IParams,
|
||||||
registerAlgorithm,
|
registerAlgorithm,
|
||||||
UnknownDeviceError,
|
UnknownDeviceError,
|
||||||
} from "./base";
|
} from "./base";
|
||||||
@ -99,6 +100,12 @@ interface IPayload extends Partial<IMessage> {
|
|||||||
algorithm?: string;
|
algorithm?: string;
|
||||||
sender_key?: string;
|
sender_key?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface IEncryptedContent {
|
||||||
|
algorithm: string;
|
||||||
|
sender_key: string;
|
||||||
|
ciphertext: Record<string, string>;
|
||||||
|
}
|
||||||
/* eslint-enable camelcase */
|
/* eslint-enable camelcase */
|
||||||
|
|
||||||
interface SharedWithData {
|
interface SharedWithData {
|
||||||
@ -238,7 +245,7 @@ class MegolmEncryption extends EncryptionAlgorithm {
|
|||||||
startTime: number;
|
startTime: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(params) {
|
constructor(params: IParams) {
|
||||||
super(params);
|
super(params);
|
||||||
|
|
||||||
this.sessionRotationPeriodMsgs = params.config?.rotation_period_msgs ?? 100;
|
this.sessionRotationPeriodMsgs = params.config?.rotation_period_msgs ?? 100;
|
||||||
@ -263,7 +270,7 @@ class MegolmEncryption extends EncryptionAlgorithm {
|
|||||||
blocked: IBlockedMap,
|
blocked: IBlockedMap,
|
||||||
singleOlmCreationPhase = false,
|
singleOlmCreationPhase = false,
|
||||||
): Promise<OutboundSessionInfo> {
|
): Promise<OutboundSessionInfo> {
|
||||||
let session;
|
let session: OutboundSessionInfo;
|
||||||
|
|
||||||
// takes the previous OutboundSessionInfo, and considers whether to create
|
// takes the previous OutboundSessionInfo, and considers whether to create
|
||||||
// a new one. Also shares the key with any (new) devices in the room.
|
// a new one. Also shares the key with any (new) devices in the room.
|
||||||
@ -302,7 +309,7 @@ class MegolmEncryption extends EncryptionAlgorithm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// now check if we need to share with any devices
|
// now check if we need to share with any devices
|
||||||
const shareMap = {};
|
const shareMap: Record<string, DeviceInfo[]> = {};
|
||||||
|
|
||||||
for (const [userId, userDevices] of Object.entries(devicesInRoom)) {
|
for (const [userId, userDevices] of Object.entries(devicesInRoom)) {
|
||||||
for (const [deviceId, deviceInfo] of Object.entries(userDevices)) {
|
for (const [deviceId, deviceInfo] of Object.entries(userDevices)) {
|
||||||
@ -350,7 +357,7 @@ class MegolmEncryption extends EncryptionAlgorithm {
|
|||||||
`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,
|
||||||
);
|
);
|
||||||
const errorDevices = [];
|
const errorDevices: IOlmDevice[] = [];
|
||||||
|
|
||||||
// meanwhile, establish olm sessions for devices that we don't
|
// meanwhile, establish olm sessions for devices that we don't
|
||||||
// already have a session for, and share keys with them. If
|
// already have a session for, and share keys with them. If
|
||||||
@ -358,7 +365,7 @@ class MegolmEncryption extends EncryptionAlgorithm {
|
|||||||
// shorter timeout when fetching one-time keys for the first
|
// shorter timeout when fetching one-time keys for the first
|
||||||
// phase.
|
// phase.
|
||||||
const start = Date.now();
|
const start = Date.now();
|
||||||
const failedServers = [];
|
const failedServers: string[] = [];
|
||||||
await this.shareKeyWithDevices(
|
await this.shareKeyWithDevices(
|
||||||
session, key, payload, devicesWithoutSession, errorDevices,
|
session, key, payload, devicesWithoutSession, errorDevices,
|
||||||
singleOlmCreationPhase ? 10000 : 2000, failedServers,
|
singleOlmCreationPhase ? 10000 : 2000, failedServers,
|
||||||
@ -374,7 +381,7 @@ class MegolmEncryption extends EncryptionAlgorithm {
|
|||||||
// 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
|
||||||
// do this. We only need to retry users from servers that didn't
|
// do this. We only need to retry users from servers that didn't
|
||||||
// respond the first time.
|
// respond the first time.
|
||||||
const retryDevices = {};
|
const retryDevices: Record<string, DeviceInfo[]> = {};
|
||||||
const failedServerMap = new Set;
|
const failedServerMap = new Set;
|
||||||
for (const server of failedServers) {
|
for (const server of failedServers) {
|
||||||
failedServerMap.add(server);
|
failedServerMap.add(server);
|
||||||
@ -584,12 +591,12 @@ class MegolmEncryption extends EncryptionAlgorithm {
|
|||||||
userDeviceMap: IOlmDevice[],
|
userDeviceMap: IOlmDevice[],
|
||||||
payload: IPayload,
|
payload: IPayload,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const contentMap = {};
|
const contentMap: Record<string, Record<string, IEncryptedContent>> = {};
|
||||||
const deviceInfoByDeviceId = new Map<string, DeviceInfo>();
|
const deviceInfoByDeviceId = new Map<string, DeviceInfo>();
|
||||||
|
|
||||||
const promises = [];
|
const promises: Promise<unknown>[] = [];
|
||||||
for (let i = 0; i < userDeviceMap.length; i++) {
|
for (let i = 0; i < userDeviceMap.length; i++) {
|
||||||
const encryptedContent = {
|
const encryptedContent: IEncryptedContent = {
|
||||||
algorithm: olmlib.OLM_ALGORITHM,
|
algorithm: olmlib.OLM_ALGORITHM,
|
||||||
sender_key: this.olmDevice.deviceCurve25519Key,
|
sender_key: this.olmDevice.deviceCurve25519Key,
|
||||||
ciphertext: {},
|
ciphertext: {},
|
||||||
@ -679,7 +686,7 @@ class MegolmEncryption extends EncryptionAlgorithm {
|
|||||||
userDeviceMap: IOlmDevice<IBlockedDevice>[],
|
userDeviceMap: IOlmDevice<IBlockedDevice>[],
|
||||||
payload: IPayload,
|
payload: IPayload,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const contentMap = {};
|
const contentMap: Record<string, Record<string, IPayload>> = {};
|
||||||
|
|
||||||
for (const val of userDeviceMap) {
|
for (const val of userDeviceMap) {
|
||||||
const userId = val.userId;
|
const userId = val.userId;
|
||||||
@ -1105,7 +1112,7 @@ class MegolmEncryption extends EncryptionAlgorithm {
|
|||||||
* devices we should shared the session with.
|
* devices we should shared the session with.
|
||||||
*/
|
*/
|
||||||
private checkForUnknownDevices(devicesInRoom: DeviceInfoMap): void {
|
private checkForUnknownDevices(devicesInRoom: DeviceInfoMap): void {
|
||||||
const unknownDevices = {};
|
const unknownDevices: Record<string, Record<string, DeviceInfo>> = {};
|
||||||
|
|
||||||
Object.keys(devicesInRoom).forEach((userId)=>{
|
Object.keys(devicesInRoom).forEach((userId)=>{
|
||||||
Object.keys(devicesInRoom[userId]).forEach((deviceId)=>{
|
Object.keys(devicesInRoom[userId]).forEach((deviceId)=>{
|
||||||
@ -1304,8 +1311,7 @@ class MegolmDecryption extends DecryptionAlgorithm {
|
|||||||
content.sender_key, event.getTs() - 120000,
|
content.sender_key, event.getTs() - 120000,
|
||||||
);
|
);
|
||||||
if (problem) {
|
if (problem) {
|
||||||
let problemDescription = PROBLEM_DESCRIPTIONS[problem.type]
|
let problemDescription = PROBLEM_DESCRIPTIONS[problem.type as "no_olm"] || PROBLEM_DESCRIPTIONS.unknown;
|
||||||
|| PROBLEM_DESCRIPTIONS.unknown;
|
|
||||||
if (problem.fixed) {
|
if (problem.fixed) {
|
||||||
problemDescription +=
|
problemDescription +=
|
||||||
" Trying to create a new secure channel and re-requesting the keys.";
|
" Trying to create a new secure channel and re-requesting the keys.";
|
||||||
@ -1399,14 +1405,14 @@ class MegolmDecryption extends DecryptionAlgorithm {
|
|||||||
const senderKey = content.sender_key;
|
const senderKey = content.sender_key;
|
||||||
const sessionId = content.session_id;
|
const sessionId = content.session_id;
|
||||||
const senderPendingEvents = this.pendingEvents[senderKey];
|
const senderPendingEvents = this.pendingEvents[senderKey];
|
||||||
const pendingEvents = senderPendingEvents && senderPendingEvents.get(sessionId);
|
const pendingEvents = senderPendingEvents?.get(sessionId);
|
||||||
if (!pendingEvents) {
|
if (!pendingEvents) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pendingEvents.delete(event);
|
pendingEvents.delete(event);
|
||||||
if (pendingEvents.size === 0) {
|
if (pendingEvents.size === 0) {
|
||||||
senderPendingEvents.delete(senderKey);
|
senderPendingEvents.delete(sessionId);
|
||||||
}
|
}
|
||||||
if (senderPendingEvents.size === 0) {
|
if (senderPendingEvents.size === 0) {
|
||||||
delete this.pendingEvents[senderKey];
|
delete this.pendingEvents[senderKey];
|
||||||
@ -1760,7 +1766,7 @@ class MegolmDecryption extends DecryptionAlgorithm {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
// If decrypted successfully, they'll have been removed from pendingEvents
|
// If decrypted successfully, they'll have been removed from pendingEvents
|
||||||
return !((this.pendingEvents[senderKey] || {})[sessionId]);
|
return !this.pendingEvents[senderKey]?.has(sessionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async retryDecryptionFromSender(senderKey: string): Promise<boolean> {
|
public async retryDecryptionFromSender(senderKey: string): Promise<boolean> {
|
||||||
@ -1794,12 +1800,12 @@ class MegolmDecryption extends DecryptionAlgorithm {
|
|||||||
for (const [senderKey, sessionId] of sharedHistorySessions) {
|
for (const [senderKey, sessionId] of sharedHistorySessions) {
|
||||||
const payload = await this.buildKeyForwardingMessage(this.roomId, senderKey, sessionId);
|
const payload = await this.buildKeyForwardingMessage(this.roomId, senderKey, sessionId);
|
||||||
|
|
||||||
const promises = [];
|
const promises: Promise<unknown>[] = [];
|
||||||
const contentMap = {};
|
const contentMap: Record<string, Record<string, IEncryptedContent>> = {};
|
||||||
for (const [userId, devices] of Object.entries(devicesByUser)) {
|
for (const [userId, devices] of Object.entries(devicesByUser)) {
|
||||||
contentMap[userId] = {};
|
contentMap[userId] = {};
|
||||||
for (const deviceInfo of devices) {
|
for (const deviceInfo of devices) {
|
||||||
const encryptedContent = {
|
const encryptedContent: IEncryptedContent = {
|
||||||
algorithm: olmlib.OLM_ALGORITHM,
|
algorithm: olmlib.OLM_ALGORITHM,
|
||||||
sender_key: this.olmDevice.deviceCurve25519Key,
|
sender_key: this.olmDevice.deviceCurve25519Key,
|
||||||
ciphertext: {},
|
ciphertext: {},
|
||||||
|
@ -282,7 +282,7 @@ class OlmDecryption extends DecryptionAlgorithm {
|
|||||||
const sessionIds = await this.olmDevice.getSessionIdsForDevice(theirDeviceIdentityKey);
|
const sessionIds = await this.olmDevice.getSessionIdsForDevice(theirDeviceIdentityKey);
|
||||||
|
|
||||||
// try each session in turn.
|
// try each session in turn.
|
||||||
const decryptionErrors = {};
|
const decryptionErrors: Record<string, string> = {};
|
||||||
for (let i = 0; i < sessionIds.length; i++) {
|
for (let i = 0; i < sessionIds.length; i++) {
|
||||||
const sessionId = sessionIds[i];
|
const sessionId = sessionIds[i];
|
||||||
try {
|
try {
|
||||||
|
@ -58,7 +58,7 @@ import { BackupManager } from "./backup";
|
|||||||
import { IStore } from "../store";
|
import { IStore } from "../store";
|
||||||
import { Room } from "../models/room";
|
import { Room } from "../models/room";
|
||||||
import { RoomMember } from "../models/room-member";
|
import { RoomMember } from "../models/room-member";
|
||||||
import { MatrixEvent, EventStatus } from "../models/event";
|
import { MatrixEvent, EventStatus, IClearEvent } from "../models/event";
|
||||||
import { MatrixClient, IKeysUploadResponse, SessionStore, ISignedKey, ICrossSigningKey } from "../client";
|
import { MatrixClient, IKeysUploadResponse, SessionStore, ISignedKey, ICrossSigningKey } from "../client";
|
||||||
import type { EncryptionAlgorithm, DecryptionAlgorithm } from "./algorithms/base";
|
import type { EncryptionAlgorithm, DecryptionAlgorithm } from "./algorithms/base";
|
||||||
import type { IRoomEncryption, RoomList } from "./RoomList";
|
import type { IRoomEncryption, RoomList } from "./RoomList";
|
||||||
@ -172,10 +172,10 @@ interface ISignableObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface IEventDecryptionResult {
|
export interface IEventDecryptionResult {
|
||||||
clearEvent: object;
|
clearEvent: IClearEvent;
|
||||||
|
forwardingCurve25519KeyChain?: string[];
|
||||||
senderCurve25519Key?: string;
|
senderCurve25519Key?: string;
|
||||||
claimedEd25519Key?: string;
|
claimedEd25519Key?: string;
|
||||||
forwardingCurve25519KeyChain?: string[];
|
|
||||||
untrusted?: boolean;
|
untrusted?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,5 +67,5 @@ export interface IKeyBackupRestoreResult {
|
|||||||
|
|
||||||
export interface IKeyBackupRestoreOpts {
|
export interface IKeyBackupRestoreOpts {
|
||||||
cacheCompleteCallback?: () => void;
|
cacheCompleteCallback?: () => void;
|
||||||
progressCallback?: ({ stage: string }) => void;
|
progressCallback?: (progress: { stage: string }) => void;
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,6 @@ import { Logger } from "loglevel";
|
|||||||
import { OlmDevice } from "./OlmDevice";
|
import { OlmDevice } from "./OlmDevice";
|
||||||
import { DeviceInfo } from "./deviceinfo";
|
import { DeviceInfo } from "./deviceinfo";
|
||||||
import { logger } from '../logger';
|
import { logger } from '../logger';
|
||||||
import * as utils from "../utils";
|
|
||||||
import { IOneTimeKey } from "./dehydration";
|
import { IOneTimeKey } from "./dehydration";
|
||||||
import { MatrixClient } from "../client";
|
import { MatrixClient } from "../client";
|
||||||
|
|
||||||
@ -126,7 +125,7 @@ export async function encryptMessageForDevice(
|
|||||||
// involved in the session. If we're looking to reduce data transfer in the
|
// involved in the session. If we're looking to reduce data transfer in the
|
||||||
// future, we could elide them for subsequent messages.
|
// future, we could elide them for subsequent messages.
|
||||||
|
|
||||||
utils.extend(payload, payloadFields);
|
Object.assign(payload, payloadFields);
|
||||||
|
|
||||||
resultsObject[deviceKey] = await olmDevice.encryptMessage(
|
resultsObject[deviceKey] = await olmDevice.encryptMessage(
|
||||||
deviceKey, sessionId, JSON.stringify(payload),
|
deviceKey, sessionId, JSON.stringify(payload),
|
||||||
|
@ -36,7 +36,7 @@ const M_RELATES_TO = "m.relates_to";
|
|||||||
* Uses the event id of the initial m.key.verification.request event as a transaction id.
|
* Uses the event id of the initial m.key.verification.request event as a transaction id.
|
||||||
*/
|
*/
|
||||||
export class InRoomChannel implements IVerificationChannel {
|
export class InRoomChannel implements IVerificationChannel {
|
||||||
private requestEventId = null;
|
private requestEventId: string = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {MatrixClient} client the matrix client, to send messages with and get current user & device from.
|
* @param {MatrixClient} client the matrix client, to send messages with and get current user & device from.
|
||||||
|
@ -657,7 +657,7 @@ MatrixHttpApi.prototype = {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const headers = utils.extend({}, opts.headers || {});
|
const headers = Object.assign({}, opts.headers || {});
|
||||||
const json = opts.json === undefined ? true : opts.json;
|
const json = opts.json === undefined ? true : opts.json;
|
||||||
let bodyParser = opts.bodyParser;
|
let bodyParser = opts.bodyParser;
|
||||||
|
|
||||||
|
@ -18,7 +18,6 @@ limitations under the License.
|
|||||||
|
|
||||||
/** @module interactive-auth */
|
/** @module interactive-auth */
|
||||||
|
|
||||||
import * as utils from "./utils";
|
|
||||||
import { logger } from './logger';
|
import { logger } from './logger';
|
||||||
import { MatrixClient } from "./client";
|
import { MatrixClient } from "./client";
|
||||||
import { defer, IDeferred } from "./utils";
|
import { defer, IDeferred } from "./utils";
|
||||||
@ -68,7 +67,7 @@ export enum AuthType {
|
|||||||
export interface IAuthDict {
|
export interface IAuthDict {
|
||||||
// [key: string]: any;
|
// [key: string]: any;
|
||||||
type?: string;
|
type?: string;
|
||||||
// session?: string; // TODO
|
session?: string;
|
||||||
// TODO: Remove `user` once servers support proper UIA
|
// TODO: Remove `user` once servers support proper UIA
|
||||||
// See https://github.com/vector-im/element-web/issues/10312
|
// See https://github.com/vector-im/element-web/issues/10312
|
||||||
user?: string;
|
user?: string;
|
||||||
@ -360,12 +359,12 @@ export class InteractiveAuth {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// use the sessionid from the last request, if one is present.
|
// use the sessionid from the last request, if one is present.
|
||||||
let auth;
|
let auth: IAuthDict;
|
||||||
if (this.data.session) {
|
if (this.data.session) {
|
||||||
auth = {
|
auth = {
|
||||||
session: this.data.session,
|
session: this.data.session,
|
||||||
};
|
};
|
||||||
utils.extend(auth, authData);
|
Object.assign(auth, authData);
|
||||||
} else {
|
} else {
|
||||||
auth = authData;
|
auth = authData;
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,7 @@ function extendLogger(logger: PrefixedLogger) {
|
|||||||
|
|
||||||
extendLogger(logger);
|
extendLogger(logger);
|
||||||
|
|
||||||
function getPrefixedLogger(prefix): PrefixedLogger {
|
function getPrefixedLogger(prefix: string): PrefixedLogger {
|
||||||
const prefixLogger: PrefixedLogger = log.getLogger(`${DEFAULT_NAMESPACE}-${prefix}`);
|
const prefixLogger: PrefixedLogger = log.getLogger(`${DEFAULT_NAMESPACE}-${prefix}`);
|
||||||
if (prefixLogger.prefix !== prefix) {
|
if (prefixLogger.prefix !== prefix) {
|
||||||
// Only do this setup work the first time through, as loggers are saved by name.
|
// Only do this setup work the first time through, as loggers are saved by name.
|
||||||
|
@ -121,7 +121,7 @@ export interface ICryptoCallbacks {
|
|||||||
) => Promise<string>;
|
) => Promise<string>;
|
||||||
getDehydrationKey?: (
|
getDehydrationKey?: (
|
||||||
keyInfo: ISecretStorageKeyInfo,
|
keyInfo: ISecretStorageKeyInfo,
|
||||||
checkFunc: (Uint8Array) => void,
|
checkFunc: (key: Uint8Array) => void,
|
||||||
) => Promise<Uint8Array>;
|
) => Promise<Uint8Array>;
|
||||||
getBackupKey?: () => Promise<Uint8Array>;
|
getBackupKey?: () => Promise<Uint8Array>;
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ import { Thread } from "./thread";
|
|||||||
// var DEBUG = false;
|
// var DEBUG = false;
|
||||||
const DEBUG = true;
|
const DEBUG = true;
|
||||||
|
|
||||||
let debuglog;
|
let debuglog: (...args: any[]) => void;
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
// using bind means that we get to keep useful line numbers in the console
|
// using bind means that we get to keep useful line numbers in the console
|
||||||
debuglog = logger.log.bind(logger);
|
debuglog = logger.log.bind(logger);
|
||||||
|
@ -29,7 +29,7 @@ import {
|
|||||||
MsgType,
|
MsgType,
|
||||||
RelationType,
|
RelationType,
|
||||||
} from "../@types/event";
|
} from "../@types/event";
|
||||||
import { Crypto } from "../crypto";
|
import { Crypto, IEventDecryptionResult } from "../crypto";
|
||||||
import { deepSortedObjectEntries } from "../utils";
|
import { deepSortedObjectEntries } from "../utils";
|
||||||
import { RoomMember } from "./room-member";
|
import { RoomMember } from "./room-member";
|
||||||
import { Thread, ThreadEvent } from "./thread";
|
import { Thread, ThreadEvent } from "./thread";
|
||||||
@ -85,7 +85,7 @@ export interface IUnsigned {
|
|||||||
age?: number;
|
age?: number;
|
||||||
prev_sender?: string;
|
prev_sender?: string;
|
||||||
prev_content?: IContent;
|
prev_content?: IContent;
|
||||||
redacted_because?: IEvent;
|
redacted_because?: IClearEvent;
|
||||||
transaction_id?: string;
|
transaction_id?: string;
|
||||||
invite_room_state?: StrippedState[];
|
invite_room_state?: StrippedState[];
|
||||||
}
|
}
|
||||||
@ -124,25 +124,13 @@ export interface IEventRelation {
|
|||||||
key?: string;
|
key?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IDecryptionResult {
|
|
||||||
clearEvent: {
|
|
||||||
room_id?: string;
|
|
||||||
type: string;
|
|
||||||
content: IContent;
|
|
||||||
unsigned?: IUnsigned;
|
|
||||||
};
|
|
||||||
forwardingCurve25519KeyChain?: string[];
|
|
||||||
senderCurve25519Key?: string;
|
|
||||||
claimedEd25519Key?: string;
|
|
||||||
untrusted?: boolean;
|
|
||||||
}
|
|
||||||
/* eslint-enable camelcase */
|
|
||||||
|
|
||||||
export interface IClearEvent {
|
export interface IClearEvent {
|
||||||
|
room_id?: string;
|
||||||
type: string;
|
type: string;
|
||||||
content: Omit<IContent, "membership" | "avatar_url" | "displayname" | "m.relates_to">;
|
content: Omit<IContent, "membership" | "avatar_url" | "displayname" | "m.relates_to">;
|
||||||
unsigned?: IUnsigned;
|
unsigned?: IUnsigned;
|
||||||
}
|
}
|
||||||
|
/* eslint-enable camelcase */
|
||||||
|
|
||||||
interface IKeyRequestRecipient {
|
interface IKeyRequestRecipient {
|
||||||
userId: string;
|
userId: string;
|
||||||
@ -215,14 +203,14 @@ export class MatrixEvent extends EventEmitter {
|
|||||||
public sender: RoomMember = null;
|
public sender: RoomMember = null;
|
||||||
public target: RoomMember = null;
|
public target: RoomMember = null;
|
||||||
public status: EventStatus = null;
|
public status: EventStatus = null;
|
||||||
public error = null;
|
public error: Error = null;
|
||||||
public forwardLooking = true;
|
public forwardLooking = true;
|
||||||
|
|
||||||
/* If the event is a `m.key.verification.request` (or to_device `m.key.verification.start`) event,
|
/* If the event is a `m.key.verification.request` (or to_device `m.key.verification.start`) event,
|
||||||
* `Crypto` will set this the `VerificationRequest` for the event
|
* `Crypto` will set this the `VerificationRequest` for the event
|
||||||
* so it can be easily accessed from the timeline.
|
* so it can be easily accessed from the timeline.
|
||||||
*/
|
*/
|
||||||
public verificationRequest = null;
|
public verificationRequest: VerificationRequest = null;
|
||||||
|
|
||||||
private readonly reEmitter: ReEmitter;
|
private readonly reEmitter: ReEmitter;
|
||||||
|
|
||||||
@ -690,8 +678,8 @@ export class MatrixEvent extends EventEmitter {
|
|||||||
while (true) {
|
while (true) {
|
||||||
this.retryDecryption = false;
|
this.retryDecryption = false;
|
||||||
|
|
||||||
let res;
|
let res: IEventDecryptionResult;
|
||||||
let err;
|
let err: Error;
|
||||||
try {
|
try {
|
||||||
if (!crypto) {
|
if (!crypto) {
|
||||||
res = this.badEncryptedMessage("Encryption not enabled");
|
res = this.badEncryptedMessage("Encryption not enabled");
|
||||||
@ -779,7 +767,7 @@ export class MatrixEvent extends EventEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private badEncryptedMessage(reason: string): IDecryptionResult {
|
private badEncryptedMessage(reason: string): IEventDecryptionResult {
|
||||||
return {
|
return {
|
||||||
clearEvent: {
|
clearEvent: {
|
||||||
type: "m.room.message",
|
type: "m.room.message",
|
||||||
@ -803,7 +791,7 @@ export class MatrixEvent extends EventEmitter {
|
|||||||
* @param {module:crypto~EventDecryptionResult} decryptionResult
|
* @param {module:crypto~EventDecryptionResult} decryptionResult
|
||||||
* the decryption result, including the plaintext and some key info
|
* the decryption result, including the plaintext and some key info
|
||||||
*/
|
*/
|
||||||
private setClearData(decryptionResult: IDecryptionResult): void {
|
private setClearData(decryptionResult: IEventDecryptionResult): void {
|
||||||
this.clearEvent = decryptionResult.clearEvent;
|
this.clearEvent = decryptionResult.clearEvent;
|
||||||
this.senderCurve25519Key =
|
this.senderCurve25519Key =
|
||||||
decryptionResult.senderCurve25519Key || null;
|
decryptionResult.senderCurve25519Key || null;
|
||||||
|
@ -48,19 +48,19 @@ const SAFE_ROOM_VERSIONS = ['1', '2', '3', '4', '5', '6'];
|
|||||||
|
|
||||||
function synthesizeReceipt(userId: string, event: MatrixEvent, receiptType: string): MatrixEvent {
|
function synthesizeReceipt(userId: string, event: MatrixEvent, receiptType: string): MatrixEvent {
|
||||||
// console.log("synthesizing receipt for "+event.getId());
|
// console.log("synthesizing receipt for "+event.getId());
|
||||||
// This is really ugly because JS has no way to express an object literal
|
return new MatrixEvent({
|
||||||
// where the name of a key comes from an expression
|
content: {
|
||||||
const fakeReceipt = {
|
[event.getId()]: {
|
||||||
content: {},
|
[receiptType]: {
|
||||||
|
[userId]: {
|
||||||
|
ts: event.getTs(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
type: "m.receipt",
|
type: "m.receipt",
|
||||||
room_id: event.getRoomId(),
|
room_id: event.getRoomId(),
|
||||||
};
|
});
|
||||||
fakeReceipt.content[event.getId()] = {};
|
|
||||||
fakeReceipt.content[event.getId()][receiptType] = {};
|
|
||||||
fakeReceipt.content[event.getId()][receiptType][userId] = {
|
|
||||||
ts: event.getTs(),
|
|
||||||
};
|
|
||||||
return new MatrixEvent(fakeReceipt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IOpts {
|
interface IOpts {
|
||||||
@ -240,7 +240,7 @@ export class Room extends EventEmitter {
|
|||||||
const serializedPendingEventList = client.sessionStore.store.getItem(pendingEventsKey(this.roomId));
|
const serializedPendingEventList = client.sessionStore.store.getItem(pendingEventsKey(this.roomId));
|
||||||
if (serializedPendingEventList) {
|
if (serializedPendingEventList) {
|
||||||
JSON.parse(serializedPendingEventList)
|
JSON.parse(serializedPendingEventList)
|
||||||
.forEach(async serializedEvent => {
|
.forEach(async (serializedEvent: Partial<IEvent>) => {
|
||||||
const event = new MatrixEvent(serializedEvent);
|
const event = new MatrixEvent(serializedEvent);
|
||||||
if (event.getType() === EventType.RoomMessageEncrypted) {
|
if (event.getType() === EventType.RoomMessageEncrypted) {
|
||||||
await event.attemptDecryption(this.client.crypto);
|
await event.attemptDecryption(this.client.crypto);
|
||||||
@ -997,14 +997,14 @@ export class Room extends EventEmitter {
|
|||||||
* @return {array} The room's alias as an array of strings
|
* @return {array} The room's alias as an array of strings
|
||||||
*/
|
*/
|
||||||
public getAliases(): string[] {
|
public getAliases(): string[] {
|
||||||
const aliasStrings = [];
|
const aliasStrings: string[] = [];
|
||||||
|
|
||||||
const aliasEvents = this.currentState.getStateEvents(EventType.RoomAliases);
|
const aliasEvents = this.currentState.getStateEvents(EventType.RoomAliases);
|
||||||
if (aliasEvents) {
|
if (aliasEvents) {
|
||||||
for (let i = 0; i < aliasEvents.length; ++i) {
|
for (let i = 0; i < aliasEvents.length; ++i) {
|
||||||
const aliasEvent = aliasEvents[i];
|
const aliasEvent = aliasEvents[i];
|
||||||
if (Array.isArray(aliasEvent.getContent().aliases)) {
|
if (Array.isArray(aliasEvent.getContent().aliases)) {
|
||||||
const filteredAliases = aliasEvent.getContent().aliases.filter(a => {
|
const filteredAliases = aliasEvent.getContent<{ aliases: string[] }>().aliases.filter(a => {
|
||||||
if (typeof(a) !== "string") return false;
|
if (typeof(a) !== "string") return false;
|
||||||
if (a[0] !== '#') return false;
|
if (a[0] !== '#') return false;
|
||||||
if (!a.endsWith(`:${aliasEvent.getStateKey()}`)) return false;
|
if (!a.endsWith(`:${aliasEvent.getStateKey()}`)) return false;
|
||||||
@ -1992,7 +1992,7 @@ export class Room extends EventEmitter {
|
|||||||
* @return {Object} Map of receipts by event ID
|
* @return {Object} Map of receipts by event ID
|
||||||
*/
|
*/
|
||||||
private buildReceiptCache(receipts: Receipts): ReceiptCache {
|
private buildReceiptCache(receipts: Receipts): ReceiptCache {
|
||||||
const receiptCacheByEventId = {};
|
const receiptCacheByEventId: ReceiptCache = {};
|
||||||
Object.keys(receipts).forEach(function(receiptType) {
|
Object.keys(receipts).forEach(function(receiptType) {
|
||||||
Object.keys(receipts[receiptType]).forEach(function(userId) {
|
Object.keys(receipts[receiptType]).forEach(function(userId) {
|
||||||
const receipt = receipts[receiptType][userId];
|
const receipt = receipts[receiptType][userId];
|
||||||
@ -2185,7 +2185,7 @@ export class Room extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get members that are NOT ourselves and are actually in the room.
|
// get members that are NOT ourselves and are actually in the room.
|
||||||
let otherNames = null;
|
let otherNames: string[] = null;
|
||||||
if (this.summaryHeroes) {
|
if (this.summaryHeroes) {
|
||||||
// if we have a summary, the member state events
|
// if we have a summary, the member state events
|
||||||
// should be in the room state
|
// should be in the room state
|
||||||
@ -2266,31 +2266,29 @@ function pendingEventsKey(roomId: string): string {
|
|||||||
|
|
||||||
/* a map from current event status to a list of allowed next statuses
|
/* a map from current event status to a list of allowed next statuses
|
||||||
*/
|
*/
|
||||||
const ALLOWED_TRANSITIONS = {};
|
const ALLOWED_TRANSITIONS: Record<EventStatus, EventStatus[]> = {
|
||||||
|
[EventStatus.ENCRYPTING]: [
|
||||||
ALLOWED_TRANSITIONS[EventStatus.ENCRYPTING] = [
|
EventStatus.SENDING,
|
||||||
EventStatus.SENDING,
|
EventStatus.NOT_SENT,
|
||||||
EventStatus.NOT_SENT,
|
],
|
||||||
];
|
[EventStatus.SENDING]: [
|
||||||
|
EventStatus.ENCRYPTING,
|
||||||
ALLOWED_TRANSITIONS[EventStatus.SENDING] = [
|
EventStatus.QUEUED,
|
||||||
EventStatus.ENCRYPTING,
|
EventStatus.NOT_SENT,
|
||||||
EventStatus.QUEUED,
|
EventStatus.SENT,
|
||||||
EventStatus.NOT_SENT,
|
],
|
||||||
EventStatus.SENT,
|
[EventStatus.QUEUED]: [
|
||||||
];
|
EventStatus.SENDING,
|
||||||
|
EventStatus.CANCELLED,
|
||||||
ALLOWED_TRANSITIONS[EventStatus.QUEUED] =
|
],
|
||||||
[EventStatus.SENDING, EventStatus.CANCELLED];
|
[EventStatus.SENT]: [],
|
||||||
|
[EventStatus.NOT_SENT]: [
|
||||||
ALLOWED_TRANSITIONS[EventStatus.SENT] =
|
EventStatus.SENDING,
|
||||||
[];
|
EventStatus.QUEUED,
|
||||||
|
EventStatus.CANCELLED,
|
||||||
ALLOWED_TRANSITIONS[EventStatus.NOT_SENT] =
|
],
|
||||||
[EventStatus.SENDING, EventStatus.QUEUED, EventStatus.CANCELLED];
|
[EventStatus.CANCELLED]: [],
|
||||||
|
};
|
||||||
ALLOWED_TRANSITIONS[EventStatus.CANCELLED] =
|
|
||||||
[];
|
|
||||||
|
|
||||||
// TODO i18n
|
// TODO i18n
|
||||||
function memberNamesToRoomName(names: string[], count = (names.length + 1)) {
|
function memberNamesToRoomName(names: string[], count = (names.length + 1)) {
|
||||||
|
@ -284,7 +284,7 @@ export class MatrixScheduler<T = ISendEventResponse> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function debuglog(...args) {
|
function debuglog(...args: any[]) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
logger.log(...args);
|
logger.log(...args);
|
||||||
}
|
}
|
||||||
|
@ -51,14 +51,14 @@ export interface IStore {
|
|||||||
* Set the sync token.
|
* Set the sync token.
|
||||||
* @param {string} token
|
* @param {string} token
|
||||||
*/
|
*/
|
||||||
setSyncToken(token: string);
|
setSyncToken(token: string): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* No-op.
|
* No-op.
|
||||||
* @param {Group} group
|
* @param {Group} group
|
||||||
* @deprecated groups/communities never made it to the spec and support for them is being discontinued.
|
* @deprecated groups/communities never made it to the spec and support for them is being discontinued.
|
||||||
*/
|
*/
|
||||||
storeGroup(group: Group);
|
storeGroup(group: Group): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* No-op.
|
* No-op.
|
||||||
@ -79,7 +79,7 @@ export interface IStore {
|
|||||||
* No-op.
|
* No-op.
|
||||||
* @param {Room} room
|
* @param {Room} room
|
||||||
*/
|
*/
|
||||||
storeRoom(room: Room);
|
storeRoom(room: Room): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* No-op.
|
* No-op.
|
||||||
@ -98,7 +98,7 @@ export interface IStore {
|
|||||||
* Permanently delete a room.
|
* Permanently delete a room.
|
||||||
* @param {string} roomId
|
* @param {string} roomId
|
||||||
*/
|
*/
|
||||||
removeRoom(roomId: string);
|
removeRoom(roomId: string): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* No-op.
|
* No-op.
|
||||||
@ -110,7 +110,7 @@ export interface IStore {
|
|||||||
* No-op.
|
* No-op.
|
||||||
* @param {User} user
|
* @param {User} user
|
||||||
*/
|
*/
|
||||||
storeUser(user: User);
|
storeUser(user: User): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* No-op.
|
* No-op.
|
||||||
@ -140,13 +140,13 @@ export interface 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.
|
||||||
*/
|
*/
|
||||||
storeEvents(room: Room, events: MatrixEvent[], token: string, toStart: boolean);
|
storeEvents(room: Room, events: MatrixEvent[], token: string, toStart: boolean): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store a filter.
|
* Store a filter.
|
||||||
* @param {Filter} filter
|
* @param {Filter} filter
|
||||||
*/
|
*/
|
||||||
storeFilter(filter: Filter);
|
storeFilter(filter: Filter): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve a filter.
|
* Retrieve a filter.
|
||||||
@ -168,13 +168,13 @@ export interface IStore {
|
|||||||
* @param {string} filterName
|
* @param {string} filterName
|
||||||
* @param {string} filterId
|
* @param {string} filterId
|
||||||
*/
|
*/
|
||||||
setFilterIdByName(filterName: string, filterId: string);
|
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.
|
||||||
*/
|
*/
|
||||||
storeAccountDataEvents(events: MatrixEvent[]);
|
storeAccountDataEvents(events: MatrixEvent[]): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get account data event by event type
|
* Get account data event by event type
|
||||||
|
@ -66,7 +66,7 @@ function selectQuery<T>(
|
|||||||
): Promise<T[]> {
|
): Promise<T[]> {
|
||||||
const query = store.openCursor(keyRange);
|
const query = store.openCursor(keyRange);
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const results = [];
|
const results: T[] = [];
|
||||||
query.onerror = () => {
|
query.onerror = () => {
|
||||||
reject(new Error("Query failed: " + query.error));
|
reject(new Error("Query failed: " + query.error));
|
||||||
};
|
};
|
||||||
@ -238,7 +238,7 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend {
|
|||||||
const range = IDBKeyRange.only(roomId);
|
const range = IDBKeyRange.only(roomId);
|
||||||
const request = roomIndex.openCursor(range);
|
const request = roomIndex.openCursor(range);
|
||||||
|
|
||||||
const membershipEvents = [];
|
const membershipEvents: IEvent[] = [];
|
||||||
// did we encounter the oob_written marker object
|
// did we encounter the oob_written marker object
|
||||||
// amongst the results? That means OOB member
|
// amongst the results? That means OOB member
|
||||||
// loading already happened for this room
|
// loading already happened for this room
|
||||||
|
36
src/utils.ts
36
src/utils.ts
@ -90,23 +90,20 @@ export function removeElement<T>(
|
|||||||
array: T[],
|
array: T[],
|
||||||
fn: (t: T, i?: number, a?: T[]) => boolean,
|
fn: (t: T, i?: number, a?: T[]) => boolean,
|
||||||
reverse?: boolean,
|
reverse?: boolean,
|
||||||
) {
|
): boolean {
|
||||||
let i;
|
let i: number;
|
||||||
let removed;
|
|
||||||
if (reverse) {
|
if (reverse) {
|
||||||
for (i = array.length - 1; i >= 0; i--) {
|
for (i = array.length - 1; i >= 0; i--) {
|
||||||
if (fn(array[i], i, array)) {
|
if (fn(array[i], i, array)) {
|
||||||
removed = array[i];
|
|
||||||
array.splice(i, 1);
|
array.splice(i, 1);
|
||||||
return removed;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (i = 0; i < array.length; i++) {
|
for (i = 0; i < array.length; i++) {
|
||||||
if (fn(array[i], i, array)) {
|
if (fn(array[i], i, array)) {
|
||||||
removed = array[i];
|
|
||||||
array.splice(i, 1);
|
array.splice(i, 1);
|
||||||
return removed;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -276,31 +273,6 @@ export function deepSortedObjectEntries(obj: any): [string, any][] {
|
|||||||
return pairs;
|
return pairs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy properties from one object to another.
|
|
||||||
*
|
|
||||||
* All enumerable properties, included inherited ones, are copied.
|
|
||||||
*
|
|
||||||
* This is approximately equivalent to ES6's Object.assign, except
|
|
||||||
* that the latter doesn't copy inherited properties.
|
|
||||||
*
|
|
||||||
* @param {Object} target The object that will receive new properties
|
|
||||||
* @param {...Object} source Objects from which to copy properties
|
|
||||||
*
|
|
||||||
* @return {Object} target
|
|
||||||
*/
|
|
||||||
export function extend(...restParams) {
|
|
||||||
const target = restParams[0] || {};
|
|
||||||
for (let i = 1; i < restParams.length; i++) {
|
|
||||||
const source = restParams[i];
|
|
||||||
if (!source) continue;
|
|
||||||
for (const propName in source) { // eslint-disable-line guard-for-in
|
|
||||||
target[propName] = source[propName];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inherit the prototype methods from one constructor into another. This is a
|
* Inherit the prototype methods from one constructor into another. This is a
|
||||||
* port of the Node.js implementation with an Object.create polyfill.
|
* port of the Node.js implementation with an Object.create polyfill.
|
||||||
|
Reference in New Issue
Block a user