Skip to content

About

Provider-agnostic captcha components for Vaadin Flow - Friendly Captcha, Cloudflare Turnstile, and hCaptcha.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

captchas-addon

Maven Central License: Apache 2.0 Vaadin Friendly Captcha Turnstile hCaptcha

Provider-agnostic captcha components for Vaadin Flow. Google reCAPTCHA is intentionally not supported.

Supported providers

  • Friendly Captcha (com.gladtek.vaadin.captchas.friendlycaptcha)
  • Cloudflare Turnstile (com.gladtek.vaadin.captchas.turnstile)
  • hCaptcha (com.gladtek.vaadin.captchas.hcaptcha)

Each provider ships a Flow Component implementing the shared Captcha interface, and a matching CaptchaVerifier for server-side token verification.

Installation

<dependency>
    <groupId>com.gladtek.vaadin.addons</groupId>
    <artifactId>captchas-addon</artifactId>
    <version>1.0.1</version>
</dependency>

Published to Maven Central.

Vaadin compatibility

Addon version Vaadin version
1.0.1 25.0.0+
1.0.0 25.0.0+

Usage

All three providers implement the same Captcha (getSiteKey(), reset(), addTokenListener(...)) and CaptchaVerifier (verify(String token)) interfaces, so application code written against those interfaces is portable, so swap FriendlyCaptcha/FriendlyCaptchaVerifier for Turnstile/TurnstileVerifier or HCaptcha/HCaptchaVerifier freely. The verifier constructors differ per provider's actual API requirements: FriendlyCaptchaVerifier(String secret, String siteKey) needs both, while TurnstileVerifier(String secret) and HCaptchaVerifier(String secret) only need the secret.

Verify as soon as the challenge is solved

FriendlyCaptcha captcha = new FriendlyCaptcha("your-site-key");
captcha.addTokenListener(event -> {
    String token = event.getToken();
    VerificationResult result = new FriendlyCaptchaVerifier("your-secret", "your-site-key")
            .verify(token);
    if (result.success()) {
        // proceed
    }
});
add(captcha);

Verify on form submit instead

Read captcha.getValue() at click time rather than reacting to the token event immediately, useful when verification should only happen once, as part of an overall form submission:

Turnstile captcha = new Turnstile("your-site-key");
Button submit = new Button("Submit", event -> {
    VerificationResult result = new TurnstileVerifier("your-secret")
            .verify(captcha.getValue());
    if (result.success()) {
        // proceed
    } else {
        captcha.reset();
    }
});
add(captcha, submit);

Reject a failed challenge and let the user retry

reset() clears the solved token and re-triggers the widget's own challenge flow, so the user gets a fresh attempt after a failed server-side verification:

VerificationResult result = new HCaptchaVerifier("your-secret").verify(captcha.getValue());
if (!result.success()) {
    captcha.reset();
}

Binder / required-field integration

Each component is also a Vaadin HasValue<String> field: its value is the solved token, or null until the challenge is completed. That means it can be treated exactly like a TextField in a Binder, with zero extra wiring:

Turnstile captcha = new Turnstile("your-site-key");
Binder<MyForm> binder = new Binder<>(MyForm.class);
binder.forField(captcha)
        .asRequired("Captcha is required")
        .bind(MyForm::getCaptchaToken, MyForm::setCaptchaToken);

binder.validate() will show the standard "required" error until the challenge is solved, the same way it does for any other empty required field. This only validates that a token was produced client-side; call the matching CaptchaVerifier server-side (e.g. on submit) to actually verify it, same as always.

Theme and display options

Each component exposes optional setters for provider-specific display options, on top of the required siteKey. All default to the provider's own behavior when left unset:

  • Turnstile: setTheme(CaptchaTheme), setSize(TurnstileSize), setAppearance(TurnstileAppearance) (e.g. INTERACTION_ONLY for a managed/invisible-style challenge).
  • HCaptcha: setTheme(CaptchaTheme), setSize(HCaptchaSize) (including INVISIBLE).
  • FriendlyCaptcha: setTheme(CaptchaTheme), setStartMode(FriendlyCaptchaStartMode) (FOCUS/NONE to defer solving until the widget is interacted with or started manually).
Turnstile captcha = new Turnstile("your-site-key");
captcha.setTheme(CaptchaTheme.DARK);
captcha.setSize(TurnstileSize.COMPACT);

These must be set before the component is attached to the page; the widget reads them once, on first render.

Testing limitation

Automated tests cover DOM-event-to-server-token wiring and verifier HTTP behavior against a stub server. They cannot solve a real provider challenge in a headless browser; manual/exploratory testing against each provider's sandbox/test keys is required before shipping a change to the widget scripts.

About

Provider-agnostic captcha components for Vaadin Flow - Friendly Captcha, Cloudflare Turnstile, and hCaptcha.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages