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

Switch to using Matrix 1.1+ compatible endpoints #226

Merged
merged 1 commit into from
May 30, 2022
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
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,16 @@ TypeScript/JavaScript SDK for Matrix bots. For help and support, visit [#matrix-
# Documentation

Documentation for the project is available [here](https://turt2live.github.io/matrix-bot-sdk/index.html).

# Matrix version support

The Matrix protocol is [versioned](https://spec.matrix.org/latest/#specification-versions) to ensure endpoints and
functionality can safely rotate in and out of the ecosystem. The bot-sdk will assume it is connected to a homeserver
with support for at least one of the last 2 versions, at the time of the bot-sdk's release. This means that if you
connect the bot-sdk to a homeserver which is 3 or more Matrix versions out of date, things might not work for you.

It is recommended to update the bot-sdk as frequently as spec releases themselves (or faster) to avoid this situation,
and watch the repo for updates in the event a release is delayed.

**Note**: Currently the bot-sdk does not throw an error if the server appears to be incompatible, however this might
change in the future.
2 changes: 1 addition & 1 deletion src/AdminApis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,6 @@ export class AdminApis {
* @returns {Promise<WhoisInfo>} resolves to the whois information
*/
public whoisUser(userId: string): Promise<WhoisInfo> {
return this.client.doRequest("GET", "/_matrix/client/r0/admin/whois/" + encodeURIComponent(userId));
return this.client.doRequest("GET", "/_matrix/client/v3/admin/whois/" + encodeURIComponent(userId));
}
}
6 changes: 3 additions & 3 deletions src/MatrixAuth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export class MatrixAuth {
let response;

try {
response = await this.createTemplateClient().doRequest("POST", "/_matrix/client/r0/register", null, body);
response = await this.createTemplateClient().doRequest("POST", "/_matrix/client/v3/register", null, body);
} catch (e) {
if (e.statusCode === 401) {
if (typeof (e.body) === "string") e.body = JSON.parse(e.body);
Expand Down Expand Up @@ -83,7 +83,7 @@ export class MatrixAuth {
type: expectedFlow[0], // HACK: We assume we only have one entry here
session: sessionId,
};
response = await this.createTemplateClient().doRequest("POST", "/_matrix/client/r0/register", null, body);
response = await this.createTemplateClient().doRequest("POST", "/_matrix/client/v3/register", null, body);
}
}

Expand Down Expand Up @@ -115,7 +115,7 @@ export class MatrixAuth {
initial_device_display_name: deviceName,
};

const response = await this.createTemplateClient().doRequest("POST", "/_matrix/client/r0/login", null, body);
const response = await this.createTemplateClient().doRequest("POST", "/_matrix/client/v3/login", null, body);
const accessToken = response["access_token"];
if (!accessToken) throw new Error("Expected access token in response - got nothing");

Expand Down
153 changes: 102 additions & 51 deletions src/MatrixClient.ts

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/appservice/Appservice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -578,7 +578,7 @@ export class Appservice extends EventEmitter {
public setRoomDirectoryVisibility(networkId: string, roomId: string, visibility: "public" | "private") {
roomId = encodeURIComponent(roomId);
networkId = encodeURIComponent(networkId);
return this.botClient.doRequest("PUT", `/_matrix/client/r0/directory/list/appservice/${networkId}/${roomId}`, null, {
return this.botClient.doRequest("PUT", `/_matrix/client/v3/directory/list/appservice/${networkId}/${roomId}`, null, {
visibility,
});
}
Expand Down
4 changes: 2 additions & 2 deletions src/appservice/Intent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ export class Intent {
},
};
this.client.impersonateUserId(null); // avoid confusing homeserver
const res = await this.client.doRequest("POST", "/_matrix/client/r0/login", {}, loginBody);
const res = await this.client.doRequest("POST", "/_matrix/client/v3/login", {}, loginBody);
this.makeClient(true, res['access_token']);
storage.storeValue("accessToken", this.client.accessToken);
prepared = true;
Expand Down Expand Up @@ -299,7 +299,7 @@ export class Intent {
public async ensureRegistered() {
if (!(await Promise.resolve(this.storage.isUserRegistered(this.userId)))) {
try {
const result = await this.client.doRequest("POST", "/_matrix/client/r0/register", null, {
const result = await this.client.doRequest("POST", "/_matrix/client/v3/register", null, {
type: "m.login.application_service",
username: this.userId.substring(1).split(":")[0],
});
Expand Down
4 changes: 2 additions & 2 deletions src/appservice/UnstableAppserviceApis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export class UnstableAppserviceApis {
*/
public async sendEventWithTimestamp(roomId: string, eventType: string, content: any, ts: number) {
const txnId = `${(new Date().getTime())}__inc_appts${++this.requestId}`;
const path = `/_matrix/client/r0/rooms/${encodeURIComponent(roomId)}/send/${encodeURIComponent(eventType)}/${encodeURIComponent(txnId)}`;
const path = `/_matrix/client/v3/rooms/${encodeURIComponent(roomId)}/send/${encodeURIComponent(eventType)}/${encodeURIComponent(txnId)}`;
const response = await this.client.doRequest("PUT", path, { ts }, content);
return response.event_id;
}
Expand All @@ -56,7 +56,7 @@ export class UnstableAppserviceApis {
* @returns {Promise<string>} resolves to the event ID that represents the message
*/
public async sendStateEventWithTimestamp(roomId: string, type: string, stateKey: string, content: any, ts: number): Promise<string> {
const path = `/_matrix/client/r0/rooms/${encodeURIComponent(roomId)}/state/${encodeURIComponent(type)}/${encodeURIComponent(stateKey)}`;
const path = `/_matrix/client/v3/rooms/${encodeURIComponent(roomId)}/state/${encodeURIComponent(type)}/${encodeURIComponent(stateKey)}`;
const response = await this.client.doRequest("PUT", path, { ts }, content);
return response.event_id;
}
Expand Down
2 changes: 1 addition & 1 deletion src/e2ee/SdkOlmEngine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export class SdkOlmEngine implements OlmEngine {
}

public uploadOneTimeKeys(body: { device_keys?: DeviceKeys, one_time_keys?: GenericKeys }): Promise<OTKCounts> {
return this.client.doRequest("POST", "/_matrix/client/r0/keys/upload", null, body);
return this.client.doRequest("POST", "/_matrix/client/v3/keys/upload", null, body);
}

public getEffectiveJoinedUsersInRoom(roomId: string): Promise<string[]> {
Expand Down
2 changes: 1 addition & 1 deletion src/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ let lastRequestId = 0;
* @category Unit testing
* @param {string} baseUrl The base URL to apply to the call.
* @param {"GET"|"POST"|"PUT"|"DELETE"} method The HTTP method to use in the request
* @param {string} endpoint The endpoint to call. For example: "/_matrix/client/r0/account/whoami"
* @param {string} endpoint The endpoint to call. For example: "/_matrix/client/v3/account/whoami"
* @param {any} qs The query string to send. Optional.
* @param {any} body The request body to send. Optional. Will be converted to JSON unless the type is a Buffer.
* @param {any} headers Additional headers to send in the request.
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export * from "./models/Crypto";
export * from "./models/MSC2176";
export * from "./models/Account";
export * from "./models/PowerLevelAction";
export * from "./models/ServerVersions";

// Unstable models
export * from "./models/unstable/MediaInfo";
Expand Down
8 changes: 8 additions & 0 deletions src/models/ServerVersions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/**
* Representation of the server's supported specification versions and unstable feature flags.
* @category Models
*/
export type ServerVersions = {
unstable_features?: Record<string, boolean>;
versions: string[];
};
4 changes: 2 additions & 2 deletions test/AdminApisTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ describe('AdminApis', () => {
},
};

http.when("GET", "/_matrix/client/r0/admin/whois").respond(200, (path, content) => {
expect(path).toEqual(`${hsUrl}/_matrix/client/r0/admin/whois/${encodeURIComponent(userId)}`);
http.when("GET", "/_matrix/client/v3/admin/whois").respond(200, (path, content) => {
expect(path).toEqual(`${hsUrl}/_matrix/client/v3/admin/whois/${encodeURIComponent(userId)}`);
return response;
});

Expand Down
8 changes: 4 additions & 4 deletions test/MatrixAuthTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ describe('MatrixAuth', () => {
const password = "P@ssw0rd";
const accessToken = "1234";

http.when("POST", "/_matrix/client/r0/register").respond(200, (path, content) => {
http.when("POST", "/_matrix/client/v3/register").respond(200, (path, content) => {
expect(content).toMatchObject({ username, password });
return { access_token: accessToken };
});
Expand All @@ -51,7 +51,7 @@ describe('MatrixAuth', () => {
const sessionId = "5678";

// First is UIA
http.when("POST", "/_matrix/client/r0/register").respond(401, (path, content) => {
http.when("POST", "/_matrix/client/v3/register").respond(401, (path, content) => {
expect(content).toMatchObject({ username, password });
return {
session: sessionId,
Expand All @@ -61,7 +61,7 @@ describe('MatrixAuth', () => {
params: {},
};
});
http.when("POST", "/_matrix/client/r0/register").respond(200, (path, content) => {
http.when("POST", "/_matrix/client/v3/register").respond(200, (path, content) => {
expect(content).toMatchObject({
username,
password,
Expand All @@ -87,7 +87,7 @@ describe('MatrixAuth', () => {
const password = "P@ssw0rd";
const accessToken = "1234";

http.when("POST", "/_matrix/client/r0/login").respond(200, (path, content) => {
http.when("POST", "/_matrix/client/v3/login").respond(200, (path, content) => {
expect(content).toMatchObject({
type: "m.login.password",
identifier: {
Expand Down
Loading