diff --git a/config/config.ini.example b/config/config.ini.example index d55b50a..f657b1f 100644 --- a/config/config.ini.example +++ b/config/config.ini.example @@ -59,12 +59,13 @@ google.analytics.id = "" ; Google gtag analytics google.gtag.id = "" -; Google reCaptcha -; https://www.google.com/recaptcha/admin. Options "false" and "true" +; Login protection system Choose "google", "cloudflare", or "disable". +; https://www.google.com/recaptcha/admin +; https://developers.cloudflare.com/turnstile/ -google.reCaptcha = "false" -google.reCaptcha.public = "" -google.reCaptcha.private = "" +login.protect.system = "disable" +login.protect.public = "" +login.protect.private = "" ; Pagination, RSS, and JSON posts.perpage = "10" diff --git a/lang/en_US.ini b/lang/en_US.ini index aaa42ad..2b91046 100644 --- a/lang/en_US.ini +++ b/lang/en_US.ini @@ -37,7 +37,7 @@ cache_off = "Cache off" cache_timestamp = "Cache timestamp" cancel = "Cancel" cannot_read_feed_content = "Cannot read feed content" -captcha_error = "reCaptcha not correct" +captcha_error = "Captcha failed" categories = "Categories" category = "Category" check_update = "Check for update" @@ -87,7 +87,7 @@ front_page_displays = "Front page displays" full_post = "Full post" general = "General" general_settings = "General Settings" -get_one_here = "Get one here" +get_one_here = "Obtain your reCaptcha keys here: " github_pre_release = "Github pre-release" google_analytics = "Google Analytics" google_analytics_legacy = "Google Analytics (legacy)" @@ -186,7 +186,7 @@ reading = "Reading" writing = "Writing" reading_settings = "Reading Settings" writing_settings = "Writing Settings" -recaptcha = "reCAPTCHA" +recaptcha = "Login Protection" recent_posts = "Recent posts" recent_posts_widget_at_most = "Recent posts widget at most" regular_post = "Regular post" @@ -297,3 +297,5 @@ mfa_error = "MFA code is not correct" disablemfa = "Disable MFA" enable_auto_save = "Enable Auto Save to Drafts" explain_autosave = "When enabled, new posts or pages will automatically be saved as a draft every 60 seconds after you start writing." +login_protect_system = "Login protection system" +cloudflare_info = "Review Cloudflare's Turnstile documentation: " \ No newline at end of file diff --git a/system/admin/views/config-widget.html.php b/system/admin/views/config-widget.html.php index c83f9fc..f1bf7bd 100644 --- a/system/admin/views/config-widget.html.php +++ b/system/admin/views/config-widget.html.php @@ -176,35 +176,42 @@


https://www.google.com/recaptcha/admin +

https://developers.cloudflare.com/turnstile/

- checked> -
- checked> -
+
+ checked> +
- +
- +
- +
- +

diff --git a/system/admin/views/login.html.php b/system/admin/views/login.html.php index 8ab940d..3501edc 100644 --- a/system/admin/views/login.html.php +++ b/system/admin/views/login.html.php @@ -24,9 +24,14 @@
- + -
">
+
">
+
+ + + +
">

diff --git a/system/configList.json b/system/configList.json index 84f89b1..b5ea594 100644 --- a/system/configList.json +++ b/system/configList.json @@ -27,9 +27,9 @@ "google.wmt.id", "google.analytics.id", "google.gtag.id", - "google.reCaptcha", - "google.reCaptcha.public", - "google.reCaptcha.private", + "login.protect.system", + "login.protect.public", + "login.protect.private", "posts.perpage", "category.perpage", "tag.perpage", diff --git a/system/htmly.php b/system/htmly.php index b4d72f8..6400388 100644 --- a/system/htmly.php +++ b/system/htmly.php @@ -121,7 +121,13 @@ get('/index', function () { post('/login', function () { $proper = (is_csrf_proper(from($_REQUEST, 'csrf_token'))); + if (config('login.protect.system') === 'google') { $captcha = isCaptcha(from($_REQUEST, 'g-recaptcha-response')); + } elseif (config('login.protect.system') === 'cloudflare') { + $captcha = isTurnstile(from($_REQUEST, 'cf-turnstile-response')); + } else { + $captcha = true; + } $user = from($_REQUEST, 'user'); $pass = from($_REQUEST, 'password'); diff --git a/system/includes/functions.php b/system/includes/functions.php index aa76d08..5ab35c6 100644 --- a/system/includes/functions.php +++ b/system/includes/functions.php @@ -3561,12 +3561,9 @@ function remove_html_comments($content) // Google recaptcha function isCaptcha($reCaptchaResponse) { - if (config('google.reCaptcha') != 'true') { - return true; - } $url = "https://www.google.com/recaptcha/api/siteverify"; $options = array( - "secret" => config("google.reCaptcha.private"), + "secret" => config("login.protect.private"), "response" => $reCaptchaResponse, "remoteip" => $_SERVER['REMOTE_ADDR'], ); @@ -3581,6 +3578,35 @@ function isCaptcha($reCaptchaResponse) return ($json['success']); } +// Cloudflare Turnstile +function isTurnstile($turnstileResponse) +{ + $public = config("login.protect.public"); + $private = config("login.protect.private"); + $ip = $_SERVER['REMOTE_ADDR']; + + $url = 'https://challenges.cloudflare.com/turnstile/v0/siteverify'; + $data = array('secret' => $private, 'response' => $turnstileResponse, 'remoteip' => $ip); + + $options = array( + 'http' => array( + 'method' => 'POST', + 'content' => http_build_query($data)) + ); + + $stream = stream_context_create($options); + $fileContent = file_get_contents($url, false, $stream); + + if ($fileContent === false) { + return false; + } + $json = json_decode($fileContent, true); + if ($json == false) { + return false; + } + return ($json['success']); +} + // Get video ID function get_video_id($url) {