diff options
| author | Anders Betts <anders.betts@gmail.com> | 2026-09-23 11:36:11 +0200 |
|---|---|---|
| committer | Anders Betts <anders.betts@gmail.com> | 2026-09-23 11:36:11 +0200 |
| commit | 1abb7649b930d35d1f5a76fd72856659b1ee8275 (patch) | |
| tree | 50d1d3dd905056b75749e22a58e7247e4a4bb0e2 /scripts | |
| parent | 71a702f375750829c634b552217c9925d549828b (diff) | |
| download | bokf-1abb7649b930d35d1f5a76fd72856659b1ee8275.tar.gz bokf-1abb7649b930d35d1f5a76fd72856659b1ee8275.zip | |
web: bokftui in the browser (ttyd + bokfweb login gate); per-user login limitv0.1.69
New image bokf-web (Dockerfile target "web", compose service "web" on
127.0.0.1:8790): Caddy routing with forward_auth, the bokfweb login gate
(C, authenticates with bokfd's session.open, per-address limit, cookie +
terminal handle, one login handed to the TUI via /redeem) and ttyd running
bokftui in web mode in an isolated throwaway HOME. TLS stays with the
host's reverse proxy. BOKF_WEB=1 blocks every local file and viewer path in
the TUI. bokfd's login limiter is now per user name instead of one global
counter (5 wrong guesses from anyone locked out everybody), and a full
counter table no longer disables it. The cross build and deploy.sh build
and ship both images.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'scripts')
| -rwxr-xr-x | scripts/deploy.sh | 38 | ||||
| -rwxr-xr-x | scripts/tui-golden.py | 29 |
2 files changed, 58 insertions, 9 deletions
diff --git a/scripts/deploy.sh b/scripts/deploy.sh index b625ac5..29e477f 100755 --- a/scripts/deploy.sh +++ b/scripts/deploy.sh @@ -143,19 +143,29 @@ if [ "$DEV" = 1 ]; then exit 1 fi +# Two images from one Dockerfile: bokf (the daemon, the last stage) and +# bokf-web (the web frontend, target "web"). if [ "$BOKF_BUILD" = local ]; then - echo "deploy: building image bokf:$TAG locally" + echo "deploy: building images bokf:$TAG and bokf-web:$TAG locally" docker build --build-arg "VERSION=$TAG" -t "bokf:$TAG" . - echo "deploy: shipping image to $BOKF_HOST" - docker save "bokf:$TAG" | gzip | "${SSH[@]}" 'gunzip | docker load' + docker build --build-arg "VERSION=$TAG" --target web \ + -t "bokf-web:$TAG" . + echo "deploy: shipping images to $BOKF_HOST" + docker save "bokf:$TAG" "bokf-web:$TAG" | gzip | + "${SSH[@]}" 'gunzip | docker load' else cross_build - echo "deploy: assembling image bokf:$TAG on $BOKF_HOST" - tar -cf - \ - --exclude=./.git --exclude=./build --exclude=./var --exclude=./.env \ - --exclude='./*.se' --exclude='./*.db' --exclude='./*.db-wal' \ - --exclude='./*.db-shm' --exclude=./docs . | + source_tar() { + tar -cf - \ + --exclude=./.git --exclude=./build --exclude=./var \ + --exclude=./.env --exclude='./*.se' --exclude='./*.db' \ + --exclude='./*.db-wal' --exclude='./*.db-shm' --exclude=./docs . + } + echo "deploy: assembling images bokf:$TAG and bokf-web:$TAG on $BOKF_HOST" + source_tar | "${SSH[@]}" "docker build --build-arg 'VERSION=$TAG' -t 'bokf:$TAG' -" + source_tar | + "${SSH[@]}" "docker build --build-arg 'VERSION=$TAG' --target web -t 'bokf-web:$TAG' -" rm -rf .prebuilt fi @@ -182,6 +192,18 @@ remote "cd '$BOKF_REMOTE_DIR' && docker compose up -d --no-build" if wait_healthy; then echo "deploy: bokf:$TAG is healthy on $BOKF_HOST" + web="" + for _ in $(seq 1 15); do + web="$(remote "cd '$BOKF_REMOTE_DIR' && docker inspect --format '{{.State.Health.Status}}' \$(docker compose ps -q web) 2>/dev/null" || true)" + [ "$web" = healthy ] && break + sleep 2 + done + if [ "$web" = healthy ]; then + echo "deploy: bokf-web:$TAG is healthy (http://127.0.0.1:8790 on the host)" + else + echo "deploy: warning: bokf-web is '${web:-not running}'" >&2 + remote "cd '$BOKF_REMOTE_DIR' && docker compose logs --tail=20 web" >&2 || true + fi exit 0 fi diff --git a/scripts/tui-golden.py b/scripts/tui-golden.py index bce00eb..deca6ef 100755 --- a/scripts/tui-golden.py +++ b/scripts/tui-golden.py @@ -709,6 +709,31 @@ SCENARIOS = [ ], }, { + # Web mode (the browser-terminal wrapper sets BOKF_WEB=1): nothing + # may touch the frontend's files or start a viewer there. + "name": "web-mode", + "screen": "vouchers", + "env": {"BOKF_WEB": "1"}, + "steps": [ + { + "keys": ["home", "enter"], + "expect": ["Golden verifikat", "a = bifoga"], + }, + { + "keys": ["a"], + "expect": ["Inte tillgängligt i webbversionen"], + }, + { + "keys": ["enter", "f", "enter", "right", "enter"], + "expect": ["Inte tillgängligt i webbversionen"], + }, + { + "keys": ["enter"], + "expect": ["Underlag"], + }, + ], + }, + { # Keep last: changes the rig's login password, then restores it so # a rerun of the list still logs in. "name": "change-password", @@ -1362,7 +1387,9 @@ def main(argv): "--socket", str(sock), "--user", "admin", "--org", str(org_id), "--fy", str(fy["id"]), "--screen", sc["screen"]] - app = PtyApp(argv_tui, env, TERM_COLS, TERM_ROWS) + sc_env = dict(env) + sc_env.update(sc.get("env", {})) + app = PtyApp(argv_tui, sc_env, TERM_COLS, TERM_ROWS) name = sc["name"] missing = None before = current = "" |
