fix(signup): stop an unsolved anti-spam check clearing the form, and say what the check is #171
Inga granskare
Etiketter
Inga etiketter
area/backups
area/ci
area/control-panel
area/identity
area/infra
area/observability
area/payments
area/security
area/storage
area/web
blocked
needs-info
needs-triage
ready-for-implementation
type
bug
type
chore
type
docs
type
epic
type
feature
type
task
wontfix
Ingen milstolpe
Inget projekt
Inga tilldelade
1 deltagare
Notiser
Förfallodatum
Inget förfallodatum satt.
Beroenden
Inga beroenden satta
Referens
bitborg/bitborg-web!171
Läser in…
Hänvisa till i nytt ärende
Ingen beskrivning angiven.
Ta bort grenen "fix/signup-captcha-ux"
Borttagning av en gren är permanent. Även om den borttagna grenen kan fortsätta existera en kort tid innan den faktiskt tas bort, kan det INTE ångras i de flesta fall. Vill du fortsätta?
Closes #162, closes #163.
#162 — an unsolved anti-spam check no longer clears the form.
The captcha was the only control on the form without a native constraint. Every other field has
required,patternortype="email", so the browser already blocks an incomplete submit; thecaptcha did not, which is why it was the one that appeared to wipe everything.
/api/signupanswersevery outcome with a 303 to
/signup?status=…and the re-rendered form echoes nothing, so theresponse was a fresh empty page.
cap-widgetis a form-associated custom element and already implements this: givenrequireditsets
valueMissingvalidity and scrolls itself into view oninvalid. So the form never leaves thepage and there is nothing to restore. Because the validity anchor lives in the widget's shadow root,
an always-rendered
role="alert"message is unhidden from aninvalidlistener — a colour flashalone is not accessible. It is re-hidden on
solveso a stale complaint cannot sit under a solvedwidget.
Verified in a real browser: with username, email and terms filled and only the captcha missing,
formValid: false, the URL never gains a?status=parameter — so no request reached the endpoint— and every field retains its value.
#163 — the check now explains itself, in both languages.
A visitor who has met the usual third-party image puzzles has no way to know this one is
self-hosted, image-free and does no tracking. Adds a permanent description to both forms, wired
through
aria-describedbyon the wrapperrole="group"— not on<cap-widget>, which has no ARIArole of its own. The description id is rendered unconditionally, so the dangling-id shape fixed in
#146 is not reintroduced.
Also adds a
<noscript>line: the token field is created at runtime and the solver is WebAssembly,so with JavaScript off sign-up cannot succeed at all — and today the only way to discover that is to
submit and be told the check failed.
docs/content-style.mdgains the Swedish house term "arbetsbevis (proof of work)" so it stopsbeing decided per writer.
Not in scope
Preserving typed values after a server-side rejection (
taken,ratelimited,error,nomail)is #164 and needs a privacy-policy decision first. No draft cookie is added here.
Verification
pnpm lint,pnpm check,pnpm lang-check,pnpm test(206),pnpm test:e2eandpnpm mdlintall clean.
5d71aacab76b3db94a07