feat(network): captive portal detection and sign-in popup#2678
Open
Rocho-EL-Locho wants to merge 2 commits into
Open
feat(network): captive portal detection and sign-in popup#2678Rocho-EL-Locho wants to merge 2 commits into
Rocho-EL-Locho wants to merge 2 commits into
Conversation
Detect captive portals and prompt the user to sign in, similar to mainstream desktop and mobile OSes. A backend-agnostic connectivity probe in the network manager requests a known endpoint (configurable via DMS_CAPTIVE_PROBE_URL); a redirect or an unexpected body means traffic is being intercepted. The result is exposed as new connectivity and portalURL fields over the socket. A modal opens when a portal is detected and closes once the user signs in, with the login page opening in the default browser. The popup can be disabled, and a manual entry point is available while a portal is active. Fixes AvengeMedia#2632
Adds the captivePortal section and captivePortalAutoOpen toggle to the generated settings search index (extract_settings_index.py).
bbedward
requested changes
Jun 22, 2026
| DankModal { | ||
| id: root | ||
|
|
||
| readonly property string fallbackURL: "http://nmcheck.gnome.org/check_network_status.txt" |
Collaborator
There was a problem hiding this comment.
Probably better if we don't hardcode this in 2 places on th e QML side, can be a constant in NetworkService
| ConnectivityUnknown Connectivity = "unknown" | ||
| ConnectivityNone Connectivity = "none" | ||
| ConnectivityPortal Connectivity = "portal" | ||
| ConnectivityLimited Connectivity = "limited" |
Collaborator
There was a problem hiding this comment.
Doesnt seem to do anything with the limited case, should we? I'd rather remove it or add a // TODO than leave the unused value
| } | ||
|
|
||
| Rectangle { | ||
| width: Math.max(120, openText.contentWidth + Theme.spacingM * 2) |
Collaborator
There was a problem hiding this comment.
Better to use standard Widgets/ than hand-rolling custom buttons, e.g. Dankbutton
|
|
||
| func (p *portalProbe) run() { | ||
| defer p.wg.Done() | ||
| ticker := time.NewTicker(portalProbeInterval) |
Collaborator
There was a problem hiding this comment.
Not a fan of using a ticker here, better to rewrite polling to be event-driven. I'd re-work that as a timer thats conditionalled armed, cancelled when sign in is "full" . We can probably subscribe to NM PropertiesChanged, or something like that to catch portal changes.
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.
Description
Adds captive portal detection and a sign-in popup, similar to mainstream desktop and mobile OSes: when you join a network that requires sign-in before reaching the internet, DMS surfaces a popup and opens the login page in your default browser.
How it works:
204/expected body means full connectivity. The result is exposed as two newNetworkStatefields,connectivity(unknown/none/portal/limited/full) andportalURL, which flow over the socket to the QML services.CaptivePortalModalauto-opens when a portal is detected (gated by a setting) and closes automatically once the user signs in (the periodic re-probe flips the state tofull).Notes / design decisions (open to feedback):
Managerrather than the NetworkManager backend, so it works across all backends (NetworkManager, iwd, networkd) and does not depend on NM's connectivity checking being enabled.http://nmcheck.gnome.org/check_network_status.txt(the same default NetworkManager uses) and is overridable viaDMS_CAPTIVE_PROBE_URL. Once a connection is healthy, it is re-checked only every ~5 minutes to keep background traffic low.Type of change
Related issues
Fixes #2632
Screenshots / video
The popup ("Sign in to network") shows the network name with Open login page and Dismiss actions. I can attach a screenshot/recording with demo data on request.
Checklist
I18n.tr()and registered inen.json, reusing existing terms where possiblemake fmt, added/updated tests,make testpasses, andgo mod tidyis cleanmake lint-qmlwas not run locally — generating the tooling VFS requires a newer Quickshell than the packaged 0.3.0 here. QML was verified withqmllintsyntax checks and a live runtime load; happy to address anything CI flags.