summaryrefslogtreecommitdiffstats
path: root/packages/meshbay-client
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-client')
-rw-r--r--packages/meshbay-client/build/installer.nsh174
1 files changed, 131 insertions, 43 deletions
diff --git a/packages/meshbay-client/build/installer.nsh b/packages/meshbay-client/build/installer.nsh
index 70858c6..3157f22 100644
--- a/packages/meshbay-client/build/installer.nsh
+++ b/packages/meshbay-client/build/installer.nsh
@@ -1,21 +1,31 @@
; electron-builder NSIS customisation (auto-included: build/installer.nsh).
;
-; Per-user install, no elevation (package.json build.nsis) -- that part never
-; changes. What this adds, all conditional on interactive setup (never
-; ${Silent}):
+; Per-user install, no elevation at install time (package.json build.nsis) --
+; that part never changes. What this adds, all conditional on interactive setup
+; (never ${Silent}):
+; - the per-machine ("anyone who uses this computer") option removed from
+; electron-builder's install-mode page: MeshBay is per-user only -- the
+; keystore and the DPAPI-protected secrets are bound to the signed-in
+; account (MESHBAY_DESIGN.md §11.2 / §7.5) -- so that option was only ever
+; shown disabled here. customInstallMode forces current-user and the page
+; is skipped entirely;
; - the bundled daemon dir on the user's PATH, so `meshbay-node` works in a
; terminal;
-; - a choice of autostart: the normal per-user Startup-folder launcher (no
-; admin, starts at sign-in -- see meshbay_node.platform._startup_vbs),
-; or a background-service mode (one admin confirmation, starts at boot,
-; no sign-in required -- see meshbay_node.platform.service_install and
-; packaging/win/service.ps1);
-; - the inbound firewall rules, folded into that SAME elevation when service
-; mode is chosen, or offered on their own otherwise -- never two UAC
-; prompts for one install;
+; - a custom page (radio buttons, like the rest of setup) choosing when the
+; node runs: only while the MeshBay app is open, at each sign-in (a per-user
+; Startup-folder launcher -- no admin -- see
+; meshbay_node.platform.autostart_install), or as a background service
+; (a boot-time S4U scheduled task -- one admin confirmation -- see
+; meshbay_node.platform.service_install and packaging/win/service.ps1).
+; Default: background service;
+; - the inbound firewall rules, set up in EVERY mode (a node that silently
+; accepts no connections is the failure mode called out in
+; MESHBAY_DESIGN.md §7.5). Folded into the SAME elevation as the boot
+; 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).
+; user opts in at uninstall time).
;
; Deliberately NOT touched:
; - %LOCALAPPDATA%\meshbay\ (node.toml, keystore.enc, unlock.key, data/) --
@@ -27,6 +37,7 @@
!include "WinMessages.nsh"
!include "WordFunc.nsh"
!include "LogicLib.nsh"
+!include "nsDialogs.nsh"
!insertmacro WordAdd
!insertmacro un.WordAdd
@@ -38,6 +49,79 @@
; the exact same string.
!define MB_NODE_BIN "$INSTDIR\resources\node-runtime"
+; ── force per-user, skip the all-users / current-user page ──────────────────
+!macro customInstallMode
+ StrCpy $isForceCurrentInstall "1"
+!macroend
+
+!macro customInit
+ StrCpy $MB_AutoMode "2"
+!macroend
+
+; ── the autostart choice, as a radio page ─────────────────────────────────
+; MB_AutoMode: "0" only-while-open, "1" at sign-in, "2" background service.
+; Declared here (not at file scope) so the uninstaller pass -- which inserts
+; none of the macros that touch it -- does not warn about an unused Var, which
+; electron-builder's makensis promotes to a hard error. customInit defaults it
+; for silent installs, where this page never runs.
+!macro customPageAfterChangeDir
+ Var MB_AutoMode
+ Var MB_Dlg
+ Var MB_RbOpen
+ Var MB_RbSignin
+ Var MB_RbService
+
+ Page custom mbAutostartPageCreate mbAutostartPageLeave
+
+ Function mbAutostartPageCreate
+ !insertmacro MUI_HEADER_TEXT "MeshBay Node" "Choose when the node runs on this computer."
+
+ nsDialogs::Create 1018
+ Pop $MB_Dlg
+ ${If} $MB_Dlg == error
+ Abort
+ ${EndIf}
+
+ ${NSD_CreateLabel} 0 0 100% 26u "The node makes your groups' content available to other members. It can run only while the MeshBay window is open, start on its own when you sign in, or run as a background service that is up even before you sign in."
+ Pop $0
+
+ ${NSD_CreateRadioButton} 6u 34u 96% 12u "Only while MeshBay is open"
+ Pop $MB_RbOpen
+ ${NSD_CreateRadioButton} 6u 48u 96% 12u "Automatically when I sign in to Windows"
+ Pop $MB_RbSignin
+ ${NSD_CreateRadioButton} 6u 62u 96% 12u "As a background service (starts at boot, before sign-in) -- recommended"
+ Pop $MB_RbService
+
+ ${NSD_CreateLabel} 0 82u 100% 34u "Setup adds Windows Firewall rules for local-network connections in every case. The background-service option, and those firewall rules, together need one administrator confirmation now -- without it the node cannot be reached and the app is not operational."
+ Pop $0
+
+ ${If} $MB_AutoMode == "0"
+ ${NSD_Check} $MB_RbOpen
+ ${ElseIf} $MB_AutoMode == "1"
+ ${NSD_Check} $MB_RbSignin
+ ${Else}
+ ${NSD_Check} $MB_RbService
+ ${EndIf}
+
+ nsDialogs::Show
+ FunctionEnd
+
+ Function mbAutostartPageLeave
+ ${NSD_GetState} $MB_RbOpen $0
+ ${If} $0 == ${BST_CHECKED}
+ StrCpy $MB_AutoMode "0"
+ ${EndIf}
+ ${NSD_GetState} $MB_RbSignin $0
+ ${If} $0 == ${BST_CHECKED}
+ StrCpy $MB_AutoMode "1"
+ ${EndIf}
+ ${NSD_GetState} $MB_RbService $0
+ ${If} $0 == ${BST_CHECKED}
+ StrCpy $MB_AutoMode "2"
+ ${EndIf}
+ FunctionEnd
+!macroend
+
!macro customInstall
; resources\node-runtime\meshbay-node.exe is about to be overwritten; a
; daemon still running from a previous version holds the file open.
@@ -53,41 +137,45 @@
SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
${IfNot} ${Silent}
- ; Already configured -- an upgrade, or a repair install -- asks nothing.
- ; Checked unelevated: reading firewall rules needs no admin, only
- ; creating them does (same reasoning as the service task below). Whether
- ; service mode or per-user mode was chosen last time, firewall rules
- ; existing already means there is nothing left for this dialog to do.
+ ; The firewall rules go in for every autostart mode. Read their state
+ ; first, unelevated -- Get-NetFirewallRule needs no admin, only New/Remove
+ ; do -- so an upgrade or repair that changes nothing triggers no UAC.
nsExec::Exec '"${MB_PWSH}" -NoProfile -ExecutionPolicy Bypass -File "$INSTDIR\resources\firewall.ps1" check'
- Pop $0
- ${If} $0 == 0
- Goto mb_mode_done
- ${EndIf}
+ Pop $R0 ; 0 = every rule already present
- ; The choice. Service mode needs admin to CREATE (a boot trigger touches
- ; system-wide scheduler state -- the same reason /sc onlogon needed it
- ; too); day-to-day start/stop from the Node page does not, once the task
- ; exists, because Task Scheduler grants the owning user that much itself.
- MessageBox MB_YESNO|MB_ICONQUESTION \
- "Run MeshBay Node as a background service?$\n$\nIt starts automatically at boot, even before you sign in, and needs one administrator confirmation now (which also sets up the Windows Firewall rules, in the same step).$\n$\nChoose No for the normal per-user mode instead: it starts when you sign in, no admin needed, and you will be asked about the firewall rules separately." \
- IDNO mb_peruser_mode
-
- ; -- Service mode: one elevation, both jobs --------------------------
+ ${If} $MB_AutoMode == "2"
+ ; Background service: the boot-time Scheduled Task AND the firewall
+ ; rules, in ONE elevation (service-mode.ps1 does both). Skip it only
+ ; when the task already exists and the rules are already there.
+ nsExec::Exec '"${MB_PWSH}" -NoProfile -ExecutionPolicy Bypass -File "$INSTDIR\resources\service.ps1" status'
+ Pop $R1 ; 0 = task installed
+ ${If} $R1 == 0
+ ${AndIf} $R0 == 0
+ Goto mb_auto_done
+ ${EndIf}
ExecShellWait "runas" "${MB_PWSH}" \
'-NoProfile -ExecutionPolicy Bypass -File "$INSTDIR\resources\service-mode.ps1" -Action install' \
SW_HIDE
- Goto mb_mode_done
+ Goto mb_auto_done
+ ${EndIf}
+
+ ; Modes 0 and 1: no scheduled task. One elevation for the firewall rules,
+ ; and only if one is actually missing.
+ ${If} $R0 != 0
+ ExecShellWait "runas" "${MB_PWSH}" \
+ '-NoProfile -ExecutionPolicy Bypass -File "$INSTDIR\resources\firewall.ps1" add' \
+ SW_HIDE
+ ${EndIf}
- mb_peruser_mode:
- ; -- Per-user mode: the firewall question stands on its own ----------
- MessageBox MB_YESNO|MB_ICONQUESTION \
- "Allow MeshBay through Windows Firewall now?$\n$\nMeshBay connects to other devices on your local network. Choosing Yes adds the rules in one step (Windows will ask for administrator confirmation). Choosing No is fine too -- Windows will ask you to allow access the first time MeshBay connects." \
- /SD IDYES IDNO mb_mode_done
- ExecShellWait "runas" "${MB_PWSH}" \
- '-NoProfile -ExecutionPolicy Bypass -File "$INSTDIR\resources\firewall.ps1" add' \
- SW_HIDE
+ ; Mode 1 also drops the per-user sign-in launcher (no admin -- it is just
+ ; a .vbs in this account's Startup folder). Idempotent, so a repeat run is
+ ; harmless. meshbay_node.platform.service_install() removes this itself if
+ ; the user later switches to service mode from the Node page.
+ ${If} $MB_AutoMode == "1"
+ nsExec::Exec '"${MB_NODE_BIN}\meshbay-node.exe" autostart install'
+ ${EndIf}
- mb_mode_done:
+ mb_auto_done:
${EndIf}
!macroend
@@ -117,8 +205,8 @@
mb_keep_privileged:
${EndIf}
- ; meshbay_node.platform._startup_vbs() -- if the user ran "meshbay-node
- ; autostart install" (or toggled it in the client), this points wscript at
- ; the binary we are about to delete, and would error at every sign-in.
+ ; meshbay_node.platform.autostart_install() -- if the user picked "at sign-in"
+ ; (here, or later in the client), this points wscript at the binary we are
+ ; about to delete, and would error at every sign-in.
Delete "$APPDATA\Microsoft\Windows\Start Menu\Programs\Startup\MeshBay Node.vbs"
!macroend