Skip to content

Add network wake functionality to external integrations - #2848

Closed
vincentBesseau wants to merge 11 commits into
GladysAssistant:masterfrom
vincentBesseau:master
Closed

Add network wake functionality to external integrations#2848
vincentBesseau wants to merge 11 commits into
GladysAssistant:masterfrom
vincentBesseau:master

Conversation

@vincentBesseau

@vincentBesseau vincentBesseau commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Description

Add Wake-on-LAN support to the external integration Host API.

External integrations can now request Gladys Core to send a Wake-on-LAN magic packet from its network namespace through:

POST /api/integration/v1/network/wake

The API supports:

  • MAC addresses in common formats (64:e4:d5:b4:12:66, 64-e4-d5-b4-12-66, 64E4D5B41266)
  • Custom destination IPv4 address
  • Custom UDP destination port
  • Custom UDP source port

This allows external integrations running in isolated Docker networks to wake LAN devices through Gladys Core.

Tests cover magic packet generation, MAC address formats, source port handling, input validation and the external integration Host API controller.

Forum

Forum: https://community.gladysassistant.com/t/api-sdk-wake-on-lan-via-le-coeur-gladys/10522

Checklist

  • Tests pass: cd server && npm run coverage (Codecov requires 100% coverage on changed lines) and Cypress (npm run cypress:run) if the UI changed
  • Linter and prettier pass on both front and server (npm run eslint, npm run prettier)
  • No undocumented breaking change

Summary by CodeRabbit

  • New Features
    • Added Wake-on-LAN support for remotely waking compatible devices.
    • Added an authenticated network endpoint for sending wake requests.
    • Supports configurable device address, destination port, and source port.
    • Wake requests require the appropriate network-wake permission.
  • Bug Fixes
    • Added validation for MAC addresses, IPv4 addresses, and port values.
  • Tests
    • Added coverage for packet generation, supported address formats, configuration options, permissions, and error handling.

@github-actions github-actions Bot added area:server Node.js server code type:feature New user-facing feature or improvement labels Aug 11, 2026
@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The change adds Wake-on-LAN packet transmission with input validation, exposes it through ExternalIntegration, and adds an authenticated POST /api/integration/v1/network/wake endpoint. Tests cover packet formats, validation, source ports, successful responses, and error propagation.

Changes

Wake-on-LAN feature

Layer / File(s) Summary
Packet construction and transmission
server/lib/external-integration/externalIntegration.wakeOnLan.js, server/test/lib/external-integration/externalIntegration.wakeOnLan.test.js
The implementation validates MAC addresses, IPv4 addresses, ports, options, and permissions. It builds and sends UDP/IPv4 magic packets. Tests cover packet contents, MAC formats, source ports, invalid options, permission failures, and socket errors.
ExternalIntegration API wiring
server/lib/external-integration/index.js
wakeOnLan is imported and exposed on the ExternalIntegration prototype.
Authenticated controller endpoint
server/api/controllers/integrationHost.controller.js, server/api/routes.js, server/test/controllers/integrationHost/integrationHost.controller.test.js, server/test/api/routes.test.js
The controller forwards request options and returns { success: true }. The authenticated POST route is registered. Tests cover route registration, successful calls, and error propagation.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested reviewers: pierre-gilles

Poem

I’m a rabbit with packets to send,
A magic burst hops round the bend.
MACs line up, ports glow bright,
The network wakes before moonlight.
Errors return, tests cheer: “All clear!”

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant IntegrationRoute
  participant IntegrationHostController
  participant ExternalIntegration
  participant UDPSocket
  Client->>IntegrationRoute: POST /api/integration/v1/network/wake
  IntegrationRoute->>IntegrationHostController: authenticate and dispatch request
  IntegrationHostController->>ExternalIntegration: wakeOnLan(service, options)
  ExternalIntegration->>UDPSocket: bind and send magic packet
  UDPSocket-->>ExternalIntegration: report completion or error
  ExternalIntegration-->>IntegrationHostController: resolve or reject
  IntegrationHostController-->>Client: success response or propagated error
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding network wake functionality for external integrations.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@Pierre-Gilles Pierre-Gilles added the needs:human-review Automated review is not confident, maintainer must take a look label Aug 11, 2026 — with Cursor
@cursor
cursor Bot requested a review from Pierre-Gilles August 11, 2026 11:46

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale comment

Thanks for this — the core idea matches a real Host API gap (bridge containers cannot emit LAN broadcasts, so WoL has to be mediated by the core, same family as B.16).

Requesting changes before merge:

  1. Living spec missingdocs/specs/external-integrations.md is the source of truth for Host API contracts. This PR adds POST /api/integration/v1/network/wake and must document it in the same diff (C.3 at minimum; C.1/C.8 if a manifest/SDK surface is introduced).
  2. No authorization contract — sibling host-mediated capabilities (network_discovery, location) are declared in the manifest, shown at install time, and enforced server-side with 403. This endpoint is available to every authenticated external integration with no declaration, no disclosure, and no rate bound, while emitting UDP from the core’s network=host namespace to an arbitrary IPv4/port. That needs a deliberate design choice (likely a manifest flag + gate, and probably a rate limit), not an ungated free-for-all.
  3. Invalid MAC returns a generic Error → HTTP 500 instead of BadParameters → 400.
  4. UDP socket leak on the error path when bind/send fails before close().

Magic-packet construction, MAC format support, and the unit tests look solid. No device categories/types involved.

Flagged needs:human-review and requested @Pierre-Gilles — this is a Host API / external-integration authorization-contract question and should align with the living-spec philosophy before landing.

Open in Web View Automation 

Sent by Cursor Automation: Automatic PR review

Comment thread server/api/controllers/integrationHost.controller.js Outdated
Comment thread server/lib/external-integration/externalIntegration.wakeOnLan.js Outdated
Comment thread server/lib/external-integration/externalIntegration.wakeOnLan.js Outdated
@codecov

codecov Bot commented Aug 11, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.49%. Comparing base (5416580) to head (6f4dab9).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff            @@
##           master    #2848    +/-   ##
========================================
  Coverage   99.49%   99.49%            
========================================
  Files        1221     1222     +1     
  Lines       85594    85754   +160     
========================================
+ Hits        85158    85318   +160     
  Misses        436      436            

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@server/lib/external-integration/externalIntegration.wakeOnLan.js`:
- Around line 15-19: Ensure every malformed Wake-on-LAN request returns
BadParameters: update normalizeMac to throw BadParameters, validate the options
object before destructuring in wakeOnLan, and have integrationHost.controller
pass req.body to the service. Update the specified tests to assert BadParameters
for malformed MACs, null options, and other invalid options; apply changes at
server/lib/external-integration/externalIntegration.wakeOnLan.js lines 15-19 and
49-52, server/api/controllers/integrationHost.controller.js lines 142-148, and
the corresponding test ranges at lines 133-148 and 215-233.
- Around line 72-93: Ensure every UDP socket is closed on failure: in
externalIntegration.wakeOnLan.js, close the production socket when bind emits an
error; in
server/test/lib/external-integration/externalIntegration.wakeOnLan.test.js lines
13-24, close each test receiver in finally; and in lines 41-130, make
waitForUdpMessage remove its message listener on timeout or abort and close
receivers in finally, including failed sends, timeouts, and assertion failures.

In `@server/test/lib/external-integration/externalIntegration.wakeOnLan.test.js`:
- Around line 235-307: Move the networkWake success and error controller tests
from server/test/lib/external-integration/externalIntegration.wakeOnLan.test.js
lines 235-307 to server/test/api/controllers/integrationHost.controller.test.js,
preserving coverage of option forwarding, success responses, and error
propagation. Add a mirrored route-registration test for server/api/routes.js
lines 673-677 that verifies externalIntegrationAuth is true and the route
handler is integrationHostController.networkWake.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d4826bf3-5058-44bb-92ab-28581375f9f1

📥 Commits

Reviewing files that changed from the base of the PR and between 12bc5f2 and a585e5d.

📒 Files selected for processing (5)
  • server/api/controllers/integrationHost.controller.js
  • server/api/routes.js
  • server/lib/external-integration/externalIntegration.wakeOnLan.js
  • server/lib/external-integration/index.js
  • server/test/lib/external-integration/externalIntegration.wakeOnLan.test.js

Comment thread server/lib/external-integration/externalIntegration.wakeOnLan.js Outdated
Comment thread server/lib/external-integration/externalIntegration.wakeOnLan.js
Comment thread server/test/lib/external-integration/externalIntegration.wakeOnLan.test.js Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@server/lib/external-integration/externalIntegration.wakeOnLan.js`:
- Line 56: Validate the address in the options-handling flow before calling
dgram.Socket#send, using net.isIPv4(address) and rejecting non-IPv4 values,
including hostnames and “invalid-ip”, with BadParameters. Add or update the
relevant test to assert that invalid-ip produces BadParameters.

In `@server/test/lib/external-integration/externalIntegration.wakeOnLan.test.js`:
- Around line 6-10: Add a denial test in the external integration suite using a
service fixture whose manifest omits network_wake, then invoke the relevant
wake-on-LAN operation and assert that it rejects with ForbiddenError. Keep the
existing permitted-service fixture and success coverage unchanged.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 562c5040-abeb-4b51-846e-9a8a0c1dcd6a

📥 Commits

Reviewing files that changed from the base of the PR and between a585e5d and e7fd19a.

📒 Files selected for processing (5)
  • server/api/controllers/integrationHost.controller.js
  • server/lib/external-integration/externalIntegration.wakeOnLan.js
  • server/test/api/routes.test.js
  • server/test/controllers/integrationHost/integrationHost.controller.test.js
  • server/test/lib/external-integration/externalIntegration.wakeOnLan.test.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • server/api/controllers/integrationHost.controller.js

Comment thread server/lib/external-integration/externalIntegration.wakeOnLan.js Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@server/test/lib/external-integration/externalIntegration.wakeOnLan.test.js`:
- Line 3: Replace the shared Sinon singleton import in the test file with a
per-file Sinon sandbox, and update the tests to create, use, and restore that
sandbox for stubs and cleanup.
- Around line 283-342: Update the external integration test file to use a
per-file Sinon sandbox by creating it from require('sinon').createSandbox(), and
use that sandbox for stubbing and restoration. Add coverage for the socket
error-event path in wakeOnLan: capture the error listener registered through
socket.once, invoke it while the operation is pending, assert the original error
is rejected, and verify socket.close is called.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: daa34bac-bb40-4ef0-ae3c-171694c53fa1

📥 Commits

Reviewing files that changed from the base of the PR and between a5df4b3 and 25e29b0.

📒 Files selected for processing (2)
  • server/lib/external-integration/externalIntegration.wakeOnLan.js
  • server/test/lib/external-integration/externalIntegration.wakeOnLan.test.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • server/lib/external-integration/externalIntegration.wakeOnLan.js

Comment thread server/test/lib/external-integration/externalIntegration.wakeOnLan.test.js Outdated
@Pierre-Gilles Pierre-Gilles added the needs:cursor-review Automated review by Cursor is needed label Aug 11, 2026 — with Cursor
@Pierre-Gilles Pierre-Gilles removed the needs:cursor-review Automated review by Cursor is needed label Aug 11, 2026

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale comment

Re-reviewed at 21d53300 after the follow-up commits. Thanks for addressing the earlier BadParameters MAC path and the UDP socket close-on-error leak — those look good.

Still requesting changes before merge:

  1. Authorization contract is only half-wired. Runtime now gates on service.manifest.network_wake with ForbiddenError, which is the right direction — but network_wake is not in MANIFEST_FIELDS / manifest.schema.json, is not validated as a boolean, is not shown on the install screen, and is not documented in docs/specs/external-integrations.md. Because unknown top-level manifest keys are rejected (network_wake: unknown field), a real integration cannot declare the capability through the normal install/update path, so the Host API is unreachable in production while also skipping the user-consent surface that location / network_discovery / webhooks provide. Please complete the full contract in this PR (schema + validator + install disclosure + living spec C.1/C.3; SDK follow-up in C.8 is fine later).

  2. Missing/non-string mac still becomes HTTP 500. {} / { mac: null } skip the options-object guard, pass the permission check, then crash in normalizeMac on .replace.

  3. Codecov patch coverage is not 100%. CI reports uncovered lines 88-89 and 106-107 (the if (settled) return branches). Gladys requires 100% patch coverage on changed server lines — add a socket error-event / double-settle test (CodeRabbit already flagged the missing error path).

Magic-packet construction, MAC format support, IPv4/port validation, controller wiring, and the unit tests that exist remain solid. No device categories/types involved.

Server test is red on this run, but the failure is the known parallel t_session schema-drift flake (table t_session has 15 columns but 14 values were supplied), not the WoL suite (all externalIntegration.wakeOnLan / networkWake cases passed).

Keeping needs:human-review + @Pierre-Gilles — Host API authorization-contract / LAN-emission philosophy (including whether arbitrary unicast destinations and unbounded wake rate are acceptable vs B.16’s broadcast-only + rate-bound active scan). Not tagging risk:high: fixed 102-byte WoL payload, not a general UDP proxy.

Open in Web View Automation 

Sent by Cursor Automation: Automatic PR review

Comment thread server/lib/external-integration/externalIntegration.wakeOnLan.js
Comment thread server/lib/external-integration/externalIntegration.wakeOnLan.js
Comment thread server/lib/external-integration/externalIntegration.wakeOnLan.js
@github-actions github-actions Bot added the area:front Preact front-end label Aug 11, 2026
@Pierre-Gilles Pierre-Gilles added the needs:cursor-review Automated review by Cursor is needed label Aug 11, 2026 — with Cursor
@Pierre-Gilles Pierre-Gilles removed the needs:cursor-review Automated review by Cursor is needed label Aug 11, 2026

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale comment

Re-reviewed at 7b7f8f3d after the follow-up commits. Thanks — the previous blockers are largely fixed:

  • network_wake is now in MANIFEST_FIELDS / manifest.schema.json, validated as boolean, shown on the install screen, and gated with ForbiddenError
  • missing/non-string macBadParameters
  • socket close-on-error + double-settle coverage
  • CI is green (including codecov/patch)

Still requesting changes before merge:

  1. German install consent text is wrong. de.json networkWakeText still describes network discovery (“Netzwerkankündigungen … erfassen”), not Wake-on-LAN. That breaks the authorization-contract disclosure for German users — please translate the EN/FR meaning.
  2. Living-spec C.3 entry is unfinished. The new POST /network/wake line is truncated (100% reliable wake-on-LAN,) and overclaims reliability. Please finish it in the style of GET /house / camera: required network_wake: true403, optional address/port/sourcePort defaults, fixed 102-byte magic packet. Also add network_wake to the C.1 prose list of authorization contracts (containers, network_discovery, webhooks, location, …).

Soft / non-blocking:

  • Rename NetworkWakeSumamary.jsxNetworkWakeSummary.jsx (typo in the filename).
  • Prefer service.manifest && service.manifest.network_wake === true like getHouses / location.
  • SDK helper (C.8) can land as a follow-up once the Host API contract is settled.

Keeping needs:human-review + @Pierre-Gilles for the Host API philosophy question left open: arbitrary unicast destinations + no per-integration rate bound vs B.16’s broadcast-only + 1/10s active-scan guardrails. Not tagging risk:high: fixed 102-byte WoL payload, not a general UDP proxy. No device categories/types involved.

Open in Web View Automation 

Sent by Cursor Automation: Automatic PR review

Comment thread front/src/config/i18n/de.json Outdated
Comment thread docs/specs/external-integrations.md Outdated
Comment thread docs/specs/external-integrations.md Outdated
Comment thread server/lib/external-integration/externalIntegration.wakeOnLan.js Outdated
@Pierre-Gilles Pierre-Gilles added the needs:cursor-review Automated review by Cursor is needed label Aug 12, 2026 — with Cursor
@Pierre-Gilles Pierre-Gilles removed the needs:cursor-review Automated review by Cursor is needed label Aug 12, 2026
cursor[bot]
cursor Bot previously approved these changes Aug 12, 2026

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale comment

Re-reviewed at ca0fd332. Previous blockers are fixed — thanks:

  • German install consent text now describes Wake-on-LAN (not discovery)
  • Living-spec C.3 documents the endpoint correctly (required network_wake: true → 403, defaults, fixed 102-byte payload, success ≠ device woke)
  • C.1 authorization-contracts list includes network_wake
  • Filename rename NetworkWakeSummary.jsx + strict network_wake === true gate

CI is green (Front/Server/Cypress/Docker/codecov patch+project).

Approving from a code/contract standpoint. Soft nits left inline (spec punctuation; tests asserting Error instead of BadParameters).

Keeping needs:human-review + @Pierre-Gilles for the Host API philosophy still open vs B.16: arbitrary unicast destinations and no per-integration rate bound. Not tagging risk:high — fixed magic-packet payload, not a general UDP proxy. No device categories/types involved. SDK helper (C.8) can land as a follow-up.

Open in Web View Automation 

Sent by Cursor Automation: Automatic PR review

Comment thread docs/specs/external-integrations.md Outdated
Comment thread server/test/lib/external-integration/externalIntegration.wakeOnLan.test.js Outdated
@vincentBesseau

Copy link
Copy Markdown
Contributor Author

@Pierre-Gilles Pull request tests / Server test est en erreur et je ne pense pas y être pour grand chose.

J'attend tes retours côté SDK aussi :
GladysAssistant/integration-sdk-js#27

@Pierre-Gilles Pierre-Gilles added the needs:cursor-review Automated review by Cursor is needed label Aug 13, 2026 — with Cursor
@Pierre-Gilles Pierre-Gilles removed the needs:cursor-review Automated review by Cursor is needed label Aug 13, 2026

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-reviewed at 1d9c787. The two leftover nits from the previous approval are fixed — thanks:

  • C.3 now matches sibling Host API entries (em dash, \u2192, capitalized “Sends”)
  • Invalid destination/source port tests assert BadParameters (so a generic Error → HTTP 500 would fail the suite)

The Host API contract remains complete: network_wake in C.1 + schema/validator, install-screen disclosure (en/fr/de), strict network_wake === true gate, fixed 102-byte magic packet, MAC/IPv4/port validation → BadParameters.

Approving again from a code/contract standpoint (previous approval was dismissed by this push).

Keeping needs:human-review + @Pierre-Gilles for the Host API philosophy still open vs B.16: arbitrary unicast destinations and no per-integration rate bound. Not tagging risk:high — fixed magic-packet payload, not a general UDP proxy. No device categories/types involved.

Follow-ups (not blocking this PR):

  • SDK helper (C.8) — already opened as integration-sdk-js#27
  • Current Server test red is unrelated: zigbee2mqttManager.publish “should log the topic and the message published” (AssertError on logger.debug). All WoL / networkWake cases passed (5672 passing). Worth a re-run; not caused by this diff.
Open in Web View Automation 

Sent by Cursor Automation: Automatic PR review

@Pierre-Gilles

Copy link
Copy Markdown
Contributor

Merged in #2864

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

Labels

area:front Preact front-end area:server Node.js server code needs:human-review Automated review is not confident, maintainer must take a look type:feature New user-facing feature or improvement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants