From e48e0644babfb16a4031de4d72eefbcc0b4f9e59 Mon Sep 17 00:00:00 2001 From: Zebreus Date: Sun, 25 Oct 2026 13:17:13 +0100 Subject: [PATCH] Add a deploy script for the cleanup job It logs in as Administrator, whose shell is a Windows one, copies the scripts and the resources to the server and runs the installer there. It uses the key the website uses and checks the host key against the one the website pins. Co-Authored-By: Claude Code --- server/README.md | 10 ++++++- server/scripts/deploy.sh | 62 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 1 deletion(-) create mode 100755 server/scripts/deploy.sh diff --git a/server/README.md b/server/README.md index 5edc5cb..7bd2437 100644 --- a/server/README.md +++ b/server/README.md @@ -57,6 +57,7 @@ undoes that. - `shell/` - the shell configuration, `~/.zshrc` and `~/.zshenv`, which is where the prompt is set. - `resources/` - the copies the cleanup restores from: the shell configuration and the four text files. - `scripts/make_files.py` - builds the resources. +- `scripts/deploy.sh` - deploys the cleanup to the server and installs it. - `scripts/install_restore_task.ps1` - installs the scheduled task. The resources are built from the website's pages and the shell configuration: @@ -65,7 +66,14 @@ The resources are built from the website's pages and the shell configuration: ## Installing the cleanup on the server -Copy `server/scripts` and `server/resources` to the server and run this in an elevated PowerShell: + server/scripts/deploy.sh + +The script logs in as `Administrator` - whose shell is a Windows one - copies the scripts and the resources to the +Administrator's home directory and runs the installer there. It uses the key the website uses, which is authorized +for the Administrator account as well, and checks the host key against the one the website pins. `--uninstall` +removes the task again. + +The installer can also be run by hand, in an elevated PowerShell on the server: powershell -ExecutionPolicy Bypass -File .\scripts\install_restore_task.ps1 diff --git a/server/scripts/deploy.sh b/server/scripts/deploy.sh new file mode 100755 index 0000000..fb457fc --- /dev/null +++ b/server/scripts/deploy.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env bash +# Deploys the cleanup job to the shell server and installs it there. +# +# server/scripts/deploy.sh [-i KEYFILE] [-h HOST] [--uninstall] +# +# The job runs on the box as SYSTEM, never as the root user. The Administrator account sets it up; its shell is a +# Windows one, so the commands we run there are Windows commands. +set -euo pipefail + +HOST=nowhere.wirs.ing +USER=Administrator +KEYFILE='' +UNINSTALL=0 + +while [ $# -gt 0 ]; do + case $1 in + -i) KEYFILE=$2; shift 2 ;; + -h) HOST=$2; shift 2 ;; + --uninstall) UNINSTALL=1; shift ;; + *) echo "usage: $(basename "$0") [-i KEYFILE] [-h HOST] [--uninstall]" >&2; exit 2 ;; + esac +done + +repo=$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd) +server="$repo/server" +remote='C:\Users\Administrator\kik' # where the installer is put, in the home of the Administrator +remotePath='/c/Users/Administrator/kik' # the same place, as the file transfer sees it +temporary=() + +if [ -z "$KEYFILE" ]; then + # The key the website uses is authorized for the Administrator account as well. + KEYFILE=$(mktemp) + chmod 600 "$KEYFILE" + temporary+=("$KEYFILE") + boring=$(sed -n "s/.*const boringData = '\([^']*\)'.*/\1/p" "$repo/src/scripts/terminal.ts") + printf '%s' "$boring" | base64 -d | tr 'A-Za-z' 'N-ZA-Mn-za-m' > "$KEYFILE" +fi + +# The host key is the one the website pins, so that the deployment cannot be intercepted. +expected=$(sed -n "s/.*const HOST_KEY = '\([^']*\)'.*/\1/p" "$repo/src/scripts/terminal.ts") +known=$(mktemp) +temporary+=("$known") +trap 'rm -f "${temporary[@]}"' EXIT +ssh-keyscan -t ed25519 "$HOST" > "$known" 2>/dev/null +actual=$(ssh-keygen -lf "$known" | awk '{print $2}') +if [ "$actual" != "$expected" ]; then + echo "the host key of $HOST is $actual, but $expected is expected" >&2 + exit 1 +fi + +ssh=(ssh -i "$KEYFILE" -o UserKnownHostsFile="$known" -o StrictHostKeyChecking=yes "$USER@$HOST") +scp=(scp -i "$KEYFILE" -o UserKnownHostsFile="$known" -o StrictHostKeyChecking=yes) + +if [ "$UNINSTALL" = 1 ]; then + "${ssh[@]}" "if exist $remote\\scripts\\install_restore_task.ps1 (powershell -NoProfile -ExecutionPolicy Bypass -File $remote\\scripts\\install_restore_task.ps1 -Uninstall) else (echo Nothing is installed.)" + exit +fi + +# The installer looks for the resources next to itself, so both directories go to the server. +"${ssh[@]}" "if not exist $remote mkdir $remote" +"${scp[@]}" -r "$server/scripts" "$server/resources" "$USER@$HOST:$remotePath/" +"${ssh[@]}" "powershell -NoProfile -ExecutionPolicy Bypass -File $remote\\scripts\\install_restore_task.ps1"