mirror of
https://github.com/turt2live/matrix-dimension.git
synced 2024-10-01 01:05:53 -04:00
Support explicit setting of the federation/client URLs
The client/server URL is needed for go-neb to work correctly, and to remove our complete dependence on federation. The federation URL is also configurable so servers that don't wish to federate can specify a local address.
This commit is contained in:
parent
cc921779ae
commit
8cdae3359d
@ -3,9 +3,23 @@ web:
|
||||
port: 8184
|
||||
address: '0.0.0.0'
|
||||
|
||||
# Homeserver configuration (used to proxy some requests to the homeserver for processing)
|
||||
# Homeserver configuration
|
||||
homeserver:
|
||||
# The domain name of the homeserver. This is used in many places, such as with go-neb
|
||||
# setups, to identify the homeserver.
|
||||
name: "t2bot.io"
|
||||
|
||||
# The URL that Dimension, go-neb, and other services provisioned by Dimension should
|
||||
# use to access the homeserver with.
|
||||
clientServerUrl: "https://t2bot.io"
|
||||
|
||||
# The URL that Dimension should use when trying to communicate with federated APIs on
|
||||
# the homeserver. If not supplied or left empty Dimension will try to resolve the address
|
||||
# through the normal federation process.
|
||||
#federationUrl: "https://t2bot.io:8448"
|
||||
|
||||
# The access token Dimension should use for miscellaneous access to the homeserver. This
|
||||
# should be for a valid user.
|
||||
accessToken: "something"
|
||||
|
||||
# These users can modify the integrations this Dimension supports.
|
||||
@ -16,10 +30,10 @@ admins:
|
||||
# IPs and CIDR ranges listed here will be blocked from being widgets.
|
||||
# Note: Widgets may still be embedded with restricted content, although not through Dimension directly.
|
||||
widgetBlacklist:
|
||||
- 10.0.0.0/8
|
||||
- 172.16.0.0/12
|
||||
- 192.168.0.0/16
|
||||
- 127.0.0.0/8
|
||||
- 10.0.0.0/8
|
||||
- 172.16.0.0/12
|
||||
- 192.168.0.0/16
|
||||
- 127.0.0.0/8
|
||||
|
||||
# Where the database for Dimension is
|
||||
database:
|
||||
|
@ -4,7 +4,6 @@ import AppService from "../../db/models/AppService";
|
||||
import { AppserviceStore } from "../../db/AppserviceStore";
|
||||
import { ApiError } from "../ApiError";
|
||||
import { MatrixAppserviceClient } from "../../matrix/MatrixAppserviceClient";
|
||||
import config from "../../config";
|
||||
import { LogService } from "matrix-js-snippets";
|
||||
|
||||
interface AppserviceResponse {
|
||||
@ -67,7 +66,7 @@ export class AdminAppserviceService {
|
||||
await AdminService.validateAndGetAdminTokenOwner(scalarToken);
|
||||
|
||||
const appservice = await AppserviceStore.getAppservice(asId);
|
||||
const client = new MatrixAppserviceClient(config.homeserver.name, appservice);
|
||||
const client = new MatrixAppserviceClient(appservice);
|
||||
const userId = await client.whoAmI();
|
||||
|
||||
if (userId.startsWith("@" + appservice.userPrefix)) return {}; // 200 OK
|
||||
|
@ -4,6 +4,7 @@ import config from "../../config";
|
||||
import { ApiError } from "../ApiError";
|
||||
import { MatrixLiteClient } from "../../matrix/MatrixLiteClient";
|
||||
import { CURRENT_VERSION } from "../../version";
|
||||
import { getFederationUrl } from "../../matrix/helpers";
|
||||
|
||||
interface DimensionVersionResponse {
|
||||
version: string;
|
||||
@ -16,6 +17,7 @@ interface DimensionConfigResponse {
|
||||
name: string;
|
||||
userId: string;
|
||||
federationUrl: string;
|
||||
clientServerUrl: string;
|
||||
};
|
||||
}
|
||||
|
||||
@ -52,14 +54,15 @@ export class AdminService {
|
||||
public async getConfig(@QueryParam("scalar_token") scalarToken: string): Promise<DimensionConfigResponse> {
|
||||
await AdminService.validateAndGetAdminTokenOwner(scalarToken);
|
||||
|
||||
const client = new MatrixLiteClient(config.homeserver.name, config.homeserver.accessToken);
|
||||
const client = new MatrixLiteClient(config.homeserver.accessToken);
|
||||
return {
|
||||
admins: config.admins,
|
||||
widgetBlacklist: config.widgetBlacklist,
|
||||
homeserver: {
|
||||
name: config.homeserver.name,
|
||||
userId: await client.whoAmI(),
|
||||
federationUrl: await client.getFederationUrl(),
|
||||
federationUrl: await getFederationUrl(config.homeserver.name),
|
||||
clientServerUrl: config.homeserver.clientServerUrl,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ export class ScalarWidgetService {
|
||||
return cachedResult;
|
||||
}
|
||||
|
||||
const client = new MatrixLiteClient(config.homeserver.name, config.homeserver.accessToken);
|
||||
const client = new MatrixLiteClient(config.homeserver.accessToken);
|
||||
|
||||
try {
|
||||
const preview = await client.getUrlPreview(url);
|
||||
|
@ -9,6 +9,8 @@ export interface DimensionConfig {
|
||||
homeserver: {
|
||||
name: string;
|
||||
accessToken: string;
|
||||
clientServerUrl: string;
|
||||
federationUrl: string;
|
||||
};
|
||||
widgetBlacklist: string[];
|
||||
database: {
|
||||
|
@ -2,7 +2,6 @@ import AppService from "./models/AppService";
|
||||
import AppServiceUser from "./models/AppServiceUser";
|
||||
import * as randomString from "random-string";
|
||||
import { MatrixAppserviceClient } from "../matrix/MatrixAppserviceClient";
|
||||
import config from "../config";
|
||||
|
||||
export class AppserviceStore {
|
||||
|
||||
@ -49,7 +48,7 @@ export class AppserviceStore {
|
||||
const appservice = await AppService.findOne({where: {id: appserviceId}});
|
||||
if (!appservice) throw new Error("Appservice not found");
|
||||
|
||||
const client = new MatrixAppserviceClient(config.homeserver.name, appservice);
|
||||
const client = new MatrixAppserviceClient(appservice);
|
||||
const localpart = AppserviceStore.getSafeUserId(userId.substring(1).split(":")[0]);
|
||||
const response = await client.registerUser(localpart);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { doFederatedApiCall } from "./helpers";
|
||||
import { doClientApiCall } from "./helpers";
|
||||
import AppService from "../db/models/AppService";
|
||||
|
||||
export interface MatrixUserResponse {
|
||||
@ -10,13 +10,12 @@ export interface MatrixUserResponse {
|
||||
|
||||
export class MatrixAppserviceClient {
|
||||
|
||||
constructor(private homeserverName: string, private appservice: AppService) {
|
||||
constructor(private appservice: AppService) {
|
||||
}
|
||||
|
||||
public async registerUser(localpart: string): Promise<MatrixUserResponse> {
|
||||
return doFederatedApiCall(
|
||||
return doClientApiCall(
|
||||
"POST",
|
||||
this.homeserverName,
|
||||
"/_matrix/client/r0/register",
|
||||
{access_token: this.appservice.asToken},
|
||||
{type: "m.login.application_service", username: localpart},
|
||||
@ -24,9 +23,8 @@ export class MatrixAppserviceClient {
|
||||
}
|
||||
|
||||
public async whoAmI(): Promise<string> {
|
||||
const response = await doFederatedApiCall(
|
||||
const response = await doClientApiCall(
|
||||
"GET",
|
||||
this.homeserverName,
|
||||
"/_matrix/client/r0/account/whoami",
|
||||
{access_token: this.appservice.asToken},
|
||||
);
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { doFederatedApiCall, getFederationUrl as getFedUrl } from "./helpers";
|
||||
import { doClientApiCall } from "./helpers";
|
||||
|
||||
export interface MatrixUrlPreview {
|
||||
// This is really the only parameter we care about
|
||||
@ -7,26 +7,20 @@ export interface MatrixUrlPreview {
|
||||
|
||||
export class MatrixLiteClient {
|
||||
|
||||
constructor(private homeserverName: string, private accessToken: string) {
|
||||
}
|
||||
|
||||
public async getFederationUrl(): Promise<string> {
|
||||
return getFedUrl(this.homeserverName);
|
||||
constructor(private accessToken: string) {
|
||||
}
|
||||
|
||||
public async getUrlPreview(url: string): Promise<MatrixUrlPreview> {
|
||||
return doFederatedApiCall(
|
||||
return doClientApiCall(
|
||||
"GET",
|
||||
this.homeserverName,
|
||||
"/_matrix/media/r0/preview_url",
|
||||
{access_token: this.accessToken, url: url}
|
||||
);
|
||||
}
|
||||
|
||||
public async whoAmI(): Promise<string> {
|
||||
const response = await doFederatedApiCall(
|
||||
const response = await doClientApiCall(
|
||||
"GET",
|
||||
this.homeserverName,
|
||||
"/_matrix/client/r0/account/whoami",
|
||||
{access_token: this.accessToken}
|
||||
);
|
||||
|
@ -7,6 +7,8 @@ export class MatrixOpenIdClient {
|
||||
}
|
||||
|
||||
public async getUserId(): Promise<string> {
|
||||
// TODO: Implement/prefer https://github.com/matrix-org/matrix-doc/issues/1115
|
||||
// #1115 also means this should become a client API call, not a federated one (finally)
|
||||
const response = await doFederatedApiCall(
|
||||
"GET",
|
||||
this.openId.matrix_server_name,
|
||||
|
@ -2,6 +2,7 @@ import * as dns from "dns-then";
|
||||
import { LogService } from "matrix-js-snippets";
|
||||
import { Cache, CACHE_FEDERATION } from "../MemoryCache";
|
||||
import * as request from "request";
|
||||
import config from "../config";
|
||||
|
||||
export async function getFederationUrl(serverName: string): Promise<string> {
|
||||
const cachedUrl = Cache.for(CACHE_FEDERATION).get(serverName);
|
||||
@ -10,6 +11,17 @@ export async function getFederationUrl(serverName: string): Promise<string> {
|
||||
return cachedUrl;
|
||||
}
|
||||
|
||||
if (serverName === config.homeserver.name && config.homeserver.federationUrl) {
|
||||
let url = config.homeserver.federationUrl;
|
||||
if (url.endsWith("/")) {
|
||||
url = url.substring(0, url.length - 1);
|
||||
}
|
||||
|
||||
LogService.info("matrix", "Using configured federation URL for " + serverName);
|
||||
Cache.for(CACHE_FEDERATION).put(serverName, url);
|
||||
return url;
|
||||
}
|
||||
|
||||
let serverUrl = null;
|
||||
let expirationMs = 4 * 60 * 60 * 1000; // default is 4 hours
|
||||
|
||||
@ -49,7 +61,33 @@ export async function doFederatedApiCall(method: string, serverName: string, end
|
||||
LogService.error("matrix", err);
|
||||
reject(err);
|
||||
} else if (res.statusCode !== 200) {
|
||||
LogService.error("matrix", "Got status code " + res.statusCode + " while calling " + endpoint);
|
||||
LogService.error("matrix", "Got status code " + res.statusCode + " while calling federated endpoint " + endpoint);
|
||||
reject(new Error("Error in request: invalid status code"));
|
||||
} else {
|
||||
if (typeof(res.body) === "string") res.body = JSON.parse(res.body);
|
||||
resolve(res.body);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export async function doClientApiCall(method: string, endpoint: string, query?: object, body?: object): Promise<any> {
|
||||
let url = config.homeserver.clientServerUrl;
|
||||
if (url.endsWith("/")) url = url.substring(0, url.length - 1);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
request({
|
||||
method: method,
|
||||
url: url + endpoint,
|
||||
qs: query,
|
||||
json: body,
|
||||
}, (err, res, _body) => {
|
||||
if (err) {
|
||||
LogService.error("matrix", "Error calling " + endpoint);
|
||||
LogService.error("matrix", err);
|
||||
reject(err);
|
||||
} else if (res.statusCode !== 200) {
|
||||
LogService.error("matrix", "Got status code " + res.statusCode + " while calling client endpoint " + endpoint);
|
||||
reject(new Error("Error in request: invalid status code"));
|
||||
} else {
|
||||
if (typeof(res.body) === "string") res.body = JSON.parse(res.body);
|
||||
|
@ -2,7 +2,6 @@ import { NebConfig } from "../models/neb";
|
||||
import { AppserviceStore } from "../db/AppserviceStore";
|
||||
import { Client } from "./models/client";
|
||||
import config from "../config";
|
||||
import { getFederationUrl } from "../matrix/helpers";
|
||||
import { LogService } from "matrix-js-snippets";
|
||||
import { Service } from "./models/service";
|
||||
import * as request from "request";
|
||||
@ -19,7 +18,7 @@ export class NebClient {
|
||||
public async updateUser(userId: string, isEnabled: boolean, sync = true, autoAcceptInvites = true): Promise<any> {
|
||||
const nebRequest: Client = {
|
||||
UserID: userId,
|
||||
HomeserverURL: await getFederationUrl(config.homeserver.name),
|
||||
HomeserverURL: config.homeserver.clientServerUrl,
|
||||
AccessToken: (isEnabled ? await this.getAccessToken(userId) : "DISABLED"),
|
||||
Sync: isEnabled ? sync : false,
|
||||
AutoJoinRooms: autoAcceptInvites
|
||||
|
@ -23,9 +23,8 @@
|
||||
<strong>Homeserver</strong><br />
|
||||
Name: {{ config.homeserver.name }}<br />
|
||||
Federation URL: {{ config.homeserver.federationUrl }}<br />
|
||||
<!-- Dimension makes no distinction for the csapi -->
|
||||
Client/Server URL: {{ config.homeserver.federationUrl }}<br />
|
||||
User ID: {{ config.homeserver.userId }}
|
||||
Client/Server URL: {{ config.homeserver.clientServerUrl }}<br />
|
||||
Utility User ID: {{ config.homeserver.userId }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -7,6 +7,7 @@ export interface FE_DimensionConfig {
|
||||
name: string;
|
||||
userId: string;
|
||||
federationUrl: string;
|
||||
clientServerUrl: string;
|
||||
};
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user