mirror of
https://github.com/turt2live/matrix-dimension.git
synced 2024-10-01 05:05:53 +00:00
Support MSC1708 (and co.) and prepare for MSC1711
Fixes https://github.com/turt2live/matrix-dimension/issues/234 Later support for MSC1711 will be done in https://github.com/turt2live/matrix-dimension/issues/238
This commit is contained in:
parent
3db2896d76
commit
38ea8d30db
82
package-lock.json
generated
82
package-lock.json
generated
@ -4379,14 +4379,12 @@
|
|||||||
"balanced-match": {
|
"balanced-match": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"brace-expansion": {
|
"brace-expansion": {
|
||||||
"version": "1.1.11",
|
"version": "1.1.11",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"balanced-match": "^1.0.0",
|
"balanced-match": "^1.0.0",
|
||||||
"concat-map": "0.0.1"
|
"concat-map": "0.0.1"
|
||||||
@ -4401,20 +4399,17 @@
|
|||||||
"code-point-at": {
|
"code-point-at": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"concat-map": {
|
"concat-map": {
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"console-control-strings": {
|
"console-control-strings": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"core-util-is": {
|
"core-util-is": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
@ -4531,8 +4526,7 @@
|
|||||||
"inherits": {
|
"inherits": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"ini": {
|
"ini": {
|
||||||
"version": "1.3.5",
|
"version": "1.3.5",
|
||||||
@ -4544,7 +4538,6 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"number-is-nan": "^1.0.0"
|
"number-is-nan": "^1.0.0"
|
||||||
}
|
}
|
||||||
@ -4559,7 +4552,6 @@
|
|||||||
"version": "3.0.4",
|
"version": "3.0.4",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"brace-expansion": "^1.1.7"
|
"brace-expansion": "^1.1.7"
|
||||||
}
|
}
|
||||||
@ -4567,14 +4559,12 @@
|
|||||||
"minimist": {
|
"minimist": {
|
||||||
"version": "0.0.8",
|
"version": "0.0.8",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"minipass": {
|
"minipass": {
|
||||||
"version": "2.2.4",
|
"version": "2.2.4",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"safe-buffer": "^5.1.1",
|
"safe-buffer": "^5.1.1",
|
||||||
"yallist": "^3.0.0"
|
"yallist": "^3.0.0"
|
||||||
@ -4593,7 +4583,6 @@
|
|||||||
"version": "0.5.1",
|
"version": "0.5.1",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"minimist": "0.0.8"
|
"minimist": "0.0.8"
|
||||||
}
|
}
|
||||||
@ -4674,8 +4663,7 @@
|
|||||||
"number-is-nan": {
|
"number-is-nan": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"object-assign": {
|
"object-assign": {
|
||||||
"version": "4.1.1",
|
"version": "4.1.1",
|
||||||
@ -4687,7 +4675,6 @@
|
|||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"wrappy": "1"
|
"wrappy": "1"
|
||||||
}
|
}
|
||||||
@ -4809,7 +4796,6 @@
|
|||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"code-point-at": "^1.0.0",
|
"code-point-at": "^1.0.0",
|
||||||
"is-fullwidth-code-point": "^1.0.0",
|
"is-fullwidth-code-point": "^1.0.0",
|
||||||
@ -5672,8 +5658,7 @@
|
|||||||
"ip-regex": {
|
"ip-regex": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz",
|
||||||
"integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=",
|
"integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"ipaddr.js": {
|
"ipaddr.js": {
|
||||||
"version": "1.8.0",
|
"version": "1.8.0",
|
||||||
@ -5948,6 +5933,11 @@
|
|||||||
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
|
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"isipaddress": {
|
||||||
|
"version": "0.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/isipaddress/-/isipaddress-0.0.2.tgz",
|
||||||
|
"integrity": "sha1-qeRIRlEGrwHmCFHPI146wwEUUNM="
|
||||||
|
},
|
||||||
"isnumeric": {
|
"isnumeric": {
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/isnumeric/-/isnumeric-0.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/isnumeric/-/isnumeric-0.2.0.tgz",
|
||||||
@ -11018,6 +11008,25 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"request-promise": {
|
||||||
|
"version": "4.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.2.tgz",
|
||||||
|
"integrity": "sha1-0epG1lSm7k+O5qT+oQGMIpEZBLQ=",
|
||||||
|
"requires": {
|
||||||
|
"bluebird": "^3.5.0",
|
||||||
|
"request-promise-core": "1.1.1",
|
||||||
|
"stealthy-require": "^1.1.0",
|
||||||
|
"tough-cookie": ">=2.3.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"request-promise-core": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.1.tgz",
|
||||||
|
"integrity": "sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=",
|
||||||
|
"requires": {
|
||||||
|
"lodash": "^4.13.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"require-dir-all": {
|
"require-dir-all": {
|
||||||
"version": "0.4.15",
|
"version": "0.4.15",
|
||||||
"resolved": "https://registry.npmjs.org/require-dir-all/-/require-dir-all-0.4.15.tgz",
|
"resolved": "https://registry.npmjs.org/require-dir-all/-/require-dir-all-0.4.15.tgz",
|
||||||
@ -12003,6 +12012,11 @@
|
|||||||
"integrity": "sha1-kPn0ZqIOjjnvJNqVnB5hHCow3VQ=",
|
"integrity": "sha1-kPn0ZqIOjjnvJNqVnB5hHCow3VQ=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"split-host": {
|
||||||
|
"version": "0.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/split-host/-/split-host-0.1.1.tgz",
|
||||||
|
"integrity": "sha512-nrlaPJMHkr3hKx7aCyr+S0OgUvAm/xKzWWMHej0IsMamWjRC52Fv+NGZwuqRE1lyu1iNWCmcrpZ1S1qvk+Uiwg=="
|
||||||
|
},
|
||||||
"split-string": {
|
"split-string": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
|
||||||
@ -12153,6 +12167,11 @@
|
|||||||
"readable-stream": "^2.0.1"
|
"readable-stream": "^2.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"stealthy-require": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
|
||||||
|
"integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks="
|
||||||
|
},
|
||||||
"stream-browserify": {
|
"stream-browserify": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz",
|
||||||
@ -12758,6 +12777,23 @@
|
|||||||
"resolved": "https://registry.npmjs.org/toposort-class/-/toposort-class-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/toposort-class/-/toposort-class-1.0.1.tgz",
|
||||||
"integrity": "sha1-f/0feMi+KMO6Rc1OGj9e4ZO9mYg="
|
"integrity": "sha1-f/0feMi+KMO6Rc1OGj9e4ZO9mYg="
|
||||||
},
|
},
|
||||||
|
"tough-cookie": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==",
|
||||||
|
"requires": {
|
||||||
|
"ip-regex": "^2.1.0",
|
||||||
|
"psl": "^1.1.28",
|
||||||
|
"punycode": "^2.1.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"punycode": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"trim-newlines": {
|
"trim-newlines": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
"dns-then": "^0.1.0",
|
"dns-then": "^0.1.0",
|
||||||
"express": "^4.16.4",
|
"express": "^4.16.4",
|
||||||
"git-rev-sync": "^1.12.0",
|
"git-rev-sync": "^1.12.0",
|
||||||
|
"isipaddress": "0.0.2",
|
||||||
"js-yaml": "^3.12.0",
|
"js-yaml": "^3.12.0",
|
||||||
"lodash": "^4.17.5",
|
"lodash": "^4.17.5",
|
||||||
"matrix-js-snippets": "^0.2.8",
|
"matrix-js-snippets": "^0.2.8",
|
||||||
@ -36,10 +37,12 @@
|
|||||||
"netmask": "^1.0.6",
|
"netmask": "^1.0.6",
|
||||||
"random-string": "^0.2.0",
|
"random-string": "^0.2.0",
|
||||||
"request": "^2.88.0",
|
"request": "^2.88.0",
|
||||||
|
"request-promise": "^4.2.2",
|
||||||
"require-dir-all": "^0.4.15",
|
"require-dir-all": "^0.4.15",
|
||||||
"sequelize": "^4.39.1",
|
"sequelize": "^4.39.1",
|
||||||
"sequelize-typescript": "^0.6.6",
|
"sequelize-typescript": "^0.6.6",
|
||||||
"sharp": "^0.21.1",
|
"sharp": "^0.21.1",
|
||||||
|
"split-host": "^0.1.1",
|
||||||
"spotify-uri": "^1.0.0",
|
"spotify-uri": "^1.0.0",
|
||||||
"sqlite3": "^4.0.4",
|
"sqlite3": "^4.0.4",
|
||||||
"telegraf": "^3.25.5",
|
"telegraf": "^3.25.5",
|
||||||
|
@ -4,7 +4,7 @@ import config from "../../config";
|
|||||||
import { ApiError } from "../ApiError";
|
import { ApiError } from "../ApiError";
|
||||||
import { MatrixLiteClient } from "../../matrix/MatrixLiteClient";
|
import { MatrixLiteClient } from "../../matrix/MatrixLiteClient";
|
||||||
import { CURRENT_VERSION } from "../../version";
|
import { CURRENT_VERSION } from "../../version";
|
||||||
import { getFederationUrl } from "../../matrix/helpers";
|
import { getFederationConnInfo } from "../../matrix/helpers";
|
||||||
|
|
||||||
interface DimensionVersionResponse {
|
interface DimensionVersionResponse {
|
||||||
version: string;
|
version: string;
|
||||||
@ -17,6 +17,7 @@ interface DimensionConfigResponse {
|
|||||||
name: string;
|
name: string;
|
||||||
userId: string;
|
userId: string;
|
||||||
federationUrl: string;
|
federationUrl: string;
|
||||||
|
federationHostname: string;
|
||||||
clientServerUrl: string;
|
clientServerUrl: string;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -70,15 +71,28 @@ export class AdminService {
|
|||||||
await AdminService.validateAndGetAdminTokenOwner(scalarToken);
|
await AdminService.validateAndGetAdminTokenOwner(scalarToken);
|
||||||
|
|
||||||
const client = new MatrixLiteClient(config.homeserver.accessToken);
|
const client = new MatrixLiteClient(config.homeserver.accessToken);
|
||||||
|
const fedInfo = await getFederationConnInfo(config.homeserver.name);
|
||||||
return {
|
return {
|
||||||
admins: config.admins,
|
admins: config.admins,
|
||||||
widgetBlacklist: config.widgetBlacklist,
|
widgetBlacklist: config.widgetBlacklist,
|
||||||
homeserver: {
|
homeserver: {
|
||||||
name: config.homeserver.name,
|
name: config.homeserver.name,
|
||||||
userId: await client.whoAmI(),
|
userId: await client.whoAmI(),
|
||||||
federationUrl: await getFederationUrl(config.homeserver.name),
|
federationUrl: fedInfo.url,
|
||||||
|
federationHostname: fedInfo.hostname,
|
||||||
clientServerUrl: config.homeserver.clientServerUrl,
|
clientServerUrl: config.homeserver.clientServerUrl,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("test/federation")
|
||||||
|
public async testFederationRouting(@QueryParam("scalar_token") scalarToken: string, @QueryParam("server_name") serverName: string): Promise<any> {
|
||||||
|
await AdminService.validateAndGetAdminTokenOwner(scalarToken);
|
||||||
|
|
||||||
|
return {
|
||||||
|
inputServerName: serverName,
|
||||||
|
resolvedServer: await getFederationConnInfo(serverName),
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
@ -3,14 +3,26 @@ import { LogService } from "matrix-js-snippets";
|
|||||||
import { Cache, CACHE_FEDERATION } from "../MemoryCache";
|
import { Cache, CACHE_FEDERATION } from "../MemoryCache";
|
||||||
import * as request from "request";
|
import * as request from "request";
|
||||||
import config from "../config";
|
import config from "../config";
|
||||||
|
import splitHost from 'split-host';
|
||||||
|
import * as isIP from "isipaddress";
|
||||||
|
import * as requestPromise from "request-promise";
|
||||||
|
|
||||||
export async function getFederationUrl(serverName: string): Promise<string> {
|
export interface IFederationConnectionInfo {
|
||||||
|
hostname: string;
|
||||||
|
url: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getFederationConnInfo(serverName: string): Promise<IFederationConnectionInfo> {
|
||||||
|
const expirationMs = 2 * 60 * 60 * 1000; // 2 hours
|
||||||
|
|
||||||
|
// Check to see if we've cached the hostname at all already
|
||||||
const cachedUrl = Cache.for(CACHE_FEDERATION).get(serverName);
|
const cachedUrl = Cache.for(CACHE_FEDERATION).get(serverName);
|
||||||
if (cachedUrl) {
|
if (cachedUrl) {
|
||||||
LogService.verbose("matrix", "Cached federation URL for " + serverName + " is " + cachedUrl);
|
LogService.verbose("matrix", "Cached federation URL for " + serverName + " is " + cachedUrl.url);
|
||||||
return cachedUrl;
|
return cachedUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Rely on the configuration for a federation URL if we can
|
||||||
if (serverName === config.homeserver.name && config.homeserver.federationUrl) {
|
if (serverName === config.homeserver.name && config.homeserver.federationUrl) {
|
||||||
let url = config.homeserver.federationUrl;
|
let url = config.homeserver.federationUrl;
|
||||||
if (url.endsWith("/")) {
|
if (url.endsWith("/")) {
|
||||||
@ -18,50 +30,137 @@ export async function getFederationUrl(serverName: string): Promise<string> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
LogService.info("matrix", "Using configured federation URL for " + serverName);
|
LogService.info("matrix", "Using configured federation URL for " + serverName);
|
||||||
Cache.for(CACHE_FEDERATION).put(serverName, url);
|
const fedObj = {url, hostname: serverName};
|
||||||
return url;
|
Cache.for(CACHE_FEDERATION).put(serverName, fedObj, expirationMs);
|
||||||
|
return fedObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
let serverUrl = null;
|
// Dev note: The remainder of this is largely transcribed from matrix-media-repo
|
||||||
let expirationMs = 4 * 60 * 60 * 1000; // default is 4 hours
|
|
||||||
|
|
||||||
|
const hp = splitHost(serverName);
|
||||||
|
if (!hp.host) throw new Error("No hostname provided");
|
||||||
|
let defaultPort = false;
|
||||||
|
if (!hp.port) {
|
||||||
|
defaultPort = true;
|
||||||
|
hp.port = 8448;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 1 of the discovery process: if the hostname is an IP, use that with explicit or default port
|
||||||
|
if (isIP.test(hp.host)) {
|
||||||
|
const fedUrl = `https://${hp.host}:${hp.port}`;
|
||||||
|
const fedObj = {url: fedUrl, hostname: serverName};
|
||||||
|
Cache.for(CACHE_FEDERATION).put(serverName, fedObj, expirationMs);
|
||||||
|
LogService.info("matrix", `Federation URL for ${serverName} is ${fedUrl} (IP address)`);
|
||||||
|
return fedObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 2: if the hostname is not an IP address, and an explicit port is given, use that
|
||||||
|
if (!defaultPort) {
|
||||||
|
const fedUrl = `https://${hp.host}:${hp.port}`;
|
||||||
|
const fedObj = {url: fedUrl, hostname: hp.host};
|
||||||
|
Cache.for(CACHE_FEDERATION).put(serverName, fedObj, expirationMs);
|
||||||
|
LogService.info("matrix", `Federation URL for ${serverName} is ${fedUrl} (explicit port)`);
|
||||||
|
return fedObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 3: if the hostname is not an IP address and no explicit port is given, do .well-known
|
||||||
try {
|
try {
|
||||||
const records = await dns.resolveSrv("_matrix._tcp." + serverName);
|
let result = await requestPromise(`https://${hp.host}/.well-known/matrix/server`);
|
||||||
|
if (typeof (result) === 'string') result = JSON.parse(result);
|
||||||
|
const wkServerAddr = result['m.server'];
|
||||||
|
if (wkServerAddr) {
|
||||||
|
const wkHp = splitHost(wkServerAddr);
|
||||||
|
if (!wkHp.host) {
|
||||||
|
// noinspection ExceptionCaughtLocallyJS
|
||||||
|
throw new Error("No hostname provided for m.server");
|
||||||
|
}
|
||||||
|
let wkDefaultPort = false;
|
||||||
|
if (!wkHp.port) {
|
||||||
|
wkDefaultPort = true;
|
||||||
|
wkHp.port = 8448;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 3a: if the delegated host is an IP address, use that (regardless of port)
|
||||||
|
if (isIP.test(wkHp.host)) {
|
||||||
|
const fedUrl = `https://${wkHp.host}:${wkHp.port}`;
|
||||||
|
const fedObj = {url: fedUrl, hostname: wkServerAddr};
|
||||||
|
Cache.for(CACHE_FEDERATION).put(serverName, fedObj, expirationMs);
|
||||||
|
LogService.info("matrix", `Federation URL for ${serverName} is ${fedUrl} (WK; IP address)`);
|
||||||
|
return fedObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 3b: if the delegated host is not an IP and an explicit port is given, use that
|
||||||
|
if (!wkDefaultPort) {
|
||||||
|
const fedUrl = `https://${wkHp.host}:${wkHp.port}`;
|
||||||
|
const fedObj = {url: fedUrl, hostname: wkHp.host};
|
||||||
|
Cache.for(CACHE_FEDERATION).put(serverName, fedObj, expirationMs);
|
||||||
|
LogService.info("matrix", `Federation URL for ${serverName} is ${fedUrl} (WK; explicit port)`);
|
||||||
|
return fedObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 3c: if the delegated host is not an IP and doesn't have a port, start a SRV lookup and use that
|
||||||
|
try {
|
||||||
|
const records = await dns.resolveSrv("_matrix._tcp." + hp.host);
|
||||||
if (records && records.length > 0) {
|
if (records && records.length > 0) {
|
||||||
serverUrl = "https://" + records[0].name + ":" + records[0].port;
|
const fedUrl = `https://${records[0].name}:${records[0].port}`;
|
||||||
expirationMs = records[0].ttl * 1000;
|
const fedObj = {url: fedUrl, hostname: wkHp.host};
|
||||||
|
Cache.for(CACHE_FEDERATION).put(serverName, fedObj, expirationMs);
|
||||||
|
LogService.info("matrix", `Federation URL for ${serverName} is ${fedUrl} (WK; SRV)`);
|
||||||
|
return fedObj;
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (e) {
|
||||||
// Not having the SRV record isn't bad, it just means that the server operator decided to not use SRV records.
|
LogService.warn("matrix", "Non-fatal error looking up .well-known SRV for " + serverName);
|
||||||
// When there's no SRV record we default to port 8448 (as per the federation rules) in the lower .then()
|
LogService.warn("matrix", e);
|
||||||
// People tend to think that the lack of an SRV record is bad, but in reality it's only a problem if one was set and
|
|
||||||
// it's not being found. Most people don't set up the SRV record, but some do.
|
|
||||||
LogService.verbose("matrix", err);
|
|
||||||
LogService.warn("matrix", "Could not find _matrix._tcp." + serverName + " DNS record. This is normal for most servers.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(expirationMs > 0)) { // This is weird so we can catch NaN easier
|
// Step 3d: use the delegated host as-is
|
||||||
expirationMs = 4 * 60 * 60 * 1000;
|
const fedUrl = `https://${wkHp.host}:${wkHp.port}`;
|
||||||
|
const fedObj = {url: fedUrl, hostname: wkHp.host};
|
||||||
|
Cache.for(CACHE_FEDERATION).put(serverName, fedObj, expirationMs);
|
||||||
|
LogService.info("matrix", `Federation URL for ${serverName} is ${fedUrl} (WK; fallback)`);
|
||||||
|
return fedObj;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
LogService.warn("matrix", "Non-fatal error looking up .well-known for " + serverName);
|
||||||
|
LogService.warn("matrix", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!serverUrl) serverUrl = "https://" + serverName + ":8448";
|
// Step 4: try resolving a hostname using SRV records and use that
|
||||||
LogService.verbose("matrix", "Federation URL for " + serverName + " is " + serverUrl + " - caching for " + expirationMs + " ms");
|
try {
|
||||||
Cache.for(CACHE_FEDERATION).put(serverName, serverUrl, expirationMs);
|
const records = await dns.resolveSrv("_matrix._tcp." + hp.host);
|
||||||
return serverUrl;
|
if (records && records.length > 0) {
|
||||||
|
const fedUrl = `https://${records[0].name}:${records[0].port}`;
|
||||||
|
const fedObj = {url: fedUrl, hostname: hp.host};
|
||||||
|
Cache.for(CACHE_FEDERATION).put(serverName, fedObj, expirationMs);
|
||||||
|
LogService.info("matrix", `Federation URL for ${serverName} is ${fedUrl} (SRV)`);
|
||||||
|
return fedObj;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
LogService.warn("matrix", "Non-fatal error looking up SRV for " + serverName);
|
||||||
|
LogService.warn("matrix", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 5: use the target host as-is
|
||||||
|
const fedUrl = `https://${hp.host}:${hp.port}`;
|
||||||
|
const fedObj = {url: fedUrl, hostname: hp.host};
|
||||||
|
Cache.for(CACHE_FEDERATION).put(serverName, fedObj, expirationMs);
|
||||||
|
LogService.info("matrix", `Federation URL for ${serverName} is ${fedUrl} (SRV)`);
|
||||||
|
return fedObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function doFederatedApiCall(method: string, serverName: string, endpoint: string, query?: object, body?: object): Promise<any> {
|
export async function doFederatedApiCall(method: string, serverName: string, endpoint: string, query?: object, body?: object): Promise<any> {
|
||||||
const federationUrl = await getFederationUrl(serverName);
|
const federationInfo = await getFederationConnInfo(serverName);
|
||||||
LogService.info("matrix", "Doing federated API call: " + federationUrl + endpoint);
|
LogService.info("matrix", "Doing federated API call: " + federationInfo.url + endpoint);
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
request({
|
request({
|
||||||
method: method,
|
method: method,
|
||||||
url: federationUrl + endpoint,
|
url: federationInfo.url + endpoint,
|
||||||
qs: query,
|
qs: query,
|
||||||
json: body,
|
json: body,
|
||||||
|
// TODO: Remove this for MSC1711 support
|
||||||
rejectUnauthorized: false, // allow self signed certs (for federation)
|
rejectUnauthorized: false, // allow self signed certs (for federation)
|
||||||
headers: {
|
headers: {
|
||||||
"Host": serverName,
|
"Host": federationInfo.hostname,
|
||||||
},
|
},
|
||||||
}, (err, res, _body) => {
|
}, (err, res, _body) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
<strong>Homeserver</strong><br />
|
<strong>Homeserver</strong><br />
|
||||||
Name: {{ config.homeserver.name }}<br />
|
Name: {{ config.homeserver.name }}<br />
|
||||||
Federation URL: {{ config.homeserver.federationUrl }}<br />
|
Federation URL: {{ config.homeserver.federationUrl }}<br />
|
||||||
|
Federation Hostname: {{ config.homeserver.federationHostname }}<br />
|
||||||
Client/Server URL: {{ config.homeserver.clientServerUrl }}<br />
|
Client/Server URL: {{ config.homeserver.clientServerUrl }}<br />
|
||||||
Utility User ID: {{ config.homeserver.userId }}
|
Utility User ID: {{ config.homeserver.userId }}
|
||||||
</div>
|
</div>
|
||||||
|
@ -7,6 +7,7 @@ export interface FE_DimensionConfig {
|
|||||||
name: string;
|
name: string;
|
||||||
userId: string;
|
userId: string;
|
||||||
federationUrl: string;
|
federationUrl: string;
|
||||||
|
federationHostname: string;
|
||||||
clientServerUrl: string;
|
clientServerUrl: string;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user