mirror of
https://codeberg.org/doesnm/snailtrix.git
synced 2025-10-18 19:00:59 +00:00
Upload files to "/"
This commit is contained in:
parent
9220daddf1
commit
f9c3761082
1 changed files with 172 additions and 0 deletions
172
matrix.js
Normal file
172
matrix.js
Normal file
|
|
@ -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"));
|
||||
Loading…
Add table
Add a link
Reference in a new issue