aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorX. Ding <dingsm@gmail.com>2022-10-28 18:25:01 +0800
committerGitHub <noreply@github.com>2022-10-28 11:25:01 +0100
commit0782011f54dca98d96a8c5a78f68569ed045892a (patch)
tree238f27eeddc4d20b3876fb3e3dcbae7c456f0745
parentf6035822e75ad000869a0e01eff35941280f0250 (diff)
Add hcaptcha support besides Google ReCaptcha (#2834)
### Pull Request Checklist This PR add support for hcaptcha.com as an alternative to Google ReCaptcha. It also makes possible for user to customize ReCaptcha URL when needed. (Such as use recaptcha.net instead of www.google.com) This feature needs manual test cuz it involves 3rd party _captcha_. Signed-off-by: `Simon Ding <dxl@plotbridge.com>` Co-authored-by: dxl <dxl@plotbridge.com>
-rw-r--r--clientapi/routing/auth_fallback.go18
-rw-r--r--clientapi/routing/register.go4
-rw-r--r--dendrite-sample.monolith.yaml8
-rw-r--r--dendrite-sample.polylith.yaml8
-rw-r--r--setup/config/config_clientapi.go18
5 files changed, 45 insertions, 11 deletions
diff --git a/clientapi/routing/auth_fallback.go b/clientapi/routing/auth_fallback.go
index abfe830f..ad870993 100644
--- a/clientapi/routing/auth_fallback.go
+++ b/clientapi/routing/auth_fallback.go
@@ -31,8 +31,7 @@ const recaptchaTemplate = `
<title>Authentication</title>
<meta name='viewport' content='width=device-width, initial-scale=1,
user-scalable=no, minimum-scale=1.0, maximum-scale=1.0'>
-<script src="https://www.google.com/recaptcha/api.js"
- async defer></script>
+<script src="{{.apiJsUrl}}" async defer></script>
<script src="//code.jquery.com/jquery-1.11.2.min.js"></script>
<script>
function captchaDone() {
@@ -51,8 +50,8 @@ function captchaDone() {
Please verify that you're not a robot.
</p>
<input type="hidden" name="session" value="{{.session}}" />
- <div class="g-recaptcha"
- data-sitekey="{{.siteKey}}"
+ <div class="{{.sitekeyClass}}"
+ data-sitekey="{{.sitekey}}"
data-callback="captchaDone">
</div>
<noscript>
@@ -114,9 +113,12 @@ func AuthFallback(
serveRecaptcha := func() {
data := map[string]string{
- "myUrl": req.URL.String(),
- "session": sessionID,
- "siteKey": cfg.RecaptchaPublicKey,
+ "myUrl": req.URL.String(),
+ "session": sessionID,
+ "apiJsUrl": cfg.RecaptchaApiJsUrl,
+ "sitekey": cfg.RecaptchaPublicKey,
+ "sitekeyClass": cfg.RecaptchaSitekeyClass,
+ "formField": cfg.RecaptchaFormField,
}
serveTemplate(w, recaptchaTemplate, data)
}
@@ -155,7 +157,7 @@ func AuthFallback(
return &res
}
- response := req.Form.Get("g-recaptcha-response")
+ response := req.Form.Get(cfg.RecaptchaFormField)
if err := validateRecaptcha(cfg, response, clientIP); err != nil {
util.GetLogger(req.Context()).Error(err)
return err
diff --git a/clientapi/routing/register.go b/clientapi/routing/register.go
index 698d185b..b9ebb051 100644
--- a/clientapi/routing/register.go
+++ b/clientapi/routing/register.go
@@ -20,6 +20,7 @@ import (
"encoding/json"
"fmt"
"io"
+ "net"
"net/http"
"net/url"
"regexp"
@@ -336,6 +337,7 @@ func validateRecaptcha(
response string,
clientip string,
) *util.JSONResponse {
+ ip, _, _ := net.SplitHostPort(clientip)
if !cfg.RecaptchaEnabled {
return &util.JSONResponse{
Code: http.StatusConflict,
@@ -355,7 +357,7 @@ func validateRecaptcha(
url.Values{
"secret": {cfg.RecaptchaPrivateKey},
"response": {response},
- "remoteip": {clientip},
+ "remoteip": {ip},
},
)
diff --git a/dendrite-sample.monolith.yaml b/dendrite-sample.monolith.yaml
index 5195c29b..d86e9da9 100644
--- a/dendrite-sample.monolith.yaml
+++ b/dendrite-sample.monolith.yaml
@@ -179,7 +179,13 @@ client_api:
recaptcha_public_key: ""
recaptcha_private_key: ""
recaptcha_bypass_secret: ""
- recaptcha_siteverify_api: ""
+
+ # To use hcaptcha.com instead of ReCAPTCHA, set the following parameters, otherwise just keep them empty.
+ # recaptcha_siteverify_api: "https://hcaptcha.com/siteverify"
+ # recaptcha_api_js_url: "https://js.hcaptcha.com/1/api.js"
+ # recaptcha_form_field: "h-captcha-response"
+ # recaptcha_sitekey_class: "h-captcha"
+
# TURN server information that this homeserver should send to clients.
turn:
diff --git a/dendrite-sample.polylith.yaml b/dendrite-sample.polylith.yaml
index bbbe16fd..ecc3f405 100644
--- a/dendrite-sample.polylith.yaml
+++ b/dendrite-sample.polylith.yaml
@@ -175,7 +175,13 @@ client_api:
recaptcha_public_key: ""
recaptcha_private_key: ""
recaptcha_bypass_secret: ""
- recaptcha_siteverify_api: ""
+
+ # To use hcaptcha.com instead of ReCAPTCHA, set the following parameters, otherwise just keep them empty.
+ # recaptcha_siteverify_api: "https://hcaptcha.com/siteverify"
+ # recaptcha_api_js_url: "https://js.hcaptcha.com/1/api.js"
+ # recaptcha_form_field: "h-captcha-response"
+ # recaptcha_sitekey_class: "h-captcha"
+
# TURN server information that this homeserver should send to clients.
turn:
diff --git a/setup/config/config_clientapi.go b/setup/config/config_clientapi.go
index 56f4b3f9..0a871da1 100644
--- a/setup/config/config_clientapi.go
+++ b/setup/config/config_clientapi.go
@@ -32,6 +32,12 @@ type ClientAPI struct {
// Boolean stating whether catpcha registration is enabled
// and required
RecaptchaEnabled bool `yaml:"enable_registration_captcha"`
+ // Recaptcha api.js Url, for compatible with hcaptcha.com, etc.
+ RecaptchaApiJsUrl string `yaml:"recaptcha_api_js_url"`
+ // Recaptcha div class for sitekey, for compatible with hcaptcha.com, etc.
+ RecaptchaSitekeyClass string `yaml:"recaptcha_sitekey_class"`
+ // Recaptcha form field, for compatible with hcaptcha.com, etc.
+ RecaptchaFormField string `yaml:"recaptcha_form_field"`
// This Home Server's ReCAPTCHA public key.
RecaptchaPublicKey string `yaml:"recaptcha_public_key"`
// This Home Server's ReCAPTCHA private key.
@@ -75,6 +81,18 @@ func (c *ClientAPI) Verify(configErrs *ConfigErrors, isMonolith bool) {
checkNotEmpty(configErrs, "client_api.recaptcha_public_key", c.RecaptchaPublicKey)
checkNotEmpty(configErrs, "client_api.recaptcha_private_key", c.RecaptchaPrivateKey)
checkNotEmpty(configErrs, "client_api.recaptcha_siteverify_api", c.RecaptchaSiteVerifyAPI)
+ if c.RecaptchaSiteVerifyAPI == "" {
+ c.RecaptchaSiteVerifyAPI = "https://www.google.com/recaptcha/api/siteverify"
+ }
+ if c.RecaptchaApiJsUrl == "" {
+ c.RecaptchaApiJsUrl = "https://www.google.com/recaptcha/api.js"
+ }
+ if c.RecaptchaFormField == "" {
+ c.RecaptchaFormField = "g-recaptcha"
+ }
+ if c.RecaptchaSitekeyClass == "" {
+ c.RecaptchaSitekeyClass = "g-recaptcha-response"
+ }
}
// Ensure there is any spam counter measure when enabling registration
if !c.RegistrationDisabled && !c.OpenRegistrationWithoutVerificationEnabled {