Skip to content

fix(newsfeed): fix full article view and add framing check#4039

Open
KristjanESPERANTO wants to merge 3 commits intoMagicMirrorOrg:developfrom
KristjanESPERANTO:newsfeed
Open

fix(newsfeed): fix full article view and add framing check#4039
KristjanESPERANTO wants to merge 3 commits intoMagicMirrorOrg:developfrom
KristjanESPERANTO:newsfeed

Conversation

@KristjanESPERANTO
Copy link
Collaborator

I was playing around with the newsfeed notification system (ARTICLE_MORE_DETAILS, ARTICLE_TOGGLE_FULL, …) and discovered some issues with the full article view:

The iframe was loading the CORS proxy URL instead of the actual article URL, which could cause blank screens depending on the feed. Also, many news sites block iframes entirely (X-Frame-Options: DENY) and the user got no feedback at all — just an empty page. On top of that, scrolling used window.scrollTo() which moved the entire MagicMirror page instead of just the article.

This PR cleans that up:

  • Use the raw article URL for the iframe (CORS proxy is only needed for server-side feed fetching)
  • Check X-Frame-Options / Content-Security-Policy headers server-side before showing the iframe — if the site blocks it, show a brief "Article cannot be displayed here." message and return to normal view
  • Show the iframe as a fixed full-screen overlay so other modules aren't affected, scroll via container.scrollTop
  • Keep the progressive disclosure behavior for ARTICLE_MORE_DETAILS (title → description → iframe → scroll)
  • Delete fullarticle.njk, replace with getDom() override
  • Fix ARTICLE_INFO_RESPONSE returning proxy URL instead of real URL
  • A few smaller fixes (negative scroll, null guard)
  • Add NEWSFEED_ARTICLE_UNAVAILABLE translation to all 47 language files
  • Add e2e tests for the notification handlers (ARTICLE_NEXT, ARTICLE_PREVIOUS, ARTICLE_INFO_REQUEST, ARTICLE_LESS_DETAILS)

What this means for users

  • The full article view now works reliably across different feeds
  • If a news site blocks iframes, the user sees a brief message instead of a blank screen
  • Additional e2e tests make the module more robust and less likely to break silently in future MagicMirror versions

The iframe src was built using getActiveItemURL() which prepends the
CORS proxy prefix (http://localhost:8080/cors?url=...). Browsers refuse
to load that URL in an iframe, resulting in 403/500 errors with no
visible feedback to the user.

Changes:
- Delete fullarticle.njk (3-line file, replaced by getDom() override)
- Add getDom() override that renders loading/unavailable/iframe states
  directly via DOM API, using the raw article URL for the iframe src
- Add server-side framing check in node_helper: sends a HEAD request
  and inspects X-Frame-Options / Content-Security-Policy headers before
  showing the iframe; sends ARTICLE_URL_STATUS socket notification back
- When an article cannot be framed: show NEWSFEED_ARTICLE_UNAVAILABLE
  message for 3 seconds, then auto-return to normal newsfeed view
- Replace window.scrollTo() with container.scrollTop on an
  overflow-y:auto container � prevents scrolling other modules out of view
- iframe is now a position:fixed full-screen overlay (z-index:1000) so
  other module positions are unaffected
- Simplify showFullArticle(): always opens iframe directly; guard
  against missing article URL
- Implement ARTICLE_MORE_DETAILS as progressive disclosure:
  title → description → iframe → scroll down
- Fix ARTICLE_INFO_RESPONSE returning CORS proxy URL instead of raw URL
- Fix ARTICLE_SCROLL_UP allowing negative scrollPosition
- Add null guard in ARTICLE_INFO_REQUEST handler to prevent crash when
  newsItems not yet loaded
Add the new key to all 47 language files. The message is shown for
3 seconds when a news article cannot be displayed in an iframe (e.g.
because the site sends X-Frame-Options: DENY).

Also fix ps.json: add missing NEWSFEED_NO_ITEMS key and correct
indentation of UPDATE_INFO_MULTIPLE.
Add a dedicated 'Newsfeed module > Notifications' describe block with
tests for: ARTICLE_NEXT, ARTICLE_PREVIOUS (including wrap-around in
both directions), ARTICLE_INFO_REQUEST (verifying response payload and
that the URL is the raw article URL, not a CORS proxy URL), and
ARTICLE_LESS_DETAILS.

Add tests/configs/modules/newsfeed/notifications.js with a long
updateInterval (1 hour) to prevent auto-rotation during tests.
@sdetweil
Copy link
Collaborator

Nice work.
one investigative question

why not use the jdk file?

Supposedly it’s as functional as direct dom.
just a question. I have used similar functionality via Angular

@KristjanESPERANTO
Copy link
Collaborator Author

why not use the jdk file?

The full article view now has an async step (server checks headers before showing the iframe), so the DOM needs to react to a callback. With a template you'd render it and then immediately manipulate the result via querySelector anyway — at that point the template doesn't add much. The old one was only 3 lines, so moving it into getDom() felt simpler.

@rejas
Copy link
Collaborator

rejas commented Feb 28, 2026

No complains from my side other then the question if the translations were done with AI?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants