Subversion Repositories oidplus

Rev

Rev 1050 | Rev 1116 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. <?php
  2.  
  3. /*
  4.  * OIDplus 2.0
  5.  * Copyright 2019 - 2023 Daniel Marschall, ViaThinkSoft
  6.  *
  7.  * Licensed under the Apache License, Version 2.0 (the "License");
  8.  * you may not use this file except in compliance with the License.
  9.  * You may obtain a copy of the License at
  10.  *
  11.  *     http://www.apache.org/licenses/LICENSE-2.0
  12.  *
  13.  * Unless required by applicable law or agreed to in writing, software
  14.  * distributed under the License is distributed on an "AS IS" BASIS,
  15.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16.  * See the License for the specific language governing permissions and
  17.  * limitations under the License.
  18.  */
  19.  
  20. namespace ViaThinkSoft\OIDplus;
  21.  
  22. // phpcs:disable PSR1.Files.SideEffects
  23. \defined('INSIDE_OIDPLUS') or die;
  24. // phpcs:enable PSR1.Files.SideEffects
  25.  
  26. class OIDplusCaptchaPluginHCaptcha extends OIDplusCaptchaPlugin {
  27.  
  28.         public static function id(): string {
  29.                 return 'hCaptcha';
  30.         }
  31.  
  32.         public function isVisible(): bool {
  33.                 return true;
  34.         }
  35.  
  36.         public function captchaGenerate($header_text=null, $footer_text=null) {
  37.                 return ($header_text ? '<p>'.$header_text.'</p>' : '') .
  38.                        '<noscript>'.
  39.                        '<p><font color="red">'._L('You need to enable JavaScript to solve the CAPTCHA.').'</font></p>'.
  40.                        '</noscript>'.
  41.                        '<div id="h-captcha"></div>'.
  42.                        '<script src="https://js.hcaptcha.com/1/api.js"></script>'.
  43.                        '<script>'.
  44.                        'OIDplusCaptchaPluginHCaptcha.captchaShow('.js_escape(OIDplus::baseConfig()->getValue('HCAPTCHA_SITEKEY', '')).')'.
  45.                        '</script>'.
  46.                        ($footer_text ? '<p>'.$footer_text.'</p>' : '');
  47.         }
  48.  
  49.         public function captchaVerify($params, $fieldname=null) {
  50.                 $sitekey=OIDplus::baseConfig()->getValue('HCAPTCHA_SITEKEY', '');
  51.                 $secret=OIDplus::baseConfig()->getValue('HCAPTCHA_SECRET', '');
  52.  
  53.                 if (!function_exists('curl_init')) {
  54.                         throw new OIDplusException(_L('hCaptcha plugin needs the PHP extension php_curl'));
  55.                 }
  56.  
  57.                 // Yes, it is really "g-recaptcha-response"!
  58.                 if (is_null($fieldname)) $fieldname = 'g-recaptcha-response'; // no individual field name (created by oidplus_captcha_response()) means that it is a plain POST event (e.g. by oobe.php)
  59.                 _CheckParamExists($params, $fieldname);
  60.                 $response=$params[$fieldname];
  61.  
  62.                 $ch = curl_init();
  63.                 if (ini_get('curl.cainfo') == '') curl_setopt($ch, CURLOPT_CAINFO, OIDplus::localpath() . 'vendor/cacert.pem');
  64.                 curl_setopt($ch, CURLOPT_URL, 'https://hcaptcha.com/siteverify');
  65.                 curl_setopt($ch, CURLOPT_USERAGENT, 'ViaThinkSoft-OIDplus/2.0');
  66.                 curl_setopt($ch, CURLOPT_POST, 1);
  67.                 curl_setopt($ch, CURLOPT_POSTFIELDS, "secret=".urlencode($secret)."&response=".urlencode($response)."&remoteip=".urlencode($_SERVER['REMOTE_ADDR'])."&sitekey=".urlencode($sitekey));
  68.                 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  69.                 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
  70.                 curl_setopt($ch, CURLOPT_AUTOREFERER, true);
  71.                 if (!($res = @curl_exec($ch))) {
  72.                         throw new OIDplusException(_L('Communication with hCaptcha server failed: %1',curl_error($ch)));
  73.                 }
  74.                 curl_close($ch);
  75.  
  76.                 $captcha_success=@json_decode($res);
  77.                 if (!$captcha_success || ($captcha_success->success==false)) {
  78.                         throw new OIDplusException(_L('CAPTCHA not successfully verified').' ('.implode(", ",$captcha_success->{'error-codes'}).')');
  79.                 }
  80.         }
  81.  
  82.         public static function setupHTML(): string {
  83.                 $curl_status = function_exists('curl_init') ? 1 : 0;
  84.                 return '<div id="CAPTCHAPLUGIN_PARAMS_HCAPTCHA">'.
  85.                        '<p>(<a href="https://www.hcaptcha.com/" target="_blank">'._L('more information and obtain key').'</a>)</p>'.
  86.                        '<p>'._L('hCaptcha Site key').'<br><input id="hcaptcha_sitekey" type="text" onkeypress="rebuild()" onkeyup="rebuild()"> <span id="hcaptcha_sitekey_warn"></span></p>'.
  87.                        '<p>'._L('hCaptcha Secret').'<br><input id="hcaptcha_secret" type="text" onkeypress="rebuild()" onkeyup="rebuild()"> <span id="hcaptcha_secret_warn"></span></p>'.
  88.                        '<input id="hcaptcha_curl_status" value="'.$curl_status.'" type="hidden">'.
  89.                        (!$curl_status ? '<p><font color="red">'._L('hCaptcha plugin needs the PHP extension php_curl').'</font></p>' : '').
  90.                        '</div>';
  91.         }
  92.  
  93.         function httpHeaderCheck(&$http_headers) {
  94.  
  95.                 // If you use CSP headers, please add the following to your configuration:
  96.                 // script-src should include https://hcaptcha.com, https://*.hcaptcha.com
  97.                 $http_headers["Content-Security-Policy"]["script-src"][] = "https://hcaptcha.com";
  98.                 $http_headers["Content-Security-Policy"]["script-src"][] = "https://*.hcaptcha.com";
  99.                 // frame-src should include https://hcaptcha.com, https://*.hcaptcha.com
  100.                 $http_headers["Content-Security-Policy"]["frame-src"][] = "https://hcaptcha.com";
  101.                 $http_headers["Content-Security-Policy"]["frame-src"][] = "https://*.hcaptcha.com";
  102.                 // style-src should include https://hcaptcha.com, https://*.hcaptcha.com
  103.                 $http_headers["Content-Security-Policy"]["style-src"][] = "https://hcaptcha.com";
  104.                 $http_headers["Content-Security-Policy"]["style-src"][] = "https://*.hcaptcha.com";
  105.                 // connect-src should include https://hcaptcha.com, https://*.hcaptcha.com
  106.                 $http_headers["Content-Security-Policy"]["connect-src"][] = "https://hcaptcha.com";
  107.                 $http_headers["Content-Security-Policy"]["connect-src"][] = "https://*.hcaptcha.com";
  108.  
  109.                 //If you are an enterprise customer and would like to enable additional verification to be performed, you can optionally choose the following CSP strategy:
  110.                 //unsafe-eval and unsafe-inline should include https://hcaptcha.com, https://*.hcaptcha.com
  111.                 //$http_headers["Content-Security-Policy"]["unsafe-eval"][] = "https://hcaptcha.com";
  112.                 //$http_headers["Content-Security-Policy"]["unsafe-eval"][] = "https://*.hcaptcha.com";
  113.                 //$http_headers["Content-Security-Policy"]["unsafe-inline"][] = "https://hcaptcha.com";
  114.                 //$http_headers["Content-Security-Policy"]["unsafe-inline"][] = "https://*.hcaptcha.com";
  115.  
  116.         }
  117.  
  118. }
  119.