From 157cd02433ea755f12368289755bda9cce6c8638 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 21 Dec 2022 15:45:51 -0700 Subject: [PATCH 01/17] Check server API versions when validating the homeserver --- src/autodiscovery.ts | 20 +++++++++++++++++++- src/version-support.ts | 20 ++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 src/version-support.ts diff --git a/src/autodiscovery.ts b/src/autodiscovery.ts index aa839550f9e..dae12ef534c 100644 --- a/src/autodiscovery.ts +++ b/src/autodiscovery.ts @@ -18,6 +18,7 @@ limitations under the License. import { IClientWellKnown, IWellKnownConfig } from "./client"; import { logger } from "./logger"; import { MatrixError, Method, timeoutSignal } from "./http-api"; +import { MINIMUM_MATRIX_VERSION } from "./version-support"; // Dev note: Auto discovery is part of the spec. // See: https://matrix.org/docs/spec/client_server/r0.4.0.html#server-discovery @@ -40,6 +41,9 @@ enum AutoDiscoveryError { InvalidIs = "Invalid identity server discovery response", MissingWellknown = "No .well-known JSON file found", InvalidJson = "Invalid JSON", + HomeserverTooOld = "The homeserver does not meet the minimum version requirements", + // TODO: Implement when Sydent supports the `/versions` endpoint - https://github.com/matrix-org/sydent/issues/424 + //IdentityServerTooOld = "The identity server does not meet the minimum version requirements", } interface WellKnownConfig extends Omit { @@ -80,6 +84,8 @@ export class AutoDiscovery { public static readonly ERROR_INVALID_JSON = AutoDiscoveryError.InvalidJson; + public static readonly ERROR_HOMESERVER_TOO_OLD = AutoDiscoveryError.HomeserverTooOld; + public static readonly ALL_ERRORS = Object.keys(AutoDiscoveryError); /** @@ -171,7 +177,7 @@ export class AutoDiscovery { // Step 3: Make sure the homeserver URL points to a homeserver. const hsVersions = await this.fetchWellKnownObject(`${hsUrl}/_matrix/client/versions`); - if (!hsVersions || !hsVersions.raw?.["versions"]) { + if (!hsVersions || !Array.isArray(hsVersions.raw?.["versions"])) { logger.error("Invalid /versions response"); clientConfig["m.homeserver"].error = AutoDiscovery.ERROR_INVALID_HOMESERVER; @@ -182,6 +188,18 @@ export class AutoDiscovery { return Promise.resolve(clientConfig); } + // Step 3.1: Non-spec check to ensure the server will actually work for us + if (!hsVersions.raw!["versions"].includes(MINIMUM_MATRIX_VERSION)) { + logger.error("Homeserver does not meet minimum version requirements"); + clientConfig["m.homeserver"].error = AutoDiscovery.ERROR_HOMESERVER_TOO_OLD; + + // Supply the base_url to the caller because they may be ignoring liveliness + // errors, like this one. + clientConfig["m.homeserver"].base_url = hsUrl; + + return Promise.resolve(clientConfig); + } + // Step 4: Now that the homeserver looks valid, update our client config. clientConfig["m.homeserver"] = { state: AutoDiscovery.SUCCESS, diff --git a/src/version-support.ts b/src/version-support.ts new file mode 100644 index 00000000000..dd2d55ad9e2 --- /dev/null +++ b/src/version-support.ts @@ -0,0 +1,20 @@ +/* +Copyright 2022 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/** + * The minimum Matrix specification version the js-sdk supports. + */ +export const MINIMUM_MATRIX_VERSION = "v1.1"; From b671edfc3b09995cb9c6f919198584d243311490 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 28 Jul 2023 12:06:29 +0100 Subject: [PATCH 02/17] Update media APIs to v3 as per v1.1 spec --- spec/integ/matrix-client-methods.spec.ts | 4 ++-- spec/unit/content-repo.spec.ts | 8 ++++---- spec/unit/http-api/__snapshots__/index.spec.ts.snap | 2 +- spec/unit/http-api/index.spec.ts | 8 ++++---- src/client.ts | 4 ++-- src/content-repo.ts | 4 ++-- src/http-api/index.ts | 6 +++--- src/http-api/prefix.ts | 2 +- 8 files changed, 19 insertions(+), 19 deletions(-) diff --git a/spec/integ/matrix-client-methods.spec.ts b/spec/integ/matrix-client-methods.spec.ts index a44b3815bd5..5535237b42c 100644 --- a/spec/integ/matrix-client-methods.spec.ts +++ b/spec/integ/matrix-client-methods.spec.ts @@ -73,7 +73,7 @@ describe("MatrixClient", function () { it("should upload the file", function () { httpBackend - .when("POST", "/_matrix/media/r0/upload") + .when("POST", "/_matrix/media/v3/upload") .check(function (req) { expect(req.rawData).toEqual(buf); expect(req.queryParams?.filename).toEqual("hi.txt"); @@ -108,7 +108,7 @@ describe("MatrixClient", function () { it("should parse errors into a MatrixError", function () { httpBackend - .when("POST", "/_matrix/media/r0/upload") + .when("POST", "/_matrix/media/v3/upload") .check(function (req) { expect(req.rawData).toEqual(buf); // @ts-ignore private property diff --git a/spec/unit/content-repo.spec.ts b/spec/unit/content-repo.spec.ts index 2cbd361239e..91953945ac7 100644 --- a/spec/unit/content-repo.spec.ts +++ b/spec/unit/content-repo.spec.ts @@ -33,7 +33,7 @@ describe("ContentRepo", function () { it("should return a download URL if no width/height/resize are specified", function () { const mxcUri = "mxc://server.name/resourceid"; expect(getHttpUriForMxc(baseUrl, mxcUri)).toEqual( - baseUrl + "/_matrix/media/r0/download/server.name/resourceid", + baseUrl + "/_matrix/media/v3/download/server.name/resourceid", ); }); @@ -44,21 +44,21 @@ describe("ContentRepo", function () { it("should return a thumbnail URL if a width/height/resize is specified", function () { const mxcUri = "mxc://server.name/resourceid"; expect(getHttpUriForMxc(baseUrl, mxcUri, 32, 64, "crop")).toEqual( - baseUrl + "/_matrix/media/r0/thumbnail/server.name/resourceid" + "?width=32&height=64&method=crop", + baseUrl + "/_matrix/media/v3/thumbnail/server.name/resourceid" + "?width=32&height=64&method=crop", ); }); it("should put fragments from mxc:// URIs after any query parameters", function () { const mxcUri = "mxc://server.name/resourceid#automade"; expect(getHttpUriForMxc(baseUrl, mxcUri, 32)).toEqual( - baseUrl + "/_matrix/media/r0/thumbnail/server.name/resourceid" + "?width=32#automade", + baseUrl + "/_matrix/media/v3/thumbnail/server.name/resourceid" + "?width=32#automade", ); }); it("should put fragments from mxc:// URIs at the end of the HTTP URI", function () { const mxcUri = "mxc://server.name/resourceid#automade"; expect(getHttpUriForMxc(baseUrl, mxcUri)).toEqual( - baseUrl + "/_matrix/media/r0/download/server.name/resourceid#automade", + baseUrl + "/_matrix/media/v3/download/server.name/resourceid#automade", ); }); }); diff --git a/spec/unit/http-api/__snapshots__/index.spec.ts.snap b/spec/unit/http-api/__snapshots__/index.spec.ts.snap index e6487ddeb0f..f60866aa238 100644 --- a/spec/unit/http-api/__snapshots__/index.spec.ts.snap +++ b/spec/unit/http-api/__snapshots__/index.spec.ts.snap @@ -6,6 +6,6 @@ exports[`MatrixHttpApi should return expected object from \`getContentUri\` 1`] "params": { "access_token": "token", }, - "path": "/_matrix/media/r0/upload", + "path": "/_matrix/media/v3/upload", } `; diff --git a/spec/unit/http-api/index.spec.ts b/spec/unit/http-api/index.spec.ts index cbaa15aa417..668417ea9eb 100644 --- a/spec/unit/http-api/index.spec.ts +++ b/spec/unit/http-api/index.spec.ts @@ -84,7 +84,7 @@ describe("MatrixHttpApi", () => { upload = api.uploadContent({} as File); expect(xhr.open).toHaveBeenCalledWith( Method.Post, - baseUrl.toLowerCase() + "/_matrix/media/r0/upload?access_token=token", + baseUrl.toLowerCase() + "/_matrix/media/v3/upload?access_token=token", ); expect(xhr.setRequestHeader).not.toHaveBeenCalledWith("Authorization"); }); @@ -96,7 +96,7 @@ describe("MatrixHttpApi", () => { accessToken: "token", }); upload = api.uploadContent({} as File); - expect(xhr.open).toHaveBeenCalledWith(Method.Post, baseUrl.toLowerCase() + "/_matrix/media/r0/upload"); + expect(xhr.open).toHaveBeenCalledWith(Method.Post, baseUrl.toLowerCase() + "/_matrix/media/v3/upload"); expect(xhr.setRequestHeader).toHaveBeenCalledWith("Authorization", "Bearer token"); }); @@ -105,14 +105,14 @@ describe("MatrixHttpApi", () => { upload = api.uploadContent({} as File, { name: "name" }); expect(xhr.open).toHaveBeenCalledWith( Method.Post, - baseUrl.toLowerCase() + "/_matrix/media/r0/upload?filename=name", + baseUrl.toLowerCase() + "/_matrix/media/v3/upload?filename=name", ); }); it("should allow not sending the filename", () => { const api = new MatrixHttpApi(new TypedEventEmitter(), { baseUrl, prefix }); upload = api.uploadContent({} as File, { name: "name", includeFilename: false }); - expect(xhr.open).toHaveBeenCalledWith(Method.Post, baseUrl.toLowerCase() + "/_matrix/media/r0/upload"); + expect(xhr.open).toHaveBeenCalledWith(Method.Post, baseUrl.toLowerCase() + "/_matrix/media/v3/upload"); }); it("should abort xhr when the upload is aborted", () => { diff --git a/src/client.ts b/src/client.ts index f50a1c74058..dee9bcd9585 100644 --- a/src/client.ts +++ b/src/client.ts @@ -3920,7 +3920,7 @@ export class MatrixClient extends TypedEventEmitter { return this.http.authedRequest(Method.Get, "/config", undefined, undefined, { - prefix: MediaPrefix.R0, + prefix: MediaPrefix.V3, }); } @@ -5147,7 +5147,7 @@ export class MatrixClient extends TypedEventEmitter = {}; if (width) { @@ -64,7 +64,7 @@ export function getHttpUriForMxc( if (Object.keys(params).length > 0) { // these are thumbnailing params so they probably want the // thumbnailing API... - prefix = "/_matrix/media/r0/thumbnail/"; + prefix = "/_matrix/media/v3/thumbnail/"; } const fragmentOffset = serverAndMediaId.indexOf("#"); diff --git a/src/http-api/index.ts b/src/http-api/index.ts index 1de1f847b27..4f9097665f8 100644 --- a/src/http-api/index.ts +++ b/src/http-api/index.ts @@ -110,7 +110,7 @@ export class MatrixHttpApi extends FetchHttpApi { }); }; - const url = this.getUrl("/upload", undefined, MediaPrefix.R0); + const url = this.getUrl("/upload", undefined, MediaPrefix.V3); if (includeFilename && fileName) { url.searchParams.set("filename", encodeURIComponent(fileName)); @@ -139,7 +139,7 @@ export class MatrixHttpApi extends FetchHttpApi { const headers: Record = { "Content-Type": contentType }; this.authedRequest(Method.Post, "/upload", queryParams, file, { - prefix: MediaPrefix.R0, + prefix: MediaPrefix.V3, headers, abortSignal: abortController.signal, }) @@ -182,7 +182,7 @@ export class MatrixHttpApi extends FetchHttpApi { public getContentUri(): IContentUri { return { base: this.opts.baseUrl, - path: MediaPrefix.R0 + "/upload", + path: MediaPrefix.V3 + "/upload", params: { access_token: this.opts.accessToken!, }, diff --git a/src/http-api/prefix.ts b/src/http-api/prefix.ts index f15b1ac1e77..06a0413f0fa 100644 --- a/src/http-api/prefix.ts +++ b/src/http-api/prefix.ts @@ -44,5 +44,5 @@ export enum MediaPrefix { /** * URI path for the media repo API */ - R0 = "/_matrix/media/r0", + V3 = "/_matrix/media/v3", } From 57305fd1da4157f6505f6b81078478588885ef44 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 28 Jul 2023 12:06:52 +0100 Subject: [PATCH 03/17] Update Matrix version in tests to meet minimum reqs --- spec/unit/autodiscovery.spec.ts | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/spec/unit/autodiscovery.spec.ts b/spec/unit/autodiscovery.spec.ts index 2ffe9be1a68..7bda961e323 100644 --- a/spec/unit/autodiscovery.spec.ts +++ b/spec/unit/autodiscovery.spec.ts @@ -351,7 +351,7 @@ describe("AutoDiscovery", function () { function () { const httpBackend = getHttpBackend(); httpBackend.when("GET", "/_matrix/client/versions").respond(200, { - not_matrix_versions: ["r0.0.1"], + not_matrix_versions: ["v1.1"], }); httpBackend.when("GET", "/.well-known/matrix/client").respond(200, { "m.homeserver": { @@ -388,7 +388,7 @@ describe("AutoDiscovery", function () { expect(req.path).toEqual("https://example.org/_matrix/client/versions"); }) .respond(200, { - versions: ["r0.0.1"], + versions: ["v1.1"], }); httpBackend.when("GET", "/.well-known/matrix/client").respond(200, { "m.homeserver": { @@ -428,7 +428,7 @@ describe("AutoDiscovery", function () { expect(req.path).toEqual("https://chat.example.org/_matrix/client/versions"); }) .respond(200, { - versions: ["r0.0.1"], + versions: ["v1.1"], }); httpBackend.when("GET", "/.well-known/matrix/client").respond(200, { "m.homeserver": { @@ -469,7 +469,7 @@ describe("AutoDiscovery", function () { expect(req.path).toEqual("https://chat.example.org/_matrix/client/versions"); }) .respond(200, { - versions: ["r0.0.1"], + versions: ["v1.1"], }); httpBackend.when("GET", "/.well-known/matrix/client").respond(200, { "m.homeserver": { @@ -515,7 +515,7 @@ describe("AutoDiscovery", function () { expect(req.path).toEqual("https://chat.example.org/_matrix/client/versions"); }) .respond(200, { - versions: ["r0.0.1"], + versions: ["v1.1"], }); httpBackend.when("GET", "/.well-known/matrix/client").respond(200, { "m.homeserver": { @@ -560,7 +560,7 @@ describe("AutoDiscovery", function () { expect(req.path).toEqual("https://chat.example.org/_matrix/client/versions"); }) .respond(200, { - versions: ["r0.0.1"], + versions: ["v1.1"], }); httpBackend.when("GET", "/.well-known/matrix/client").respond(200, { "m.homeserver": { @@ -606,7 +606,7 @@ describe("AutoDiscovery", function () { expect(req.path).toEqual("https://chat.example.org/_matrix/client/versions"); }) .respond(200, { - versions: ["r0.0.1"], + versions: ["v1.1"], }); httpBackend.when("GET", "/_matrix/identity/v2").respond(404, {}); httpBackend.when("GET", "/.well-known/matrix/client").respond(200, { @@ -653,7 +653,7 @@ describe("AutoDiscovery", function () { expect(req.path).toEqual("https://chat.example.org/_matrix/client/versions"); }) .respond(200, { - versions: ["r0.0.1"], + versions: ["v1.1"], }); httpBackend.when("GET", "/_matrix/identity/v2").respond(500, {}); httpBackend.when("GET", "/.well-known/matrix/client").respond(200, { @@ -697,7 +697,7 @@ describe("AutoDiscovery", function () { expect(req.path).toEqual("https://chat.example.org/_matrix/client/versions"); }) .respond(200, { - versions: ["r0.0.1"], + versions: ["v1.1"], }); httpBackend .when("GET", "/_matrix/identity/v2") @@ -747,7 +747,7 @@ describe("AutoDiscovery", function () { expect(req.path).toEqual("https://chat.example.org/_matrix/client/versions"); }) .respond(200, { - versions: ["r0.0.1"], + versions: ["v1.1"], }); httpBackend .when("GET", "/_matrix/identity/v2") @@ -879,7 +879,7 @@ describe("AutoDiscovery", function () { beforeEach(() => { fetchMock.resetBehavior(); - fetchMock.get(`${homeserverUrl}_matrix/client/versions`, { versions: ["r0.0.1"] }); + fetchMock.get(`${homeserverUrl}_matrix/client/versions`, { versions: ["v1.1"] }); fetchMock.get("https://example.org/.well-known/matrix/client", { "m.homeserver": { From 405183215b47e6e79baeaad28a4675721226fe95 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 28 Jul 2023 12:07:03 +0100 Subject: [PATCH 04/17] Mark r0 and v1 as deprecated --- src/http-api/prefix.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/http-api/prefix.ts b/src/http-api/prefix.ts index 06a0413f0fa..59d41d7ef26 100644 --- a/src/http-api/prefix.ts +++ b/src/http-api/prefix.ts @@ -17,10 +17,12 @@ limitations under the License. export enum ClientPrefix { /** * A constant representing the URI path for release 0 of the Client-Server HTTP API. + * @deprecated - the Matrix spec is moving away from this prefix but in v1.1 some endpoints still used it */ R0 = "/_matrix/client/r0", /** * A constant representing the URI path for the legacy release v1 of the Client-Server HTTP API. + * @deprecated - the Matrix spec is moving away from this prefix but in v1.1 some endpoints still used it */ V1 = "/_matrix/client/v1", /** From dd8c8e6cb6a18888b8e149a03ab10c87c4a9c23c Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 28 Jul 2023 12:10:55 +0100 Subject: [PATCH 05/17] Remove pre 1.1 code --- src/client.ts | 75 +++++---------------------------------------------- 1 file changed, 7 insertions(+), 68 deletions(-) diff --git a/src/client.ts b/src/client.ts index dee9bcd9585..b663984c8af 100644 --- a/src/client.ts +++ b/src/client.ts @@ -7885,18 +7885,6 @@ export class MatrixClient extends TypedEventEmitter { - return this.login("m.login.saml2", { - relay_state: relayState, - }); - } - /** * @param redirectUrl - The URL to redirect to after the HS * authenticates with CAS. @@ -7926,7 +7914,7 @@ export class MatrixClient extends TypedEventEmitter { - const path = utils.encodeUri("/directory/list/appservice/$networkId/$roomId", { - $networkId: networkId, - $roomId: roomId, - }); - return this.http.authedRequest(Method.Put, path, undefined, { visibility: visibility }); - } - /** * Query the user directory with a term matching user IDs, display names and domains. * @param term - the term with which to search. @@ -8534,24 +8494,6 @@ export class MatrixClient extends TypedEventEmitter { - const path = "/account/3pid"; - const data = { - threePidCreds: creds, - bind: bind, - }; - return this.http.authedRequest(Method.Post, path, undefined, data); - } - /** * Add a 3PID to your homeserver account. This API does not use an identity * server, as the homeserver is expected to handle 3PID ownership validation. @@ -8566,8 +8508,7 @@ export class MatrixClient extends TypedEventEmitter { const path = "/account/3pid/add"; - const prefix = (await this.isVersionSupported("r0.6.0")) ? ClientPrefix.R0 : ClientPrefix.Unstable; - return this.http.authedRequest(Method.Post, path, undefined, data, { prefix }); + return this.http.authedRequest(Method.Post, path, undefined, data); } /** @@ -8586,8 +8527,7 @@ export class MatrixClient extends TypedEventEmitter { const path = "/account/3pid/bind"; - const prefix = (await this.isVersionSupported("r0.6.0")) ? ClientPrefix.R0 : ClientPrefix.Unstable; - return this.http.authedRequest(Method.Post, path, undefined, data, { prefix }); + return this.http.authedRequest(Method.Post, path, undefined, data); } /** @@ -8612,8 +8552,7 @@ export class MatrixClient extends TypedEventEmitter Date: Fri, 28 Jul 2023 12:21:41 +0100 Subject: [PATCH 06/17] Iterate --- src/@types/requests.ts | 6 ------ src/client.ts | 1 - 2 files changed, 7 deletions(-) diff --git a/src/@types/requests.ts b/src/@types/requests.ts index eca0132fb31..0c79534e875 100644 --- a/src/@types/requests.ts +++ b/src/@types/requests.ts @@ -181,12 +181,6 @@ export interface IBindThreePidBody { sid: string; } -export interface IAddThreePidBody { - client_secret: string; - id_server: string; - sid: string; -} - export interface IRelationsRequestOpts { from?: string; to?: string; diff --git a/src/client.ts b/src/client.ts index b663984c8af..67bda259998 100644 --- a/src/client.ts +++ b/src/client.ts @@ -133,7 +133,6 @@ import { IFilterResponse, ITagsResponse, IStatusResponse, - IAddThreePidBody, } from "./@types/requests"; import { EventType, From a9db4423760e830d2e6d5b75bb203a58fe19d2df Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 8 Aug 2023 09:00:41 +0100 Subject: [PATCH 07/17] Remove doesServerSupportSeparateAddAndBind as we now require v1.1 --- spec/test-utils/client.ts | 1 - src/client.ts | 36 ------------------------------------ 2 files changed, 37 deletions(-) diff --git a/spec/test-utils/client.ts b/spec/test-utils/client.ts index 1e8a4643893..8123d0d65e6 100644 --- a/spec/test-utils/client.ts +++ b/spec/test-utils/client.ts @@ -86,7 +86,6 @@ export const mockClientMethodsEvents = () => ({ * Returns basic mocked client methods related to server support */ export const mockClientMethodsServer = (): Partial, unknown>> => ({ - doesServerSupportSeparateAddAndBind: jest.fn(), getIdentityServerUrl: jest.fn(), getHomeserverUrl: jest.fn(), getCapabilities: jest.fn().mockReturnValue({}), diff --git a/src/client.ts b/src/client.ts index 2843e9d1aa4..57148300e8c 100644 --- a/src/client.ts +++ b/src/client.ts @@ -6663,20 +6663,6 @@ export class MatrixClient extends TypedEventEmitter { const postParams = Object.assign({}, params); - // If the HS supports separate add and bind, then requestToken endpoints - // don't need an IS as they are all validated by the HS directly. - if (!(await this.doesServerSupportSeparateAddAndBind()) && this.idBaseUrl) { - const idServerUrl = new URL(this.idBaseUrl); - postParams.id_server = idServerUrl.host; - - if (this.identityServer?.getAccessToken && (await this.doesServerAcceptIdentityAccessToken())) { - const identityAccessToken = await this.identityServer.getAccessToken(); - if (identityAccessToken) { - postParams.id_access_token = identityAccessToken; - } - } - } - return this.http.request(Method.Post, endpoint, undefined, postParams); } @@ -7437,22 +7423,6 @@ export class MatrixClient extends TypedEventEmitter { - const response = await this.getVersions(); - if (!response) return false; - - const versions = response["versions"]; - const unstableFeatures = response["unstable_features"]; - - return versions?.includes("r0.6.0") || unstableFeatures?.["m.separate_add_and_bind"]; - } - /** * Query the server to see if it lists support for an unstable feature * in the /versions response @@ -8529,9 +8499,6 @@ export class MatrixClient extends TypedEventEmitter/requestToken` on the homeserver. * @returns Promise which resolves: to an empty object `{}` @@ -8547,9 +8514,6 @@ export class MatrixClient extends TypedEventEmitter/requestToken` on the identity server. It should also * contain `id_server` and `id_access_token` fields as well. From d433e0ec51f315be522ca3f72c41ea30b9939798 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 8 Aug 2023 09:06:55 +0100 Subject: [PATCH 08/17] Add tests --- spec/integ/matrix-client-methods.spec.ts | 76 ++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/spec/integ/matrix-client-methods.spec.ts b/spec/integ/matrix-client-methods.spec.ts index 69a6a5eacb5..ffa14651de1 100644 --- a/spec/integ/matrix-client-methods.spec.ts +++ b/spec/integ/matrix-client-methods.spec.ts @@ -1652,6 +1652,82 @@ describe("MatrixClient", function () { ]); }); }); + + describe("getFallbackAuthUrl", () => { + it("should return fallback url", () => { + expect(client.getFallbackAuthUrl("loginType", "authSessionId")).toMatchInlineSnapshot( + `"http://alice.localhost.test.server/_matrix/client/r0/auth/loginType/fallback/web?session=authSessionId"`, + ); + }); + }); + + describe("addThreePidOnly", () => { + it("should make expected POST request", async () => { + httpBackend + .when("POST", "/_matrix/client/r0/account/3pid/add") + .check(function (req) { + expect(req.data).toEqual({ + client_secret: "secret", + sid: "sid", + }); + expect(req.headers["Authorization"]).toBe("Bearer " + accessToken); + }) + .respond(200, {}); + + await Promise.all([ + client.addThreePidOnly({ + client_secret: "secret", + sid: "sid", + }), + httpBackend.flushAllExpected(), + ]); + }); + }); + + describe("bindThreePid", () => { + it("should make expected POST request", async () => { + httpBackend + .when("POST", "/_matrix/client/r0/account/3pid/bind") + .check(function (req) { + expect(req.data).toEqual({ + client_secret: "secret", + id_server: "server", + id_access_token: "token", + sid: "sid", + }); + expect(req.headers["Authorization"]).toBe("Bearer " + accessToken); + }) + .respond(200, {}); + + await Promise.all([ + client.bindThreePid({ + client_secret: "secret", + id_server: "server", + id_access_token: "token", + sid: "sid", + }), + httpBackend.flushAllExpected(), + ]); + }); + }); + + describe("unbindThreePid", () => { + it("should make expected POST request", async () => { + httpBackend + .when("POST", "/_matrix/client/r0/account/3pid/unbind") + .check(function (req) { + expect(req.data).toEqual({ + medium: "email", + address: "alice@server.com", + id_server: "identity.localhost", + }); + expect(req.headers["Authorization"]).toBe("Bearer " + accessToken); + }) + .respond(200, {}); + + await Promise.all([client.unbindThreePid("email", "alice@server.com"), httpBackend.flushAllExpected()]); + }); + }); }); function withThreadId(event: MatrixEvent, newThreadId: string): MatrixEvent { From c93823ef35c29346a2f32af81acc989e27021ed9 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 8 Aug 2023 09:14:53 +0100 Subject: [PATCH 09/17] Iterate --- spec/integ/matrix-client-methods.spec.ts | 12 ----- spec/unit/matrix-client.spec.ts | 2 +- src/client.ts | 64 +----------------------- src/interactive-auth.ts | 6 +-- src/sync.ts | 15 ++---- 5 files changed, 9 insertions(+), 90 deletions(-) diff --git a/spec/integ/matrix-client-methods.spec.ts b/spec/integ/matrix-client-methods.spec.ts index ffa14651de1..f14b8963288 100644 --- a/spec/integ/matrix-client-methods.spec.ts +++ b/spec/integ/matrix-client-methods.spec.ts @@ -1102,10 +1102,6 @@ describe("MatrixClient", function () { submit_url: "https://foobar.matrix/_matrix/matrix", }; - httpBackend.when("GET", "/_matrix/client/versions").respond(200, { - versions: ["r0.6.0"], - }); - const prom = client.requestRegisterEmailToken("bob@email", "secret", 1); httpBackend .when("POST", "/register/email/requestToken") @@ -1126,10 +1122,6 @@ describe("MatrixClient", function () { it("should supply an id_access_token", async () => { const targetEmail = "gerald@example.org"; - httpBackend.when("GET", "/_matrix/client/versions").respond(200, { - versions: ["r0.6.0"], - }); - httpBackend .when("POST", "/invite") .check((req) => { @@ -1165,10 +1157,6 @@ describe("MatrixClient", function () { ], }; - httpBackend.when("GET", "/_matrix/client/versions").respond(200, { - versions: ["r0.6.0"], - }); - httpBackend .when("POST", "/createRoom") .check((req) => { diff --git a/spec/unit/matrix-client.spec.ts b/spec/unit/matrix-client.spec.ts index 404f7fcd7fc..d90d3c9ed03 100644 --- a/spec/unit/matrix-client.spec.ts +++ b/spec/unit/matrix-client.spec.ts @@ -201,7 +201,7 @@ describe("MatrixClient", function () { if (path === KEEP_ALIVE_PATH && acceptKeepalives) { return Promise.resolve({ unstable_features: unstableFeatures, - versions: ["r0.6.0", "r0.6.1"], + versions: ["v1.1"], }); } const next = httpLookups.shift(); diff --git a/src/client.ts b/src/client.ts index 57148300e8c..05bea99bae8 100644 --- a/src/client.ts +++ b/src/client.ts @@ -5345,7 +5345,7 @@ export class MatrixClient extends TypedEventEmitter { - const response = await this.getVersions(); - if (!response) return false; - - const versions = response["versions"]; - const unstableFeatures = response["unstable_features"]; - - return ( - (versions && versions.includes("r0.5.0")) || (unstableFeatures && unstableFeatures["m.lazy_load_members"]) - ); - } - - /** - * Query the server to see if the `id_server` parameter is required - * when registering with an 3pid, adding a 3pid or resetting password. - * @returns true if id_server parameter is required - */ - public async doesServerRequireIdServerParam(): Promise { - const response = await this.getVersions(); - if (!response) return true; - - const versions = response["versions"]; - - // Supporting r0.6.0 is the same as having the flag set to false - if (versions && versions.includes("r0.6.0")) { - return false; - } - - const unstableFeatures = response["unstable_features"]; - if (!unstableFeatures) return true; - if (unstableFeatures["m.require_identity_server"] === undefined) { - return true; - } else { - return unstableFeatures["m.require_identity_server"]; - } - } - - /** - * Query the server to see if the `id_access_token` parameter can be safely - * passed to the homeserver. Some homeservers may trigger errors if they are not - * prepared for the new parameter. - * @returns true if id_access_token can be sent - */ - public async doesServerAcceptIdentityAccessToken(): Promise { - const response = await this.getVersions(); - if (!response) return false; - - const versions = response["versions"]; - const unstableFeatures = response["unstable_features"]; - return (versions && versions.includes("r0.6.0")) || (unstableFeatures && unstableFeatures["m.id_access_token"]); - } - /** * Query the server to see if it lists support for an unstable feature * in the /versions response @@ -8050,11 +7994,7 @@ export class MatrixClient extends TypedEventEmitter !i.id_access_token); - if ( - invitesNeedingToken.length > 0 && - this.identityServer?.getAccessToken && - (await this.doesServerAcceptIdentityAccessToken()) - ) { + if (invitesNeedingToken.length > 0 && this.identityServer?.getAccessToken) { const identityAccessToken = await this.identityServer.getAccessToken(); if (identityAccessToken) { for (const invite of invitesNeedingToken) { diff --git a/src/interactive-auth.ts b/src/interactive-auth.ts index 3617ce1765f..d2a1fe087ab 100644 --- a/src/interactive-auth.ts +++ b/src/interactive-auth.ts @@ -345,10 +345,8 @@ export class InteractiveAuth { sid: this.emailSid, client_secret: this.clientSecret, }; - if (await this.matrixClient.doesServerRequireIdServerParam()) { - const idServerParsedUrl = new URL(this.matrixClient.getIdentityServerUrl()!); - creds.id_server = idServerParsedUrl.host; - } + const idServerParsedUrl = new URL(this.matrixClient.getIdentityServerUrl()!); + creds.id_server = idServerParsedUrl.host; authDict = { type: EMAIL_STAGE_TYPE, // TODO: Remove `threepid_creds` once servers support proper UIA diff --git a/src/sync.ts b/src/sync.ts index f2ec1b32b0f..8e8fde2199c 100644 --- a/src/sync.ts +++ b/src/sync.ts @@ -649,18 +649,11 @@ export class SyncApi { this.opts.lazyLoadMembers = false; } if (this.opts.lazyLoadMembers) { - debuglog("Checking server lazy load support..."); - const supported = await this.client.doesServerSupportLazyLoading(); - if (supported) { - debuglog("Enabling lazy load on sync filter..."); - if (!this.opts.filter) { - this.opts.filter = this.buildDefaultFilter(); - } - this.opts.filter.setLazyLoadMembers(true); - } else { - debuglog("LL: lazy loading requested but not supported " + "by server, so disabling"); - this.opts.lazyLoadMembers = false; + debuglog("Enabling lazy load on sync filter..."); + if (!this.opts.filter) { + this.opts.filter = this.buildDefaultFilter(); } + this.opts.filter.setLazyLoadMembers(true); } // need to vape the store when enabling LL and wasn't enabled before debuglog("Checking whether lazy loading has changed in store..."); From ac77b24da2fef694d33781051edbaafc4e8586dc Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 8 Aug 2023 09:18:21 +0100 Subject: [PATCH 10/17] Iterate --- spec/integ/matrix-client-syncing.spec.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/spec/integ/matrix-client-syncing.spec.ts b/spec/integ/matrix-client-syncing.spec.ts index 45b6f42b4a6..cea06d10d87 100644 --- a/spec/integ/matrix-client-syncing.spec.ts +++ b/spec/integ/matrix-client-syncing.spec.ts @@ -224,8 +224,6 @@ describe("MatrixClient syncing", () => { }); it("should honour lazyLoadMembers if user is not a guest", () => { - client!.doesServerSupportLazyLoading = jest.fn().mockResolvedValue(true); - httpBackend! .when("GET", "/sync") .check((req) => { @@ -242,8 +240,6 @@ describe("MatrixClient syncing", () => { it("should not honour lazyLoadMembers if user is a guest", () => { httpBackend!.expectedRequests = []; httpBackend!.when("GET", "/versions").respond(200, {}); - client!.doesServerSupportLazyLoading = jest.fn().mockResolvedValue(true); - httpBackend! .when("GET", "/sync") .check((req) => { From 9a73ea952ab5419bca46eff85116b66c120f4cb3 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 10 Aug 2023 09:30:22 +0100 Subject: [PATCH 11/17] Add readme note --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index ee41f49b0e2..add491156dd 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,8 @@ This is the [Matrix](https://matrix.org) Client-Server SDK for JavaScript and TypeScript. This SDK can be run in a browser or in Node.js. +#### Minimum Matrix server version: v1.1 + The Matrix specification is constantly evolving - while this SDK aims for maximum backwards compatibility, it only guarantees that a feature will be supported for at least 4 spec releases. For example, if a feature the js-sdk supports is removed in v1.4 then the feature is _eligible_ for removal from the SDK when v1.8 is released. This SDK has no From 3b8c10c8bd3b34a2d9f47caa4069cdd031e3b7c8 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 10 Aug 2023 09:46:17 +0100 Subject: [PATCH 12/17] Add test --- spec/unit/autodiscovery.spec.ts | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/spec/unit/autodiscovery.spec.ts b/spec/unit/autodiscovery.spec.ts index 7bda961e323..b7614d7240f 100644 --- a/spec/unit/autodiscovery.spec.ts +++ b/spec/unit/autodiscovery.spec.ts @@ -18,7 +18,7 @@ limitations under the License. import fetchMock from "fetch-mock-jest"; import MockHttpBackend from "matrix-mock-request"; -import { M_AUTHENTICATION } from "../../src"; +import { AutoDiscoveryAction, M_AUTHENTICATION } from "../../src"; import { AutoDiscovery } from "../../src/autodiscovery"; import { OidcError } from "../../src/oidc/error"; import { makeDelegatedAuthConfig } from "../test-utils/oidc"; @@ -867,6 +867,37 @@ describe("AutoDiscovery", function () { ]); }); + it("should FAIL_ERROR for unsupported Matrix version", () => { + const httpBackend = getHttpBackend(); + httpBackend.when("GET", "/.well-known/matrix/client").respond(200, { + "m.homeserver": { + base_url: "https://example.org", + }, + }); + httpBackend.when("GET", "/_matrix/client/versions").respond(200, { + versions: ["r0.6.0"], + }); + return Promise.all([ + httpBackend.flushAllExpected(), + AutoDiscovery.findClientConfig("example.org").then((conf) => { + const expected = { + "m.homeserver": { + state: AutoDiscoveryAction.FAIL_ERROR, + error: AutoDiscovery.ERROR_HOMESERVER_TOO_OLD, + base_url: "https://example.org", + }, + "m.identity_server": { + state: "PROMPT", + error: null, + base_url: null, + }, + }; + + expect(conf).toEqual(expected); + }), + ]); + }); + describe("m.authentication", () => { const homeserverName = "example.org"; const homeserverUrl = "https://chat.example.org/"; From ea7e987f9799fff3ea84b2bc8bb6637905f3df3b Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 10 Aug 2023 11:39:01 +0100 Subject: [PATCH 13/17] Stop using r0 API endpoints --- spec/integ/crypto/crypto.spec.ts | 12 ++++++------ spec/integ/matrix-client-event-timeline.spec.ts | 6 +++--- spec/integ/matrix-client-methods.spec.ts | 10 +++++----- spec/integ/sliding-sync-sdk.spec.ts | 2 +- spec/test-utils/E2EKeyReceiver.ts | 2 +- spec/test-utils/E2EKeyResponder.ts | 2 +- spec/test-utils/SyncResponder.ts | 2 +- spec/test-utils/mockEndpoints.ts | 8 ++++---- src/client.ts | 12 ++++-------- src/http-api/prefix.ts | 14 ++++++-------- 10 files changed, 32 insertions(+), 38 deletions(-) diff --git a/spec/integ/crypto/crypto.spec.ts b/spec/integ/crypto/crypto.spec.ts index 8d2b386c413..252db523080 100644 --- a/spec/integ/crypto/crypto.spec.ts +++ b/spec/integ/crypto/crypto.spec.ts @@ -1945,7 +1945,7 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("crypto (%s)", (backend: string, }; }; - for (const path of ["/_matrix/client/r0/keys/upload", "/_matrix/client/v3/keys/upload"]) { + for (const path of ["/_matrix/client/v3/keys/upload", "/_matrix/client/v3/keys/upload"]) { fetchMock.post(new URL(path, aliceClient.getHomeserverUrl()).toString(), listener, { // These routes are already defined in the E2EKeyReceiver // We want to overwrite the behaviour of the E2EKeyReceiver @@ -2082,7 +2082,7 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("crypto (%s)", (backend: string, return queryResponseBody; }; - for (const path of ["/_matrix/client/r0/keys/query", "/_matrix/client/v3/keys/query"]) { + for (const path of ["/_matrix/client/v3/keys/query", "/_matrix/client/v3/keys/query"]) { fetchMock.post(new URL(path, aliceClient.getHomeserverUrl()).toString(), listener); } }); @@ -2175,7 +2175,7 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("crypto (%s)", (backend: string, }); /** - * Create a mock to respond to the PUT request `/_matrix/client/r0/user/:userId/account_data/:type(m.secret_storage.*)` + * Create a mock to respond to the PUT request `/_matrix/client/v3/user/:userId/account_data/:type(m.secret_storage.*)` * Resolved when a key is uploaded (ie in `body.content.key`) * https://spec.matrix.org/v1.6/client-server-api/#put_matrixclientv3useruseridaccount_datatype */ @@ -2184,7 +2184,7 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("crypto (%s)", (backend: string, // This url is called multiple times during the secret storage bootstrap process // When we received the newly generated key, we return it fetchMock.put( - "express:/_matrix/client/r0/user/:userId/account_data/:type(m.secret_storage.*)", + "express:/_matrix/client/v3/user/:userId/account_data/:type(m.secret_storage.*)", (url: string, options: RequestInit) => { const content = JSON.parse(options.body as string); @@ -2200,7 +2200,7 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("crypto (%s)", (backend: string, } /** - * Create a mock to respond to the PUT request `/_matrix/client/r0/user/:userId/account_data/m.cross_signing.${key}` + * Create a mock to respond to the PUT request `/_matrix/client/v3/user/:userId/account_data/m.cross_signing.${key}` * Resolved when the cross signing key is uploaded * https://spec.matrix.org/v1.6/client-server-api/#put_matrixclientv3useruseridaccount_datatype */ @@ -2208,7 +2208,7 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("crypto (%s)", (backend: string, return new Promise((resolve) => { // Called when the cross signing key is uploaded fetchMock.put( - `express:/_matrix/client/r0/user/:userId/account_data/m.cross_signing.${key}`, + `express:/_matrix/client/v3/user/:userId/account_data/m.cross_signing.${key}`, (url: string, options: RequestInit) => { const content = JSON.parse(options.body as string); resolve(content.encrypted); diff --git a/spec/integ/matrix-client-event-timeline.spec.ts b/spec/integ/matrix-client-event-timeline.spec.ts index 26e968d7154..0d519cbc596 100644 --- a/spec/integ/matrix-client-event-timeline.spec.ts +++ b/spec/integ/matrix-client-event-timeline.spec.ts @@ -1342,7 +1342,7 @@ describe("MatrixClient event timelines", function () { function respondToContext(event: Partial = THREAD_ROOT): ExpectedHttpRequest { const request = httpBackend.when( "GET", - encodeUri("/_matrix/client/r0/rooms/$roomId/context/$eventId", { + encodeUri("/_matrix/client/v3/rooms/$roomId/context/$eventId", { $roomId: roomId, $eventId: event.event_id!, }), @@ -1360,7 +1360,7 @@ describe("MatrixClient event timelines", function () { function respondToEvent(event: Partial = THREAD_ROOT): ExpectedHttpRequest { const request = httpBackend.when( "GET", - encodeUri("/_matrix/client/r0/rooms/$roomId/event/$eventId", { + encodeUri("/_matrix/client/v3/rooms/$roomId/event/$eventId", { $roomId: roomId, $eventId: event.event_id!, }), @@ -1371,7 +1371,7 @@ describe("MatrixClient event timelines", function () { function respondToMessagesRequest(): ExpectedHttpRequest { const request = httpBackend.when( "GET", - encodeUri("/_matrix/client/r0/rooms/$roomId/messages", { + encodeUri("/_matrix/client/v3/rooms/$roomId/messages", { $roomId: roomId, }), ); diff --git a/spec/integ/matrix-client-methods.spec.ts b/spec/integ/matrix-client-methods.spec.ts index f14b8963288..977190abddb 100644 --- a/spec/integ/matrix-client-methods.spec.ts +++ b/spec/integ/matrix-client-methods.spec.ts @@ -708,7 +708,7 @@ describe("MatrixClient", function () { const auth = { identifier: 1 }; it("should pass through an auth dict", function () { httpBackend - .when("DELETE", "/_matrix/client/r0/devices/my_device") + .when("DELETE", "/_matrix/client/v3/devices/my_device") .check(function (req) { expect(req.data).toEqual({ auth: auth }); }) @@ -1644,7 +1644,7 @@ describe("MatrixClient", function () { describe("getFallbackAuthUrl", () => { it("should return fallback url", () => { expect(client.getFallbackAuthUrl("loginType", "authSessionId")).toMatchInlineSnapshot( - `"http://alice.localhost.test.server/_matrix/client/r0/auth/loginType/fallback/web?session=authSessionId"`, + `"http://alice.localhost.test.server/_matrix/client/v3/auth/loginType/fallback/web?session=authSessionId"`, ); }); }); @@ -1652,7 +1652,7 @@ describe("MatrixClient", function () { describe("addThreePidOnly", () => { it("should make expected POST request", async () => { httpBackend - .when("POST", "/_matrix/client/r0/account/3pid/add") + .when("POST", "/_matrix/client/v3/account/3pid/add") .check(function (req) { expect(req.data).toEqual({ client_secret: "secret", @@ -1675,7 +1675,7 @@ describe("MatrixClient", function () { describe("bindThreePid", () => { it("should make expected POST request", async () => { httpBackend - .when("POST", "/_matrix/client/r0/account/3pid/bind") + .when("POST", "/_matrix/client/v3/account/3pid/bind") .check(function (req) { expect(req.data).toEqual({ client_secret: "secret", @@ -1702,7 +1702,7 @@ describe("MatrixClient", function () { describe("unbindThreePid", () => { it("should make expected POST request", async () => { httpBackend - .when("POST", "/_matrix/client/r0/account/3pid/unbind") + .when("POST", "/_matrix/client/v3/account/3pid/unbind") .check(function (req) { expect(req.data).toEqual({ medium: "email", diff --git a/spec/integ/sliding-sync-sdk.spec.ts b/spec/integ/sliding-sync-sdk.spec.ts index a55316b5fa5..4785ca73b9c 100644 --- a/spec/integ/sliding-sync-sdk.spec.ts +++ b/spec/integ/sliding-sync-sdk.spec.ts @@ -121,7 +121,7 @@ describe("SlidingSyncSdk", () => { await client!.initCrypto(); syncOpts.cryptoCallbacks = syncOpts.crypto = client!.crypto; } - httpBackend!.when("GET", "/_matrix/client/r0/pushrules").respond(200, {}); + httpBackend!.when("GET", "/_matrix/client/v3/pushrules").respond(200, {}); sdk = new SlidingSyncSdk(mockSlidingSync, client, testOpts, syncOpts); }; diff --git a/spec/test-utils/E2EKeyReceiver.ts b/spec/test-utils/E2EKeyReceiver.ts index 44a863e8b07..2d381253272 100644 --- a/spec/test-utils/E2EKeyReceiver.ts +++ b/spec/test-utils/E2EKeyReceiver.ts @@ -76,7 +76,7 @@ export class E2EKeyReceiver implements IE2EKeyReceiver { this.onKeyUploadRequest(resolveOneTimeKeys, options); // catch both r0 and v3 variants - fetchMock.post(new URL("/_matrix/client/r0/keys/upload", homeserverUrl).toString(), listener); + fetchMock.post(new URL("/_matrix/client/v3/keys/upload", homeserverUrl).toString(), listener); fetchMock.post(new URL("/_matrix/client/v3/keys/upload", homeserverUrl).toString(), listener); }); } diff --git a/spec/test-utils/E2EKeyResponder.ts b/spec/test-utils/E2EKeyResponder.ts index e779e8c5e87..59b28168d4e 100644 --- a/spec/test-utils/E2EKeyResponder.ts +++ b/spec/test-utils/E2EKeyResponder.ts @@ -44,7 +44,7 @@ export class E2EKeyResponder { // set up a listener for /keys/query. const listener = (url: string, options: RequestInit) => this.onKeyQueryRequest(options); // catch both r0 and v3 variants - fetchMock.post(new URL("/_matrix/client/r0/keys/query", homeserverUrl).toString(), listener); + fetchMock.post(new URL("/_matrix/client/v3/keys/query", homeserverUrl).toString(), listener); fetchMock.post(new URL("/_matrix/client/v3/keys/query", homeserverUrl).toString(), listener); } diff --git a/spec/test-utils/SyncResponder.ts b/spec/test-utils/SyncResponder.ts index 56a9c30c8ac..31fae7147a8 100644 --- a/spec/test-utils/SyncResponder.ts +++ b/spec/test-utils/SyncResponder.ts @@ -75,7 +75,7 @@ export class SyncResponder implements ISyncResponder { */ public constructor(homeserverUrl: string) { this.debug = debugFunc(`sync-responder:[${homeserverUrl}]`); - fetchMock.get("begin:" + new URL("/_matrix/client/r0/sync?", homeserverUrl).toString(), (_url, _options) => + fetchMock.get("begin:" + new URL("/_matrix/client/v3/sync?", homeserverUrl).toString(), (_url, _options) => this.onSyncRequest(), ); } diff --git a/spec/test-utils/mockEndpoints.ts b/spec/test-utils/mockEndpoints.ts index 386b7a4cb00..3a9ce5250fa 100644 --- a/spec/test-utils/mockEndpoints.ts +++ b/spec/test-utils/mockEndpoints.ts @@ -23,8 +23,8 @@ import fetchMock from "fetch-mock-jest"; */ export function mockInitialApiRequests(homeserverUrl: string) { fetchMock.getOnce(new URL("/_matrix/client/versions", homeserverUrl).toString(), { versions: ["r0.5.0"] }); - fetchMock.getOnce(new URL("/_matrix/client/r0/pushrules/", homeserverUrl).toString(), {}); - fetchMock.postOnce(new URL("/_matrix/client/r0/user/%40alice%3Alocalhost/filter", homeserverUrl).toString(), { + fetchMock.getOnce(new URL("/_matrix/client/v3/pushrules/", homeserverUrl).toString(), {}); + fetchMock.postOnce(new URL("/_matrix/client/v3/user/%40alice%3Alocalhost/filter", homeserverUrl).toString(), { filter_id: "fid", }); } @@ -32,13 +32,13 @@ export function mockInitialApiRequests(homeserverUrl: string) { /** * Mock the requests needed to set up cross signing * - * Return 404 error for `GET _matrix/client/r0/user/:userId/account_data/:type` request + * Return 404 error for `GET _matrix/client/v3/user/:userId/account_data/:type` request * Return `{}` for `POST _matrix/client/v3/keys/signatures/upload` request (named `upload-sigs` for fetchMock check) * Return `{}` for `POST /_matrix/client/(unstable|v3)/keys/device_signing/upload` request (named `upload-keys` for fetchMock check) */ export function mockSetupCrossSigningRequests(): void { // have account_data requests return an empty object - fetchMock.get("express:/_matrix/client/r0/user/:userId/account_data/:type", { + fetchMock.get("express:/_matrix/client/v3/user/:userId/account_data/:type", { status: 404, body: { errcode: "M_NOT_FOUND", error: "Account data not found." }, }); diff --git a/src/client.ts b/src/client.ts index 05bea99bae8..822a24a61db 100644 --- a/src/client.ts +++ b/src/client.ts @@ -1286,7 +1286,7 @@ export class MatrixClient extends TypedEventEmitter(Method.Post, "/room_keys/version", undefined, data, { - prefix: ClientPrefix.V3, - }); + const res = await this.http.authedRequest(Method.Post, "/room_keys/version", undefined, data); // We could assume everything's okay and enable directly, but this ensures // we run the same signature verification that will be used for future @@ -6137,7 +6135,7 @@ export class MatrixClient extends TypedEventEmitter { - return this.http.authedRequest(Method.Post, "/keys/signatures/upload", undefined, content, { - prefix: ClientPrefix.V3, - }); + return this.http.authedRequest(Method.Post, "/keys/signatures/upload", undefined, content); } /** diff --git a/src/http-api/prefix.ts b/src/http-api/prefix.ts index 59d41d7ef26..ea868dcafda 100644 --- a/src/http-api/prefix.ts +++ b/src/http-api/prefix.ts @@ -16,13 +16,7 @@ limitations under the License. export enum ClientPrefix { /** - * A constant representing the URI path for release 0 of the Client-Server HTTP API. - * @deprecated - the Matrix spec is moving away from this prefix but in v1.1 some endpoints still used it - */ - R0 = "/_matrix/client/r0", - /** - * A constant representing the URI path for the legacy release v1 of the Client-Server HTTP API. - * @deprecated - the Matrix spec is moving away from this prefix but in v1.1 some endpoints still used it + A constant representing the URI path for Client-Server API endpoints versioned at v1. */ V1 = "/_matrix/client/v1", /** @@ -44,7 +38,11 @@ export enum IdentityPrefix { export enum MediaPrefix { /** - * URI path for the media repo API + * A constant representing the URI path for Client-Server API Media endpoints versioned at v1. + */ + V1 = "/_matrix/media/v3", + /** + * A constant representing the URI path for Client-Server API Media endpoints versioned at v3. */ V3 = "/_matrix/media/v3", } From 216f0124bef75e5b42690f75984fee96f7d5a051 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 10 Aug 2023 11:52:13 +0100 Subject: [PATCH 14/17] Fix double-handling of v3 endpoints in test utilities --- spec/test-utils/E2EKeyReceiver.ts | 2 -- spec/test-utils/E2EKeyResponder.ts | 2 -- 2 files changed, 4 deletions(-) diff --git a/spec/test-utils/E2EKeyReceiver.ts b/spec/test-utils/E2EKeyReceiver.ts index 2d381253272..24af06d6e37 100644 --- a/spec/test-utils/E2EKeyReceiver.ts +++ b/spec/test-utils/E2EKeyReceiver.ts @@ -75,8 +75,6 @@ export class E2EKeyReceiver implements IE2EKeyReceiver { const listener = (url: string, options: RequestInit) => this.onKeyUploadRequest(resolveOneTimeKeys, options); - // catch both r0 and v3 variants - fetchMock.post(new URL("/_matrix/client/v3/keys/upload", homeserverUrl).toString(), listener); fetchMock.post(new URL("/_matrix/client/v3/keys/upload", homeserverUrl).toString(), listener); }); } diff --git a/spec/test-utils/E2EKeyResponder.ts b/spec/test-utils/E2EKeyResponder.ts index 59b28168d4e..57152f17621 100644 --- a/spec/test-utils/E2EKeyResponder.ts +++ b/spec/test-utils/E2EKeyResponder.ts @@ -43,8 +43,6 @@ export class E2EKeyResponder { public constructor(homeserverUrl: string) { // set up a listener for /keys/query. const listener = (url: string, options: RequestInit) => this.onKeyQueryRequest(options); - // catch both r0 and v3 variants - fetchMock.post(new URL("/_matrix/client/v3/keys/query", homeserverUrl).toString(), listener); fetchMock.post(new URL("/_matrix/client/v3/keys/query", homeserverUrl).toString(), listener); } From ff68f29c15f915b8cac369c96ea25e9beae3a752 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 10 Aug 2023 11:53:40 +0100 Subject: [PATCH 15/17] Remove more { - return this.isVersionSupported("r0.6.1"); - } - /** * Get if lazy loading members is being used. * @returns Whether or not members are lazy loaded by this client From 65397a52deeea1020a6d7c48ae294335a2f0acff Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 10 Aug 2023 12:02:05 +0100 Subject: [PATCH 16/17] iterate --- spec/integ/crypto/crypto.spec.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/spec/integ/crypto/crypto.spec.ts b/spec/integ/crypto/crypto.spec.ts index 252db523080..fd578084fb6 100644 --- a/spec/integ/crypto/crypto.spec.ts +++ b/spec/integ/crypto/crypto.spec.ts @@ -2082,9 +2082,10 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("crypto (%s)", (backend: string, return queryResponseBody; }; - for (const path of ["/_matrix/client/v3/keys/query", "/_matrix/client/v3/keys/query"]) { - fetchMock.post(new URL(path, aliceClient.getHomeserverUrl()).toString(), listener); - } + fetchMock.post( + new URL("/_matrix/client/v3/keys/query", aliceClient.getHomeserverUrl()).toString(), + listener, + ); }); } From 764a3d58a58e724599d00f0df5ce4fd3018e7f5b Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 14 Aug 2023 08:48:09 +0100 Subject: [PATCH 17/17] Update src/http-api/prefix.ts Co-authored-by: Germain --- src/http-api/prefix.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/http-api/prefix.ts b/src/http-api/prefix.ts index ea868dcafda..5eee4672ae1 100644 --- a/src/http-api/prefix.ts +++ b/src/http-api/prefix.ts @@ -16,7 +16,7 @@ limitations under the License. export enum ClientPrefix { /** - A constant representing the URI path for Client-Server API endpoints versioned at v1. + * A constant representing the URI path for Client-Server API endpoints versioned at v1. */ V1 = "/_matrix/client/v1", /**