Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion js/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ const defaults = {
customCss: "config/custom.css",
foreignModulesDir: "modules",
defaultModulesDir: "defaultmodules",
hideConfigSecrets: false,
// httpHeaders used by helmet, see https://helmetjs.github.io/. You can add other/more object values by overriding this in config.js,
// e.g. you need to add `frameguard: false` for embedding MagicMirror in another website, see https://github.com/MagicMirrorOrg/MagicMirror/issues/2847
httpHeaders: { contentSecurityPolicy: false, crossOriginOpenerPolicy: false, crossOriginEmbedderPolicy: false, crossOriginResourcePolicy: false, originAgentCluster: false },
Expand Down
2 changes: 1 addition & 1 deletion js/node_helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ class NodeHelper {
io.of(this.name).on("connection", (socket) => {
// register catch all.
socket.onAny((notification, payload) => {
if (global.config?.hideConfigSecrets && payload && typeof payload === "object") {
if (payload && typeof payload === "object") {
try {
// Calculate exactly which secrets this module is allowed to receive
const allowedSecrets = getAllowedSecrets(this.name);
Expand Down
19 changes: 7 additions & 12 deletions js/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,17 +108,12 @@ class Server {
app.use(helmet(config.httpHeaders));
app.use("/js", express.static(__dirname));

if (config.hideConfigSecrets) {
const getErrorText = (filename) => {
return `<!DOCTYPE html>\n<html lang="en">\n<head>\n<meta charset="utf-8">\n<title>Error</title>\n</head>\n<body>\n<pre>Cannot GET /config/${filename}</pre>\n</body>\n</html>`;
};
app.get("/config/config.env", (req, res) => {
res.status(404).send(getErrorText("config.env"));
});
app.get("/config/config.js", (req, res) => {
res.status(404).send(getErrorText("config.js"));
});
}
const getConfigFileError = (filename) => (req, res) => {
const errorText = `<!DOCTYPE html>\n<html lang="en">\n<head>\n<meta charset="utf-8">\n<title>Error</title>\n</head>\n<body>\n<pre>Cannot GET /config/${filename}</pre>\n</body>\n</html>`;
res.status(404).send(errorText);
};
app.get("/config/config.env", getConfigFileError("config.env"));
app.get("/config/config.js", getConfigFileError("config.js"));

const directories = ["/config", "/css", "/favicon.svg", "/defaultmodules", "/modules", "/node_modules/animate.css", "/node_modules/@fontsource", "/node_modules/@fortawesome", "/node_modules/suncalc", "/translations", "/tests/configs", "/tests/mocks"];
for (const value of Object.values(vendor)) {
Expand All @@ -135,7 +130,7 @@ class Server {
const getStartup = (req, res) => res.send(startUp);

const getConfig = (req, res) => {
const obj = config.hideConfigSecrets ? configObj.redactedConf : configObj.fullConf;
const obj = configObj.redactedConf;
// Functions can't survive JSON.stringify, so we wrap them in a
// tagged object { __mmFunction: "<source>" }. The client-side
// JSON reviver in main.js recognises this tag and reconstructs
Expand Down
6 changes: 1 addition & 5 deletions js/server_functions.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,7 @@ const cors = async (req, res) => {
return res.status(400).send(url);
} else {
url = match[1];
if (typeof global.config !== "undefined") {
if (global.config.hideConfigSecrets) {
url = replaceSecretPlaceholder(url);
}
}
if (typeof global.config !== "undefined") url = replaceSecretPlaceholder(url);

// Validate protocol before attempting connection (non-http/https are never allowed)
let parsed;
Expand Down
16 changes: 6 additions & 10 deletions js/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,21 +141,17 @@ const loadConfig = () => {
// Load config.js and catch errors if not accessible
try {
const configContent = fs.readFileSync(configFilename, "utf-8");
const hideConfigSecrets = configContent.match(/^\s*hideConfigSecrets: true.*$/m);
let configContentFull = configContent;
let configContentRedacted = hideConfigSecrets ? configContent : undefined;
let configContentRedacted = configContent;
Object.keys(process.env).forEach((env) => {
configContentFull = configContentFull.replaceAll(`\${${env}}`, process.env[env]);
if (hideConfigSecrets) {
if (env.startsWith("SECRET_")) {
configContentRedacted = configContentRedacted.replaceAll(`"\${${env}}"`, `"**${env}**"`);
configContentRedacted = configContentRedacted.replaceAll(`\${${env}}`, `**${env}**`);
} else {
configContentRedacted = configContentRedacted.replaceAll(`\${${env}}`, process.env[env]);
}
if (env.startsWith("SECRET_")) {
configContentRedacted = configContentRedacted.replaceAll(`"\${${env}}"`, `"**${env}**"`);
configContentRedacted = configContentRedacted.replaceAll(`\${${env}}`, `**${env}**`);
} else {
configContentRedacted = configContentRedacted.replaceAll(`\${${env}}`, process.env[env]);
}
});
configContentRedacted = configContentRedacted ? configContentRedacted : configContentFull;
const configObj = {
configFilename: configFilename,
configContentFull: configContentFull,
Expand Down
1 change: 0 additions & 1 deletion tests/configs/config_variables.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ const config = require(`${process.cwd()}/tests/configs/default.js`).configFactor
language: "${MM_LANGUAGE}",
logLevel: ["${MM_LOG_ERROR}", "LOG", "WARN", "${MM_LOG_INFO}"],
timeFormat: ${MM_TIME_FORMAT},
hideConfigSecrets: true,
ipWhitelist: ["${SECRET_IP2}", "::${SECRET_IP3}", "${SECRET_IP1}", "192.168.0.0/16", "172.16.0.0/12"],
address: "0.0.0.0",

Expand Down
Loading