From f9c37610821f9e3e0894ed89c2d1f1da51195760 Mon Sep 17 00:00:00 2001 From: doesnm Date: Sat, 18 Oct 2025 18:31:10 +0200 Subject: [PATCH] Upload files to "/" --- matrix.js | 172 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 matrix.js diff --git a/matrix.js b/matrix.js new file mode 100644 index 0000000..b021d97 --- /dev/null +++ b/matrix.js @@ -0,0 +1,172 @@ +const express = require("express"); +const ed = require("@noble/ed25519"); +const { sha512 } = require("@noble/hashes/sha2.js"); +ed.hashes.sha512 = sha512; +const config = require("./config.json"); +const fs = require("node:fs"); +const { parse: parseUrl } = require("node:url"); +const dns = require("node:dns"); +const fetch = require("sync-fetch"); +const app = express(); +const deasync = require("deasync"); +const keysToBase64 = (keys) => { + return { + secretKey: new Buffer(keys.secretKey) + .toString("base64") + .replace("+", "-") + .replace("/", "_") + .replace(/=+$/, ""), + publicKey: new Buffer(keys.publicKey) + .toString("base64") + .replace("+", "-") + .replace("/", "_") + .replace(/=+$/, ""), + }; +}; +const base64ToKeys = (keys) => { + const fixBase64 = (str) => + str + .replace("-", "+") + .replace("_", "/") + .padEnd(str.length + ((4 - (str.length % 4)) % 4), "="); + return { + secretKey: new Uint8Array(Buffer.from(fixBase64(keys.secretKey), "base64")), + publicKey: new Uint8Array(Buffer.from(fixBase64(keys.publicKey), "base64")), + }; +}; + +if (!config.secretKey) { + const keys = ed.keygen(); + config.secretKey = keys.secretKey; + config.publicKey = keys.publicKey; + fs.writeFileSync( + "config.json", + JSON.stringify({ ...config, ...keysToBase64(config) }), + ); +} +const delegation = (name) => { + const res = fetch(`https://${name}/.well-known/matrix/server`); + if (res.status === 200) { + const json = res.json(); + if (!json["m.server"].includes(":")) { + return delegation(json["m.server"]); + } + return { domain: json["m.server"], host: json["m.server"] }; + } else { + const resolve = deasync(dns.resolveSrv); + try { + const res = resolve(`_matrix-fed._tcp.${name}`)[0]; + return { + domain: `${res.name}:${res.port}`, + host: name || res.name, + }; + } catch (_e) { + try { + const res = resolve(`_matrix._tcp.${name}`)[0]; + return { domain: `${res.name}:${res.port}`, host: name || res.name }; + } catch (_e) { + return { + domain: `${name}:8448`, + host: name || res.name, + }; + } + } + } +}; +const makeSignedRequest = (origin, method, url) => { + const parsed = parseUrl(url); + let payload = { + method: method, + uri: parsed.path, + destination: parsed.hostname, + origin: origin, + }; + payload = Object.fromEntries( + Object.entries(payload).sort(([keyA], [keyB]) => keyA.localeCompare(keyB)), + ); + const delegate = delegation(parsed.hostname); + const keys = base64ToKeys(config); + const signature = ed.sign( + new TextEncoder().encode(JSON.stringify(payload)), + keys.secretKey, + ); + console.log( + `X-Matrix origin="${origin}",destination="${parsed.hostname}",key="ed25519:${config.publicKey.slice(0, 5)}",sig="${new Buffer(signature).toString("base64").replace("+", "-").replace("/", "_").replace(/=+$/, "")}"`, + ); + return fetch( + `https://${delegate.domain}${parsed.path}`, + { + headers: { + Host: delegate.host, + Authorization: `X-Matrix origin="${origin}",destination="${parsed.hostname}",key="ed25519:${config.publicKey.slice(0, 5)}",sig="${new Buffer(signature).toString("base64").replace("+", "-").replace("/", "_").replace(/=+$/, "")}"`, + }, + }, + ); +}; + +app.get("/.well-known/matrix/server", (req, res) => { + return res.json({ + "m.server": req.host.includes(":") ? req.host : `${req.host}:443`, + }); +}); +app.get("/_matrix/federation/v1/version", (_req, res) => { + res.json({ + server: { + name: "idk", + version: "0.0.0.0.0.0.0.1", + }, + }); +}); +app.get("/_matrix/key/v2/server", (req, res) => { + const payload = { + old_verify_keys: {}, + server_name: req.host.replace(":443", ""), + valid_until_ts: Number.MAX_SAFE_INTEGER, + verify_keys: {}, + }; + payload.verify_keys[`ed25519:${config.publicKey.slice(0, 5)}`] = { + key: config.publicKey, + }; + const keys = base64ToKeys(config); + const signature = ed.sign( + new TextEncoder().encode( + JSON.stringify( + Object.fromEntries( + Object.entries(payload).sort(([keyA], [keyB]) => + keyA.localeCompare(keyB), + ), + ), + ), + ), + keys.secretKey, + ); + payload.signatures = {}; + payload.signatures[req.host.replace(":443", "")] = {}; + payload.signatures[req.host.replace(":443", "")][ + `ed25519:${config.publicKey.slice(0, 5)}` + ] = new Buffer(signature) + .toString("base64") + .replace("+", "-") + .replace("/", "_") + .replace(/=+$/, ""); + res.json(payload); +}); +app.get("/_test/version", (req, res) => { + const result = delegation(req.query.domain); + console.log(result); + res.json( + fetch(`https://${result.domain}/_matrix/federation/v1/version`, { + headers: { Host: result.host }, + }).json(), + ); +}); +app.get("/_test/alias", (req, res) => { + res.json( + makeSignedRequest( + req.host.replace(":443", ""), + "GET", + "https://yjsryd6gyhgl5eyikakf2xe5o4.srv.us/_matrix/federation/v1/query/directory?room_alias=%23ok%3Aorehus.club", + ).json(), + ); +}); +app.listen(3000, () => console.log("Listening at 3000"));