diff --git a/src/stores/widgets/StopGapWidgetDriver.ts b/src/stores/widgets/StopGapWidgetDriver.ts index bf4ee16b5d8..b5609dc5fb9 100644 --- a/src/stores/widgets/StopGapWidgetDriver.ts +++ b/src/stores/widgets/StopGapWidgetDriver.ts @@ -414,6 +414,30 @@ export class StopGapWidgetDriver extends WidgetDriver { await client._unstable_updateDelayedEvent(delayId, action); } + /** + * Implements {@link WidgetDriver#sendToDevice} + * Encrypted to-device events are not supported. + */ + public async sendToDevice( + eventType: string, + encrypted: boolean, + contentMap: { [userId: string]: { [deviceId: string]: object } }, + ): Promise { + if (encrypted) throw new Error("Encrypted to-device events are not supported"); + + const client = MatrixClientPeg.safeGet(); + await client.queueToDevice({ + eventType, + batch: Object.entries(contentMap).flatMap(([userId, userContentMap]) => + Object.entries(userContentMap).map(([deviceId, content]) => ({ + userId, + deviceId, + payload: content, + })), + ), + }); + } + private pickRooms(roomIds?: (string | Symbols.AnyRoom)[]): Room[] { const client = MatrixClientPeg.get(); if (!client) throw new Error("Not attached to a client"); diff --git a/test/unit-tests/stores/widgets/StopGapWidgetDriver-test.ts b/test/unit-tests/stores/widgets/StopGapWidgetDriver-test.ts index 738c3504036..961b702452d 100644 --- a/test/unit-tests/stores/widgets/StopGapWidgetDriver-test.ts +++ b/test/unit-tests/stores/widgets/StopGapWidgetDriver-test.ts @@ -170,6 +170,44 @@ describe("StopGapWidgetDriver", () => { expect(listener).toHaveBeenCalledWith(openIdUpdate); }); + describe("sendToDevice", () => { + const contentMap = { + "@alice:example.org": { + "*": { + hello: "alice", + }, + }, + "@bob:example.org": { + bobDesktop: { + hello: "bob", + }, + }, + }; + + let driver: WidgetDriver; + + beforeEach(() => { + driver = mkDefaultDriver(); + }); + + it("sends unencrypted messages", async () => { + await driver.sendToDevice("org.example.foo", false, contentMap); + expect(client.queueToDevice).toHaveBeenCalledWith({ + eventType: "org.example.foo", + batch: [ + { deviceId: "*", payload: { hello: "alice" }, userId: "@alice:example.org" }, + { deviceId: "bobDesktop", payload: { hello: "bob" }, userId: "@bob:example.org" }, + ], + }); + }); + + it("raises an error if encrypted", async () => { + await expect(driver.sendToDevice("org.example.foo", true, contentMap)).rejects.toThrow( + "Encrypted to-device events are not supported", + ); + }); + }); + describe("getTurnServers", () => { let driver: WidgetDriver;