Harden the site: CI, form endpoint, SEO, privacy and accessibility #9

Merged
rob merged 39 commits from site-hardening into main 2026-10-07 14:29:12 +00:00
Collaborator

Twelve ticket PRs merged into this branch, each reviewed and green on its own CI run: #5 and #14 CC-7 CI and deploy, #4 and #13 CC-8 SEO and canonical domain, #3 CC-3 dummy register endpoint and thanks page, #6 CC-2 hash-link redirects, #7 and #15 CC-5 privacy notice, #8 CC-9 accessibility pass, #10 CC-13 favicon, #11 CC-4 spam protection, #12 CC-11 How it works and Install copy.

Behavioural changes: POST /api/register logs each submission as one JSON line to stdout and redirects to /thanks; the form works without JavaScript; a filled honeypot is dropped silently and more than five posts a minute from one address get 429. campercan.net is canonical; campercan.io and www hosts 301 to it. Every page has its own title, description, canonical and share tags, plus sitemap.xml, robots.txt and a favicon. New /privacy page with contact hello@campercan.net. Skip link, focus rings, nav landmarks, and a slightly darker muted text colour for AA contrast. Old /#/… links redirect to the real pages. How it works and Install have real copy; spec rows stay TBC.

Rollout: merging this triggers the new deploy job, which builds the image and pushes git.robware.uk/rob/campercan:latest. If the push fails with 401 the automatic token lacks package scope; add a repo secret REGISTRY_TOKEN with write:package and re-run. Then on the host: docker compose pull && docker compose up -d, and point Nginx Proxy Manager at port 34817 with Force SSL and HSTS on.

Tested: CI on every merge to this branch (build, html-validate, 16 tests). axe 4.10.2 reports 0 violations on all 12 pages via test/axe.js locally. The deploy job itself is untested until the first push to main.

Twelve ticket PRs merged into this branch, each reviewed and green on its own CI run: #5 and #14 CC-7 CI and deploy, #4 and #13 CC-8 SEO and canonical domain, #3 CC-3 dummy register endpoint and thanks page, #6 CC-2 hash-link redirects, #7 and #15 CC-5 privacy notice, #8 CC-9 accessibility pass, #10 CC-13 favicon, #11 CC-4 spam protection, #12 CC-11 How it works and Install copy. Behavioural changes: `POST /api/register` logs each submission as one JSON line to stdout and redirects to `/thanks`; the form works without JavaScript; a filled honeypot is dropped silently and more than five posts a minute from one address get 429. `campercan.net` is canonical; `campercan.io` and `www` hosts 301 to it. Every page has its own title, description, canonical and share tags, plus `sitemap.xml`, `robots.txt` and a favicon. New `/privacy` page with contact `hello@campercan.net`. Skip link, focus rings, nav landmarks, and a slightly darker muted text colour for AA contrast. Old `/#/…` links redirect to the real pages. How it works and Install have real copy; spec rows stay TBC. Rollout: merging this triggers the new `deploy` job, which builds the image and pushes `git.robware.uk/rob/campercan:latest`. If the push fails with 401 the automatic token lacks package scope; add a repo secret `REGISTRY_TOKEN` with `write:package` and re-run. Then on the host: `docker compose pull && docker compose up -d`, and point Nginx Proxy Manager at port 34817 with Force SSL and HSTS on. Tested: CI on every merge to this branch (build, html-validate, 16 tests). axe 4.10.2 reports 0 violations on all 12 pages via `test/axe.js` locally. The deploy job itself is untested until the first push to main.
Add CI workflow, HTML lint and page smoke test
All checks were successful
CI / check (pull_request) Successful in 11s
9ac5aca54e
Pin html-validate and drop version step from CI
All checks were successful
CI / check (pull_request) Successful in 10s
a8f9b41d67
Reviewed-on: #5
Reviewed-on: #4
Fix thanks page title suffix
All checks were successful
CI / check (pull_request) Successful in 9s
017d3e082f
Reviewed-on: #3
Load site.js on every page so old hash links redirect
All checks were successful
CI / check (pull_request) Successful in 9s
af5acbd25d
Restrict hash redirects to safe paths and test them
All checks were successful
CI / check (pull_request) Successful in 11s
a540ee95fc
Clarify log wipe in README and loosen privacy link test
All checks were successful
CI / check (pull_request) Successful in 9s
29459c03e6
Add skip-link markup to privacy page and fix footer link contrast
All checks were successful
CI / check (pull_request) Successful in 9s
ff6048426c
Merge pull request 'Add skip link, focus rings, landmarks and contrast fixes' (#8) from cc-9-accessibility into site-hardening
All checks were successful
CI / check (push) Successful in 10s
CI / check (pull_request) Successful in 9s
9129aa1ab9
Add favicon and apple touch icon
All checks were successful
CI / check (pull_request) Successful in 10s
d379903ae0
Use cream tile with two-tone CC and check touch icon link
All checks were successful
CI / check (pull_request) Successful in 9s
2b241ca2c6
Merge pull request 'Add favicon and apple touch icon' (#10) from cc-13-favicon into site-hardening
All checks were successful
CI / check (push) Successful in 10s
CI / check (pull_request) Successful in 10s
01db579fb7
Add honeypot field and per-IP rate limit to registration
All checks were successful
CI / check (pull_request) Successful in 9s
04ed9cf23a
Give each test POST its own forwarded address
All checks were successful
CI / check (pull_request) Successful in 11s
91b44ad49e
Merge pull request 'Add honeypot field and per-IP rate limit to registration' (#11) from cc-4-spam into site-hardening
Some checks failed
CI / check (pull_request) Has been cancelled
CI / check (push) Has been cancelled
841b3d9e31
Write How it works and Install page copy
All checks were successful
CI / check (pull_request) Successful in 9s
0e64e99c64
Trim invented benefit and connector wording
All checks were successful
CI / check (pull_request) Successful in 9s
3507f335fd
Merge pull request 'Write How it works and Install page copy' (#12) from cc-11-content into site-hardening
All checks were successful
CI / check (pull_request) Successful in 10s
CI / check (push) Successful in 10s
a81cfa1e51
Redirect other domains to campercan.net
All checks were successful
CI / check (pull_request) Successful in 9s
e8820d9e71
Match redirect hosts case-insensitively and test www and port
All checks were successful
CI / check (pull_request) Successful in 11s
2393203754
Use confirmed contact address in privacy notice
All checks were successful
CI / check (pull_request) Successful in 8s
f11afa43bb
Merge pull request 'Use confirmed contact address in privacy notice' (#15) from cc-5-contact into site-hardening
All checks were successful
CI / check (pull_request) Successful in 9s
CI / check (push) Successful in 10s
30b8832cb1
Build and push the Docker image to the Forgejo registry on main
All checks were successful
CI / check (pull_request) Successful in 9s
CI / deploy (pull_request) Has been skipped
ad598b29ee
Keep main deploys running and log in as the repository owner
All checks were successful
CI / check (pull_request) Successful in 10s
CI / deploy (pull_request) Has been skipped
72fe9f5e9b
Merge pull request 'Build and push the Docker image to the Forgejo registry on main' (#14) from cc-7-deploy into site-hardening
All checks were successful
CI / check (pull_request) Successful in 9s
CI / deploy (pull_request) Has been skipped
CI / check (push) Successful in 10s
CI / deploy (push) Has been skipped
2509ad083c
rob merged commit b5b53bb3fb into main 2026-10-07 14:29:12 +00:00
rob deleted branch site-hardening 2026-10-07 14:29:12 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
rob/CamperCan!9
No description provided.