Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ planned for 2025-10-01

Thanks to: @dathbe.

### Added

- Added configuration option for `User-Agent`, used by calendar & news module

### Changed

- [clock] Add CSS to prevent line breaking of sunset/sunrise time display (#3816)
Expand Down
3 changes: 1 addition & 2 deletions js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@ const Log = require("logger");
const Server = require(`${__dirname}/server`);
const Utils = require(`${__dirname}/utils`);
const defaultModules = require(`${__dirname}/../modules/default/defaultmodules`);
const { getEnvVarsAsObj } = require(`${__dirname}/server_functions`);

// used to control fetch timeout for node_helpers
const { setGlobalDispatcher, Agent } = require("undici");
const { getEnvVarsAsObj } = require("#server_functions");
// common timeout value, provide environment override in case
const fetch_timeout = process.env.mmFetchTimeout !== undefined ? process.env.mmFetchTimeout : 30000;

Expand Down
2 changes: 1 addition & 1 deletion js/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ 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");
const { cors, getConfig, getHtml, getVersion, getStartup, getEnvVars } = require("#server_functions");

const vendor = require(`${__dirname}/vendor`);

Expand Down
25 changes: 23 additions & 2 deletions js/server_functions.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ async function cors (req, res) {
* @returns {object} An object specifying name and value of the headers.
*/
function getHeadersToSend (url) {
const headersToSend = { "User-Agent": `Mozilla/5.0 MagicMirror/${global.version}` };
const headersToSend = { "User-Agent": getUserAgent() };
const headersToSendMatch = new RegExp("sendheaders=(.+?)(&|$)", "g").exec(url);
if (headersToSendMatch) {
const headers = headersToSendMatch[1].split(",");
Expand Down Expand Up @@ -129,6 +129,27 @@ function getVersion (req, res) {
res.send(global.version);
}

/**
* Gets the preferred `User-Agent`
* @returns {string} `User-Agent` to be used
*/
function getUserAgent () {
const defaultUserAgent = `Mozilla/5.0 (Node.js ${Number(process.version.match(/^v(\d+\.\d+)/)[1])}) MagicMirror/${global.version}`;

if (typeof config === "undefined") {
return defaultUserAgent;
}

switch (typeof config.userAgent) {
case "function":
return config.userAgent();
case "string":
return config.userAgent;
default:
return defaultUserAgent;
}
}

/**
* Gets environment variables needed in the browser.
* @returns {object} environment variables key: values
Expand All @@ -155,4 +176,4 @@ function getEnvVars (req, res) {
res.send(obj);
}

module.exports = { cors, getConfig, getHtml, getVersion, getStartup, getEnvVars, getEnvVarsAsObj };
module.exports = { cors, getConfig, getHtml, getVersion, getStartup, getEnvVars, getEnvVarsAsObj, getUserAgent };
4 changes: 2 additions & 2 deletions modules/default/calendar/calendarfetcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const ical = require("node-ical");
const Log = require("logger");
const NodeHelper = require("node_helper");
const CalendarFetcherUtils = require("./calendarfetcherutils");
const { getUserAgent } = require("#server_functions");
const { scheduleTimer } = require("#module_functions");

/**
Expand Down Expand Up @@ -30,10 +31,9 @@ const CalendarFetcher = function (url, reloadInterval, excludedEvents, maximumEn
const fetchCalendar = () => {
clearTimeout(reloadTimer);
reloadTimer = null;
const nodeVersion = Number(process.version.match(/^v(\d+\.\d+)/)[1]);
let httpsAgent = null;
let headers = {
"User-Agent": `Mozilla/5.0 (Node.js ${nodeVersion}) MagicMirror/${global.version}`
"User-Agent": getUserAgent()
};

if (selfSignedCert) {
Expand Down
4 changes: 2 additions & 2 deletions modules/default/newsfeed/newsfeedfetcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const iconv = require("iconv-lite");
const { htmlToText } = require("html-to-text");
const Log = require("logger");
const NodeHelper = require("node_helper");
const { getUserAgent } = require("#server_functions");
const { scheduleTimer } = require("#module_functions");

/**
Expand Down Expand Up @@ -101,9 +102,8 @@ const NewsfeedFetcher = function (url, reloadInterval, encoding, logFeedWarnings
}
});

const nodeVersion = Number(process.version.match(/^v(\d+\.\d+)/)[1]);
const headers = {
"User-Agent": `Mozilla/5.0 (Node.js ${nodeVersion}) MagicMirror/${global.version}`,
"User-Agent": getUserAgent(),
"Cache-Control": "max-age=0, no-cache, no-store, must-revalidate",
Pragma: "no-cache"
};
Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
"imports": {
"#module_functions": {
"default": "./js/module_functions.js"
},
"#server_functions": {
"default": "./js/server_functions.js"
}
},
"main": "js/electron.js",
Expand Down
19 changes: 18 additions & 1 deletion tests/unit/functions/server_functions_spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const { cors } = require("../../../js/server_functions");
const { expect } = require("playwright/test");
const { cors, getUserAgent } = require("#server_functions");

describe("server_functions tests", () => {
describe("The cors method", () => {
Expand Down Expand Up @@ -142,5 +143,21 @@ describe("server_functions tests", () => {
expect(corsResponse.set.mock.calls[2][0]).toBe("header2");
expect(corsResponse.set.mock.calls[2][1]).toBe("value2");
});

it("Gets User-Agent from configuration", async () => {
config = {};
let userAgent;

userAgent = getUserAgent();
expect(userAgent).toContain("Mozilla/5.0 (Node.js ");

config.userAgent = "Mozilla/5.0 (Foo)";
userAgent = getUserAgent();
expect(userAgent).toBe("Mozilla/5.0 (Foo)");

config.userAgent = () => "Mozilla/5.0 (Bar)";
userAgent = getUserAgent();
expect(userAgent).toBe("Mozilla/5.0 (Bar)");
});
});
});