Conversation
clientonly: - did work only with xserver and `DISPLAY` env var - now checks for `WAYLAND_DISPLAY` or `DISPLAY` env var before running - if `WAYLAND_DISPLAY` is set now starts with wayland parameters electron tests see #3676
fixes #3267 AGAIN, correctly, add testcase add testcase for #3679 , broadcast clipping incorrectly I added a test module (tests/testNotification) to catch the notification and check the count. (one way to configure) i put this module in the tests folder, and added /tests to the server paths. (can't have a module in a nested folder, like tests/modules/xxx) but I have a problem. i can run the test config (MM_CONFIG_FILE), and the two modules work correctly, but in the spec runner, the calendar module times out on the broadcast test.. there is only local ics file access, no outside hosts I forced my system date to 1/1/24 (same as runner) and again the manual testcase works fine I added two test config.js,(configs/calendar) one works great (symbols) , one fails (broadcast test) I added additional delay in the calendarspec runner to try to debug the module, but it still not long enough.. no messages of trouble when I get into the browser.. BUT, this may be because of the log being turned off... (just thought of this) I created a special ICS (in mocks) that has 12 events, 1 for each month.. (so I can check clipping and broadcast) the US holidays one is sensitive to the current date, and I couldn't get it to work on 1/1/2024.. also, in general, is there a mechanism to run test:just_one_runner? waiting thru the electron test to get to one testcase.. ugh..
I also added a few new words to the cspell dictionary that were added in the changelog. I have not made an extra entry in the changelog for these tiny things.
- fix setup to run with xserver and labwc - remove electronParams from calendar_spec.js (forgotten in #3680) fixes [running tests locally without labwc installed](#3681 (comment)) follow up to #3680
Since we don't use the `raspberry` information, calling it in `si.get` is useless. I also made the string construction in the code a bit more readable. The output remains the same.
Due to a typo the icon displayed in the openmeteo provider was "N/A" for a certain weather condition <img width="284" alt="Bildschirmfoto 2025-01-13 um 16 35 40" src="https://github.com/user-attachments/assets/e64bf0f8-32d9-44a5-a2b0-42d4f2d6b6df" /> --------- Co-authored-by: veeck <gitkraken@veeck.de>
after updating deps 2 files needed formatting updates
This PR will introduce different issue templates for bug reports, feature requests and so on on GitHub. There is still room for fine-tuning, but it's reached a state to show it to you and get feedback. I think that this can lead to better bug reports. You can see the result in my repo: https://github.com/KristjanESPERANTO/MagicMirror/issues/new/choose Feel free to create new issues for testing. What do you think? Do we want to pursue this further?
Fixes #3296 The problem was that the fetch-methods threw errors when something went wrong instead of calling `updateAvailable()`. `updateAvailable()` must be called in order to schedule the next update. I added some filtering for the hourly forecast that removes hours in the past. If the API call fails we use the cached data, but we should only display hours in the future.
to call `sudo apt-get update` before `sudo apt-get install` I had problems running the tests on my fork, while running the `apt-get install` command in automated tests workflow I got ```bash E: Failed to fetch http://security.ubuntu.com/ubuntu/pool/main/m/mesa/libegl-mesa0_24.0.9-0ubuntu0.3_amd64.deb 404 Not Found [IP: 52.147.219.192 80] ``` Found a similar [Issue](actions/runner-images#10785 (comment)) with a solution which is to run `sudo apt-get update` before.
Therefor -> Therefore refs: #3690
nothing to see here really --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: veeck <gitkraken@veeck.de>
Hello and thank you for wanting to contribute to the MagicMirror² project! **Please make sure that you have followed these 4 rules before submitting your Pull Request:** > 1. Base your pull requests against the `develop` branch. > 2. Include these infos in the description: > > - Does the pull request solve a **related** issue? > - If so, can you reference the issue like this `Fixes #<issue_number>`? > - What does the pull request accomplish? Use a list if needed. > - If it includes major visual changes please add screenshots. > > 3. Please run `npm run lint:prettier` before submitting so that > style issues are fixed. > 4. Don't forget to add an entry about your changes to > the CHANGELOG.md file. **Note**: Sometimes the development moves very fast. It is highly recommended that you update your branch of `develop` before creating a pull request to send us your changes. This makes everyone's lives easier (including yours) and helps us out on the development team. Thanks again and have a nice day!
This does not change the rules of ESLint. It's just a little cosmetic fine-tuning.
Fixes #3727 --------- Co-authored-by: veeck <gitkraken@veeck.de>
I have updated weatherflow.js to implement the following changes (as described in #3728) - Fixed: Weather icons now show up properly - Added: Location Name support - Added: Hourly weather forecast support - Added to current conditions: - "Feels like" temp - Fixed icon for current conditions to be sourced from current conditions (rather than daily forecast) - UV index - Added to daily forecast - Precipitation amount and UV index (via hourly forecast data) Before:  After: 
I've had this on my agenda for a long time 🙂
Hello, we have updated the core Greek translation and added Greek translation to Alerts module. Thank you! --------- Co-authored-by: Savvas Adamtziloglou <savvas-gr@greeklug.gr> Co-authored-by: Konstantinos <geraki@gmail.com> Co-authored-by: Veeck <github@veeck.de>
see https://forum.magicmirror.builders/topic/19440/digital-clock-minutes-darker changelog added question.. we have a config parm for seconds color, but not hour/minute I have used css here.. is that too inconsistent? --------- Co-authored-by: Kristjan ESPERANTO <35647502+KristjanESPERANTO@users.noreply.github.com> Co-authored-by: Veeck <github@veeck.de>
This will fix #3745.
see discussion in #3746 As [electron v35 requires node js v22.14.0](https://www.electronjs.org/blog/electron-35-0) we should update this here too.
exclude issues with label `ready (coming with next release)` from stale job
The command wasn't correct.
…V Index, add config option to hide precipitation entries that are zero [Rebased Version of PR #3526] (#3748) Fixed Version of PR #3526 since that was against the wrong branch and had issues. Original PR Text: Basically the title. Just some existing weather data included into hourly, some config option ("hideZeroes") to hide precipitation when it is zero (this actually shrinks the entire table, removing columns that are completely empty), and add a spacing column to fix the UV Index column. --------- Co-authored-by: Veeck <github@veeck.de>
## Summary This PR migrates the SMHI weather provider from the deprecated PMP3gv2 API to the new SNOW1gv1 API. The old API (pmp3g/version/2) started returning HTTP 404 on 2026-03-31. ## Changes - Updated API endpoint: - `pmp3g/version/2` → `snow1g/version/1` - Updated response parsing: - `validTime` → `time` - `parameters[]` → `data` (flat structure) - Updated parameter names: - `t` → `air_temperature` - `ws` → `wind_speed` - etc. - Updated precipitation handling to match new `predominant_precipitation_type_at_surface` - Updated coordinate parsing (flat `[lon, lat]`) - Added missing value handling (`9999 → null`) ## Notes - Maintains backward compatibility for `precipitationValue` config - No UI changes - Symbol mapping unchanged (same codes 1–27) ## Testing - Verified against live SMHI SNOW1gv1 API responses - Confirmed old API returns HTTP 404 ## Impact Fixes broken SMHI provider due to API deprecation.
…line (#4083) In PR #4072 GitHub Bot complained that `newsfeedfetcher.js` used the old `.pipe()` method to connect streams (HTTP body → iconv decoding → RSS parser). `.pipe()` has a weakness: errors in one stream are **not** automatically forwarded to downstream streams. An I/O or decoding error would silently disappear. ## Solution Replaced `.pipe()` with `await stream.promises.pipeline()`. The `pipeline()` API is designed to propagate errors correctly through the entire chain and to clean up all streams on failure. Errors now reliably land in the `catch` block and call `fetchFailedCallback` exactly once. The redundant `parser.on("error")` handler was removed, as it would have caught the same error again and called the callback a second time. ## Why not the bot's suggested fix? The GitHub Bot suggested the older callback-based `stream.pipeline(callback)` variant: ```js stream.pipeline(nodeStream, iconv.decodeStream(...), parser, (error) => { if (!error) return; // error handling... }); ``` This has two drawbacks compared to my approach: 1. It uses the older callback style — `stream.promises.pipeline()` with `async/await` is the modern, more readable API. 2. The bot's suggestion kept both the `parser.on("error")` handler **and** the `catch` block, which would not have fixed the double-callback problem. ---- Related to #4073
…4085) In PR #4072 the GitHub bot complained about a missing variable declaration for `config` in `app.js` and suggested adding `let config`. Applying that suggestion broke the app because `server_functions.js` was accessing `config` as an implicit global variable - the `let` declaration made it unreachable from there. So instead of the `let` declaration, I replaced all bare `config` references with explicit `global.config`. This makes the dependency on the global variable visible without changing runtime behavior, consistent with how other globals like `global.root_path` and `global.version` are already handled throughout the codebase. Related to #4073
…#4084) Resolve target hostname before proxying and reject any address that is not globally routable (loopback, RFC 1918, link-local, etc.) using ipaddr.js and dns.lookup().
`node-ical` has released a new version that fixes an issue reported by one of our users (jens-maus/node-ical#495). I'd like to have that in the develop branch. Instead of just updating that, I think it would make sense to include the others as well. `undici` had a major release but according to the release notes we are not affected.
Previously only master was scanned via the default CodeQL setup. Since development happens on develop, this PR replaces the default setup with a custom workflow that covers both branches. This gives an overview of the security status across the current release (master) and the development branch (develop). As a result we should also see issues in the develop branch here: https://github.com/MagicMirrorOrg/MagicMirror/security/code-scanning
PR #4084 blocked SSRF by checking the IP before `fetch()` — but `fetch()` resolves DNS again on its own. With DNS rebinding (TTL=0, alternating IPs) an attacker can slip a private IP through between check and connection. Fix: resolve DNS once, validate, pin the validated IP for the connection. No second DNS query → no rebinding window. `isPrivateTarget()` is gone, code is shorter than before. Not a likely attack for a typical MagicMirror setup, but it doesn't add complexity so there's no reason not to close the gap.
) During the server-side migration (PR #4032), the `instanceId` was built with `Date.now()`, making it unique per client reload. This approach was fine in the old browser-based architecture where reloads cleaned up everything automatically. But now the node_helper persists across reloads, so each reconnect created a new `HTTPFetcher` while the old one kept polling - silently multiplying API calls over time. The fix is simple: use `this.identifier` as the `instanceId`, which is already stable and unique per module slot. This is the same approach the Calendar module uses. On the node_helper side, when a provider already exists for the same `instanceId`, we now skip re-creation and just resend `WEATHER_INITIALIZED` so the client picks up where it left off. Fixes https://forum.magicmirror.builders/topic/20199
I provide docker images with alpine linux and tested the new cors
approach.
It didn't work because after calling
```js
const dispatcher = new Agent({ connect: { lookup: (_h, _o, cb) => cb(null, address, family) } });
```
the dispatcher variable was undefined.
This PR solves this and I tested this under debian too.
The mix of internal fetch and newer undici did not work and alpine needs
additionally the `process.nextTick`.
---------
Co-authored-by: Kristjan ESPERANTO <35647502+KristjanESPERANTO@users.noreply.github.com>
If a module uses this.io.of() to register a custom socket.io namespace, connections on that namespace trigger the onAny handler in setSocketIO before config is set, causing a TypeError. Fixes #4089
### What's the problem? The `selfSignedCert` option passes an undici `Agent` as `dispatcher` to `fetch()`. But Node's built-in `fetch()` and undici@8's `Agent` use different internal handler APIs - passing them together throws: ``` invalid onRequestStart method ``` ### What's the fix? When `selfSignedCert` is enabled (i.e. a `dispatcher` is set), use undici's own `fetch()` instead of the global one. For all other requests, keep using `globalThis.fetch`. ```js const fetchFn = requestOptions.dispatcher ? undiciFetch : globalThis.fetch; ``` ### Why not just always use undici's fetch? That would fix the crash - but it would break some tests. MSW (Mock Service Worker), which is used in our test suite to intercept HTTP requests, only hooks into `globalThis.fetch`. Undici's fetch bypasses those interceptors entirely, so tests would start making real network requests instead of getting the mocked responses. We could rewrite all tests to use undici-compatible mocking instead - but that would be a massive change for no real benefit. ---- Fixes #4093
After the big weather refactor (#4032), OpenWeatherMap was effectively hard-wired to One Call v3. One Call 2.5 is deprecated and no longer available, so it looked like v2.5 support was effectively over — but the classic `/weather` and `/forecast` endpoints were never actually dropped. This restores support for those. Fixes #4100. ## What this PR does - handles OpenWeatherMap responses by endpoint again (`/onecall`, `/weather`, `/forecast`) - restores v2.5 current and forecast support (including hourly via 3-hour forecast slots) - filters outdated hourly entries centrally while keeping the current hour visible (if available) ## Screenshot <img width="768" height="481" alt="bildo" src="https://github.com/user-attachments/assets/9bce3531-3731-4fd7-b41e-e20603afa725" />
and cleanup spelling
Disable secret substitution only for cors=allowAll, the last attempt in #4102 was to restrictive. Secret substitution should also work if cors=disabled. --------- Co-authored-by: Kristjan ESPERANTO <35647502+KristjanESPERANTO@users.noreply.github.com>
Fixes #4105 ```bash In JavaScript, standard JSON does not support functions. If you use JSON.stringify() on an object containing functions, those functions will be omitted (if they are object properties) or changed to null (if they are in an array). ``` --------- Co-authored-by: Kristjan ESPERANTO <35647502+KristjanESPERANTO@users.noreply.github.com>
While looking at the WeatherFlow provider (to evaluate #4107), I noticed a few things that weren't quite right. 1. **UV index was broken for most providers in forecast/hourly views.** The templates read `uv_index`, but only the WeatherAPI provider actually wrote that key. All other providers (OpenWeatherMap, WeatherFlow, PirateWeather, etc.) use `uvIndex` - so UV was silently never displayed for them. This went unnoticed because `showUVIndex` defaults to `false` and there were no test assertions for it. Standardized everything on `uvIndex` and added test coverage. 2. **WeatherFlow didn't map precipitation for current weather.** The API provides `precip_accum_local_day` and `precip_probability`, but they weren't passed through. While adding them I also noticed the template used truthiness checks, which hid valid zero values. Fixed both. 3. **`||` vs `??` in WeatherFlow provider.** Several numeric fields used `|| null`, replacing valid `0` with `null`. Switched to `??` for correctness.
Add minimal GITHUB_TOKEN permissions to electron-rebuild workflow to enforce least privilege and satisfy CodeQL alert [#14](https://github.com/MagicMirrorOrg/MagicMirror/security/code-scanning/14).
#4113) As reported in #4109, the weather module retries much more frequently than expected after network errors. #4092 already fixed the main cause (duplicate fetchers), but the backoff logic in `HTTPFetcher` still has a gap: once retries are exhausted, `calculateBackoffDelay` keeps returning a short fixed delay (60s) instead of falling back to `reloadInterval`. The same problem existed for 5xx errors, where the delay grew to 8× the configured interval. Inspired by #4110 (thanks @CodeLine9), this PR makes both error paths fall back to `reloadInterval` after retries are exhausted. I also simplified the catch block, extracted a `#shortenUrl()` helper for log messages, and added tests for the backoff progression.
…kUpdates (#4115) This fixes CodeQL alert [#16](https://github.com/MagicMirrorOrg/MagicMirror/security/code-scanning/16) by replacing shell-built git commands with `execFile` + `cwd` in updatenotification’s `git_helper`. It also includes a small cleanup in `checkUpdates()` (remove unnecessary async/Promise wrapper) and updates the related unit tests.
## Summary This updates `js/http_fetcher.js` so HTTP `304 Not Modified` responses are emitted through the normal `response` event instead of being treated as errors. That aligns the core fetcher with the built-in `yr` weather provider in `v2.35.0`, which already includes explicit logic to handle `304` and reuse cached data. Closes #4119. ## Root cause `HTTPFetcher` currently treats all non-OK responses as errors. Since `304` is not an OK response, it never reaches providers listening on the `response` event. At the same time, `defaultmodules/weather/providers/yr.js` expects to receive `304` and handle it by reusing cached data. ## What changed - special-case HTTP `304` in `HTTPFetcher` - emit `304` through the normal `response` event - preserve the existing error path for other non-OK statuses ## Validation - confirmed `defaultmodules/weather/providers/yr.js` already expects `response.status === 304` - compared the unpatched `v2.35.0` `HTTPFetcher` behavior to the provider logic - ran `node --check js/http_fetcher.js` Co-authored-by: sonnyb9 <sonnyb9@users.noreply.github.com>
When a client reconnects while the backend is still in its rate-limit protection phase, the weather module has no data to show and stays on `Loading...` until the next scheduled API call. This mainly affects server mode setups, where the server keeps running while a remote client temporarily loses its connection and reloads. It was [raised in the forum](https://forum.magicmirror.builders/topic/20218/request-loop-loading...-in-standard-weather-module-open-meteo-after-update/11?_=1777106416020) and is worthy of a fix to improve the user experience. With this PR the node helper caches the last successful `WEATHER_DATA` payload per instance and replays it immediately on reconnect. The client gets its last known state right away instead of waiting for the next fetch. The cache is cleaned up when the provider stops. Tests are included to cover reconnect with and without cached data, and the cleanup path.
Open-Meteo updates `current_weather` every 15 minutes, but the hourly array only has entries at full hours. The old code did an exact timestamp match - so at 14:15, 14:30 or 14:45 it never found a match and silently fell back to index 0, showing midnight values for humidity, feels-like temp, precipitation, etc. Fix: `findLastIndex((hour) => hour.time <= currentMs)` - the last hourly entry at or before the current time. While fixing the bug I found several dead branches left over from the #4032 refactor: a path for pre-transposed hourly data that `#parseWeatherApiResponse` makes unreachable, an `Array.isArray` guard that's always true, and a `Log.debug` inside the dead branch. Removing those accounts for most of the ~40 deleted lines - the actual fix is one line. Fixes #4122.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Release Notes
Thanks to: @cgillinger, @khassel, @KristjanESPERANTO, @sonnyb9
Compare to previous Release v2.35.0
This release falls outside the quarterly schedule. We opted for an early release due to:
Breaking Changes
The cors proxy is now disabled by default. If required, it must be explicitly enabled in the
config.jsfile. See the documentation.You can find several publicly accessible MagicMirror² instances.
This should never be done. Doing so makes your entire configuration, including secrets and API keys, publicly visible. Furthermore, it allows attackers to target the host; this is only prevented beginning with this release.
Public MagicMirror² instances should always run behind a reverse proxy with authentication.
[core]
[dependencies]
[modules/newsfeed]
[modules/updatenotification]
[modules/weather]
[testing]