Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions packaging/windows/flocks-setup.iss
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,14 @@ Root: HKCU; Subkey: "Environment"; ValueType: string; ValueName: "FLOCKS_INSTALL
Root: HKCU; Subkey: "Environment"; ValueType: string; ValueName: "FLOCKS_REPO_ROOT"; ValueData: "{app}\flocks"; Flags: uninsdeletevalue
Root: HKCU; Subkey: "Environment"; ValueType: string; ValueName: "FLOCKS_NODE_HOME"; ValueData: "{app}\tools\node"; Flags: uninsdeletevalue

; Shortcuts intentionally target the same wrapper path that `scripts\install.ps1`
; writes, so the Start menu / desktop icon and `flocks start` typed in a new
; terminal are strictly equivalent across all install flows.
; Installer-created launch shortcuts intentionally go through a tiny elevation
; helper first, then invoke the same `%USERPROFILE%\.local\bin\flocks.cmd`
; wrapper that `scripts\install.ps1` writes. This keeps the app entrypoint
; consistent while letting Windows prompt for UAC on shortcut launches.
[Icons]
Name: "{autoprograms}\{#MyAppName}\Start Flocks"; Filename: "{%USERPROFILE}\.local\bin\flocks.cmd"; Parameters: "start"; WorkingDir: "{%USERPROFILE}"
Name: "{autoprograms}\{#MyAppName}\Start Flocks"; Filename: "powershell.exe"; Parameters: "-NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -File ""{app}\flocks\packaging\windows\start-flocks-elevated.ps1"""; WorkingDir: "{%USERPROFILE}"
Name: "{autoprograms}\{#MyAppName}\Flocks repository"; Filename: "{app}\flocks"; WorkingDir: "{app}\flocks"
Name: "{userdesktop}\{#MyAppName}"; Filename: "{%USERPROFILE}\.local\bin\flocks.cmd"; Parameters: "start"; WorkingDir: "{%USERPROFILE}"; Tasks: desktopicon
Name: "{userdesktop}\{#MyAppName}"; Filename: "powershell.exe"; Parameters: "-NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -File ""{app}\flocks\packaging\windows\start-flocks-elevated.ps1"""; WorkingDir: "{%USERPROFILE}"; Tasks: desktopicon

[Run]
Filename: "powershell.exe"; Parameters: "-NoProfile -ExecutionPolicy Bypass -File ""{app}\flocks\packaging\windows\bootstrap-windows.ps1"" -InstallRoot ""{app}"""; StatusMsg: "Setting up Python and JavaScript dependencies..."; Flags: runascurrentuser waituntilterminated
Expand Down
16 changes: 16 additions & 0 deletions packaging/windows/start-flocks-elevated.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[CmdletBinding()]
param()

$wrapperPath = Join-Path $HOME ".local\bin\flocks.cmd"
if (-not (Test-Path -LiteralPath $wrapperPath)) {
throw "Flocks launcher not found: $wrapperPath"
}

$cmdPath = $env:ComSpec
if ([string]::IsNullOrWhiteSpace($cmdPath)) {
$cmdPath = "cmd.exe"
}

# Route installer-created shortcuts through UAC, but keep the real app entrypoint
# on the shared flocks.cmd wrapper so shortcut launches match terminal launches.
Start-Process -FilePath $cmdPath -ArgumentList @("/c", "`"$wrapperPath`" start") -WorkingDirectory $HOME -WindowStyle Hidden -Verb RunAs
36 changes: 24 additions & 12 deletions tests/scripts/test_browser_runtime_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,19 +87,18 @@ def test_inno_setup_points_to_packaging_bootstrap() -> None:
assert "scripts\\bootstrap-windows.ps1" not in iss


def test_inno_shortcuts_point_to_user_local_bin_wrapper() -> None:
"""Start-menu and desktop shortcuts must match the CLI wrapper location that
`scripts/install.ps1` writes, so `flocks start` triggered from the shortcut
and from a freshly opened terminal are strictly equivalent across all
install flows (source, one-liner, bundled installer)."""
def test_inno_shortcuts_point_to_elevated_launcher() -> None:
"""Installer-created launch shortcuts should route through the elevated
launcher so clicking them triggers UAC before running the shared wrapper."""
iss = (PACKAGING_WINDOWS_DIR / "flocks-setup.iss").read_text(encoding="utf-8")

icons_section_idx = iss.find("[Icons]")
run_section_idx = iss.find("[Run]", icons_section_idx)
assert icons_section_idx != -1 and run_section_idx != -1
icons_block = iss[icons_section_idx:run_section_idx]

expected_target = "{%USERPROFILE}\\.local\\bin\\flocks.cmd"
expected_target = 'Filename: "powershell.exe"'
expected_script = 'start-flocks-elevated.ps1'
start_menu_lines = [
line
for line in icons_block.splitlines()
Expand All @@ -108,14 +107,27 @@ def test_inno_shortcuts_point_to_user_local_bin_wrapper() -> None:
assert start_menu_lines, "expected Start Flocks + desktop shortcut entries"
for line in start_menu_lines:
assert expected_target in line, (
f"shortcut must target the shared wrapper path; got: {line}"
f"shortcut must target PowerShell launcher; got: {line}"
)
assert 'Parameters: "start"' in line
assert expected_script in line
assert "-WindowStyle Hidden" in line

# Guard against accidentally re-introducing a shortcut to {app}\bin, which
# would point to a non-existent file because install.ps1 writes the wrapper
# under %USERPROFILE%\.local\bin.
assert "{app}\\bin\\flocks.cmd" not in icons_block
# Guard against accidentally re-introducing direct shortcut launches that
# bypass the UAC prompt.
assert "{%USERPROFILE}\\.local\\bin\\flocks.cmd" not in icons_block


def test_windows_elevated_launcher_runs_shared_wrapper_as_admin() -> None:
"""The elevation helper should re-use the shared CLI wrapper and request
Administrator rights via Start-Process."""
script = (PACKAGING_WINDOWS_DIR / "start-flocks-elevated.ps1").read_text(
encoding="utf-8-sig"
)

assert 'Join-Path $HOME ".local\\bin\\flocks.cmd"' in script
assert "Start-Process" in script
assert "-Verb RunAs" in script
assert "`\"$wrapperPath`\" start" in script


def test_inno_finish_page_reminds_user_to_reopen_terminal() -> None:
Expand Down
Loading