diff --git a/README.md b/README.md index d97e48f..6f87243 100644 --- a/README.md +++ b/README.md @@ -126,30 +126,29 @@ Automations are declared in `lib/automations.ts` — one entry per firm, with th steps inside. Adding a button means editing that file; the page and the runner pick it up from the server. -### 1. Load the extension +### 1. Install the extension -`chrome://extensions` → enable **Developer mode** → **Load unpacked** → -select the `extension` folder. - -That is the development install. On a machine that just runs trades, install it -from our own update server instead, and Chrome keeps it updated by itself — the -setup scripts offer this as their last step, and it can be run on its own at any -time: +The setup scripts do this as their last step: give them the Chrome Enterprise +Core enrolment token from the Admin console (Devices → Chrome → Managed +browsers) and they enrol this machine's Chrome. The extension then arrives from +the console already set to force install, and Chrome keeps it updated. Run on +its own at any time: ```powershell -powershell -NoProfile -ExecutionPolicy Bypass -File scripts\install-extension-policy.ps1 +powershell -NoProfile -ExecutionPolicy Bypass -File scripts\enroll-chrome-management.ps1 -Token ``` ```bash -sudo scripts/install-extension-policy.sh +sudo scripts/enroll-chrome-management.sh ``` -**This only works on an enterprise-managed machine** — domain-joined, -Entra-joined, or enrolled in Chrome Enterprise Core. No Chromium browser will -force-install an off-store extension on an ordinary PC, whatever the registry -says; the scripts check and refuse rather than leave a dead policy behind. On an -unmanaged box, load `extension/` unpacked and let it reload itself. See -[deploy/README.md](deploy/README.md). Either way the extension notices when +**Enrolment is not optional.** No Chromium browser will force-install an +off-store extension on an unmanaged machine, whatever the registry says — it +reads the policy and blanks it. Enrolling is what makes Chrome managed without +joining a domain; Edge cannot be used this way at all. `install-extension-policy` +is still there for a genuinely domain-joined machine, where local policy is +honoured. See [deploy/README.md](deploy/README.md). Either way the extension +notices when the dashboard is running newer code than it is: a policy install asks Chrome to fetch the new CRX, an unpacked one reloads itself from disk. Clicking the reload icon on its card still works and is the thing to try when something looks diff --git a/scripts/enroll-chrome-management.ps1 b/scripts/enroll-chrome-management.ps1 index ad8f9ca..9ad5f69 100644 --- a/scripts/enroll-chrome-management.ps1 +++ b/scripts/enroll-chrome-management.ps1 @@ -30,7 +30,11 @@ param( [switch]$Mandatory, [Parameter(Mandatory = $true, ParameterSetName = 'Remove')] - [switch]$Remove + [switch]$Remove, + + # Fail instead of asking for elevation. Also the loop-breaker: the elevated + # copy is launched with this set, so it can never spawn another. + [switch]$NoElevate ) $ErrorActionPreference = 'Stop' @@ -38,7 +42,25 @@ $ErrorActionPreference = 'Stop' $identity = [Security.Principal.WindowsIdentity]::GetCurrent() if (-not ([Security.Principal.WindowsPrincipal]$identity).IsInRole( [Security.Principal.WindowsBuiltInRole]::Administrator)) { - throw 'Run this from an elevated PowerShell — the enrolment token is machine-level.' + if ($NoElevate) { + throw 'Run this from an elevated PowerShell — the enrolment token is machine-level.' + } + + # Relaunch elevated rather than making the caller do it. setup-windows.bat + # runs unelevated on purpose — nothing else it does needs admin — so this is + # the one UAC prompt in the whole install, and it is raised here where the + # arguments are already parsed and can be passed on intact. + Write-Host 'Asking for administrator rights — the enrolment token is machine-level.' + $psArgs = @('-NoProfile', '-ExecutionPolicy', 'Bypass', '-File', "`"$PSCommandPath`"", '-NoElevate') + if ($Remove) { $psArgs += '-Remove' } + else { + $psArgs += @('-Token', $Token) + if ($Mandatory) { $psArgs += '-Mandatory' } + } + + $elevated = Start-Process -FilePath (Get-Process -Id $PID).Path -Verb RunAs -Wait -PassThru ` + -ArgumentList $psArgs + exit $elevated.ExitCode } $key = 'HKLM:\SOFTWARE\Policies\Google\Chrome' diff --git a/setup-linux.sh b/setup-linux.sh index 64aaebe..1fe7b1d 100755 --- a/setup-linux.sh +++ b/setup-linux.sh @@ -141,22 +141,25 @@ else fi # ── 7. extension ──────────────────────────────────────────────────────────── -# Chrome refuses to side-load a CRX and will not update an unpacked folder, so -# the extension goes in the way a self-hosted one has to: a managed-policy file -# naming our update server. That lives under /etc, hence sudo — there is no -# per-user equivalent on Linux. +# Chrome will not update an unpacked folder, and only force-installs an off-store +# extension on a managed browser. Enrolling in Chrome Enterprise Core is what +# makes this machine's Chrome managed; the extension then arrives from the Admin +# console already set to force install. The token file lives under /etc, hence +# sudo. echo info "[7/7] Chrome extension" -info " Installs it from the update server and lets Chrome keep it current" -info " by itself. Needs sudo - the policy file lives under /etc." -read -r -p " Set this up now? [Y/n] " DOEXT +info " Enrols this machine's Chrome, after which the extension installs" +info " itself from the Admin console and stays updated on its own." +info " The token is in the Admin console under Devices > Chrome >" +info " Managed browsers. Blank to skip." +read -r -p " Enrollment token: " ENROLTOKEN EXTPOLICY=0 -if [ "${DOEXT,,}" != "n" ]; then - if sudo bash scripts/install-extension-policy.sh; then EXTPOLICY=1; else - warn "extension policy failed - load $TARGET/extension unpacked for now" +if [ -n "${ENROLTOKEN:-}" ]; then + if sudo bash scripts/enroll-chrome-management.sh "$ENROLTOKEN"; then EXTPOLICY=1; else + warn "enrolment failed - re-run: sudo scripts/enroll-chrome-management.sh " fi else - info " Skipped. Run: sudo scripts/install-extension-policy.sh" + info " Skipped. Run: sudo scripts/enroll-chrome-management.sh " fi # ── summary ───────────────────────────────────────────────────────────────── @@ -179,11 +182,11 @@ fi echo info "Still manual:" if [ "$EXTPOLICY" -eq 1 ]; then - info " - Restart Chrome, and remove any unpacked copy of the extension" - info " (it shares the same id now, and Chrome will not load both)" + info " - Restart Chrome. chrome://management should name your organisation," + info " and the extension installs itself within a minute or two." else - info " - Load the Chrome extension: chrome://extensions -> Developer mode" - info " -> Load unpacked -> $TARGET/extension" + info " - Enrol Chrome so it can install the extension:" + info " sudo scripts/enroll-chrome-management.sh " fi info " - Add your firm credentials on the dashboard's Settings page" if [ -n "${WAYLAND_DISPLAY:-}" ] && [ -z "${DISPLAY:-}" ]; then diff --git a/setup-windows.bat b/setup-windows.bat index 8652375..d93a9ff 100644 --- a/setup-windows.bat +++ b/setup-windows.bat @@ -325,23 +325,27 @@ set "AUTOSTART=0" :autostart_done -REM ------------------------------------------------------- extension policy -REM Chrome refuses to side-load a CRX and will not update an unpacked folder, so -REM the extension is installed the way a self-hosted one has to be: a policy -REM entry naming our update server. Written to this user's hive, which needs no -REM elevation - install-extension-policy.ps1 -Scope Machine covers every account. +REM ------------------------------------------------------------ extension +REM Chrome refuses to side-load a CRX and will not update an unpacked folder, and +REM it only force-installs an off-store extension on a managed browser. Enrolling +REM in Chrome Enterprise Core is what makes this machine's Chrome managed; the +REM extension itself then arrives from the Admin console, already set to force +REM install, with nothing further to configure here. echo. -echo [7/7] Browser extension -echo Installs it from the update server into whichever of Chrome, Edge -echo and Brave are present, and lets them keep it current by themselves. -echo No administrator rights needed. -set "DOEXT=" -set /p "DOEXT= Set this up now? [Y/n] " -if /i "%DOEXT%"=="n" goto :ext_skipped -powershell -NoProfile -ExecutionPolicy Bypass -File "%TARGET%\scripts\install-extension-policy.ps1" +echo [7/7] Chrome extension +echo Enrols this machine's Chrome, after which the extension installs +echo itself from the Admin console and stays updated on its own. +echo The token is in the Admin console under +echo Devices ^> Chrome ^> Managed browsers. Blank to skip. +set "ENROLTOKEN=" +set /p "ENROLTOKEN= Enrollment token: " +if not defined ENROLTOKEN goto :ext_skipped +REM The token is machine-scoped, so this raises a UAC prompt and only this. The +REM script asks for elevation itself; nothing else in this installer needs it. +powershell -NoProfile -ExecutionPolicy Bypass -File "%TARGET%\scripts\enroll-chrome-management.ps1" -Token "%ENROLTOKEN%" if errorlevel 1 ( - echo [!] Extension policy failed. Load %TARGET%\extension unpacked for now, - echo and re-run scripts\install-extension-policy.ps1 to try again. + echo [!] Enrolment failed. Re-run scripts\enroll-chrome-management.ps1 with + echo a fresh token from the Admin console to try again. set "EXTPOLICY=0" ) else ( set "EXTPOLICY=1" @@ -349,8 +353,8 @@ if errorlevel 1 ( goto :ext_done :ext_skipped -echo Skipped. Run scripts\install-extension-policy.ps1 later, or load -echo %TARGET%\extension unpacked and reload it by hand after updates. +echo Skipped. Run scripts\enroll-chrome-management.ps1 -Token ^ +echo later; until then this machine gets no extension. set "EXTPOLICY=0" :ext_done @@ -392,13 +396,11 @@ echo Handy : pm2 list ^| pm2 logs autofirmer ^| pm2 logs clicker echo. echo Still manual: if "%EXTPOLICY%"=="1" ( - echo - Restart Chrome, and remove any unpacked copy of the extension - echo ^(it shares the same id now, and Chrome will not load both^) + echo - Restart Chrome. chrome://management should name your organisation, + echo and the extension installs itself within a minute or two. ) else ( - echo - Load the Chrome extension: chrome://extensions, enable Developer - echo mode, "Load unpacked", select %TARGET%\extension - echo ^(loaded that way it reloads itself from disk after a pull; - echo the policy install lets Chrome update it properly^) + echo - Enrol Chrome so it can install the extension: + echo scripts\enroll-chrome-management.ps1 -Token ^ ) echo - Add your firm credentials on the dashboard's Settings page echo.