feat: add 'proof of React' challenge (#1038)

* feat: add 'proof of React' challenge

Signed-off-by: Xe Iaso <me@xeiaso.net>

* fix(challenge/preact): use JSX fragments

Signed-off-by: Xe Iaso <me@xeiaso.net>

* fix(challenge/preact): ensure that the client waits as long as it needs to

Signed-off-by: Xe Iaso <me@xeiaso.net>

* docs: fix spelling

Signed-off-by: Xe Iaso <me@xeiaso.net>

* fix(challenges/xeact): add noscript warning

Signed-off-by: Xe Iaso <me@xeiaso.net>

* fix(challenges/xeact): add default loading message

Signed-off-by: Xe Iaso <me@xeiaso.net>

* fix(challenges/xeact): make a UI render without JS

Signed-off-by: Xe Iaso <me@xeiaso.net>

* fix(challenges/xeact): use %s here, not %w

Signed-off-by: Xe Iaso <me@xeiaso.net>

* fix(test/healthcheck): run asset build

Signed-off-by: Xe Iaso <me@xeiaso.net>

* fix(challenge/preact): fix build in ci

Signed-off-by: Xe Iaso <me@xeiaso.net>

---------

Signed-off-by: Xe Iaso <me@xeiaso.net>
Signed-off-by: Xe Iaso <xe.iaso@techaro.lol>
This commit is contained in:
Xe Iaso 2025-08-29 16:09:27 -04:00 committed by GitHub
parent 00afa72c4b
commit 0e0847cbeb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 518 additions and 4 deletions

View file

@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
<!-- This changes the project to: -->
- Add a "proof of React" challenge to prove that the client is able to run a simple JSX app.
- Added possibility to disable HTTP keep-alive to support backends not properly
handling it
- Added a missing link to the Caddy installation environment in the installation documentation.

View file

@ -0,0 +1,19 @@
# Preact
The `preact` challenge sends the browser a simple challenge that makes it run very lightweight JavaScript that proves the client is able to execute client-side JavaScript. It uses [Preact](https://www.npmjs.com/package/preact) (a lightweight client side web framework in the vein of React) to do this.
To use it in your Anubis configuration:
```yaml
# Generic catchall rule
- name: generic-browser
user_agent_regex: >-
Mozilla|Opera
action: CHALLENGE
challenge:
difficulty: 1 # Number of seconds to wait before refreshing the page
report_as: 4 # Unused by this challenge method
algorithm: preact
```
This is the default challenge method for most clients.