2022-06-27 17:53:00 +00:00
|
|
|
// @ts-ignore
|
|
|
|
import DHT from "@hyperswarm/dht";
|
|
|
|
// @ts-ignore
|
2022-07-19 22:24:53 +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:24:53 +00:00
|
|
|
import express, {Express} from "express";
|
2022-07-04 21:22:48 +00:00
|
|
|
import path from "path";
|
2022-07-19 22:24:53 +00:00
|
|
|
import {fileURLToPath} from "url";
|
2022-07-05 19:02:07 +00:00
|
|
|
import config from "./config.js";
|
2022-07-19 22:24:53 +00:00
|
|
|
import * as http from "http";
|
|
|
|
import * as https from "https";
|
|
|
|
import * as tls from "tls";
|
|
|
|
import * as acme from "acme-client";
|
|
|
|
import {Buffer} from "buffer";
|
|
|
|
import {intervalToDuration} from "date-fns";
|
|
|
|
import cron from "node-cron";
|
|
|
|
import {get as getDHT} from "./dht.js";
|
|
|
|
import WS from "ws";
|
|
|
|
// @ts-ignore
|
|
|
|
import DHT from "@hyperswarm/dht";
|
|
|
|
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
|
|
|
|
2022-07-19 22:24:53 +00:00
|
|
|
const sslPrivateKey = await acme.forge.createPrivateKey();
|
|
|
|
const acmeClient = new acme.Client({
|
|
|
|
accountKey: sslPrivateKey,
|
|
|
|
directoryUrl: acme.directory.letsencrypt.production,
|
|
|
|
});
|
2022-06-27 21:52:20 +00:00
|
|
|
|
2022-07-19 22:24:53 +00:00
|
|
|
let app: Express;
|
|
|
|
let router = express.Router();
|
2022-06-27 17:53:00 +00:00
|
|
|
|
2022-07-04 21:22:48 +00:00
|
|
|
export async function start() {
|
2022-07-19 22:24:53 +00:00
|
|
|
const relayPort = config.str("relay-port");
|
|
|
|
app = express();
|
|
|
|
app.use(function (req, res, next) {
|
|
|
|
router(req, res, next);
|
|
|
|
});
|
2022-06-27 17:53:00 +00:00
|
|
|
|
2022-07-19 22:24:53 +00:00
|
|
|
let httpsServer = https.createServer({
|
|
|
|
SNICallback(servername, cb) {
|
|
|
|
cb(null, sslCtx);
|
|
|
|
},
|
2022-07-04 21:22:48 +00:00
|
|
|
});
|
2022-06-27 17:53:00 +00:00
|
|
|
|
2022-07-19 22:24:53 +00:00
|
|
|
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-04 21:22:48 +00:00
|
|
|
const dht = await getDHT();
|
2022-06-27 17:53:00 +00:00
|
|
|
|
2022-07-19 22:24:53 +00:00
|
|
|
let wsServer = new WS.Server({server: httpsServer});
|
2022-06-27 17:53:00 +00:00
|
|
|
|
2022-07-04 21:22:48 +00:00
|
|
|
wsServer.on("connection", (socket: any) => {
|
2022-07-19 22:24:53 +00:00
|
|
|
relay(dht, new Stream(false, socket));
|
2022-07-04 21:22:48 +00:00
|
|
|
});
|
2022-07-19 22:24:53 +00:00
|
|
|
|
2022-07-04 21:22:48 +00:00
|
|
|
await new Promise((resolve) => {
|
2022-07-19 22:24:53 +00:00
|
|
|
httpsServer.listen(relayPort, "0.0.0.0", function () {
|
|
|
|
console.info("Relay started on ", httpsServer.address());
|
|
|
|
resolve(null);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
await createOrRenewSSl();
|
|
|
|
}
|
|
|
|
|
|
|
|
async function createOrRenewSSl() {
|
|
|
|
if (sslParams.cert) {
|
|
|
|
const expires = (
|
|
|
|
await acme.forge.readCertificateInfo(sslParams.cert as Buffer)
|
|
|
|
).notAfter;
|
|
|
|
|
|
|
|
let duration = intervalToDuration({start: new Date(), end: expires});
|
|
|
|
|
|
|
|
let daysLeft = (duration.months as number) * 30 + (duration.days as number);
|
|
|
|
|
|
|
|
if (daysLeft > 30) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const [certificateKey, certificateRequest] = await acme.forge.createCsr({
|
|
|
|
commonName: config.str("relay-domain"),
|
2022-07-04 21:22:48 +00:00
|
|
|
});
|
2022-06-27 17:53:00 +00:00
|
|
|
|
2022-07-19 22:24:53 +00:00
|
|
|
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"],
|
2022-07-04 21:22:48 +00:00
|
|
|
});
|
2022-07-19 22:24:53 +00:00
|
|
|
sslParams.key = certificateKey;
|
|
|
|
sslCtx = tls.createSecureContext(sslParams);
|
|
|
|
|
|
|
|
console.log("SSL Certificate Updated");
|
2022-06-27 17:53:00 +00:00
|
|
|
}
|