Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set minimum supported Matrix 1.1 version (drop legacy r0 versions) #3007

Merged
merged 21 commits into from
Aug 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion spec/TestClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export class TestClient implements IE2EKeyReceiver, ISyncResponder {
logger.log(this + ": starting");
this.httpBackend.when("GET", "/versions").respond(200, {
// we have tests that rely on support for lazy-loading members
versions: ["r0.5.0"],
versions: ["v1.1"],
});
this.httpBackend.when("GET", "/pushrules").respond(200, {});
this.httpBackend.when("POST", "/filter").respond(200, { filter_id: "fid" });
Expand Down
17 changes: 9 additions & 8 deletions spec/integ/crypto/crypto.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -2082,9 +2082,10 @@ 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"]) {
fetchMock.post(new URL(path, aliceClient.getHomeserverUrl()).toString(), listener);
}
fetchMock.post(
new URL("/_matrix/client/v3/keys/query", aliceClient.getHomeserverUrl()).toString(),
listener,
);
});
}

Expand Down Expand Up @@ -2175,7 +2176,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
*/
Expand All @@ -2184,7 +2185,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);

Expand All @@ -2200,15 +2201,15 @@ 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
*/
function awaitCrossSigningKeyUpload(key: string): Promise<Record<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);
Expand Down
6 changes: 3 additions & 3 deletions spec/integ/matrix-client-event-timeline.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1342,7 +1342,7 @@ describe("MatrixClient event timelines", function () {
function respondToContext(event: Partial<IEvent> = 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!,
}),
Expand All @@ -1360,7 +1360,7 @@ describe("MatrixClient event timelines", function () {
function respondToEvent(event: Partial<IEvent> = 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!,
}),
Expand All @@ -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,
}),
);
Expand Down
94 changes: 79 additions & 15 deletions spec/integ/matrix-client-methods.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 });
})
Expand Down Expand Up @@ -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")
Expand All @@ -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) => {
Expand Down Expand Up @@ -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) => {
Expand Down Expand Up @@ -1652,6 +1640,82 @@ describe("MatrixClient", function () {
]);
});
});

describe("getFallbackAuthUrl", () => {
it("should return fallback url", () => {
expect(client.getFallbackAuthUrl("loginType", "authSessionId")).toMatchInlineSnapshot(
`"http://alice.localhost.test.server/_matrix/client/v3/auth/loginType/fallback/web?session=authSessionId"`,
);
});
});

describe("addThreePidOnly", () => {
it("should make expected POST request", async () => {
httpBackend
.when("POST", "/_matrix/client/v3/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/v3/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/v3/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 {
Expand Down
4 changes: 0 additions & 4 deletions spec/integ/matrix-client-syncing.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand All @@ -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) => {
Expand Down
2 changes: 1 addition & 1 deletion spec/integ/sliding-sync-sdk.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
};

Expand Down
2 changes: 0 additions & 2 deletions spec/test-utils/E2EKeyReceiver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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/r0/keys/upload", homeserverUrl).toString(), listener);
fetchMock.post(new URL("/_matrix/client/v3/keys/upload", homeserverUrl).toString(), listener);
});
}
Expand Down
2 changes: 0 additions & 2 deletions spec/test-utils/E2EKeyResponder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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/r0/keys/query", homeserverUrl).toString(), listener);
fetchMock.post(new URL("/_matrix/client/v3/keys/query", homeserverUrl).toString(), listener);
}

Expand Down
2 changes: 1 addition & 1 deletion spec/test-utils/SyncResponder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
);
}
Expand Down
1 change: 0 additions & 1 deletion spec/test-utils/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ export const mockClientMethodsEvents = () => ({
* Returns basic mocked client methods related to server support
*/
export const mockClientMethodsServer = (): Partial<Record<MethodLikeKeys<MatrixClient>, unknown>> => ({
doesServerSupportSeparateAddAndBind: jest.fn(),
getIdentityServerUrl: jest.fn(),
getHomeserverUrl: jest.fn(),
getCapabilities: jest.fn().mockReturnValue({}),
Expand Down
10 changes: 5 additions & 5 deletions spec/test-utils/mockEndpoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,23 @@ import fetchMock from "fetch-mock-jest";
* @param homeserverUrl - the homeserver url for the client under test
*/
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/versions", homeserverUrl).toString(), { versions: ["v1.1"] });
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",
});
}

/**
* 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." },
});
Expand Down
Loading
Loading