diff --git a/changelog.d/842.bugfix b/changelog.d/842.bugfix new file mode 100644 index 00000000..3101d65d --- /dev/null +++ b/changelog.d/842.bugfix @@ -0,0 +1 @@ +Remove usage of unreliable field `age` on events, allowing the bridge to work with non-Synapse homeserver implementations. \ No newline at end of file diff --git a/src/matrixeventprocessor.ts b/src/matrixeventprocessor.ts index 6fa4fd99..f1f46115 100644 --- a/src/matrixeventprocessor.ts +++ b/src/matrixeventprocessor.ts @@ -91,11 +91,9 @@ export class MatrixEventProcessor { */ public async OnEvent(event: IMatrixEvent, rooms: IRoomStoreEntry[]): Promise { const remoteRoom = rooms[0]; - if (event.unsigned.age > AGE_LIMIT) { - log.info(`Skipping event due to age ${event.unsigned.age} > ${AGE_LIMIT}`); - // throw new Unstable.EventTooOldError( - // `Skipping event due to age ${event.unsigned.age} > ${AGE_LIMIT}`, - // ); + const age = Date.now() - event.origin_server_ts; + if (age > AGE_LIMIT) { + log.info(`Skipping event due to age ${age} > ${AGE_LIMIT}`); return; } if ( @@ -247,8 +245,8 @@ export class MatrixEventProcessor { } else if (event.type === "m.room.member") { const membership = event.content!.membership; const client = this.bridge.botIntent.underlyingClient; - const isNewJoin = event.unsigned.replaces_state === undefined ? true : ( - await client.getEvent(event.room_id, event.unsigned.replaces_state)).content.membership !== "join"; + const isNewJoin = event.unsigned?.replaces_state === undefined ? true : ( + await client.getEvent(event.room_id, event.unsigned?.replaces_state)).content.membership !== "join"; if (membership === "join") { this.mxUserProfileCache.delete(`${event.room_id}:${event.sender}`); this.mxUserProfileCache.delete(event.sender); diff --git a/src/matrixtypes.ts b/src/matrixtypes.ts index 439d7343..fd09cd84 100644 --- a/src/matrixtypes.ts +++ b/src/matrixtypes.ts @@ -40,11 +40,13 @@ export interface IMatrixEvent { redacts?: string; replaces_state?: string; content?: IMatrixEventContent; - unsigned?: any; // tslint:disable-line no-any - origin_server_ts?: number; + origin_server_ts: number; users?: any; // tslint:disable-line no-any users_default?: any; // tslint:disable-line no-any notifications?: any; // tslint:disable-line no-any + unsigned?: { + replaces_state: any; // tslint:disable-line no-any + } } export interface IMatrixMessage { diff --git a/test/test_matrixeventprocessor.ts b/test/test_matrixeventprocessor.ts index 64da1edd..6e4cedfc 100644 --- a/test/test_matrixeventprocessor.ts +++ b/test/test_matrixeventprocessor.ts @@ -25,7 +25,6 @@ import { MockChannel } from "./mocks/channel"; import { IMatrixEvent } from "../src/matrixtypes"; import { AppserviceMock } from "./mocks/appservicemock"; import { Appservice } from "matrix-bot-sdk"; -import { RemoteStoreRoom } from "../src/db/roomstore"; // we are a test file and thus need those /* tslint:disable:no-unused-expression max-file-line-count no-any */ @@ -33,12 +32,12 @@ import { RemoteStoreRoom } from "../src/db/roomstore"; const TEST_TIMESTAMP = 1337; function buildRequest(eventData): IMatrixEvent { - if (eventData.unsigned === undefined) { - eventData.unsigned = {age: 0}; - } if (eventData.sender === undefined) { eventData.sender = "@foobar:localhost"; } + if (!eventData.origin_server_ts) { + eventData.origin_server_ts = Date.now(); + } return eventData; } @@ -378,7 +377,6 @@ describe("MatrixEventProcessor", () => { }, sender: "@user:localhost", type: "m.room.member", - unsigned: {}, } as IMatrixEvent; await processor.ProcessStateEvent(event); expect(STATE_EVENT_MSG).to.equal("`@user:localhost` joined the room on Matrix."); @@ -407,7 +405,6 @@ describe("MatrixEventProcessor", () => { sender: "@user:localhost", state_key: "@user2:localhost", type: "m.room.member", - unsigned: {}, } as IMatrixEvent; await processor.ProcessStateEvent(event); expect(STATE_EVENT_MSG).to.equal("`@user:localhost` invited `@user2:localhost` to the room on Matrix."); @@ -437,7 +434,6 @@ describe("MatrixEventProcessor", () => { sender: "@user:localhost", state_key: "@user2:localhost", type: "m.room.member", - unsigned: {}, } as IMatrixEvent; await processor.ProcessStateEvent(event); expect(STATE_EVENT_MSG).to.equal("`@user:localhost` kicked `@user2:localhost` from the room on Matrix."); @@ -451,7 +447,6 @@ describe("MatrixEventProcessor", () => { sender: "@user:localhost", state_key: "@user:localhost", type: "m.room.member", - unsigned: {}, } as IMatrixEvent; await processor.ProcessStateEvent(event); expect(STATE_EVENT_MSG).to.equal("`@user:localhost` left the room on Matrix."); @@ -481,7 +476,6 @@ describe("MatrixEventProcessor", () => { sender: "@user:localhost", state_key: "@user2:localhost", type: "m.room.member", - unsigned: {}, } as IMatrixEvent; await processor.ProcessStateEvent(event); expect(STATE_EVENT_MSG).to.equal("`@user:localhost` banned `@user2:localhost` from the room on Matrix."); @@ -971,13 +965,12 @@ This is the reply`, const {processor} = createMatrixEventProcessor(); let err; try { - await processor.OnEvent(buildRequest({unsigned: {age: AGE}}), []); + await processor.OnEvent(buildRequest({ origin_server_ts: Date.now() - AGE }), []); } catch (e) { err = e; } // TODO: Not supported yet. // expect(err).to.be.an.instanceof(Unstable.EventTooOldError); }); it("should reject un-processable events", async () => { - const AGE = 900000; // 15 * 60 * 1000 const {processor} = createMatrixEventProcessor(); let err; try { @@ -985,7 +978,6 @@ This is the reply`, buildRequest({ content: {}, type: "m.potato", - unsigned: {age: AGE}, }), [], );