Widget Demo
The widget/ directory contains a minimal Vue app with the ALTCHA widget. It talks directly to CaptchaService and lets you verify locally that challenge creation and solution verification work in practice — without curl or Postman.
Prerequisites
1. Start stack and backend
From the repository root:
cd stack
podman compose up -d
cd ../backend
bash runLocalNoSecurity.shConfirm the backend is responding:
curl http://localhost:39146/actuator/health2. Start the widget
cd widget
npm install
npm run devOpen the URL from the Vite output in your browser (usually http://localhost:5173/).
3. Test the widget
- The page shows the ALTCHA checkbox (German UI by default) and a Weiter button that starts disabled.
- After clicking the checkbox, the widget requests a challenge from CaptchaService, solves the proof-of-work locally, and posts the result to
/verify. - If server-side verification succeeds, the widget state becomes
verifiedand the Weiter button is enabled.
If something goes wrong, use the browser developer tools:
- Network — watch for
POST /api/v1/captcha/challengeandPOST /api/v1/captcha/verify - Console — with
debug: truein the widget config, ALTCHA writes detailed logs
Configuration
Defaults in widget/src/config/captcha.ts match the local backend profile (application-local.yml):
| Setting | Default | Backend configuration |
|---|---|---|
| Site key | test | captcha.sites.test |
| Site secret | test | captcha.sites.test.secret |
| Client address | 127.0.0.1 | clientAddress field on every request |
Override in widget/.env.local:
VITE_CAPTCHA_SITE_KEY=test
VITE_CAPTCHA_SITE_SECRET=test
VITE_CAPTCHA_CLIENT_ADDRESS=127.0.0.1Other sites (for example loadtest) are described under Site Configuration.
Integration overview
CaptchaService expects different request bodies than the ALTCHA widget sends by default. widget/src/utils/captchaFetch.ts adapts between them:
- Challenge — intercepts the widget fetch, then POSTs
{ siteKey, siteSecret, clientAddress }. Extracts{ challenge: … }from the response. - Verify — decodes the widget payload and POSTs
{ siteKey, siteSecret, clientAddress, payload: { challenge, solution } }. Translates{ valid: true }to{ verified: true }for the widget.
This follows the same pattern as production eAppointment / zmscitizenview, where a BFF adds credentials server-side. In this demo they live in the frontend — for local testing only.
npm commands
cd widget
npm run lint # Prettier, ESLint, vue-tsc
npm run fix # auto-fix formatting and lint issues
npm run build # production build to dist/Further reading
- Create Challenge and Verify Solution — request and response reference
- Monitoring — health checks and metrics while testing