aboutsummaryrefslogtreecommitdiffstats
path: root/packages
diff options
context:
space:
mode:
Diffstat (limited to 'packages')
-rw-r--r--packages/meshbay-client/build/installer-light.nsh13
-rw-r--r--packages/meshbay-client/build/installer.nsh30
-rw-r--r--packages/meshbay-node/tests/test_packaging_win.py31
3 files changed, 44 insertions, 30 deletions
diff --git a/packages/meshbay-client/build/installer-light.nsh b/packages/meshbay-client/build/installer-light.nsh
index 86e41ba..7717331 100644
--- a/packages/meshbay-client/build/installer-light.nsh
+++ b/packages/meshbay-client/build/installer-light.nsh
@@ -53,15 +53,16 @@
!macroend
!macro customUnInstall
- ; Opt-in, default No -- a stale allow-rule is inert, so this should not
- ; nag. A silent uninstall skips it entirely (no UAC prompt of its own).
+ ; Same as the full installer: the UAC prompt alone, no question before it,
+ ; and only when a rule is still there. A silent uninstall skips it (it may
+ ; not raise UI).
${IfNot} ${Silent}
- MessageBox MB_YESNO|MB_ICONQUESTION \
- "Remove MeshBay Light's Windows Firewall rules? This needs one administrator confirmation. They are harmless if left." \
- /SD IDNO IDNO mb_keep_firewall
+ nsExec::Exec '"${MB_PWSH}" -NoProfile -ExecutionPolicy Bypass -File "$INSTDIR\resources\firewall.ps1" any'
+ Pop $R1 ; 0 = at least one rule exists
+ ${If} $R1 == 0
ExecShellWait "runas" "${MB_PWSH}" \
'-NoProfile -ExecutionPolicy Bypass -File "$INSTDIR\resources\firewall.ps1" remove' \
SW_HIDE
- mb_keep_firewall:
+ ${EndIf}
${EndIf}
!macroend
diff --git a/packages/meshbay-client/build/installer.nsh b/packages/meshbay-client/build/installer.nsh
index ef9c82a..2337088 100644
--- a/packages/meshbay-client/build/installer.nsh
+++ b/packages/meshbay-client/build/installer.nsh
@@ -24,8 +24,8 @@
; task when service mode is chosen; their own single elevation otherwise.
; One UAC prompt for an install, never two, never zero;
; - cleanup of whichever of those is outside $INSTDIR on the way out (the
-; Startup .vbs; the scheduled task and firewall rules, together, if the
-; user opts in at uninstall time).
+; Startup .vbs; the scheduled task and firewall rules, together, in one
+; elevation asked for only when one of them is still there).
;
; Deliberately NOT touched:
; - %LOCALAPPDATA%\meshbay\ (node.toml, keystore.enc, unlock.key, data/) --
@@ -268,22 +268,26 @@ Var pid
WriteRegExpandStr HKCU "Environment" "Path" "$1"
SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
- ; Offer to take the firewall rules, and the service task if one was set up,
- ; back out together (needs admin again -- one prompt for both, same as
- ; install). Both underlying removes are no-ops when there is nothing to
- ; remove, so this is safe to run unconditionally regardless of which mode
- ; was chosen. Stale rules/tasks are inert if left, so this is opt-in and
- ; default-No; a silent uninstall skips it entirely. customUnInstall runs
- ; before the files are removed, so service-mode.ps1 is still there.
+ ; The firewall rules, and the service task if one was set up, go too: one
+ ; elevation for both, the UAC prompt alone, no question before it. There
+ ; used to be a Yes/No asking first, default No, so an uninstall left them
+ ; behind unless the person thought to say yes. Both are read unelevated
+ ; first, so a machine where neither is left sees no prompt at all. A
+ ; silent uninstall skips it (it may not raise UI); so does an upgrade,
+ ; whose install keeps both. customUnInstall runs before the files are
+ ; removed, so the scripts are still there.
${IfNot} ${Silent}
${AndIfNot} ${isUpdated}
- MessageBox MB_YESNO|MB_ICONQUESTION \
- "Remove MeshBay's Windows Firewall rules and its boot-time service task, if you set one up? This needs one administrator confirmation. Both are harmless if left." \
- /SD IDNO IDNO mb_keep_privileged
+ nsExec::Exec 'schtasks /query /tn "MeshBay Node"'
+ Pop $R0 ; 0 = the boot task exists
+ nsExec::Exec '"${MB_PWSH}" -NoProfile -ExecutionPolicy Bypass -File "$INSTDIR\resources\firewall.ps1" any'
+ Pop $R1 ; 0 = at least one rule exists
+ ${If} $R0 == 0
+ ${OrIf} $R1 == 0
ExecShellWait "runas" "${MB_PWSH}" \
'-NoProfile -ExecutionPolicy Bypass -File "$INSTDIR\resources\service-mode.ps1" -Action uninstall' \
SW_HIDE
- mb_keep_privileged:
+ ${EndIf}
${EndIf}
; meshbay_node.platform.autostart_install() -- if the user picked "at sign-in"
diff --git a/packages/meshbay-node/tests/test_packaging_win.py b/packages/meshbay-node/tests/test_packaging_win.py
index 96351db..ad366d0 100644
--- a/packages/meshbay-node/tests/test_packaging_win.py
+++ b/packages/meshbay-node/tests/test_packaging_win.py
@@ -554,23 +554,32 @@ def test_reinstalling_with_everything_already_in_place_asks_nothing():
assert "Goto mb_auto_done" in install
-def test_the_uninstaller_offers_to_remove_everything_privileged_default_no():
+def test_the_uninstaller_removes_everything_privileged_without_asking():
"""
- Opt-in on the way out too, and defaulting to No: a stale allow-rule or
- Scheduled Task is inert, so this should not nag. One elevation removes
- both, unconditionally — service-mode.ps1's own remove actions are each
- no-ops when there is nothing to remove, so this is safe to run whether or
- not service mode was ever chosen.
+ No Yes/No first: there used to be one, default No, and an uninstall left
+ the firewall rules and the boot task behind unless the person thought to
+ say yes. The UAC prompt is the only question, and it is asked only when a
+ rule or the task is still there, read unelevated beforehand. One elevation
+ removes both.
"""
nsh = NSH.read_text(encoding="utf-8")
uninstall = _macro_body(nsh, "customUnInstall")
+ assert "MessageBox" not in uninstall
assert "${IfNot} ${Silent}" in uninstall
assert "${AndIfNot} ${isUpdated}" in uninstall, "not while an upgrade replaces it"
- assert "/SD IDNO" in uninstall, "the uninstall prompt should default to No"
+ i_task = uninstall.index('schtasks /query /tn "MeshBay Node"')
+ i_rules = uninstall.index('firewall.ps1" any')
+ i_runas = uninstall.index('ExecShellWait "runas"')
+ assert i_task < i_runas and i_rules < i_runas, "read first, elevate after"
# uninstall, not remove: remove keeps the firewall rules (a mode switch).
assert 'service-mode.ps1" -Action uninstall' in uninstall
- assert 'ExecShellWait "runas"' in uninstall
+
+
+def test_the_firewall_helper_can_tell_whether_any_rule_is_left():
+ ps1 = (ROOT / "packaging" / "win" / "firewall.ps1").read_text(encoding="utf-8")
+ assert '"any"' in ps1.split("ValidateSet", 1)[1].split(")", 1)[0]
+ assert '$Action -eq "any"' in ps1
def test_an_upgrade_keeps_the_sign_in_launcher():
@@ -1163,13 +1172,13 @@ def test_light_installer_never_touches_a_co_installed_full_clients_node():
"belongs to a co-installed Full client, not to Light")
-def test_light_uninstaller_offers_to_remove_the_firewall_rules_default_no():
+def test_light_uninstaller_removes_the_firewall_rules_without_asking():
nsh = LIGHT_NSH.read_text(encoding="utf-8")
uninstall = _macro_body(nsh, "customUnInstall")
+ assert "MessageBox" not in uninstall
assert "${IfNot} ${Silent}" in uninstall
- assert "/SD IDNO" in uninstall
+ assert uninstall.index('firewall.ps1" any') < uninstall.index('ExecShellWait "runas"')
assert 'firewall.ps1" remove' in uninstall
- assert 'ExecShellWait "runas"' in uninstall
# ── the app-side gaps a bundle-less build would otherwise hit ──────────────