clone

a personal forge on plain git: static pages, stacked-diff reviews, signed local ci, repo sites and releases

main
forge / test / scenarios / people-invite-once.sh
people-invite-once.sh 3.0K
1# An invite: forge user invite holds a name and prints a one-time link on2# /login/; opening it, the invitee pastes an SSH public key and is that3# user from then on (keys, home, ssh), a collaborator of the repo the4# invite names, and may add a passkey on the same page. The link then is5# dead. identity.db keeps only the code's hash.6. "$(dirname "$0")/../lib.sh"7user cat8repo cat/0129clone cat cat/012 "$T/w/cat"10at "$T/w/cat" commit "first"11ok push_as cat "$T/w/cat" origin main12export FORGE_BASE_URL=https://forge.test13private_server14ssh-keygen -q -t ed25519 -N '' -C fox@laptop -f "$T/keys/fox"15accept() {16 node -e 'console.log(JSON.stringify({ code: process.argv[1], key: process.argv[2] }))' -- "$1" "$2" >"$T/body"17 http -s -w '\n%{http_code}' -H 'Origin: https://forge.test' -H 'Content-Type: application/json' -d @"$T/body" "$PRIV/login/invite/accept"18}1920ok forge user invite fox --repo cat/012 --as collaborator21has "$T_LOG" '^ https://forge\.test/login/#invite=[A-Za-z0-9_-]{24}$'22has "$T_LOG" 'works once, until 2026-09-08 '23has "$T_LOG" 'collaborator of cat/012 too'24code=$(sed -n 's/^ .*#invite=//p' "$T_LOG")25if grep -aqF "$code" "$FORGE_ROOT/.forge/identity.db" "$FORGE_ROOT/.forge/identity.db-wal" 2>/dev/null; then fail "an invite code is in identity.db as it is"; fi26# The name is held, and the link says whose it is.27fails_with "fox is invited" forge user add fox "$T/keys/fox.pub"28fails_with "fox is invited already" forge user invite fox29eq "$(http -s -H 'Origin: https://forge.test' -d "{\"code\":\"$code\"}" "$PRIV/login/invite/options")" '{"user":"fox","repo":"cat/012","role":"collaborator"}'3031accept "$code" "$(cat "$T/keys/fox.pub")" >"$T/r"32eq "$(tail -n 1 "$T/r")" 20033has "$T/r" '^\{"user":"fox","enroll":"[A-Za-z0-9_-]{24}"\}$'34enroll=$(sed -n 's/.*"enroll":"\([^"]*\)".*/\1/p' "$T/r")35has "$FORGE_ROOT/.forge/keys" "^fox ssh-ed25519 [A-Za-z0-9+/]+ fox@laptop$"36grep -q 'shell fox" ssh-ed25519' "$FORGE_ROOT/.ssh/authorized_keys" || fail "fox's key isn't in authorized_keys"37exists "$FORGE_ROOT/fox"38eq "$(cat "$FORGE_ROOT/cat/012.git/forge/collaborators")" fox39ok ssh_as fox whoami40eq "$(output)" fox41clone fox cat/012 "$T/w/fox"42at "$T/w/fox" commit "fox was here"43ok push_as fox "$T/w/fox" origin main44# The passkey on the same page: the enrollment code it got back.45ok node "$T_HOME/test/authenticator.ts" enroll "$PRIV" "$enroll" "$T/fox.key"46ok ssh_as fox passkeys47eq "$(grep -c '^[0-9a-f]\{8\} ' "$T_LOG")" 14849# Once only: the link is dead, with any key.50ssh-keygen -q -t ed25519 -N '' -C eve -f "$T/keys/eve"51accept "$code" "$(cat "$T/keys/eve.pub")" >"$T/r"52eq "$(tail -n 1 "$T/r")" 40053has "$T/r" 'expired, been used or been taken back'54eq "$(grep -c '^fox ' "$FORGE_ROOT/.forge/keys")" 155eq "$(http -s -o /dev/null -w '%{http_code}' -H 'Origin: https://forge.test' -d "{\"code\":\"$code\"}" "$PRIV/login/invite/options")" 40056ok forge user invites57eq "$(output)" "no invites; forge user invite <name> makes one"58# Not from the forge's own page: refused.59eq "$(http -s -o /dev/null -w '%{http_code}' -H 'Origin: https://evil.test' -d '{}' "$PRIV/login/invite/accept")" 403