1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-11-25 05:23:13 +03:00

Send extensible events structure and support on-demand parsing (#2091)

* Parse extensible events on demand

* Decorate messages with MSC1767 when appropriate

We do this automatically to force a pool of messages in the wild we can use for testing.

* Include the SDK

* Appease linter and tests

* Change property name to appease linter

* Update SDK
This commit is contained in:
Travis Ralston
2022-01-13 09:56:11 -07:00
committed by GitHub
parent 4acb98c496
commit 016e24472a
6 changed files with 69 additions and 6 deletions

View File

@@ -56,6 +56,7 @@
"bs58": "^4.0.1", "bs58": "^4.0.1",
"content-type": "^1.0.4", "content-type": "^1.0.4",
"loglevel": "^1.7.1", "loglevel": "^1.7.1",
"matrix-events-sdk": "^0.0.1-beta.2",
"p-retry": "^4.5.0", "p-retry": "^4.5.0",
"qs": "^6.9.6", "qs": "^6.9.6",
"request": "^2.88.2", "request": "^2.88.2",

View File

@@ -348,7 +348,7 @@ function recvMessage(httpBackend, client, sender, message) {
return testUtils.awaitDecryption(event); return testUtils.awaitDecryption(event);
}).then((event) => { }).then((event) => {
expect(event.getType()).toEqual("m.room.message"); expect(event.getType()).toEqual("m.room.message");
expect(event.getContent()).toEqual({ expect(event.getContent()).toMatchObject({
msgtype: "m.text", msgtype: "m.text",
body: "Hello, World", body: "Hello, World",
}); });

View File

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

View File

@@ -20,6 +20,7 @@ limitations under the License.
*/ */
import { EventEmitter } from "events"; import { EventEmitter } from "events";
import { EmoteEvent, MessageEvent, NoticeEvent } from "matrix-events-sdk";
import { ISyncStateData, SyncApi, SyncState } from "./sync"; import { ISyncStateData, SyncApi, SyncState } from "./sync";
import { EventStatus, IContent, IDecryptOptions, IEvent, MatrixEvent } from "./models/event"; import { EventStatus, IContent, IDecryptOptions, IEvent, MatrixEvent } from "./models/event";
@@ -86,7 +87,14 @@ import {
} from "./crypto/keybackup"; } from "./crypto/keybackup";
import { IIdentityServerProvider } from "./@types/IIdentityServerProvider"; import { IIdentityServerProvider } from "./@types/IIdentityServerProvider";
import { MatrixScheduler } from "./scheduler"; import { MatrixScheduler } from "./scheduler";
import { IAuthData, ICryptoCallbacks, IMinimalEvent, IRoomEvent, IStateEvent, NotificationCountType } from "./matrix"; import {
IAuthData,
ICryptoCallbacks,
IMinimalEvent,
IRoomEvent,
IStateEvent,
NotificationCountType,
} from "./matrix";
import { import {
CrossSigningKey, CrossSigningKey,
IAddSecretStorageKeyOpts, IAddSecretStorageKeyOpts,
@@ -3935,11 +3943,30 @@ export class MatrixClient extends EventEmitter {
callback = txnId as any as Callback; // for legacy callback = txnId as any as Callback; // for legacy
txnId = undefined; txnId = undefined;
} }
// Populate all outbound events with Extensible Events metadata to ensure there's a
// reasonably large pool of messages to parse.
let eventType: string = EventType.RoomMessage;
let sendContent: IContent = content as IContent;
if (sendContent['msgtype'] === MsgType.Text) {
const serialized = MessageEvent.from(sendContent['body'], sendContent['formatted_body']).serialize();
eventType = serialized.type;
sendContent = serialized.content;
} else if (sendContent['msgtype'] === MsgType.Emote) {
const serialized = EmoteEvent.from(sendContent['body'], sendContent['formatted_body']).serialize();
eventType = serialized.type;
sendContent = serialized.content;
} else if (sendContent['msgtype'] === MsgType.Notice) {
const serialized = NoticeEvent.from(sendContent['body'], sendContent['formatted_body']).serialize();
eventType = serialized.type;
sendContent = serialized.content;
}
return this.sendEvent( return this.sendEvent(
roomId, roomId,
threadId as (string | null), threadId as (string | null),
EventType.RoomMessage, eventType,
content as IContent, sendContent,
txnId as string, txnId as string,
callback, callback,
); );

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2015 - 2021 The Matrix.org Foundation C.I.C. Copyright 2015 - 2022 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@ limitations under the License.
*/ */
import { EventEmitter } from 'events'; import { EventEmitter } from 'events';
import { ExtensibleEvent, ExtensibleEvents, Optional } from "matrix-events-sdk";
import { logger } from '../logger'; import { logger } from '../logger';
import { VerificationRequest } from "../crypto/verification/request/VerificationRequest"; import { VerificationRequest } from "../crypto/verification/request/VerificationRequest";
@@ -210,6 +211,12 @@ export class MatrixEvent extends EventEmitter {
*/ */
private visibility: MessageVisibility = MESSAGE_VISIBLE; private visibility: MessageVisibility = MESSAGE_VISIBLE;
// Not all events will be extensible-event compatible, so cache a flag in
// addition to a falsy cached event value. We check the flag later on in
// a public getter to decide if the cache is valid.
private _hasCachedExtEv = false;
private _cachedExtEv: Optional<ExtensibleEvent> = undefined;
/* curve25519 key which we believe belongs to the sender of the event. See /* curve25519 key which we believe belongs to the sender of the event. See
* getSenderKey() * getSenderKey()
*/ */
@@ -327,6 +334,25 @@ export class MatrixEvent extends EventEmitter {
this.reEmitter = new ReEmitter(this); this.reEmitter = new ReEmitter(this);
} }
/**
* Unstable getter to try and get an extensible event. Note that this might
* return a falsy value if the event could not be parsed as an extensible
* event.
*
* @deprecated Use stable functions where possible.
*/
public get unstableExtensibleEvent(): Optional<ExtensibleEvent> {
if (!this._hasCachedExtEv) {
this._cachedExtEv = ExtensibleEvents.parse(this.getEffectiveEvent());
}
return this._cachedExtEv;
}
private invalidateExtensibleEvent() {
// just reset the flag - that'll trick the getter into parsing a new event
this._hasCachedExtEv = false;
}
/** /**
* Gets the event as though it would appear unencrypted. If the event is already not * Gets the event as though it would appear unencrypted. If the event is already not
* encrypted, it is simply returned as-is. * encrypted, it is simply returned as-is.
@@ -861,6 +887,7 @@ export class MatrixEvent extends EventEmitter {
this.forwardingCurve25519KeyChain = this.forwardingCurve25519KeyChain =
decryptionResult.forwardingCurve25519KeyChain || []; decryptionResult.forwardingCurve25519KeyChain || [];
this.untrusted = decryptionResult.untrusted || false; this.untrusted = decryptionResult.untrusted || false;
this.invalidateExtensibleEvent();
} }
/** /**
@@ -1079,6 +1106,8 @@ export class MatrixEvent extends EventEmitter {
delete content[key]; delete content[key];
} }
} }
this.invalidateExtensibleEvent();
} }
/** /**
@@ -1282,6 +1311,7 @@ export class MatrixEvent extends EventEmitter {
if (this._replacingEvent !== newEvent) { if (this._replacingEvent !== newEvent) {
this._replacingEvent = newEvent; this._replacingEvent = newEvent;
this.emit("Event.replaced", this); this.emit("Event.replaced", this);
this.invalidateExtensibleEvent();
} }
} }

View File

@@ -5470,6 +5470,11 @@ marked@^2.0.3:
resolved "https://registry.yarnpkg.com/marked/-/marked-2.1.3.tgz#bd017cef6431724fd4b27e0657f5ceb14bff3753" resolved "https://registry.yarnpkg.com/marked/-/marked-2.1.3.tgz#bd017cef6431724fd4b27e0657f5ceb14bff3753"
integrity sha512-/Q+7MGzaETqifOMWYEA7HVMaZb4XbcRfaOzcSsHZEith83KGlvaSG33u0SKu89Mj5h+T8V2hM+8O45Qc5XTgwA== integrity sha512-/Q+7MGzaETqifOMWYEA7HVMaZb4XbcRfaOzcSsHZEith83KGlvaSG33u0SKu89Mj5h+T8V2hM+8O45Qc5XTgwA==
matrix-events-sdk@^0.0.1-beta.2:
version "0.0.1-beta.2"
resolved "https://registry.yarnpkg.com/matrix-events-sdk/-/matrix-events-sdk-0.0.1-beta.2.tgz#28efdcc3259152c4d53094cedb72b3843e5f772e"
integrity sha512-a3VIZeb9IxxxPrvFnUbt4pjP7A6irv7eWLv1GBoq+80m7v5n3QhzT/mmeUGJx2KNt7jLboFau4g1iIU82H3wEg==
matrix-mock-request@^1.2.3: matrix-mock-request@^1.2.3:
version "1.2.3" version "1.2.3"
resolved "https://registry.yarnpkg.com/matrix-mock-request/-/matrix-mock-request-1.2.3.tgz#56b15d86e2601a9b48a854844396d18caab649c8" resolved "https://registry.yarnpkg.com/matrix-mock-request/-/matrix-mock-request-1.2.3.tgz#56b15d86e2601a9b48a854844396d18caab649c8"