relay/src/relay.ts

119 lines
3.1 KiB
TypeScript
Raw Normal View History

2022-06-27 17:53:00 +00:00
// @ts-ignore
import DHT from "@hyperswarm/dht";
// @ts-ignore
2022-07-19 22:31:15 +00:00
import { relay } from "@hyperswarm/dht-relay";
2022-06-27 17:53:00 +00:00
// @ts-ignore
import Stream from "@hyperswarm/dht-relay/ws";
2022-07-19 22:31:15 +00:00
import express, { Express } from "express";
import path from "path";
2022-07-19 22:31:15 +00:00
import { fileURLToPath } from "url";
2022-07-05 19:02:07 +00:00
import config from "./config.js";
import * as http from "http";
import * as https from "https";
import * as tls from "tls";
import * as acme from "acme-client";
2022-07-19 22:31:15 +00:00
import { Buffer } from "buffer";
import { intervalToDuration } from "date-fns";
import cron from "node-cron";
2022-07-19 22:31:15 +00:00
import { get as getDHT } from "./dht.js";
import WS from "ws";
// @ts-ignore
import DHT from "@hyperswarm/dht";
2022-07-19 22:31:15 +00:00
import { pack } from "msgpackr";
import { overwriteRegistryEntry } from "libskynetnode";
import { hashDataKey } from "./util.js";
let sslCtx: tls.SecureContext = tls.createSecureContext();
const sslParams: tls.SecureContextOptions = {};
2022-06-27 17:53:00 +00:00
const sslPrivateKey = await acme.forge.createPrivateKey();
const acmeClient = new acme.Client({
2022-07-19 22:31:15 +00:00
accountKey: sslPrivateKey,
directoryUrl: acme.directory.letsencrypt.production,
});
2022-06-27 21:52:20 +00:00
let app: Express;
let router = express.Router();
2022-06-27 17:53:00 +00:00
export async function start() {
2022-07-19 22:31:15 +00:00
const relayPort = config.str("relay-port");
app = express();
app.use(function (req, res, next) {
router(req, res, next);
});
let httpsServer = https.createServer({
SNICallback(servername, cb) {
cb(null, sslCtx);
},
});
let httpServer = http.createServer(app);
cron.schedule("0 * * * *", createOrRenewSSl);
await new Promise((resolve) => {
httpServer.listen(80, "0.0.0.0", function () {
console.info("HTTP Listening on ", httpServer.address());
resolve(null);
});
2022-07-19 22:31:15 +00:00
});
const dht = await getDHT();
2022-06-27 17:53:00 +00:00
2022-07-19 22:31:15 +00:00
let wsServer = new WS.Server({ server: httpsServer });
2022-07-19 22:31:15 +00:00
wsServer.on("connection", (socket: any) => {
relay(dht, new Stream(false, socket));
});
2022-07-19 22:31:15 +00:00
await new Promise((resolve) => {
httpsServer.listen(relayPort, "0.0.0.0", function () {
console.info("Relay started on ", httpsServer.address());
resolve(null);
});
2022-07-19 22:31:15 +00:00
});
2022-07-19 22:31:15 +00:00
await createOrRenewSSl();
}
async function createOrRenewSSl() {
2022-07-19 22:31:15 +00:00
if (sslParams.cert) {
const expires = (
await acme.forge.readCertificateInfo(sslParams.cert as Buffer)
).notAfter;
2022-07-19 22:31:15 +00:00
let duration = intervalToDuration({ start: new Date(), end: expires });
2022-07-19 22:31:15 +00:00
let daysLeft = (duration.months as number) * 30 + (duration.days as number);
2022-07-19 22:31:15 +00:00
if (daysLeft > 30) {
return;
}
2022-07-19 22:31:15 +00:00
}
const [certificateKey, certificateRequest] = await acme.forge.createCsr({
commonName: config.str("relay-domain"),
});
sslParams.cert = await acmeClient.auto({
csr: certificateRequest,
termsOfServiceAgreed: true,
challengeCreateFn: async (authz, challenge, keyAuthorization) => {
router.get(
`/.well-known/acme-challenge/${challenge.token}`,
(req, res) => {
res.send(keyAuthorization);
}
);
},
challengeRemoveFn: async () => {
router = express.Router();
},
challengePriority: ["http-01"],
});
sslParams.key = certificateKey;
sslCtx = tls.createSecureContext(sslParams);
console.log("SSL Certificate Updated");
2022-06-27 17:53:00 +00:00
}