diff --git a/client/src/components/WelcomeButtons.tsx b/client/src/components/WelcomeButtons.tsx
index cae86f48..be732628 100644
--- a/client/src/components/WelcomeButtons.tsx
+++ b/client/src/components/WelcomeButtons.tsx
@@ -65,6 +65,17 @@ export const WelcomeButtons = ({className}: {className?: string}) => {
How-to Guides
+ {process.env.NODE_ENV === "production" &&
+ location.protocol !== "https" && (
+
+ Use HTTPS
+
+ )}
>
)}
diff --git a/client/src/docs/Troubleshooting/insecure.png b/client/src/docs/Troubleshooting/insecure.png
new file mode 100644
index 00000000..7330ae74
Binary files /dev/null and b/client/src/docs/Troubleshooting/insecure.png differ
diff --git a/client/src/docs/Troubleshooting/using-https.mdx b/client/src/docs/Troubleshooting/using-https.mdx
new file mode 100644
index 00000000..d0ee400f
--- /dev/null
+++ b/client/src/docs/Troubleshooting/using-https.mdx
@@ -0,0 +1,58 @@
+---
+title: Using HTTPS
+order: 1
+---
+
+# Using HTTPS
+
+Thorium Nova has clients connect using HTTP by default. However, browsers like
+Chrome only allow certain features to be used when the connection is using
+HTTPS. These include things like WebUSB, WebMIDI, WebRTC, and video and audio
+capture.
+
+None of these features are currently being used, but eventually we hope to
+incorporate them into the controls. These might be used for things like:
+
+- Connecting DMX lights and controlling them from any connected client.
+- Using a MIDI control board as an interface for the controls.
+- Peer-to-peer voice chat for conversations between remote crew members and
+ between the crew and flight director.
+
+## Activating HTTPS
+
+Since Thorium Nova is hosted within the networks of players and not on the open
+internet, it isn't possible to avoid the security warnings of browsers. However,
+it is possible to get around them.
+
+You can activate HTTPS by clicking the "Use HTTPS" button on the Thorium Nova
+main screen. This will redirect your browser to the same page, but using the
+HTTPS protocol and with the port number incremented by one, which by default
+is 4445. For example, the new URL will be `https://:4445`.
+
+The first time you do this, you will likely see a warning from the browser about
+the security of the connection. Different browsers provide different ways to
+ignore this warning.
+
+![Google Chrome showing a security warning](./insecure.png)
+
+In Google Chrome, you need to click on the page and type `thisisunsafe` into the
+window. There isn't a text box to type it into, you just type it on the window.
+This will cause the page to actually load.
+
+## A Note About Security
+
+If a web browser is giving you a security warning, that means the website does
+have some kind of security vulnerability. Using HTTPS with Thorium Nova is
+**not** an exception.
+
+Of course, Thorium Nova isn't designed to pose a risk to you or your computer.
+While it is possible Thorium Nova could use it's HTTPS connection to do
+nefarious things, if you trust the developers of Thorium Nova and the code, you
+can be reasonably confident that using HTTPS with Thorium Nova is safe. Since
+it's open-source, you are always welcome to review the code yourself.
+
+If you can't bring yourself to trust Thorium Nova, than it's probably best to
+not use it with the built-in HTTPS. There are ways you can set up Thorium Nova
+to work with HTTPS in a secure way. You could create your own security
+certificate to use with Thorium Nova or you could connect to the Thorium Nova
+HTTP server using a proxy.
diff --git a/desktop/main/electron.ts b/desktop/main/electron.ts
index 25fa0a72..a92e904f 100644
--- a/desktop/main/electron.ts
+++ b/desktop/main/electron.ts
@@ -31,7 +31,7 @@ const cert = fs.readFileSync(
),
"utf8"
);
-const port = process.env.PORT || 4444;
+const port = Number(process.env.PORT) || 4444;
async function createWindow() {
await startThoriumServer();
@@ -72,7 +72,9 @@ async function createWindow() {
// e.preventDefault();
});
- win.loadURL(`https://localhost:${port}`);
+ // We add 1 to the port, since we want to connect to the HTTPS server
+ // which is 1 more than the default port
+ win.loadURL(`https://localhost:${port + 1}`);
win.on("closed", () => {
win = null;
});
diff --git a/package-lock.json b/package-lock.json
index 96eb66a0..671ceb8e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "thorium-nova",
- "version": "0.0.0-development",
+ "version": "1.0.0-alpha.1",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "thorium-nova",
- "version": "0.0.0-development",
+ "version": "1.0.0-alpha.1",
"hasInstallScript": true,
"license": "Apache 2.0",
"workspaces": [
@@ -11568,6 +11568,35 @@
"resolved": "https://registry.npmjs.org/fastify-error/-/fastify-error-0.3.1.tgz",
"integrity": "sha512-oCfpcsDndgnDVgiI7bwFKAun2dO+4h84vBlkWsWnz/OUK9Reff5UFoFl241xTiLeHWX/vU9zkDVXqYUxjOwHcQ=="
},
+ "node_modules/fastify-http-proxy": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/fastify-http-proxy/-/fastify-http-proxy-6.2.1.tgz",
+ "integrity": "sha512-1ApZwz5v7QOWrJkHbKXf66RNJdSbxiQAEY+E9e2W/93cZRDVr+MZxG3u/P/HR06O5maVnxiERcRXRU3RquVQEg==",
+ "dependencies": {
+ "fastify-reply-from": "^6.0.0",
+ "ws": "^8.0.0"
+ }
+ },
+ "node_modules/fastify-http-proxy/node_modules/ws": {
+ "version": "8.4.2",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.4.2.tgz",
+ "integrity": "sha512-Kbk4Nxyq7/ZWqr/tarI9yIt/+iNNFOjBXEWgTb4ydaNHBNGgvf2QHbS9fdfsndfjFlFwEd4Al+mw83YkaD10ZA==",
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": "^5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
"node_modules/fastify-multipart": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/fastify-multipart/-/fastify-multipart-5.2.1.tgz",
@@ -11588,6 +11617,81 @@
"resolved": "https://registry.npmjs.org/fastify-plugin/-/fastify-plugin-3.0.0.tgz",
"integrity": "sha512-ZdCvKEEd92DNLps5n0v231Bha8bkz1DjnPP/aEz37rz/q42Z5JVLmgnqR4DYuNn3NXAO3IDCPyRvgvxtJ4Ym4w=="
},
+ "node_modules/fastify-reply-from": {
+ "version": "6.4.2",
+ "resolved": "https://registry.npmjs.org/fastify-reply-from/-/fastify-reply-from-6.4.2.tgz",
+ "integrity": "sha512-3HCP6BCWBSwtGdqQqS8A3joBuNHcp4dhQiVtkZ3zMPsfDaahBGT4ceFW4XMHL97r+oF+Rv2+l/uw4mGeQ6P/9g==",
+ "dependencies": {
+ "end-of-stream": "^1.4.4",
+ "fastify-plugin": "^3.0.0",
+ "http-errors": "^2.0.0",
+ "pump": "^3.0.0",
+ "semver": "^7.3.5",
+ "tiny-lru": "^7.0.6",
+ "undici": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=12.18"
+ }
+ },
+ "node_modules/fastify-reply-from/node_modules/depd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/fastify-reply-from/node_modules/http-errors": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
+ "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
+ "dependencies": {
+ "depd": "2.0.0",
+ "inherits": "2.0.4",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
+ "toidentifier": "1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/fastify-reply-from/node_modules/semver": {
+ "version": "7.3.5",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
+ "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/fastify-reply-from/node_modules/setprototypeof": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
+ },
+ "node_modules/fastify-reply-from/node_modules/statuses": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
+ "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/fastify-reply-from/node_modules/toidentifier": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
+ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
"node_modules/fastify-static": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/fastify-static/-/fastify-static-4.5.0.tgz",
@@ -23530,7 +23634,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
- "dev": true,
"dependencies": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
@@ -27666,6 +27769,14 @@
"integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==",
"dev": true
},
+ "node_modules/undici": {
+ "version": "4.13.0",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-4.13.0.tgz",
+ "integrity": "sha512-8lk8S/f2V0VUNGf2scU2b+KI2JSzEQLdCyRNRF3XmHu+5jectlSDaPSBCXAHFaUlt1rzngzOBVDgJS9/Gue/KA==",
+ "engines": {
+ "node": ">=12.18"
+ }
+ },
"node_modules/unicode-canonical-property-names-ecmascript": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz",
@@ -28997,6 +29108,7 @@
"fastify": "^3.25.0",
"fastify-cookie": "^5.4.0",
"fastify-cors": "^6.0.2",
+ "fastify-http-proxy": "^6.2.1",
"fastify-multipart": "^5.2.1",
"fastify-static": "^4.5.0",
"fastify-websocket": "^4.0.0",
@@ -37698,6 +37810,23 @@
"resolved": "https://registry.npmjs.org/fastify-error/-/fastify-error-0.3.1.tgz",
"integrity": "sha512-oCfpcsDndgnDVgiI7bwFKAun2dO+4h84vBlkWsWnz/OUK9Reff5UFoFl241xTiLeHWX/vU9zkDVXqYUxjOwHcQ=="
},
+ "fastify-http-proxy": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/fastify-http-proxy/-/fastify-http-proxy-6.2.1.tgz",
+ "integrity": "sha512-1ApZwz5v7QOWrJkHbKXf66RNJdSbxiQAEY+E9e2W/93cZRDVr+MZxG3u/P/HR06O5maVnxiERcRXRU3RquVQEg==",
+ "requires": {
+ "fastify-reply-from": "^6.0.0",
+ "ws": "^8.0.0"
+ },
+ "dependencies": {
+ "ws": {
+ "version": "8.4.2",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.4.2.tgz",
+ "integrity": "sha512-Kbk4Nxyq7/ZWqr/tarI9yIt/+iNNFOjBXEWgTb4ydaNHBNGgvf2QHbS9fdfsndfjFlFwEd4Al+mw83YkaD10ZA==",
+ "requires": {}
+ }
+ }
+ },
"fastify-multipart": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/fastify-multipart/-/fastify-multipart-5.2.1.tgz",
@@ -37718,6 +37847,62 @@
"resolved": "https://registry.npmjs.org/fastify-plugin/-/fastify-plugin-3.0.0.tgz",
"integrity": "sha512-ZdCvKEEd92DNLps5n0v231Bha8bkz1DjnPP/aEz37rz/q42Z5JVLmgnqR4DYuNn3NXAO3IDCPyRvgvxtJ4Ym4w=="
},
+ "fastify-reply-from": {
+ "version": "6.4.2",
+ "resolved": "https://registry.npmjs.org/fastify-reply-from/-/fastify-reply-from-6.4.2.tgz",
+ "integrity": "sha512-3HCP6BCWBSwtGdqQqS8A3joBuNHcp4dhQiVtkZ3zMPsfDaahBGT4ceFW4XMHL97r+oF+Rv2+l/uw4mGeQ6P/9g==",
+ "requires": {
+ "end-of-stream": "^1.4.4",
+ "fastify-plugin": "^3.0.0",
+ "http-errors": "^2.0.0",
+ "pump": "^3.0.0",
+ "semver": "^7.3.5",
+ "tiny-lru": "^7.0.6",
+ "undici": "^4.0.0"
+ },
+ "dependencies": {
+ "depd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="
+ },
+ "http-errors": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
+ "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
+ "requires": {
+ "depd": "2.0.0",
+ "inherits": "2.0.4",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
+ "toidentifier": "1.0.1"
+ }
+ },
+ "semver": {
+ "version": "7.3.5",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
+ "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ },
+ "setprototypeof": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
+ },
+ "statuses": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
+ "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="
+ },
+ "toidentifier": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
+ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="
+ }
+ }
+ },
"fastify-static": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/fastify-static/-/fastify-static-4.5.0.tgz",
@@ -46544,7 +46729,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
- "dev": true,
"requires": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
@@ -48213,12 +48397,13 @@
"@types/three": "^0.135.0",
"@types/ws": "^8.2.2",
"@types/yauzl": "^2.9.2",
- "@types/yazl": "*",
+ "@types/yazl": "^2.4.2",
"esbuild": "^0.14.5",
"fast-glob": "^3.2.7",
"fastify": "^3.25.0",
"fastify-cookie": "^5.4.0",
"fastify-cors": "^6.0.2",
+ "fastify-http-proxy": "*",
"fastify-multipart": "^5.2.1",
"fastify-static": "^4.5.0",
"fastify-websocket": "^4.0.0",
@@ -49709,6 +49894,11 @@
"integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==",
"dev": true
},
+ "undici": {
+ "version": "4.13.0",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-4.13.0.tgz",
+ "integrity": "sha512-8lk8S/f2V0VUNGf2scU2b+KI2JSzEQLdCyRNRF3XmHu+5jectlSDaPSBCXAHFaUlt1rzngzOBVDgJS9/Gue/KA=="
+ },
"unicode-canonical-property-names-ecmascript": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz",
diff --git a/server/API.md b/server/API.md
index 3d06f8ed..5f72d941 100644
--- a/server/API.md
+++ b/server/API.md
@@ -3,7 +3,7 @@
## Environment Variables
- `PORT` - Set the port for the HTTP server. Useful for headless setups.
- Defaults to 4444.
+ Defaults to 4444. The HTTPS server with use the port + 1, defaulting to 4445.
- `COOKIE_SECRET` - A secret key used to encrypt secure cookies. This is
currently unused.
- `THORIUM_PATH` - The directory that will contain the data and assets for
diff --git a/server/package.json b/server/package.json
index 2910821d..626d5109 100644
--- a/server/package.json
+++ b/server/package.json
@@ -33,6 +33,7 @@
"fastify": "^3.25.0",
"fastify-cookie": "^5.4.0",
"fastify-cors": "^6.0.2",
+ "fastify-http-proxy": "^6.2.1",
"fastify-multipart": "^5.2.1",
"fastify-static": "^4.5.0",
"fastify-websocket": "^4.0.0",
diff --git a/server/src/index.ts b/server/src/index.ts
index d3bde36a..47cf53e2 100644
--- a/server/src/index.ts
+++ b/server/src/index.ts
@@ -10,6 +10,7 @@ import chalk from "chalk";
import {FlightDataModel} from "./classes/FlightDataModel";
import {promises as fs, existsSync} from "fs";
import {unzip} from "./utils/unzipFolder";
+import {buildHttpsProxy} from "./init/httpsProxy";
setBasePath(thoriumPath);
const isHeadless = !process.env.FORK;
@@ -60,14 +61,22 @@ export async function startServer() {
await applyDataChannel(app, database);
setUpAPI(app, database);
const PORT =
- process.env.PORT || (process.env.NODE_ENV === "production" ? 4444 : 3001);
+ Number(process.env.PORT) ||
+ (process.env.NODE_ENV === "production" ? 4444 : 3001);
+ const HTTPSPort = PORT + 1;
+ const proxy = buildHttpsProxy(PORT);
+
try {
await app.listen(PORT, "0.0.0.0");
+ if (process.env.NODE_ENV === "production") {
+ await proxy.listen(HTTPSPort, "0.0.0.0");
+ }
console.info(chalk.greenBright(`Access app at http://localhost:${PORT}`));
console.info(
chalk.cyan(`Doing port forwarding? Open this port in your router:`)
);
console.info(chalk.cyan(` - TCP ${PORT} for web app access`));
+ console.info(chalk.cyan(` - TCP ${HTTPSPort} for HTTPS access`));
process.send?.("ready");
} catch (err) {
process.send?.("error");
diff --git a/server/src/init/httpServer.ts b/server/src/init/httpServer.ts
index 9c746063..9b342927 100644
--- a/server/src/init/httpServer.ts
+++ b/server/src/init/httpServer.ts
@@ -4,7 +4,7 @@ import staticServe from "fastify-static";
import cors from "fastify-cors";
import path from "path";
import {thoriumPath, rootPath} from "../utils/appPaths";
-import {promises as fs, createWriteStream, readFileSync} from "fs";
+import {promises as fs, createWriteStream} from "fs";
import {pipeline} from "stream/promises";
import uniqid from "@thorium/uniqid";
import os from "os";
@@ -17,16 +17,7 @@ export default function buildHTTPServer({
staticRoot?: string;
port?: number;
} = {}) {
- const certDir = isHeadless ? "./resources" : "../../app";
- const app = fastify({
- https:
- process.env.NODE_ENV === "production"
- ? {
- key: readFileSync(path.join(rootPath, certDir, "server.key")),
- cert: readFileSync(path.join(rootPath, certDir, "server.cert")),
- }
- : (undefined as any),
- });
+ const app = fastify();
async function onFile(part: MultipartFile) {
const tmpdir = os.tmpdir();
diff --git a/server/src/init/httpsProxy.ts b/server/src/init/httpsProxy.ts
new file mode 100644
index 00000000..9eadacd3
--- /dev/null
+++ b/server/src/init/httpsProxy.ts
@@ -0,0 +1,29 @@
+import fastify from "fastify";
+import fastifyHttpProxy from "fastify-http-proxy";
+import {readFileSync} from "fs";
+import path from "path";
+import {rootPath} from "../utils/appPaths";
+
+const isHeadless = !process.env.FORK;
+export function buildHttpsProxy(port: number) {
+ // Create a proxy server to handle the HTTPS requests
+ // All requests are proxied to the HTTP server
+ const certDir =
+ process.env.NODE_ENV !== "production"
+ ? "../../../desktop/resources"
+ : isHeadless
+ ? "./resources"
+ : "../../app";
+
+ const proxy = fastify({
+ https: {
+ key: readFileSync(path.join(rootPath, certDir, "server.key")),
+ cert: readFileSync(path.join(rootPath, certDir, "server.cert")),
+ },
+ });
+ proxy.register(fastifyHttpProxy, {
+ upstream: `http://localhost:${port}`,
+ });
+
+ return proxy;
+}