From 8d523b32f6c286700ba2cf9523dde99c81c14512 Mon Sep 17 00:00:00 2001 From: Darko Date: Mon, 11 May 2015 11:14:56 +0200 Subject: [PATCH] Overhaul reCaptcha support. Ported from nZEDb. Remove old recaptchalib. --- lib/copy_this/libs/ReCaptcha/ReCaptcha.php | 97 +++++++ .../libs/ReCaptcha/RequestMethod.php | 42 +++ .../libs/ReCaptcha/RequestMethod/Post.php | 70 +++++ .../libs/ReCaptcha/RequestMethod/Socket.php | 104 +++++++ .../ReCaptcha/RequestMethod/SocketPost.php | 120 ++++++++ .../libs/ReCaptcha/RequestParameters.php | 103 +++++++ lib/copy_this/libs/ReCaptcha/Response.php | 102 +++++++ .../newznab/controllers/BasePage.php | 42 +++ lib/copy_this/newznab/controllers/Captcha.php | 205 +++++++++++++ .../newznab/controllers/recaptchalib.php | 274 ------------------ lib/copy_this/www/pages/contact-us.php | 34 +-- lib/copy_this/www/pages/forgottenpassword.php | 75 +++-- lib/copy_this/www/pages/login.php | 5 +- lib/copy_this/www/pages/register.php | 114 ++++---- .../nntmux/views/frontend/captcha.tpl | 7 + .../nntmux/views/frontend/contact.tpl | 5 +- .../views/frontend/forgottenpassword.tpl | 4 +- .../templates/nntmux/views/frontend/login.tpl | 2 +- .../nntmux/views/frontend/register.tpl | 4 +- 19 files changed, 1012 insertions(+), 397 deletions(-) create mode 100644 lib/copy_this/libs/ReCaptcha/ReCaptcha.php create mode 100644 lib/copy_this/libs/ReCaptcha/RequestMethod.php create mode 100644 lib/copy_this/libs/ReCaptcha/RequestMethod/Post.php create mode 100644 lib/copy_this/libs/ReCaptcha/RequestMethod/Socket.php create mode 100644 lib/copy_this/libs/ReCaptcha/RequestMethod/SocketPost.php create mode 100644 lib/copy_this/libs/ReCaptcha/RequestParameters.php create mode 100644 lib/copy_this/libs/ReCaptcha/Response.php create mode 100644 lib/copy_this/newznab/controllers/Captcha.php delete mode 100644 lib/copy_this/newznab/controllers/recaptchalib.php create mode 100644 lib/copy_this/www/templates/nntmux/views/frontend/captcha.tpl diff --git a/lib/copy_this/libs/ReCaptcha/ReCaptcha.php b/lib/copy_this/libs/ReCaptcha/ReCaptcha.php new file mode 100644 index 000000000..523c4aae4 --- /dev/null +++ b/lib/copy_this/libs/ReCaptcha/ReCaptcha.php @@ -0,0 +1,97 @@ +secret = $secret; + + if (!is_null($requestMethod)) { + $this->requestMethod = $requestMethod; + } else { + $this->requestMethod = new RequestMethod\Post(); + } + } + + /** + * Calls the reCAPTCHA siteverify API to verify whether the user passes + * CAPTCHA test. + * + * @param string $response The value of 'g-recaptcha-response' in the submitted form. + * @param string $remoteIp The end user's IP address. + * @return Response Response from the service. + */ + public function verify($response, $remoteIp = null) + { + // Discard empty solution submissions + if (empty($response)) { + $recaptchaResponse = new Response(false, array('missing-input-response')); + return $recaptchaResponse; + } + + $params = new RequestParameters($this->secret, $response, $remoteIp, self::VERSION); + $rawResponse = $this->requestMethod->submit($params); + return Response::fromJson($rawResponse); + } +} diff --git a/lib/copy_this/libs/ReCaptcha/RequestMethod.php b/lib/copy_this/libs/ReCaptcha/RequestMethod.php new file mode 100644 index 000000000..fc4dde59c --- /dev/null +++ b/lib/copy_this/libs/ReCaptcha/RequestMethod.php @@ -0,0 +1,42 @@ + array( + 'header' => "Content-type: application/x-www-form-urlencoded\r\n", + 'method' => 'POST', + 'content' => $params->toQueryString(), + // Force the peer to validate (not needed in 5.6.0+, but still works + 'verify_peer' => true, + // Force the peer validation to use www.google.com + $peer_key => 'www.google.com', + ), + ); + $context = stream_context_create($options); + return file_get_contents(self::SITE_VERIFY_URL, false, $context); + } +} diff --git a/lib/copy_this/libs/ReCaptcha/RequestMethod/Socket.php b/lib/copy_this/libs/ReCaptcha/RequestMethod/Socket.php new file mode 100644 index 000000000..0d5dfb460 --- /dev/null +++ b/lib/copy_this/libs/ReCaptcha/RequestMethod/Socket.php @@ -0,0 +1,104 @@ +handle = fsockopen($hostname, $port, $errno, $errstr, (is_null($timeout) ? ini_get("default_socket_timeout") : $timeout)); + + if ($this->handle != false && $errno === 0 && $errstr === '') { + return $this->handle; + } else { + return false; + } + } + + /** + * fwrite + * + * @see http://php.net/fwrite + * @param string $string + * @param int $length + * @return int | bool + */ + public function fwrite($string, $length = null) + { + return fwrite($this->handle, $string, (is_null($length) ? strlen($string) : $length)); + } + + /** + * fgets + * + * @see http://php.net/fgets + * @param int $length + */ + public function fgets($length = null) + { + return fgets($this->handle, $length); + } + + /** + * feof + * + * @see http://php.net/feof + * @return bool + */ + public function feof() + { + return feof($this->handle); + } + + /** + * fclose + * + * @see http://php.net/fclose + * @return bool + */ + public function fclose() + { + return fclose($this->handle); + } +} diff --git a/lib/copy_this/libs/ReCaptcha/RequestMethod/SocketPost.php b/lib/copy_this/libs/ReCaptcha/RequestMethod/SocketPost.php new file mode 100644 index 000000000..ba9036f69 --- /dev/null +++ b/lib/copy_this/libs/ReCaptcha/RequestMethod/SocketPost.php @@ -0,0 +1,120 @@ +socket = $socket; + } else { + $this->socket = new Socket(); + } + } + + /** + * Submit the POST request with the specified parameters. + * + * @param RequestParameters $params Request parameters + * @return string Body of the reCAPTCHA response + */ + public function submit(RequestParameters $params) + { + $errno = 0; + $errstr = ''; + + if ($this->socket->fsockopen('ssl://' . self::RECAPTCHA_HOST, 443, $errno, $errstr, 30) !== false) { + $content = $params->toQueryString(); + + $request = "POST " . self::SITE_VERIFY_PATH . " HTTP/1.1\r\n"; + $request .= "Host: " . self::RECAPTCHA_HOST . "\r\n"; + $request .= "Content-Type: application/x-www-form-urlencoded\r\n"; + $request .= "Content-length: " . strlen($content) . "\r\n"; + $request .= "Connection: close\r\n\r\n"; + $request .= $content . "\r\n\r\n"; + + $this->socket->fwrite($request); + $response = ''; + + while (!$this->socket->feof()) { + $response .= $this->socket->fgets(4096); + } + + $this->socket->fclose(); + + if (0 === strpos($response, 'HTTP/1.1 200 OK')) { + $parts = preg_split("#\n\s*\n#Uis", $response); + return $parts[1]; + } + + return self::BAD_RESPONSE; + } + + return self::BAD_REQUEST; + } +} diff --git a/lib/copy_this/libs/ReCaptcha/RequestParameters.php b/lib/copy_this/libs/ReCaptcha/RequestParameters.php new file mode 100644 index 000000000..cb66f26cf --- /dev/null +++ b/lib/copy_this/libs/ReCaptcha/RequestParameters.php @@ -0,0 +1,103 @@ +secret = $secret; + $this->response = $response; + $this->remoteIp = $remoteIp; + $this->version = $version; + } + + /** + * Array representation. + * + * @return array Array formatted parameters. + */ + public function toArray() + { + $params = array('secret' => $this->secret, 'response' => $this->response); + + if (!is_null($this->remoteIp)) { + $params['remoteip'] = $this->remoteIp; + } + + if (!is_null($this->version)) { + $params['version'] = $this->version; + } + + return $params; + } + + /** + * Query string representation for HTTP request. + * + * @return string Query string formatted parameters. + */ + public function toQueryString() + { + return http_build_query($this->toArray(), '', '&'); + } +} diff --git a/lib/copy_this/libs/ReCaptcha/Response.php b/lib/copy_this/libs/ReCaptcha/Response.php new file mode 100644 index 000000000..d2d8a8bf7 --- /dev/null +++ b/lib/copy_this/libs/ReCaptcha/Response.php @@ -0,0 +1,102 @@ +success = $success; + $this->errorCodes = $errorCodes; + } + + /** + * Is success? + * + * @return boolean + */ + public function isSuccess() + { + return $this->success; + } + + /** + * Get error codes. + * + * @return array + */ + public function getErrorCodes() + { + return $this->errorCodes; + } +} diff --git a/lib/copy_this/newznab/controllers/BasePage.php b/lib/copy_this/newznab/controllers/BasePage.php index 97b8ef7ea..656e1e317 100644 --- a/lib/copy_this/newznab/controllers/BasePage.php +++ b/lib/copy_this/newznab/controllers/BasePage.php @@ -2,6 +2,8 @@ require_once SMARTY_DIR . 'Smarty.class.php'; require_once NN_LIB . 'utility' . DS . 'SmartyUtils.php'; +use newznab\controllers\Captcha; + class BasePage { /** @@ -9,6 +11,13 @@ class BasePage */ public $settings = null; + /** + * Public access to Captcha object for error checking. + * + * @var \newznab\controllers\Captcha + */ + public $captcha; + /** * @var Users */ @@ -30,6 +39,9 @@ class BasePage public $secure_connection = false; + /** + * Set up session / smarty / user variables. + */ public function __construct() { @session_start(); @@ -52,6 +64,7 @@ class BasePage // Buffer settings/DB connection. $this->settings = new newznab\db\DB(); $this->smarty = new Smarty(); + $this->captcha = new Captcha(['Settings' => $this->settings]); if ($this->site->style != "default") $this->smarty->addTemplateDir(WWW_DIR.'templates/'.$this->site->style.'/views/frontend', 'style_frontend'); @@ -128,12 +141,41 @@ class BasePage $this->smarty->assign('isadmin',"false"); $this->smarty->assign('loggedin',"false"); $this->floodCheck(); + $this->handleCaptcha(); + } $this->smarty->assign('site', $this->site); $this->smarty->assign('page', $this); } + /** + * Allow display on pages that require captcha + * and handle captcha responses. + * + * @notes Optimized for speed over code brevity since it's + * executed on every singe page. + * Instantiating Captcha() doesn't initialize the underlying libraries. + * shouldDisplay() does it if applicable. + */ + private function handleCaptcha() { + if ($this->captcha->shouldDisplay($this->page)) { + $this->smarty->assign('showCaptcha', true); + $this->smarty->assign('sitekey', $this->captcha->getSiteKey()); + + if ($this->isPostBack()) { + if (!$this->captcha->processCaptcha($_POST, $_SERVER['REMOTE_ADDR'])) { + $this->smarty->assign('error', $this->captcha->getError()); + } + //Delete this key after using so it doesn't interfere with normal $_POST + //processing. (i.e. contact-us) + unset($_POST[Captcha::RECAPTCHA_POSTKEY]); + } + } else { + $this->smarty->assign('showCaptcha', false); + } + } + /** * Unquotes quoted strings recursively in an array. * diff --git a/lib/copy_this/newznab/controllers/Captcha.php b/lib/copy_this/newznab/controllers/Captcha.php new file mode 100644 index 000000000..7986f6cb8 --- /dev/null +++ b/lib/copy_this/newznab/controllers/Captcha.php @@ -0,0 +1,205 @@ + null + ]; + $options += $defaults; + + $this->pdo = ($options['Settings'] instanceof DB ? $options['Settings'] : new DB()); + $s = new \Sites(); + $this->site = $s->get(); + } + + /** + * If site admin setup keys properly, + * allow display of recaptcha. + * + * @param string|bool $page + * @return bool + */ + public function shouldDisplay($page = false) { + if ($page !== false) { + if (in_array($page, $this->captcha_pages) && $this->_bootstrapCaptcha()) { + return true; + } + } elseif ($this->_bootstrapCaptcha()) { + return true; + } + + return false; + } + + /** + * Return formatted error messages. + * + * @return string + */ + public function getError() { + return $this->error; + } + + /** + * Return sitekey for captcha html display. + * + * @return bool|string + */ + public function getSiteKey() { + return $this->sitekey; + } + + /** + * Process the submitted captcha and validate. + * + * @param array $response + * @param string $ip + * @return bool + */ + public function processCaptcha($response, $ip) { + if (isset($response[self::RECAPTCHA_POSTKEY])) { + $post_response = $response[self::RECAPTCHA_POSTKEY]; + } else { + $post_response = ''; + } + + $verify_response = $this->recaptcha->verify($post_response, $ip); + + if (!$verify_response->isSuccess()) { + $this->_handleErrors($verify_response->getErrorCodes()); + return false; + } + + return true; + } + + /** + * Build formatted error string for output using + * Google's reCaptcha error codes. + * + * @param array $codes + */ + private function _handleErrors($codes) { + $rc_error = 'ReCaptcha Failed: '; + + foreach ($codes as $c) { + switch($c) { + case self::RECAPTCHA_ERROR_MISSING_SECRET: + $rc_error .= 'Missing Secret Key'; + break; + case self::RECAPTCHA_ERROR_INVALID_SECRET: + $rc_error .= 'Invalid Secret Key'; + break; + case self::RECAPTCHA_ERROR_MISSING_RESPONSE: + $rc_error .= 'No Response!'; + break; + case self::RECAPTCHA_ERROR_INVALID_RESPONSE: + $rc_error .= 'Invalid response! You are a bot!'; + break; + default: + $rc_error .= 'Unknown Error!'; + } + } + + $this->error = $rc_error; + } + + /** + * Instantiate the ReCaptcha library and store it. + * Return bool on success/failure. + * + * @return bool + */ + private function _bootstrapCaptcha() { + if ($this->recaptcha instanceof ReCaptcha) { + return true; + } + + $this->sitekey = $this->site->recaptchapublickey; + $this->secretkey = $this->site->recaptchaprivatekey; + + if ($this->sitekey != false && $this->sitekey != '') { + if ($this->secretkey != false && $this->secretkey != '') { + $this->recaptcha = new ReCaptcha($this->secretkey); + return true; + } + } + + return false; + } + +} \ No newline at end of file diff --git a/lib/copy_this/newznab/controllers/recaptchalib.php b/lib/copy_this/newznab/controllers/recaptchalib.php deleted file mode 100644 index f285e3200..000000000 --- a/lib/copy_this/newznab/controllers/recaptchalib.php +++ /dev/null @@ -1,274 +0,0 @@ - $value ) - $req .= $key . '=' . urlencode( stripslashes($value) ) . '&'; - - // Cut the last '&' - $req=substr($req,0,strlen($req)-1); - return $req; -} - - - -/** - * Submits an HTTP POST to a reCAPTCHA server - * @param string $host - * @param string $path - * @param array $data - * @param int port - * @return array response - */ -function _recaptcha_http_post($host, $path, $data, $port = 80) { - - $req = _recaptcha_qsencode ($data); - - $http_request = "POST $path HTTP/1.0\r\n"; - $http_request .= "Host: $host\r\n"; - $http_request .= "Content-Type: application/x-www-form-urlencoded;\r\n"; - $http_request .= "Content-Length: " . strlen($req) . "\r\n"; - $http_request .= "User-Agent: reCAPTCHA/PHP\r\n"; - $http_request .= "\r\n"; - $http_request .= $req; - - $response = ''; - if( false == ( $fs = @fsockopen($host, $port, $errno, $errstr, 10) ) ) { - die ('Could not open socket'); - } - - fwrite($fs, $http_request); - - while ( !feof($fs) ) - $response .= fgets($fs, 1160); // One TCP-IP packet - fclose($fs); - $response = explode("\r\n\r\n", $response, 2); - - return $response; -} - - - -/** - * Gets the challenge HTML (javascript and non-javascript version). - * This is called from the browser, and the resulting reCAPTCHA HTML widget - * is embedded within the HTML form it was called from. - * @param string $pubkey A public key for reCAPTCHA - * @param string $error The error given by reCAPTCHA (optional, default is null) - * @param boolean $use_ssl Should the request be made over ssl? (optional, default is false) - - * @return string - The HTML to be embedded in the user's form. - */ -function recaptcha_get_html ($pubkey, $error = null, $use_ssl = false) -{ - if ($pubkey == null || $pubkey == '') { - die ("To use reCAPTCHA you must get an API key from https://www.google.com/recaptcha/admin/create"); - } - - if ($use_ssl) { - $server = RECAPTCHA_API_SECURE_SERVER; - } else { - $server = RECAPTCHA_API_SERVER; - } - - $errorpart = ""; - if ($error) { - $errorpart = "&error=" . $error; - } - return ' - - '; -} - - - - -/** - * A ReCaptchaResponse is returned from recaptcha_check_answer() - */ -class ReCaptchaResponse { - var $is_valid; - var $error; -} - - -/** - * Calls an HTTP POST function to verify if the user's guess was correct - * @param string $privkey - * @param string $remoteip - * @param string $challenge - * @param string $response - * @param array $extra_params an array of extra variables to post to the server - * @return ReCaptchaResponse - */ -function recaptcha_check_answer ($privkey, $remoteip, $challenge, $response, $extra_params = array()) -{ - if ($privkey == null || $privkey == '') { - die ("To use reCAPTCHA you must get an API key from https://www.google.com/recaptcha/admin/create"); - } - - if ($remoteip == null || $remoteip == '') { - die ("For security reasons, you must pass the remote ip to reCAPTCHA"); - } - - - - //discard spam submissions - if ($challenge == null || strlen($challenge) == 0 || $response == null || strlen($response) == 0) { - $recaptcha_response = new ReCaptchaResponse(); - $recaptcha_response->is_valid = false; - $recaptcha_response->error = 'incorrect-captcha-sol'; - return $recaptcha_response; - } - - $response = _recaptcha_http_post (RECAPTCHA_VERIFY_SERVER, "/recaptcha/api/verify", - array ( - 'privatekey' => $privkey, - 'remoteip' => $remoteip, - 'challenge' => $challenge, - 'response' => $response - ) + $extra_params - ); - - $answers = explode ("\n", $response [1]); - $recaptcha_response = new ReCaptchaResponse(); - - if (trim ($answers [0]) == 'true') { - $recaptcha_response->is_valid = true; - } - else { - $recaptcha_response->is_valid = false; - $recaptcha_response->error = $answers [1]; - } - return $recaptcha_response; - -} - -/** - * gets a URL where the user can sign up for reCAPTCHA. If your application - * has a configuration page where you enter a key, you should provide a link - * using this function. - * @param string $domain The domain where the page is hosted - * @param string $appname The name of your application - */ -function recaptcha_get_signup_url ($domain = null, $appname = null) { - return "https://www.google.com/recaptcha/admin/create?" . _recaptcha_qsencode (array ('domains' => $domain, 'app' => $appname)); -} - -function _recaptcha_aes_pad($val) { - $block_size = 16; - $numpad = $block_size - (strlen ($val) % $block_size); - return str_pad($val, strlen ($val) + $numpad, chr($numpad)); -} - -/* Mailhide related code */ - -function _recaptcha_aes_encrypt($val,$ky) { - if (! function_exists ("mcrypt_encrypt")) { - die ("To use reCAPTCHA Mailhide, you need to have the mcrypt php module installed."); - } - $mode=MCRYPT_MODE_CBC; - $enc=MCRYPT_RIJNDAEL_128; - $val=_recaptcha_aes_pad($val); - return mcrypt_encrypt($enc, $ky, $val, $mode, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"); -} - - -function _recaptcha_mailhide_urlbase64 ($x) { - return strtr(base64_encode ($x), '+/', '-_'); -} - -/* gets the reCAPTCHA Mailhide url for a given email, public key and private key */ -function recaptcha_mailhide_url($pubkey, $privkey, $email) { - if ($pubkey == '' || $pubkey == null || $privkey == "" || $privkey == null) { - die ("To use reCAPTCHA Mailhide, you have to sign up for a public and private key, " . - "you can do so at http://www.google.com/recaptcha/mailhide/apikey"); - } - - - $ky = pack('H*', $privkey); - $cryptmail = _recaptcha_aes_encrypt ($email, $ky); - - return "http://www.google.com/recaptcha/mailhide/d?k=" . $pubkey . "&c=" . _recaptcha_mailhide_urlbase64 ($cryptmail); -} - -/** - * gets the parts of the email to expose to the user. - * eg, given johndoe@example,com return ["john", "example.com"]. - * the email is then displayed as john...@example.com - */ -function _recaptcha_mailhide_email_parts ($email) { - $arr = preg_split("/@/", $email ); - - if (strlen ($arr[0]) <= 4) { - $arr[0] = substr ($arr[0], 0, 1); - } else if (strlen ($arr[0]) <= 6) { - $arr[0] = substr ($arr[0], 0, 3); - } else { - $arr[0] = substr ($arr[0], 0, 4); - } - return $arr; -} - -/** - * Gets html to display an email address given a public an private key. - * to get a key, go to: - * - * http://www.google.com/recaptcha/mailhide/apikey - */ -function recaptcha_mailhide_html($pubkey, $privkey, $email) { - $emailparts = _recaptcha_mailhide_email_parts ($email); - $url = recaptcha_mailhide_url ($pubkey, $privkey, $email); - - return htmlentities($emailparts[0]) . "...@" . htmlentities ($emailparts [1]); - -} \ No newline at end of file diff --git a/lib/copy_this/www/pages/contact-us.php b/lib/copy_this/www/pages/contact-us.php index 349341e9a..588ee86ba 100644 --- a/lib/copy_this/www/pages/contact-us.php +++ b/lib/copy_this/www/pages/contact-us.php @@ -2,33 +2,31 @@ use newznab\utility\Utility; -if (isset($_POST["useremail"])) -{ +if (isset($_POST["useremail"])) { // // send the contact info and report back to user. // - $email = $_POST["useremail"]; - $mailto = $page->site->email; - $mailsubj = "Contact Form Submitted"; - $mailhead = "From: $email\n"; - $mailbody = "Values submitted from contact form:\n"; + if ($page->captcha->getError() === false) { + $email = $_POST["useremail"]; + $mailto = $page->site->email; + $mailsubj = "Contact Form Submitted"; + $mailhead = "From: $email\n"; + $mailbody = "Values submitted from contact form:\n"; - while (list ($key, $val) = each ($_POST)) - { - if ($key != "submit") { - $mailbody .= "$key : $val
\r\n"; + while (list ($key, $val) = each($_POST)) { + if ($key != "submit") { + $mailbody .= "$key : $val
\r\n"; + } } - } - if (!preg_match("/\n/i",$_POST["useremail"])) - { - Utility::sendEmail($mailto, $mailsubj, $mailbody, $email); - } + if (!preg_match("/\n/i", $_POST["useremail"])) { + Utility::sendEmail($mailto, $mailsubj, $mailbody, $email); + } - $page->smarty->assign("msg", "

Thanks for getting in touch with ".$page->site->title.".

"); + $page->smarty->assign("msg", "

Thanks for getting in touch with " . $page->site->title . ".

"); + } } - $page->title = "Contact ".$page->site->title; $page->meta_title = "Contact ".$page->site->title; $page->meta_keywords = "contact us,contact,get in touch,email"; diff --git a/lib/copy_this/www/pages/forgottenpassword.php b/lib/copy_this/www/pages/forgottenpassword.php index 2a89762ac..260645f61 100644 --- a/lib/copy_this/www/pages/forgottenpassword.php +++ b/lib/copy_this/www/pages/forgottenpassword.php @@ -7,23 +7,18 @@ if ($users->isLoggedIn()) $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : 'view'; -switch($action) -{ +switch($action) { case "reset": - if (!isset($_REQUEST['guid'])) - { + if (!isset($_REQUEST['guid'])) { $page->smarty->assign('error', "No reset code provided."); break; } $ret = $users->getByPassResetGuid($_REQUEST['guid']); - if (!$ret) - { + if (!$ret) { $page->smarty->assign('error', "Bad reset code provided."); break; - } - else - { + } else { // // reset the password, inform the user, send out the email // @@ -32,8 +27,8 @@ switch($action) $users->updatePassword($ret["id"], $newpass); $to = $ret["email"]; - $subject = $page->site->title." Password Reset"; - $contents = "Your password has been reset to ".$newpass; + $subject = $page->site->title . " Password Reset"; + $contents = "Your password has been reset to " . $newpass; Utility::sendEmail($to, $subject, $contents, $page->site->email); $page->smarty->assign('confirmed', "true"); @@ -44,43 +39,39 @@ switch($action) break; case 'submit': - $page->smarty->assign('email', $_POST['email']); + if ($page->captcha->getError() === false) { + $page->smarty->assign('email', $_POST['email']); - if ($_POST['email'] =="") - { - $page->smarty->assign('error', "Missing Email"); - } - else - { - // - // Check users exists and send an email - // - $ret = $users->getByEmail($_POST['email']); - if (!$ret) - { - $page->smarty->assign('error', "The email address is not recognised."); - break; - } - else - { + if ($_POST['email'] == "") { + $page->smarty->assign('error', "Missing Email"); + } else { // - // Generate a forgottenpassword guid, store it in the user table + // Check users exists and send an email // - $guid = md5(uniqid()); - $users->updatePassResetGuid($ret["id"], $guid); + $ret = $users->getByEmail($_POST['email']); + if (!$ret) { + $page->smarty->assign('error', "The email address is not recognised."); + break; + } else { + // + // Generate a forgottenpassword guid, store it in the user table + // + $guid = md5(uniqid()); + $users->updatePassResetGuid($ret["id"], $guid); - // - // Send the email - // - $to = $ret["email"]; - $subject = $page->site->title." Forgotten Password Request"; - $contents = "Someone has requested a password reset for this email address. To reset the password use the following link.\n\n ".$page->serverurl."forgottenpassword?action=reset&guid=".$guid; - $page->smarty->assign('sent', "true"); - Utility::sendEmail($to, $subject, $contents, $page->site->email); - break; + // + // Send the email + // + $to = $ret["email"]; + $subject = $page->site->title . " Forgotten Password Request"; + $contents = "Someone has requested a password reset for this email address. To reset the password use the following link.\n\n " . $page->serverurl . "forgottenpassword?action=reset&guid=" . $guid; + $page->smarty->assign('sent', "true"); + Utility::sendEmail($to, $subject, $contents, $page->site->email); + break; + } } + break; } - break; } $page->title = "Forgotten Password"; diff --git a/lib/copy_this/www/pages/login.php b/lib/copy_this/www/pages/login.php index b8bd69547..496fdfb49 100644 --- a/lib/copy_this/www/pages/login.php +++ b/lib/copy_this/www/pages/login.php @@ -2,10 +2,9 @@ if ($page->isPostBack()) { - if (!isset($_POST["username"]) || !isset($_POST["password"])) + if (!isset($_POST["username"]) || !isset($_POST["password"])){ $page->smarty->assign('error', "Please enter your username and password."); - else - { +} elseif ($page->captcha->getError() === false) { $username = htmlspecialchars($_POST["username"]); $page->smarty->assign('username', $username); $users = new Users(); diff --git a/lib/copy_this/www/pages/register.php b/lib/copy_this/www/pages/register.php index 1c1e5ad51..e68b4b8fc 100644 --- a/lib/copy_this/www/pages/register.php +++ b/lib/copy_this/www/pages/register.php @@ -16,11 +16,11 @@ elseif ($page->site->registerstatus == Sites::REGISTER_STATUS_INVITE && (!isset( $showregister = 0; } -// Use recaptcha? -if ($page->site->registerrecaptcha == 1) +// Use recaptcha? 11.05.2015 - Old code +/*if ($page->site->registerrecaptcha == 1) { $page->smarty->assign('recaptcha', recaptcha_get_html($page->site->recaptchapublickey, null, $page->secure_connection)); -} +}*/ if ($showregister == 0) { @@ -30,61 +30,69 @@ else { $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : 'view'; + //Be sure to persist the invite code in the event of multiple form submissions. (errors) + if (isset($_REQUEST['invitecode'])) { + $page->smarty->assign('invite_code_query', '&invitecode='.htmlspecialchars($_REQUEST["invitecode"])); + } else { + $page->smarty->assign('invite_code_query', ''); + } + switch ($action) { case 'submit': + if ($page->captcha->getError() === false) { + $username = htmlspecialchars($_POST['username']); + $password = htmlspecialchars($_POST['password']); + $confirmpassword = htmlspecialchars($_POST['confirmpassword']); + $email = htmlspecialchars($_POST['email']); + $invitecode = htmlspecialchars($_POST['invitecode']); - $username = htmlspecialchars($_POST['username']); - $password = htmlspecialchars($_POST['password']); - $confirmpassword = htmlspecialchars($_POST['confirmpassword']); - $email = htmlspecialchars($_POST['email']); - $invitecode = htmlspecialchars($_POST['invitecode']); + $page->smarty->assign('username', $username); + $page->smarty->assign('password', $password); + $page->smarty->assign('confirmpassword', $confirmpassword); + $page->smarty->assign('email', $email); + $page->smarty->assign('invitecode', $invitecode); - $page->smarty->assign('username', $username); - $page->smarty->assign('password', $password); - $page->smarty->assign('confirmpassword', $confirmpassword); - $page->smarty->assign('email', $email); - $page->smarty->assign('invitecode', $invitecode); - - // - // check uname/email isnt in use, password valid. - // if all good create new user account and redirect back to home page - // - if ($password != $confirmpassword) { - $page->smarty->assign('error', "Password Mismatch"); - } else { - //get the default user role - $userdefault = $users->getDefaultRole(); - - $ret = $users->signup($username, $password, $email, $_SERVER['REMOTE_ADDR'], $userdefault['id'], "", $userdefault['defaultinvites'], $invitecode, false, isset($_POST['recaptcha_challenge_field']) ? $_POST['recaptcha_challenge_field'] : null, isset($_POST['recaptcha_response_field']) ? $_POST['recaptcha_response_field'] : null); - if ($ret > 0) { - $users->login($ret, $_SERVER['REMOTE_ADDR']); - header("Location: " . WWW_TOP . "/"); + // + // check uname/email isnt in use, password valid. + // if all good create new user account and redirect back to home page + // + if ($password != $confirmpassword) { + $page->smarty->assign('error', "Password Mismatch"); } else { - switch ($ret) { - case Users::ERR_SIGNUP_BADUNAME: - $page->smarty->assign('error', "Your username must be longer than three characters."); - break; - case Users::ERR_SIGNUP_BADPASS: - $page->smarty->assign('error', "Your password must be longer than five characters."); - break; - case Users::ERR_SIGNUP_BADEMAIL: - $page->smarty->assign('error', "Your email is not a valid format."); - break; - case Users::ERR_SIGNUP_UNAMEINUSE: - $page->smarty->assign('error', "Sorry, the username is already taken."); - break; - case Users::ERR_SIGNUP_EMAILINUSE: - $page->smarty->assign('error', "Sorry, the email is already in use."); - break; - case Users::ERR_SIGNUP_BADINVITECODE: - $page->smarty->assign('error', "Sorry, the invite code is old or has been used."); - break; - case Users::ERR_SIGNUP_BADCAPTCHA: - $page->smarty->assign('error', "Sorry, your captcha code was incorrect."); - break; - default: - $page->smarty->assign('error', "Failed to register."); - break; + //get the default user role + $userdefault = $users->getDefaultRole(); + + $ret = $users->signup($username, $password, $email, $_SERVER['REMOTE_ADDR'], $userdefault['id'], "", $userdefault['defaultinvites'], $invitecode, false, isset($_POST['recaptcha_challenge_field']) ? $_POST['recaptcha_challenge_field'] : null, isset($_POST['recaptcha_response_field']) ? $_POST['recaptcha_response_field'] : null); + if ($ret > 0) { + $users->login($ret, $_SERVER['REMOTE_ADDR']); + header("Location: " . WWW_TOP . "/"); + } else { + switch ($ret) { + case Users::ERR_SIGNUP_BADUNAME: + $page->smarty->assign('error', "Your username must be longer than three characters."); + break; + case Users::ERR_SIGNUP_BADPASS: + $page->smarty->assign('error', "Your password must be longer than five characters."); + break; + case Users::ERR_SIGNUP_BADEMAIL: + $page->smarty->assign('error', "Your email is not a valid format."); + break; + case Users::ERR_SIGNUP_UNAMEINUSE: + $page->smarty->assign('error', "Sorry, the username is already taken."); + break; + case Users::ERR_SIGNUP_EMAILINUSE: + $page->smarty->assign('error', "Sorry, the email is already in use."); + break; + case Users::ERR_SIGNUP_BADINVITECODE: + $page->smarty->assign('error', "Sorry, the invite code is old or has been used."); + break; + case Users::ERR_SIGNUP_BADCAPTCHA: + $page->smarty->assign('error', "Sorry, your captcha code was incorrect."); + break; + default: + $page->smarty->assign('error', "Failed to register."); + break; + } } } } diff --git a/lib/copy_this/www/templates/nntmux/views/frontend/captcha.tpl b/lib/copy_this/www/templates/nntmux/views/frontend/captcha.tpl new file mode 100644 index 000000000..17c4483d9 --- /dev/null +++ b/lib/copy_this/www/templates/nntmux/views/frontend/captcha.tpl @@ -0,0 +1,7 @@ +{if $showCaptcha == true} +
+ +
+{/if} \ No newline at end of file diff --git a/lib/copy_this/www/templates/nntmux/views/frontend/contact.tpl b/lib/copy_this/www/templates/nntmux/views/frontend/contact.tpl index 66b172d4c..774ed7fd6 100644 --- a/lib/copy_this/www/templates/nntmux/views/frontend/contact.tpl +++ b/lib/copy_this/www/templates/nntmux/views/frontend/contact.tpl @@ -1,4 +1,4 @@ - +

{$page->title}

Getting in touch

@@ -13,7 +13,7 @@

Alternatively use our contact form to get in touch.

- +
@@ -37,6 +37,7 @@ diff --git a/lib/copy_this/www/templates/nntmux/views/frontend/forgottenpassword.tpl b/lib/copy_this/www/templates/nntmux/views/frontend/forgottenpassword.tpl index b6f90e092..1084fbc4c 100644 --- a/lib/copy_this/www/templates/nntmux/views/frontend/forgottenpassword.tpl +++ b/lib/copy_this/www/templates/nntmux/views/frontend/forgottenpassword.tpl @@ -1,4 +1,4 @@ - +

{$page->title}

{if $error != ''} @@ -18,7 +18,7 @@ - +
+ {$page->smarty->fetch('captcha.tpl')}
* Indicates mandatory field.
{$page->smarty->fetch('captcha.tpl')}
* Indicates mandatory field.
{elseif $sent != ''} diff --git a/lib/copy_this/www/templates/nntmux/views/frontend/login.tpl b/lib/copy_this/www/templates/nntmux/views/frontend/login.tpl index aabe6f05e..fafa2f19a 100644 --- a/lib/copy_this/www/templates/nntmux/views/frontend/login.tpl +++ b/lib/copy_this/www/templates/nntmux/views/frontend/login.tpl @@ -17,7 +17,7 @@ - + {$page->smarty->fetch('captcha.tpl')}
diff --git a/lib/copy_this/www/templates/nntmux/views/frontend/register.tpl b/lib/copy_this/www/templates/nntmux/views/frontend/register.tpl index c66bd8113..592ddd212 100644 --- a/lib/copy_this/www/templates/nntmux/views/frontend/register.tpl +++ b/lib/copy_this/www/templates/nntmux/views/frontend/register.tpl @@ -6,7 +6,7 @@ {/if} {if $showregister != "0"} -
+ @@ -27,7 +27,7 @@
*
- +
* Indicates mandatory field.
{$page->smarty->fetch('captcha.tpl')}
* Indicates mandatory field.