mirror of
https://github.com/MichMich/MagicMirror.git
synced 2025-06-27 19:53:36 +00:00
… for setting these things from outside (and overriding corresponding config.js properties `config.foreignModulesDir` and `customCss`) - remove elements from index.html when loading script or stylesheet files fails - removed `config.paths.vendor` (could never work because `vendor` is hardcoded in `index.html`) and renamed `config.paths.modules` to `config.foreignModulesDir`. The `config.paths. ...` properties were implemented in the initial commit in `js/defaults.js` but were never functional. - fixes `app.js` which didn't respect `config.paths.modules` before - as `modules/defaults` is directly set in many places in the source code restrict `config.paths.modules` to foreign modules (it has never worked for default modules), now renamed to `config.foreignModulesDir` - adds new `/env` section in `server.js` for getting the new env vars in the browser - fixes TODO in `server.js` so test directories are now only published when running tests These changes allow changing some main paths from outside mm with the new env vars. You now **can** put all user stuff into one directory, e.g. the `config` dir: - `config.js` as before - `custom.css` - foreign modules This would simplify other setups e.g. the docker setup. At the moment we have to deal with 3 directories where 2 of them (`modules` and `css`) contains mixed stuff, which means mm owned files and user files. This can now simplified and leads to cleaner setups (if wanted).
120 lines
3.4 KiB
JavaScript
120 lines
3.4 KiB
JavaScript
const fs = require("node:fs");
|
|
const http = require("node:http");
|
|
const https = require("node:https");
|
|
const path = require("node:path");
|
|
const express = require("express");
|
|
const ipfilter = require("express-ipfilter").IpFilter;
|
|
const helmet = require("helmet");
|
|
const socketio = require("socket.io");
|
|
|
|
const Log = require("logger");
|
|
const { cors, getConfig, getHtml, getVersion, getStartup, getEnvVars } = require("./server_functions");
|
|
|
|
/**
|
|
* Server
|
|
* @param {object} config The MM config
|
|
* @class
|
|
*/
|
|
function Server (config) {
|
|
const app = express();
|
|
const port = process.env.MM_PORT || config.port;
|
|
const serverSockets = new Set();
|
|
let server = null;
|
|
|
|
/**
|
|
* Opens the server for incoming connections
|
|
* @returns {Promise} A promise that is resolved when the server listens to connections
|
|
*/
|
|
this.open = function () {
|
|
return new Promise((resolve) => {
|
|
if (config.useHttps) {
|
|
const options = {
|
|
key: fs.readFileSync(config.httpsPrivateKey),
|
|
cert: fs.readFileSync(config.httpsCertificate)
|
|
};
|
|
server = https.Server(options, app);
|
|
} else {
|
|
server = http.Server(app);
|
|
}
|
|
const io = socketio(server, {
|
|
cors: {
|
|
origin: /.*$/,
|
|
credentials: true
|
|
},
|
|
allowEIO3: true
|
|
});
|
|
|
|
server.on("connection", (socket) => {
|
|
serverSockets.add(socket);
|
|
socket.on("close", () => {
|
|
serverSockets.delete(socket);
|
|
});
|
|
});
|
|
|
|
Log.log(`Starting server on port ${port} ... `);
|
|
server.listen(port, config.address || "localhost");
|
|
|
|
if (config.ipWhitelist instanceof Array && config.ipWhitelist.length === 0) {
|
|
Log.warn("You're using a full whitelist configuration to allow for all IPs");
|
|
}
|
|
|
|
app.use(function (req, res, next) {
|
|
ipfilter(config.ipWhitelist, { mode: config.ipWhitelist.length === 0 ? "deny" : "allow", log: false })(req, res, function (err) {
|
|
if (err === undefined) {
|
|
res.header("Access-Control-Allow-Origin", "*");
|
|
return next();
|
|
}
|
|
Log.log(err.message);
|
|
res.status(403).send("This device is not allowed to access your mirror. <br> Please check your config.js or config.js.sample to change this.");
|
|
});
|
|
});
|
|
|
|
app.use(helmet(config.httpHeaders));
|
|
app.use("/js", express.static(__dirname));
|
|
|
|
let directories = ["/config", "/css", "/fonts", "/modules", "/vendor", "/translations"];
|
|
if (process.env.JEST_WORKER_ID !== undefined) {
|
|
// add tests directories only when running tests
|
|
directories.push("/tests/configs", "/tests/mocks");
|
|
}
|
|
for (const directory of directories) {
|
|
app.use(directory, express.static(path.resolve(global.root_path + directory)));
|
|
}
|
|
|
|
app.get("/cors", async (req, res) => await cors(req, res));
|
|
|
|
app.get("/version", (req, res) => getVersion(req, res));
|
|
|
|
app.get("/config", (req, res) => getConfig(req, res));
|
|
|
|
app.get("/startup", (req, res) => getStartup(req, res));
|
|
|
|
app.get("/env", (req, res) => getEnvVars(req, res));
|
|
|
|
app.get("/", (req, res) => getHtml(req, res));
|
|
|
|
server.on("listening", () => {
|
|
resolve({
|
|
app,
|
|
io
|
|
});
|
|
});
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Closes the server and destroys all lingering connections to it.
|
|
* @returns {Promise} A promise that resolves when server has successfully shut down
|
|
*/
|
|
this.close = function () {
|
|
return new Promise((resolve) => {
|
|
for (const socket of serverSockets.values()) {
|
|
socket.destroy();
|
|
}
|
|
server.close(resolve);
|
|
});
|
|
};
|
|
}
|
|
|
|
module.exports = Server;
|