PDF.js's signature dialog saved every signature in localStorage under pdfjs.signature, "save" ticked on every open, for this origin rather than for a bau-pm user. Measured on v0.1.0: a typed and an uploaded signature were offered to a fresh page on the same browser, the way the next person on a shared tablet would get it, a Redmine logout included. Another browser profile saw nothing; the server never had anything. The glue's fifth duty, in every window before PDF.js's modules: delete the store (a device that saved signatures loses them on its first visit), refuse writes to that key, hold the save box unticked through a property on the element and hide it, and hide the dialog's Bild tab and its file picker, so a scanned signature never enters the dialog. test/signatures.mjs is the second gate, in CI and the release workflow: a browser seeded with a real saved entry (captured from v0.1.0's own store) is offered none, the dialog shows neither the box nor the tab, a typed signature is placed and not stored, a fresh page is offered nothing. Fed v0.1.0: 9 findings, exit 1. Against this image: 0, and the zero-host gate drove 117 tool pages with nothing leaving the origin. A signed PDF still exports with the signature on the page. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
55 lines
2.4 KiB
YAML
55 lines
2.4 KiB
YAML
# CI - every push to dev and every pull request: the scripts linted, the image
|
|
# built from BentoPDF's pinned commit, and the gate this repository exists for
|
|
# (README, "The gate"): a page may talk to its own origin and to nobody else.
|
|
name: CI
|
|
|
|
on:
|
|
push:
|
|
branches: [dev]
|
|
pull_request:
|
|
|
|
jobs:
|
|
gate:
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 120
|
|
steps:
|
|
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
|
|
|
|
# Over stdin: the runner passes the host's Docker socket through, so a
|
|
# mounted workspace would resolve on the host and be empty.
|
|
- name: shellcheck
|
|
run: |
|
|
for f in scripts/*.sh; do
|
|
echo "-- $f"
|
|
docker run --rm -i koalaman/shellcheck:v0.11.0 - < "$f"
|
|
done
|
|
|
|
# npm ci and the Vite build are the slow part, several minutes on the
|
|
# shared runner; the vendor stage downloads about 60 MB from npm.
|
|
- name: build the image
|
|
timeout-minutes: 60
|
|
# --pull, as in the release workflow (bau-pm BAU-191): both bases are
|
|
# floating tags, and a gate that runs against a months-old cached base
|
|
# is not testing what the release builds.
|
|
run: docker build --pull --build-arg VERSION="ci-${GITHUB_SHA::8}" -t bau-pm-pdf-tools:ci .
|
|
|
|
- name: build the gate
|
|
timeout-minutes: 15
|
|
run: docker build -f test/Dockerfile -t bau-pm-pdf-tools-gate:ci .
|
|
|
|
- name: gate - nothing leaves the origin, no signature is kept
|
|
timeout-minutes: 40
|
|
run: |
|
|
net="bau-pm-pdf-tools-ci-${GITHUB_RUN_ID}"
|
|
docker network create "$net" >/dev/null
|
|
trap 'docker rm -f -v "$net-app" >/dev/null 2>&1; docker network rm "$net" >/dev/null 2>&1' EXIT
|
|
docker run -d --name "$net-app" --network "$net" --network-alias pdf-tools bau-pm-pdf-tools:ci >/dev/null
|
|
for i in $(seq 1 30); do
|
|
docker run --rm --network "$net" bau-pm-pdf-tools-gate:ci wget -q --spider http://pdf-tools:8080/ && break
|
|
[ "$i" -eq 30 ] && { echo "the image never answered" >&2; exit 1; }
|
|
sleep 2
|
|
done
|
|
docker run --rm --network "$net" bau-pm-pdf-tools-gate:ci node test/zero-hosts.mjs http://pdf-tools:8080
|
|
# bau-pm §2.77: the signing tool keeps no signature on the device.
|
|
docker run --rm --network "$net" bau-pm-pdf-tools-gate:ci node test/signatures.mjs http://pdf-tools:8080
|