Delayed event management: split endpoints, no auth (#31183)

* Delayed event management: split endpoints, no auth

Use the new js-sdk client methods for calling the dedicated,
unauthenticated endpoints for each of the cancel/restart/send actions
for updating a delayed event.

Note that these methods are compatible with homeservers that support
only the original endpoint where the update action is in the request
body.

* REPLACEME: pull in dependant js-sdk branch

see matrix-org/matrix-js-sdk#5066

* Format with Prettier

* Update matrix-js-sdk
This commit is contained in:
Andrew Ferrazzutti 2025-11-17 11:18:25 -05:00 committed by GitHub
parent 250d6571fe
commit fcd23b48e0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 65 additions and 27 deletions

View File

@ -132,7 +132,7 @@
"matrix-encrypt-attachment": "^1.0.3", "matrix-encrypt-attachment": "^1.0.3",
"matrix-events-sdk": "0.0.1", "matrix-events-sdk": "0.0.1",
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#develop", "matrix-js-sdk": "github:matrix-org/matrix-js-sdk#develop",
"matrix-widget-api": "^1.10.0", "matrix-widget-api": "^1.14.0",
"memoize-one": "^6.0.0", "memoize-one": "^6.0.0",
"mime": "^4.0.4", "mime": "^4.0.4",
"oidc-client-ts": "^3.0.1", "oidc-client-ts": "^3.0.1",

View File

@ -26,7 +26,6 @@ import {
type IWidgetApiErrorResponseDataDetails, type IWidgetApiErrorResponseDataDetails,
type ISearchUserDirectoryResult, type ISearchUserDirectoryResult,
type IGetMediaConfigResult, type IGetMediaConfigResult,
type UpdateDelayedEventAction,
} from "matrix-widget-api"; } from "matrix-widget-api";
import { import {
ClientEvent, ClientEvent,
@ -425,12 +424,34 @@ export class StopGapWidgetDriver extends WidgetDriver {
/** /**
* @experimental Part of MSC4140 & MSC4157 * @experimental Part of MSC4140 & MSC4157
*/ */
public async updateDelayedEvent(delayId: string, action: UpdateDelayedEventAction): Promise<void> { public async cancelScheduledDelayedEvent(delayId: string): Promise<void> {
const client = MatrixClientPeg.get(); const client = MatrixClientPeg.get();
if (!client) throw new Error("Not in a room or not attached to a client"); if (!client) throw new Error("Not in a room or not attached to a client");
await client._unstable_updateDelayedEvent(delayId, action); await client._unstable_cancelScheduledDelayedEvent(delayId);
}
/**
* @experimental Part of MSC4140 & MSC4157
*/
public async restartScheduledDelayedEvent(delayId: string): Promise<void> {
const client = MatrixClientPeg.get();
if (!client) throw new Error("Not in a room or not attached to a client");
await client._unstable_restartScheduledDelayedEvent(delayId);
}
/**
* @experimental Part of MSC4140 & MSC4157
*/
public async sendScheduledDelayedEvent(delayId: string): Promise<void> {
const client = MatrixClientPeg.get();
if (!client) throw new Error("Not in a room or not attached to a client");
await client._unstable_sendScheduledDelayedEvent(delayId);
} }
/** /**

View File

@ -276,7 +276,9 @@ export function createTestClient(): MatrixClient {
_unstable_sendDelayedEvent: jest.fn(), _unstable_sendDelayedEvent: jest.fn(),
_unstable_sendDelayedStateEvent: jest.fn(), _unstable_sendDelayedStateEvent: jest.fn(),
_unstable_updateDelayedEvent: jest.fn(), _unstable_cancelScheduledDelayedEvent: jest.fn(),
_unstable_restartScheduledDelayedEvent: jest.fn(),
_unstable_sendScheduledDelayedEvent: jest.fn(),
searchUserDirectory: jest.fn().mockResolvedValue({ limited: false, results: [] }), searchUserDirectory: jest.fn().mockResolvedValue({ limited: false, results: [] }),
setDeviceVerified: jest.fn(), setDeviceVerified: jest.fn(),

View File

@ -27,7 +27,6 @@ import {
SimpleObservable, SimpleObservable,
OpenIDRequestState, OpenIDRequestState,
type IOpenIDUpdate, type IOpenIDUpdate,
UpdateDelayedEventAction,
} from "matrix-widget-api"; } from "matrix-widget-api";
import { import {
type ApprovalOpts, type ApprovalOpts,
@ -554,24 +553,40 @@ describe("StopGapWidgetDriver", () => {
driver = mkDefaultDriver(); driver = mkDefaultDriver();
}); });
it("updates delayed events", async () => { it("can cancel scheduled delayed events", async () => {
client._unstable_updateDelayedEvent.mockResolvedValue({}); client._unstable_cancelScheduledDelayedEvent.mockResolvedValue({});
for (const action of [ await expect(driver.cancelScheduledDelayedEvent("id")).resolves.toBeUndefined();
UpdateDelayedEventAction.Cancel, expect(client._unstable_cancelScheduledDelayedEvent).toHaveBeenCalledWith("id");
UpdateDelayedEventAction.Restart,
UpdateDelayedEventAction.Send,
]) {
await expect(driver.updateDelayedEvent("id", action)).resolves.toBeUndefined();
expect(client._unstable_updateDelayedEvent).toHaveBeenCalledWith("id", action);
}
}); });
it("fails to update delayed events", async () => { it("can restart scheduled delayed events", async () => {
client._unstable_restartScheduledDelayedEvent.mockResolvedValue({});
await expect(driver.restartScheduledDelayedEvent("id")).resolves.toBeUndefined();
expect(client._unstable_restartScheduledDelayedEvent).toHaveBeenCalledWith("id");
});
it("can send scheduled delayed events", async () => {
client._unstable_sendScheduledDelayedEvent.mockResolvedValue({});
await expect(driver.sendScheduledDelayedEvent("id")).resolves.toBeUndefined();
expect(client._unstable_sendScheduledDelayedEvent).toHaveBeenCalledWith("id");
});
it("fails to cancel scheduled delayed events", async () => {
const errorMessage = "Cannot cancel this delayed event";
client._unstable_cancelScheduledDelayedEvent.mockRejectedValue(new Error(errorMessage));
await expect(driver.cancelScheduledDelayedEvent("id")).rejects.toThrow(errorMessage);
});
it("fails to restart scheduled delayed events", async () => {
const errorMessage = "Cannot restart this delayed event"; const errorMessage = "Cannot restart this delayed event";
client._unstable_updateDelayedEvent.mockRejectedValue(new Error(errorMessage)); client._unstable_restartScheduledDelayedEvent.mockRejectedValue(new Error(errorMessage));
await expect(driver.updateDelayedEvent("id", UpdateDelayedEventAction.Restart)).rejects.toThrow( await expect(driver.restartScheduledDelayedEvent("id")).rejects.toThrow(errorMessage);
errorMessage, });
);
it("fails to send scheduled delayed events", async () => {
const errorMessage = "Cannot send this delayed event";
client._unstable_sendScheduledDelayedEvent.mockRejectedValue(new Error(errorMessage));
await expect(driver.sendScheduledDelayedEvent("id")).rejects.toThrow(errorMessage);
}); });
}); });

View File

@ -9659,7 +9659,7 @@ matrix-events-sdk@0.0.1:
"matrix-js-sdk@github:matrix-org/matrix-js-sdk#develop": "matrix-js-sdk@github:matrix-org/matrix-js-sdk#develop":
version "39.1.2" version "39.1.2"
resolved "https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/b489bb15cf3f5de8024a3e31ccb36cf294f82887" resolved "https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/df88edfda0aa00ad1d574e367f024db9a927e96b"
dependencies: dependencies:
"@babel/runtime" "^7.12.5" "@babel/runtime" "^7.12.5"
"@matrix-org/matrix-sdk-crypto-wasm" "^15.3.0" "@matrix-org/matrix-sdk-crypto-wasm" "^15.3.0"
@ -9669,7 +9669,7 @@ matrix-events-sdk@0.0.1:
jwt-decode "^4.0.0" jwt-decode "^4.0.0"
loglevel "^1.9.2" loglevel "^1.9.2"
matrix-events-sdk "0.0.1" matrix-events-sdk "0.0.1"
matrix-widget-api "^1.10.0" matrix-widget-api "^1.14.0"
oidc-client-ts "^3.0.1" oidc-client-ts "^3.0.1"
p-retry "7" p-retry "7"
sdp-transform "^3.0.0" sdp-transform "^3.0.0"
@ -9687,10 +9687,10 @@ matrix-web-i18n@^3.2.1, matrix-web-i18n@^3.4.0:
minimist "^1.2.8" minimist "^1.2.8"
walk "^2.3.15" walk "^2.3.15"
matrix-widget-api@^1.10.0: matrix-widget-api@^1.14.0:
version "1.13.1" version "1.14.0"
resolved "https://registry.yarnpkg.com/matrix-widget-api/-/matrix-widget-api-1.13.1.tgz#5b1caeed2fc58148bcd2984e0546d2d06a1713ad" resolved "https://registry.yarnpkg.com/matrix-widget-api/-/matrix-widget-api-1.14.0.tgz#aa90c40ace27d3165299f7dbc760a53001ce1446"
integrity sha512-mkOHUVzaN018TCbObfGOSaMW2GoUxOfcxNNlTVx5/HeMk3OSQPQM0C9oEME5Liiv/dBUoSrEB64V8wF7e/gb1w== integrity sha512-DDvZGOQhI/rilPWg5VlLN7pHIsPt0Jt14lsuHDP+KU+fmpAQNITJ6aIld1ZoXWsrVGv2PS3x6K/MHtfruIOQJQ==
dependencies: dependencies:
"@types/events" "^3.0.0" "@types/events" "^3.0.0"
events "^3.2.0" events "^3.2.0"