Repository files, collaboration, releases and project activity.
ARCHFORGE HISTORY
Blame · scripts/fix-admin-origin.sh
Branch main · the Commit author is not necessarily a verified ArchForge account.
b0c4351f2earchadmin2026-10-11
1 #!/usr/bin/env bashb0c4351f2earchadmin2026-10-11
2 # v1.0.5 one-shot safe repair of admin POST 403 Invalid origin.b0c4351f2earchadmin2026-10-11
3 # Does not delete/recreate admin accounts, SQLite, monitoring or Caddy.b0c4351f2earchadmin2026-10-11
4 set -Eeuo pipefailb0c4351f2earchadmin2026-10-11
5 umask 077b0c4351f2earchadmin2026-10-11
6 say(){ printf '[*] %s\n' "$*"; }b0c4351f2earchadmin2026-10-11
7 fail(){ printf '[ERROR] %s\n' "$*" >&2; exit 1; }b0c4351f2earchadmin2026-10-11
8 [[ $EUID -eq 0 ]] || fail 'Run this fix as root: bash ./fix-admin-origin.sh'b0c4351f2earchadmin2026-10-11
9 ROOT=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)b0c4351f2earchadmin2026-10-11
10 source "$ROOT/scripts/domain-lib.sh"b0c4351f2earchadmin2026-10-11
11 [[ -r "$ROOT/package.json" && -r "$ROOT/src/server.js" ]] || fail 'Missing status project source checkout'2109dd33b8archadmin2026-10-12
12 /usr/bin/node -e 'if(require(process.argv[1]).version!=="1.0.5")process.exit(1)' "$ROOT/package.json" || fail 'Expected ArchForge checkout v1.0.5. Run git pull --ff-only first.'b0c4351f2earchadmin2026-10-11
13 CFG=/etc/archforge-status/status.envb0c4351f2earchadmin2026-10-11
14 [[ -f "$CFG" && ! -L "$CFG" ]] || fail 'Existing status.env not found (or unsafe symlink)'b0c4351f2earchadmin2026-10-11
15 [[ -f /etc/caddy/Caddyfile ]] || fail 'Caddyfile not found'b0c4351f2earchadmin2026-10-11
16 DOMAIN=status.archforge.nlb0c4351f2earchadmin2026-10-11
17 # Verify that this VPS actually has an intended HTTPS site for our domain.b0c4351f2earchadmin2026-10-11
18 if ! grep -Eqs "^[[:space:]]*${DOMAIN//./\\.}[[:space:]]*\\{" /etc/caddy/Caddyfile /etc/caddy/conf.d/*.caddy 2>/dev/null; thenb0c4351f2earchadmin2026-10-11
19 fail 'Caddy has no configured site for status.archforge.nl. Refusing to change public URL.'b0c4351f2earchadmin2026-10-11
20 fib0c4351f2earchadmin2026-10-11
21 if ! curl -fsS --max-time 6 http://127.0.0.1:3000/healthz >/dev/null;thenb0c4351f2earchadmin2026-10-11
22 fail 'Installed status app is not running at localhost:3000. No changes made.'b0c4351f2earchadmin2026-10-11
23 fib0c4351f2earchadmin2026-10-11
24 BACKUP=$(mktemp -d /root/.archforge-origin-fix.XXXXXXXX)b0c4351f2earchadmin2026-10-11
25 cp -a -- "$CFG" "$BACKUP/status.env"b0c4351f2earchadmin2026-10-11
26 say "Configuration backup: $BACKUP/status.env (private)"b0c4351f2earchadmin2026-10-11
27 CHANGED=falseb0c4351f2earchadmin2026-10-11
28 CURRENT=$(grep -m1 '^STATUS_PUBLIC_URL=' "$CFG" | cut -d= -f2- || true)b0c4351f2earchadmin2026-10-11
29 if [[ "$CURRENT" != "https://$DOMAIN" && "$CURRENT" != "https://$DOMAIN/" ]]; thenb0c4351f2earchadmin2026-10-11
30 say "Synchronizing STATUS_PUBLIC_URL with Caddy's HTTPS domain."b0c4351f2earchadmin2026-10-11
31 af_set_public_domain "$CFG" "$DOMAIN" || fail 'Failed updating STATUS_PUBLIC_URL'b0c4351f2earchadmin2026-10-11
32 CHANGED=trueb0c4351f2earchadmin2026-10-11
33 elseb0c4351f2earchadmin2026-10-11
34 say 'Configured public hostname already matches the domain.'b0c4351f2earchadmin2026-10-11
35 fib0c4351f2earchadmin2026-10-11
36 say 'Deploying tested v1.0.5 code with built-in database backup and rollback...'b0c4351f2earchadmin2026-10-11
37 if ! bash "$ROOT/scripts/deploy.sh" "$ROOT";thenb0c4351f2earchadmin2026-10-11
38 say 'Code deployment failed. Restoring original status configuration.'b0c4351f2earchadmin2026-10-11
39 cp -a -- "$BACKUP/status.env" "$CFG"b0c4351f2earchadmin2026-10-11
40 systemctl restart archforge-status || trueb0c4351f2earchadmin2026-10-11
41 fail 'Deployment failed and configuration restored.'b0c4351f2earchadmin2026-10-11
42 fib0c4351f2earchadmin2026-10-11
43 say 'Checking login POST through HTTPS without sending any credentials...'b0c4351f2earchadmin2026-10-11
44 # Invalid CSRF MUST be rejected, but valid Origin MUST NOT receive Invalid origin.b0c4351f2earchadmin2026-10-11
45 OUT=$(mktemp "$BACKUP/response.XXXXXXXX")b0c4351f2earchadmin2026-10-11
46 if ! curl -sS --max-time 12 --resolve "$DOMAIN:443:127.0.0.1" \b0c4351f2earchadmin2026-10-11
47 -H "Origin: https://$DOMAIN" \b0c4351f2earchadmin2026-10-11
48 -H 'Content-Type: application/x-www-form-urlencoded' \b0c4351f2earchadmin2026-10-11
49 --data 'csrf=deliberately-invalid' "https://$DOMAIN/admin/login" > "$OUT";thenb0c4351f2earchadmin2026-10-11
50 say 'HTTPS local POST could not be verified; inspect Caddy/SSL separately.'b0c4351f2earchadmin2026-10-11
51 elif grep -q 'Invalid origin' "$OUT"; thenb0c4351f2earchadmin2026-10-11
52 fail 'Origin check still rejects canonical host; see service journal: journalctl -u archforge-status -n 50'b0c4351f2earchadmin2026-10-11
53 elif grep -q 'Invalid or expired form token' "$OUT"; thenb0c4351f2earchadmin2026-10-11
54 say 'PASS: same-origin login form reaches CSRF validation (as intended).'b0c4351f2earchadmin2026-10-11
55 elseb0c4351f2earchadmin2026-10-11
56 say 'The HTTPS response was received but its form result was unexpected; inspect the login page.'b0c4351f2earchadmin2026-10-11
57 fib0c4351f2earchadmin2026-10-11
58 say 'Finished. Open https://status.archforge.nl/admin/login and sign in again.'b0c4351f2earchadmin2026-10-11
59 say 'All admin credentials, SQLite data and Caddy settings were preserved.'