Add forgot password feature
This commit is contained in:
@@ -2,8 +2,6 @@
|
||||
|
||||
namespace Kanboard\Controller;
|
||||
|
||||
use Gregwar\Captcha\CaptchaBuilder;
|
||||
|
||||
/**
|
||||
* Authentication controller
|
||||
*
|
||||
@@ -61,21 +59,6 @@ class Auth extends Base
|
||||
$this->response->redirect($this->helper->url->to('auth', 'login'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Display captcha image
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function captcha()
|
||||
{
|
||||
$this->response->contentType('image/jpeg');
|
||||
|
||||
$builder = new CaptchaBuilder;
|
||||
$builder->build();
|
||||
$this->sessionStorage->captcha = $builder->getPhrase();
|
||||
$builder->output();
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect the user after the authentication
|
||||
*
|
||||
|
||||
29
app/Controller/Captcha.php
Normal file
29
app/Controller/Captcha.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Controller;
|
||||
|
||||
use Gregwar\Captcha\CaptchaBuilder;
|
||||
|
||||
/**
|
||||
* Captcha Controller
|
||||
*
|
||||
* @package controller
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class Captcha extends Base
|
||||
{
|
||||
/**
|
||||
* Display captcha image
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function image()
|
||||
{
|
||||
$this->response->contentType('image/jpeg');
|
||||
|
||||
$builder = new CaptchaBuilder;
|
||||
$builder->build();
|
||||
$this->sessionStorage->captcha = $builder->getPhrase();
|
||||
$builder->output();
|
||||
}
|
||||
}
|
||||
@@ -40,6 +40,9 @@ class Config extends Base
|
||||
$values = $this->request->getValues();
|
||||
|
||||
switch ($redirect) {
|
||||
case 'application':
|
||||
$values += array('password_reset' => 0);
|
||||
break;
|
||||
case 'project':
|
||||
$values += array('subtask_restriction' => 0, 'subtask_time_tracking' => 0, 'cfd_include_closed_tasks' => 0);
|
||||
break;
|
||||
|
||||
120
app/Controller/PasswordReset.php
Normal file
120
app/Controller/PasswordReset.php
Normal file
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Controller;
|
||||
|
||||
/**
|
||||
* Password Reset Controller
|
||||
*
|
||||
* @package controller
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class PasswordReset extends Base
|
||||
{
|
||||
/**
|
||||
* Show the form to reset the password
|
||||
*/
|
||||
public function create(array $values = array(), array $errors = array())
|
||||
{
|
||||
$this->checkActivation();
|
||||
|
||||
$this->response->html($this->template->layout('password_reset/create', array(
|
||||
'errors' => $errors,
|
||||
'values' => $values,
|
||||
'no_layout' => true,
|
||||
)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate and send the email
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
$this->checkActivation();
|
||||
|
||||
$values = $this->request->getValues();
|
||||
list($valid, $errors) = $this->passwordResetValidator->validateCreation($values);
|
||||
|
||||
if ($valid) {
|
||||
$this->sendEmail($values['username']);
|
||||
$this->response->redirect($this->helper->url->to('auth', 'login'));
|
||||
}
|
||||
|
||||
$this->create($values, $errors);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form to set a new password
|
||||
*/
|
||||
public function change(array $values = array(), array $errors = array())
|
||||
{
|
||||
$this->checkActivation();
|
||||
|
||||
$token = $this->request->getStringParam('token');
|
||||
$user_id = $this->passwordReset->getUserIdByToken($token);
|
||||
|
||||
if ($user_id !== false) {
|
||||
$this->response->html($this->template->layout('password_reset/change', array(
|
||||
'token' => $token,
|
||||
'errors' => $errors,
|
||||
'values' => $values,
|
||||
'no_layout' => true,
|
||||
)));
|
||||
}
|
||||
|
||||
$this->response->redirect($this->helper->url->to('auth', 'login'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the new password
|
||||
*/
|
||||
public function update(array $values = array(), array $errors = array())
|
||||
{
|
||||
$this->checkActivation();
|
||||
|
||||
$token = $this->request->getStringParam('token');
|
||||
$values = $this->request->getValues();
|
||||
list($valid, $errors) = $this->passwordResetValidator->validateModification($values);
|
||||
|
||||
if ($valid) {
|
||||
$user_id = $this->passwordReset->getUserIdByToken($token);
|
||||
|
||||
if ($user_id !== false) {
|
||||
$this->user->update(array('id' => $user_id, 'password' => $values['password']));
|
||||
$this->passwordReset->disable($user_id);
|
||||
}
|
||||
|
||||
$this->response->redirect($this->helper->url->to('auth', 'login'));
|
||||
}
|
||||
|
||||
$this->change($values, $errors);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the email
|
||||
*/
|
||||
private function sendEmail($username)
|
||||
{
|
||||
$token = $this->passwordReset->create($username);
|
||||
|
||||
if ($token !== false) {
|
||||
$user = $this->user->getByUsername($username);
|
||||
|
||||
$this->emailClient->send(
|
||||
$user['email'],
|
||||
$user['name'] ?: $user['username'],
|
||||
t('Password Reset for Kanboard'),
|
||||
$this->template->render('password_reset/email', array('token' => $token))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check feature availability
|
||||
*/
|
||||
private function checkActivation()
|
||||
{
|
||||
if ($this->config->get('password_reset', 0) == 0) {
|
||||
$this->response->redirect($this->helper->url->to('auth', 'login'));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -172,6 +172,20 @@ class User extends Base
|
||||
)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Display last password reset
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function passwordReset()
|
||||
{
|
||||
$user = $this->getUser();
|
||||
$this->response->html($this->layout('user/password_reset', array(
|
||||
'tokens' => $this->passwordReset->getAll($user['id']),
|
||||
'user' => $user,
|
||||
)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Display last connections
|
||||
*
|
||||
|
||||
@@ -69,6 +69,7 @@ use Pimple\Container;
|
||||
* @property \Kanboard\Model\Link $link
|
||||
* @property \Kanboard\Model\Notification $notification
|
||||
* @property \Kanboard\Model\OverdueNotification $overdueNotification
|
||||
* @property \Kanboard\Model\PasswordReset $passwordReset
|
||||
* @property \Kanboard\Model\Project $project
|
||||
* @property \Kanboard\Model\ProjectActivity $projectActivity
|
||||
* @property \Kanboard\Model\ProjectAnalytic $projectAnalytic
|
||||
@@ -112,6 +113,7 @@ use Pimple\Container;
|
||||
* @property \Kanboard\Model\UserUnreadNotification $userUnreadNotification
|
||||
* @property \Kanboard\Model\UserMetadata $userMetadata
|
||||
* @property \Kanboard\Model\Webhook $webhook
|
||||
* @property \Kanboard\Validator\PasswordResetValidator $passwordResetValidator
|
||||
* @property \Psr\Log\LoggerInterface $logger
|
||||
* @property \PicoDb\Database $db
|
||||
* @property \Symfony\Component\EventDispatcher\EventDispatcher $dispatcher
|
||||
|
||||
@@ -12,6 +12,18 @@ use Kanboard\Core\Base;
|
||||
*/
|
||||
class App extends Base
|
||||
{
|
||||
/**
|
||||
* Get config variable
|
||||
*
|
||||
* @access public
|
||||
* @param string $param
|
||||
* @return mixed
|
||||
*/
|
||||
public function config($param)
|
||||
{
|
||||
return $this->config->get($param);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sidebar menu active
|
||||
*
|
||||
|
||||
@@ -1086,4 +1086,16 @@ return array(
|
||||
// 'Disable two-factor authentication' => '',
|
||||
// 'Enable two-factor authentication' => '',
|
||||
// 'There is no integration registered at the moment.' => '',
|
||||
// 'Password Reset for Kanboard' => '',
|
||||
// 'Forgot password?' => '',
|
||||
// 'Enable "Forget Password"' => '',
|
||||
// 'Password Reset' => '',
|
||||
// 'New password' => '',
|
||||
// 'Change Password' => '',
|
||||
// 'To reset your password click on this link:' => '',
|
||||
// 'Last Password Reset' => '',
|
||||
// 'The password has never been reinitialized.' => '',
|
||||
// 'Creation' => '',
|
||||
// 'Expiration' => '',
|
||||
// 'Password reset history' => '',
|
||||
);
|
||||
|
||||
@@ -1086,4 +1086,16 @@ return array(
|
||||
// 'Disable two-factor authentication' => '',
|
||||
// 'Enable two-factor authentication' => '',
|
||||
// 'There is no integration registered at the moment.' => '',
|
||||
// 'Password Reset for Kanboard' => '',
|
||||
// 'Forgot password?' => '',
|
||||
// 'Enable "Forget Password"' => '',
|
||||
// 'Password Reset' => '',
|
||||
// 'New password' => '',
|
||||
// 'Change Password' => '',
|
||||
// 'To reset your password click on this link:' => '',
|
||||
// 'Last Password Reset' => '',
|
||||
// 'The password has never been reinitialized.' => '',
|
||||
// 'Creation' => '',
|
||||
// 'Expiration' => '',
|
||||
// 'Password reset history' => '',
|
||||
);
|
||||
|
||||
@@ -1086,4 +1086,16 @@ return array(
|
||||
// 'Disable two-factor authentication' => '',
|
||||
// 'Enable two-factor authentication' => '',
|
||||
// 'There is no integration registered at the moment.' => '',
|
||||
// 'Password Reset for Kanboard' => '',
|
||||
// 'Forgot password?' => '',
|
||||
// 'Enable "Forget Password"' => '',
|
||||
// 'Password Reset' => '',
|
||||
// 'New password' => '',
|
||||
// 'Change Password' => '',
|
||||
// 'To reset your password click on this link:' => '',
|
||||
// 'Last Password Reset' => '',
|
||||
// 'The password has never been reinitialized.' => '',
|
||||
// 'Creation' => '',
|
||||
// 'Expiration' => '',
|
||||
// 'Password reset history' => '',
|
||||
);
|
||||
|
||||
@@ -1086,4 +1086,16 @@ return array(
|
||||
// 'Disable two-factor authentication' => '',
|
||||
// 'Enable two-factor authentication' => '',
|
||||
// 'There is no integration registered at the moment.' => '',
|
||||
// 'Password Reset for Kanboard' => '',
|
||||
// 'Forgot password?' => '',
|
||||
// 'Enable "Forget Password"' => '',
|
||||
// 'Password Reset' => '',
|
||||
// 'New password' => '',
|
||||
// 'Change Password' => '',
|
||||
// 'To reset your password click on this link:' => '',
|
||||
// 'Last Password Reset' => '',
|
||||
// 'The password has never been reinitialized.' => '',
|
||||
// 'Creation' => '',
|
||||
// 'Expiration' => '',
|
||||
// 'Password reset history' => '',
|
||||
);
|
||||
|
||||
@@ -1086,4 +1086,16 @@ return array(
|
||||
// 'Disable two-factor authentication' => '',
|
||||
// 'Enable two-factor authentication' => '',
|
||||
// 'There is no integration registered at the moment.' => '',
|
||||
// 'Password Reset for Kanboard' => '',
|
||||
// 'Forgot password?' => '',
|
||||
// 'Enable "Forget Password"' => '',
|
||||
// 'Password Reset' => '',
|
||||
// 'New password' => '',
|
||||
// 'Change Password' => '',
|
||||
// 'To reset your password click on this link:' => '',
|
||||
// 'Last Password Reset' => '',
|
||||
// 'The password has never been reinitialized.' => '',
|
||||
// 'Creation' => '',
|
||||
// 'Expiration' => '',
|
||||
// 'Password reset history' => '',
|
||||
);
|
||||
|
||||
@@ -1086,4 +1086,16 @@ return array(
|
||||
// 'Disable two-factor authentication' => '',
|
||||
// 'Enable two-factor authentication' => '',
|
||||
// 'There is no integration registered at the moment.' => '',
|
||||
// 'Password Reset for Kanboard' => '',
|
||||
// 'Forgot password?' => '',
|
||||
// 'Enable "Forget Password"' => '',
|
||||
// 'Password Reset' => '',
|
||||
// 'New password' => '',
|
||||
// 'Change Password' => '',
|
||||
// 'To reset your password click on this link:' => '',
|
||||
// 'Last Password Reset' => '',
|
||||
// 'The password has never been reinitialized.' => '',
|
||||
// 'Creation' => '',
|
||||
// 'Expiration' => '',
|
||||
// 'Password reset history' => '',
|
||||
);
|
||||
|
||||
@@ -1089,4 +1089,16 @@ return array(
|
||||
'Disable two-factor authentication' => 'Désactiver l\'authentification à deux-facteurs',
|
||||
'Enable two-factor authentication' => 'Activer l\'authentification à deux-facteurs',
|
||||
'There is no integration registered at the moment.' => 'Il n\'y a aucune intégration enregistrée pour le moment.',
|
||||
'Password Reset for Kanboard' => 'Réinitialisation du mot de passe pour Kanboard',
|
||||
'Forgot password?' => 'Mot de passe oublié ?',
|
||||
'Enable "Forget Password"' => 'Activer la fonctionnalité « Mot de passe oublié »',
|
||||
'Password Reset' => 'Réinitialisation du mot de passe',
|
||||
'New password' => 'Nouveau mot de passe',
|
||||
'Change Password' => 'Changer de mot de passe',
|
||||
'To reset your password click on this link:' => 'Pour réinitialiser votre mot de passe cliquer sur ce lien :',
|
||||
'Last Password Reset' => 'Dernières réinitialisation de mot de passe',
|
||||
'The password has never been reinitialized.' => 'Le mot de passe n\'a jamais été réinitialisé.',
|
||||
'Creation' => 'Création',
|
||||
'Expiration' => 'Expiration',
|
||||
'Password reset history' => 'Historique de la réinitialisation du mot de passe',
|
||||
);
|
||||
|
||||
@@ -1086,4 +1086,16 @@ return array(
|
||||
// 'Disable two-factor authentication' => '',
|
||||
// 'Enable two-factor authentication' => '',
|
||||
// 'There is no integration registered at the moment.' => '',
|
||||
// 'Password Reset for Kanboard' => '',
|
||||
// 'Forgot password?' => '',
|
||||
// 'Enable "Forget Password"' => '',
|
||||
// 'Password Reset' => '',
|
||||
// 'New password' => '',
|
||||
// 'Change Password' => '',
|
||||
// 'To reset your password click on this link:' => '',
|
||||
// 'Last Password Reset' => '',
|
||||
// 'The password has never been reinitialized.' => '',
|
||||
// 'Creation' => '',
|
||||
// 'Expiration' => '',
|
||||
// 'Password reset history' => '',
|
||||
);
|
||||
|
||||
@@ -1086,4 +1086,16 @@ return array(
|
||||
// 'Disable two-factor authentication' => '',
|
||||
// 'Enable two-factor authentication' => '',
|
||||
// 'There is no integration registered at the moment.' => '',
|
||||
// 'Password Reset for Kanboard' => '',
|
||||
// 'Forgot password?' => '',
|
||||
// 'Enable "Forget Password"' => '',
|
||||
// 'Password Reset' => '',
|
||||
// 'New password' => '',
|
||||
// 'Change Password' => '',
|
||||
// 'To reset your password click on this link:' => '',
|
||||
// 'Last Password Reset' => '',
|
||||
// 'The password has never been reinitialized.' => '',
|
||||
// 'Creation' => '',
|
||||
// 'Expiration' => '',
|
||||
// 'Password reset history' => '',
|
||||
);
|
||||
|
||||
@@ -1086,4 +1086,16 @@ return array(
|
||||
// 'Disable two-factor authentication' => '',
|
||||
// 'Enable two-factor authentication' => '',
|
||||
// 'There is no integration registered at the moment.' => '',
|
||||
// 'Password Reset for Kanboard' => '',
|
||||
// 'Forgot password?' => '',
|
||||
// 'Enable "Forget Password"' => '',
|
||||
// 'Password Reset' => '',
|
||||
// 'New password' => '',
|
||||
// 'Change Password' => '',
|
||||
// 'To reset your password click on this link:' => '',
|
||||
// 'Last Password Reset' => '',
|
||||
// 'The password has never been reinitialized.' => '',
|
||||
// 'Creation' => '',
|
||||
// 'Expiration' => '',
|
||||
// 'Password reset history' => '',
|
||||
);
|
||||
|
||||
@@ -1086,4 +1086,16 @@ return array(
|
||||
// 'Disable two-factor authentication' => '',
|
||||
// 'Enable two-factor authentication' => '',
|
||||
// 'There is no integration registered at the moment.' => '',
|
||||
// 'Password Reset for Kanboard' => '',
|
||||
// 'Forgot password?' => '',
|
||||
// 'Enable "Forget Password"' => '',
|
||||
// 'Password Reset' => '',
|
||||
// 'New password' => '',
|
||||
// 'Change Password' => '',
|
||||
// 'To reset your password click on this link:' => '',
|
||||
// 'Last Password Reset' => '',
|
||||
// 'The password has never been reinitialized.' => '',
|
||||
// 'Creation' => '',
|
||||
// 'Expiration' => '',
|
||||
// 'Password reset history' => '',
|
||||
);
|
||||
|
||||
@@ -1086,4 +1086,16 @@ return array(
|
||||
// 'Disable two-factor authentication' => '',
|
||||
// 'Enable two-factor authentication' => '',
|
||||
// 'There is no integration registered at the moment.' => '',
|
||||
// 'Password Reset for Kanboard' => '',
|
||||
// 'Forgot password?' => '',
|
||||
// 'Enable "Forget Password"' => '',
|
||||
// 'Password Reset' => '',
|
||||
// 'New password' => '',
|
||||
// 'Change Password' => '',
|
||||
// 'To reset your password click on this link:' => '',
|
||||
// 'Last Password Reset' => '',
|
||||
// 'The password has never been reinitialized.' => '',
|
||||
// 'Creation' => '',
|
||||
// 'Expiration' => '',
|
||||
// 'Password reset history' => '',
|
||||
);
|
||||
|
||||
@@ -1086,4 +1086,16 @@ return array(
|
||||
// 'Disable two-factor authentication' => '',
|
||||
// 'Enable two-factor authentication' => '',
|
||||
// 'There is no integration registered at the moment.' => '',
|
||||
// 'Password Reset for Kanboard' => '',
|
||||
// 'Forgot password?' => '',
|
||||
// 'Enable "Forget Password"' => '',
|
||||
// 'Password Reset' => '',
|
||||
// 'New password' => '',
|
||||
// 'Change Password' => '',
|
||||
// 'To reset your password click on this link:' => '',
|
||||
// 'Last Password Reset' => '',
|
||||
// 'The password has never been reinitialized.' => '',
|
||||
// 'Creation' => '',
|
||||
// 'Expiration' => '',
|
||||
// 'Password reset history' => '',
|
||||
);
|
||||
|
||||
@@ -1086,4 +1086,16 @@ return array(
|
||||
// 'Disable two-factor authentication' => '',
|
||||
// 'Enable two-factor authentication' => '',
|
||||
// 'There is no integration registered at the moment.' => '',
|
||||
// 'Password Reset for Kanboard' => '',
|
||||
// 'Forgot password?' => '',
|
||||
// 'Enable "Forget Password"' => '',
|
||||
// 'Password Reset' => '',
|
||||
// 'New password' => '',
|
||||
// 'Change Password' => '',
|
||||
// 'To reset your password click on this link:' => '',
|
||||
// 'Last Password Reset' => '',
|
||||
// 'The password has never been reinitialized.' => '',
|
||||
// 'Creation' => '',
|
||||
// 'Expiration' => '',
|
||||
// 'Password reset history' => '',
|
||||
);
|
||||
|
||||
@@ -1086,4 +1086,16 @@ return array(
|
||||
// 'Disable two-factor authentication' => '',
|
||||
// 'Enable two-factor authentication' => '',
|
||||
// 'There is no integration registered at the moment.' => '',
|
||||
// 'Password Reset for Kanboard' => '',
|
||||
// 'Forgot password?' => '',
|
||||
// 'Enable "Forget Password"' => '',
|
||||
// 'Password Reset' => '',
|
||||
// 'New password' => '',
|
||||
// 'Change Password' => '',
|
||||
// 'To reset your password click on this link:' => '',
|
||||
// 'Last Password Reset' => '',
|
||||
// 'The password has never been reinitialized.' => '',
|
||||
// 'Creation' => '',
|
||||
// 'Expiration' => '',
|
||||
// 'Password reset history' => '',
|
||||
);
|
||||
|
||||
@@ -1086,4 +1086,16 @@ return array(
|
||||
// 'Disable two-factor authentication' => '',
|
||||
// 'Enable two-factor authentication' => '',
|
||||
// 'There is no integration registered at the moment.' => '',
|
||||
// 'Password Reset for Kanboard' => '',
|
||||
// 'Forgot password?' => '',
|
||||
// 'Enable "Forget Password"' => '',
|
||||
// 'Password Reset' => '',
|
||||
// 'New password' => '',
|
||||
// 'Change Password' => '',
|
||||
// 'To reset your password click on this link:' => '',
|
||||
// 'Last Password Reset' => '',
|
||||
// 'The password has never been reinitialized.' => '',
|
||||
// 'Creation' => '',
|
||||
// 'Expiration' => '',
|
||||
// 'Password reset history' => '',
|
||||
);
|
||||
|
||||
@@ -1086,4 +1086,16 @@ return array(
|
||||
// 'Disable two-factor authentication' => '',
|
||||
// 'Enable two-factor authentication' => '',
|
||||
// 'There is no integration registered at the moment.' => '',
|
||||
// 'Password Reset for Kanboard' => '',
|
||||
// 'Forgot password?' => '',
|
||||
// 'Enable "Forget Password"' => '',
|
||||
// 'Password Reset' => '',
|
||||
// 'New password' => '',
|
||||
// 'Change Password' => '',
|
||||
// 'To reset your password click on this link:' => '',
|
||||
// 'Last Password Reset' => '',
|
||||
// 'The password has never been reinitialized.' => '',
|
||||
// 'Creation' => '',
|
||||
// 'Expiration' => '',
|
||||
// 'Password reset history' => '',
|
||||
);
|
||||
|
||||
@@ -1086,4 +1086,16 @@ return array(
|
||||
// 'Disable two-factor authentication' => '',
|
||||
// 'Enable two-factor authentication' => '',
|
||||
// 'There is no integration registered at the moment.' => '',
|
||||
// 'Password Reset for Kanboard' => '',
|
||||
// 'Forgot password?' => '',
|
||||
// 'Enable "Forget Password"' => '',
|
||||
// 'Password Reset' => '',
|
||||
// 'New password' => '',
|
||||
// 'Change Password' => '',
|
||||
// 'To reset your password click on this link:' => '',
|
||||
// 'Last Password Reset' => '',
|
||||
// 'The password has never been reinitialized.' => '',
|
||||
// 'Creation' => '',
|
||||
// 'Expiration' => '',
|
||||
// 'Password reset history' => '',
|
||||
);
|
||||
|
||||
@@ -1086,4 +1086,16 @@ return array(
|
||||
// 'Disable two-factor authentication' => '',
|
||||
// 'Enable two-factor authentication' => '',
|
||||
// 'There is no integration registered at the moment.' => '',
|
||||
// 'Password Reset for Kanboard' => '',
|
||||
// 'Forgot password?' => '',
|
||||
// 'Enable "Forget Password"' => '',
|
||||
// 'Password Reset' => '',
|
||||
// 'New password' => '',
|
||||
// 'Change Password' => '',
|
||||
// 'To reset your password click on this link:' => '',
|
||||
// 'Last Password Reset' => '',
|
||||
// 'The password has never been reinitialized.' => '',
|
||||
// 'Creation' => '',
|
||||
// 'Expiration' => '',
|
||||
// 'Password reset history' => '',
|
||||
);
|
||||
|
||||
@@ -1086,4 +1086,16 @@ return array(
|
||||
// 'Disable two-factor authentication' => '',
|
||||
// 'Enable two-factor authentication' => '',
|
||||
// 'There is no integration registered at the moment.' => '',
|
||||
// 'Password Reset for Kanboard' => '',
|
||||
// 'Forgot password?' => '',
|
||||
// 'Enable "Forget Password"' => '',
|
||||
// 'Password Reset' => '',
|
||||
// 'New password' => '',
|
||||
// 'Change Password' => '',
|
||||
// 'To reset your password click on this link:' => '',
|
||||
// 'Last Password Reset' => '',
|
||||
// 'The password has never been reinitialized.' => '',
|
||||
// 'Creation' => '',
|
||||
// 'Expiration' => '',
|
||||
// 'Password reset history' => '',
|
||||
);
|
||||
|
||||
@@ -1086,4 +1086,16 @@ return array(
|
||||
// 'Disable two-factor authentication' => '',
|
||||
// 'Enable two-factor authentication' => '',
|
||||
// 'There is no integration registered at the moment.' => '',
|
||||
// 'Password Reset for Kanboard' => '',
|
||||
// 'Forgot password?' => '',
|
||||
// 'Enable "Forget Password"' => '',
|
||||
// 'Password Reset' => '',
|
||||
// 'New password' => '',
|
||||
// 'Change Password' => '',
|
||||
// 'To reset your password click on this link:' => '',
|
||||
// 'Last Password Reset' => '',
|
||||
// 'The password has never been reinitialized.' => '',
|
||||
// 'Creation' => '',
|
||||
// 'Expiration' => '',
|
||||
// 'Password reset history' => '',
|
||||
);
|
||||
|
||||
@@ -1086,4 +1086,16 @@ return array(
|
||||
// 'Disable two-factor authentication' => '',
|
||||
// 'Enable two-factor authentication' => '',
|
||||
// 'There is no integration registered at the moment.' => '',
|
||||
// 'Password Reset for Kanboard' => '',
|
||||
// 'Forgot password?' => '',
|
||||
// 'Enable "Forget Password"' => '',
|
||||
// 'Password Reset' => '',
|
||||
// 'New password' => '',
|
||||
// 'Change Password' => '',
|
||||
// 'To reset your password click on this link:' => '',
|
||||
// 'Last Password Reset' => '',
|
||||
// 'The password has never been reinitialized.' => '',
|
||||
// 'Creation' => '',
|
||||
// 'Expiration' => '',
|
||||
// 'Password reset history' => '',
|
||||
);
|
||||
|
||||
93
app/Model/PasswordReset.php
Normal file
93
app/Model/PasswordReset.php
Normal file
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Model;
|
||||
|
||||
/**
|
||||
* Password Reset Model
|
||||
*
|
||||
* @package model
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class PasswordReset extends Base
|
||||
{
|
||||
/**
|
||||
* SQL table name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const TABLE = 'password_reset';
|
||||
|
||||
/**
|
||||
* Token duration (30 minutes)
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const DURATION = 1800;
|
||||
|
||||
/**
|
||||
* Get all tokens
|
||||
*
|
||||
* @access public
|
||||
* @param integer $user_id
|
||||
* @return array
|
||||
*/
|
||||
public function getAll($user_id)
|
||||
{
|
||||
return $this->db->table(self::TABLE)->eq('user_id', $user_id)->desc('date_creation')->limit(100)->findAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a new reset token for a user
|
||||
*
|
||||
* @access public
|
||||
* @param string $username
|
||||
* @param integer $expiration
|
||||
* @return boolean|string
|
||||
*/
|
||||
public function create($username, $expiration = 0)
|
||||
{
|
||||
$user_id = $this->db->table(User::TABLE)->eq('username', $username)->neq('email', '')->notNull('email')->findOneColumn('id');
|
||||
|
||||
if (! $user_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$token = $this->token->getToken();
|
||||
|
||||
$result = $this->db->table(self::TABLE)->insert(array(
|
||||
'token' => $token,
|
||||
'user_id' => $user_id,
|
||||
'date_expiration' => $expiration ?: time() + self::DURATION,
|
||||
'date_creation' => time(),
|
||||
'ip' => $this->request->getIpAddress(),
|
||||
'user_agent' => $this->request->getUserAgent(),
|
||||
'is_active' => 1,
|
||||
));
|
||||
|
||||
return $result ? $token : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user id from the token
|
||||
*
|
||||
* @access public
|
||||
* @param string $token
|
||||
* @return integer
|
||||
*/
|
||||
public function getUserIdByToken($token)
|
||||
{
|
||||
return $this->db->table(self::TABLE)->eq('token', $token)->eq('is_active', 1)->gte('date_expiration', time())->findOneColumn('user_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable all tokens for a user
|
||||
*
|
||||
* @access public
|
||||
* @param integer $user_id
|
||||
* @return boolean
|
||||
*/
|
||||
public function disable($user_id)
|
||||
{
|
||||
return $this->db->table(self::TABLE)->eq('user_id', $user_id)->update(array('is_active' => 0));
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,25 @@ use PDO;
|
||||
use Kanboard\Core\Security\Token;
|
||||
use Kanboard\Core\Security\Role;
|
||||
|
||||
const VERSION = 100;
|
||||
const VERSION = 101;
|
||||
|
||||
function version_101(PDO $pdo)
|
||||
{
|
||||
$pdo->exec("
|
||||
CREATE TABLE password_reset (
|
||||
token VARCHAR(80) PRIMARY KEY,
|
||||
user_id INT NOT NULL,
|
||||
date_expiration INT NOT NULL,
|
||||
date_creation INT NOT NULL,
|
||||
ip VARCHAR(45) NOT NULL,
|
||||
user_agent VARCHAR(255) NOT NULL,
|
||||
is_active TINYINT(1) NOT NULL,
|
||||
FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB CHARSET=utf8
|
||||
");
|
||||
|
||||
$pdo->exec("INSERT INTO settings VALUES ('password_reset', '1')");
|
||||
}
|
||||
|
||||
function version_100(PDO $pdo)
|
||||
{
|
||||
@@ -1063,7 +1081,7 @@ function version_12(PDO $pdo)
|
||||
CREATE TABLE remember_me (
|
||||
id INT NOT NULL AUTO_INCREMENT,
|
||||
user_id INT,
|
||||
ip VARCHAR(40),
|
||||
ip VARCHAR(45),
|
||||
user_agent VARCHAR(255),
|
||||
token VARCHAR(255),
|
||||
sequence VARCHAR(255),
|
||||
@@ -1079,7 +1097,7 @@ function version_12(PDO $pdo)
|
||||
id INT NOT NULL AUTO_INCREMENT,
|
||||
auth_type VARCHAR(25),
|
||||
user_id INT,
|
||||
ip VARCHAR(40),
|
||||
ip VARCHAR(45),
|
||||
user_agent VARCHAR(255),
|
||||
date_creation INT,
|
||||
FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE,
|
||||
|
||||
@@ -6,7 +6,25 @@ use PDO;
|
||||
use Kanboard\Core\Security\Token;
|
||||
use Kanboard\Core\Security\Role;
|
||||
|
||||
const VERSION = 80;
|
||||
const VERSION = 81;
|
||||
|
||||
function version_81(PDO $pdo)
|
||||
{
|
||||
$pdo->exec("
|
||||
CREATE TABLE password_reset (
|
||||
token VARCHAR(80) PRIMARY KEY,
|
||||
user_id INTEGER NOT NULL,
|
||||
date_expiration INTEGER NOT NULL,
|
||||
date_creation INTEGER NOT NULL,
|
||||
ip VARCHAR(45) NOT NULL,
|
||||
user_agent VARCHAR(255) NOT NULL,
|
||||
is_active BOOLEAN NOT NULL,
|
||||
FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||
)
|
||||
");
|
||||
|
||||
$pdo->exec("INSERT INTO settings VALUES ('password_reset', '1')");
|
||||
}
|
||||
|
||||
function version_80(PDO $pdo)
|
||||
{
|
||||
@@ -983,7 +1001,7 @@ function version_1(PDO $pdo)
|
||||
CREATE TABLE remember_me (
|
||||
id SERIAL PRIMARY KEY,
|
||||
user_id INTEGER,
|
||||
ip VARCHAR(40),
|
||||
ip VARCHAR(45),
|
||||
user_agent VARCHAR(255),
|
||||
token VARCHAR(255),
|
||||
sequence VARCHAR(255),
|
||||
@@ -996,7 +1014,7 @@ function version_1(PDO $pdo)
|
||||
id SERIAL PRIMARY KEY,
|
||||
auth_type VARCHAR(25),
|
||||
user_id INTEGER,
|
||||
ip VARCHAR(40),
|
||||
ip VARCHAR(45),
|
||||
user_agent VARCHAR(255),
|
||||
date_creation INTEGER,
|
||||
FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||
|
||||
@@ -6,7 +6,25 @@ use Kanboard\Core\Security\Token;
|
||||
use Kanboard\Core\Security\Role;
|
||||
use PDO;
|
||||
|
||||
const VERSION = 92;
|
||||
const VERSION = 93;
|
||||
|
||||
function version_93(PDO $pdo)
|
||||
{
|
||||
$pdo->exec("
|
||||
CREATE TABLE password_reset (
|
||||
token TEXT PRIMARY KEY,
|
||||
user_id INTEGER NOT NULL,
|
||||
date_expiration INTEGER NOT NULL,
|
||||
date_creation INTEGER NOT NULL,
|
||||
ip TEXT NOT NULL,
|
||||
user_agent TEXT NOT NULL,
|
||||
is_active INTEGER NOT NULL,
|
||||
FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||
)
|
||||
");
|
||||
|
||||
$pdo->exec("INSERT INTO settings VALUES ('password_reset', '1')");
|
||||
}
|
||||
|
||||
function version_92(PDO $pdo)
|
||||
{
|
||||
|
||||
@@ -126,7 +126,9 @@ class AuthenticationProvider implements ServiceProviderInterface
|
||||
$acl->setRoleHierarchy(Role::APP_USER, array(Role::APP_PUBLIC));
|
||||
|
||||
$acl->add('Oauth', array('google', 'github', 'gitlab'), Role::APP_PUBLIC);
|
||||
$acl->add('Auth', array('login', 'check', 'captcha'), Role::APP_PUBLIC);
|
||||
$acl->add('Auth', array('login', 'check'), Role::APP_PUBLIC);
|
||||
$acl->add('Captcha', '*', Role::APP_PUBLIC);
|
||||
$acl->add('PasswordReset', '*', Role::APP_PUBLIC);
|
||||
$acl->add('Webhook', '*', Role::APP_PUBLIC);
|
||||
$acl->add('Task', 'readonly', Role::APP_PUBLIC);
|
||||
$acl->add('Board', 'readonly', Role::APP_PUBLIC);
|
||||
|
||||
@@ -32,6 +32,7 @@ class ClassProvider implements ServiceProviderInterface
|
||||
'Link',
|
||||
'Notification',
|
||||
'OverdueNotification',
|
||||
'PasswordReset',
|
||||
'Project',
|
||||
'ProjectActivity',
|
||||
'ProjectAnalytic',
|
||||
@@ -84,6 +85,9 @@ class ClassProvider implements ServiceProviderInterface
|
||||
'UserFilterAutoCompleteFormatter',
|
||||
'GroupAutoCompleteFormatter',
|
||||
),
|
||||
'Validator' => array(
|
||||
'PasswordResetValidator',
|
||||
),
|
||||
'Core' => array(
|
||||
'DateParser',
|
||||
'Helper',
|
||||
|
||||
@@ -205,6 +205,10 @@ class RouteProvider implements ServiceProviderInterface
|
||||
$container['route']->addRoute('oauth/gitlab', 'oauth', 'gitlab');
|
||||
$container['route']->addRoute('login', 'auth', 'login');
|
||||
$container['route']->addRoute('logout', 'auth', 'logout');
|
||||
|
||||
// PasswordReset
|
||||
$container['route']->addRoute('forgot-password', 'PasswordReset', 'create');
|
||||
$container['route']->addRoute('forgot-password/change/:token', 'PasswordReset', 'change');
|
||||
}
|
||||
|
||||
return $container;
|
||||
|
||||
@@ -19,17 +19,22 @@
|
||||
|
||||
<?php if (isset($captcha) && $captcha): ?>
|
||||
<?= $this->form->label(t('Enter the text below'), 'captcha') ?>
|
||||
<img src="<?= $this->url->href('auth', 'captcha') ?>"/>
|
||||
<?= $this->form->text('captcha', $values, $errors, array('required')) ?>
|
||||
<img src="<?= $this->url->href('Captcha', 'image') ?>"/>
|
||||
<?= $this->form->text('captcha', array(), $errors, array('required')) ?>
|
||||
<?php endif ?>
|
||||
|
||||
<?php if (REMEMBER_ME_AUTH): ?>
|
||||
<?= $this->form->checkbox('remember_me', t('Remember Me'), 1, true) ?><br/>
|
||||
<?= $this->form->checkbox('remember_me', t('Remember Me'), 1, true) ?><br>
|
||||
<?php endif ?>
|
||||
|
||||
<div class="form-actions">
|
||||
<input type="submit" value="<?= t('Sign in') ?>" class="btn btn-blue"/>
|
||||
</div>
|
||||
<?php if ($this->app->config('password_reset') == 1): ?>
|
||||
<div class="reset-password">
|
||||
<?= $this->url->link(t('Forgot password?'), 'PasswordReset', 'create') ?>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
</form>
|
||||
<?php endif ?>
|
||||
|
||||
|
||||
@@ -7,19 +7,21 @@
|
||||
<?= $this->form->csrf() ?>
|
||||
|
||||
<?= $this->form->label(t('Application URL'), 'application_url') ?>
|
||||
<?= $this->form->text('application_url', $values, $errors, array('placeholder="http://example.kanboard.net/"')) ?><br/>
|
||||
<?= $this->form->text('application_url', $values, $errors, array('placeholder="http://example.kanboard.net/"')) ?>
|
||||
<p class="form-help"><?= t('Example: http://example.kanboard.net/ (used by email notifications)') ?></p>
|
||||
|
||||
<?= $this->form->label(t('Language'), 'application_language') ?>
|
||||
<?= $this->form->select('application_language', $languages, $values, $errors) ?><br/>
|
||||
<?= $this->form->select('application_language', $languages, $values, $errors) ?>
|
||||
|
||||
<?= $this->form->label(t('Timezone'), 'application_timezone') ?>
|
||||
<?= $this->form->select('application_timezone', $timezones, $values, $errors) ?><br/>
|
||||
<?= $this->form->select('application_timezone', $timezones, $values, $errors) ?>
|
||||
|
||||
<?= $this->form->label(t('Date format'), 'application_date_format') ?>
|
||||
<?= $this->form->select('application_date_format', $date_formats, $values, $errors) ?><br/>
|
||||
<?= $this->form->select('application_date_format', $date_formats, $values, $errors) ?>
|
||||
<p class="form-help"><?= t('ISO format is always accepted, example: "%s" and "%s"', date('Y-m-d'), date('Y_m_d')) ?></p>
|
||||
|
||||
<?= $this->form->checkbox('password_reset', t('Enable "Forget Password"'), 1, $values['password_reset'] == 1) ?>
|
||||
|
||||
<?= $this->form->label(t('Custom Stylesheet'), 'application_stylesheet') ?>
|
||||
<?= $this->form->textarea('application_stylesheet', $values, $errors) ?><br/>
|
||||
|
||||
|
||||
16
app/Template/password_reset/change.php
Normal file
16
app/Template/password_reset/change.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<div class="form-login">
|
||||
<h2><?= t('Password Reset') ?></h2>
|
||||
<form method="post" action="<?= $this->url->href('PasswordReset', 'update', array('token' => $token)) ?>">
|
||||
<?= $this->form->csrf() ?>
|
||||
|
||||
<?= $this->form->label(t('New password'), 'password') ?>
|
||||
<?= $this->form->password('password', $values, $errors) ?><br/>
|
||||
|
||||
<?= $this->form->label(t('Confirmation'), 'confirmation') ?>
|
||||
<?= $this->form->password('confirmation', $values, $errors) ?>
|
||||
|
||||
<div class="form-actions">
|
||||
<input type="submit" value="<?= t('Change Password') ?>" class="btn btn-blue"/>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
17
app/Template/password_reset/create.php
Normal file
17
app/Template/password_reset/create.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<div class="form-login">
|
||||
<h2><?= t('Password Reset') ?></h2>
|
||||
<form method="post" action="<?= $this->url->href('PasswordReset', 'save') ?>">
|
||||
<?= $this->form->csrf() ?>
|
||||
|
||||
<?= $this->form->label(t('Username'), 'username') ?>
|
||||
<?= $this->form->text('username', $values, $errors, array('autofocus', 'required')) ?>
|
||||
|
||||
<?= $this->form->label(t('Enter the text below'), 'captcha') ?>
|
||||
<img src="<?= $this->url->href('Captcha', 'image') ?>"/>
|
||||
<?= $this->form->text('captcha', array(), $errors, array('required')) ?>
|
||||
|
||||
<div class="form-actions">
|
||||
<input type="submit" value="<?= t('Change Password') ?>" class="btn btn-blue"/>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
6
app/Template/password_reset/email.php
Normal file
6
app/Template/password_reset/email.php
Normal file
@@ -0,0 +1,6 @@
|
||||
<p><?= t('To reset your password click on this link:') ?></p>
|
||||
|
||||
<p><?= $this->url->to('PasswordReset', 'change', array('token' => $token), '', true) ?></p>
|
||||
|
||||
<hr>
|
||||
Kanboard
|
||||
26
app/Template/user/password_reset.php
Normal file
26
app/Template/user/password_reset.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<div class="page-header">
|
||||
<h2><?= t('Last Password Reset') ?></h2>
|
||||
</div>
|
||||
|
||||
<?php if (empty($tokens)): ?>
|
||||
<p class="alert"><?= t('The password has never been reinitialized.') ?></p>
|
||||
<?php else: ?>
|
||||
<table class="table-small table-fixed">
|
||||
<tr>
|
||||
<th class="column-20"><?= t('Creation') ?></th>
|
||||
<th class="column-20"><?= t('Expiration') ?></th>
|
||||
<th class="column-5"><?= t('Active') ?></th>
|
||||
<th class="column-15"><?= t('IP address') ?></th>
|
||||
<th><?= t('User agent') ?></th>
|
||||
</tr>
|
||||
<?php foreach ($tokens as $token): ?>
|
||||
<tr>
|
||||
<td><?= dt('%B %e, %Y at %k:%M %p', $token['date_creation']) ?></td>
|
||||
<td><?= dt('%B %e, %Y at %k:%M %p', $token['date_expiration']) ?></td>
|
||||
<td><?= $token['is_active'] == 0 ? t('No') : t('Yes') ?></td>
|
||||
<td><?= $this->e($token['ip']) ?></td>
|
||||
<td><?= $this->e($token['user_agent']) ?></td>
|
||||
</tr>
|
||||
<?php endforeach ?>
|
||||
</table>
|
||||
<?php endif ?>
|
||||
@@ -19,6 +19,9 @@
|
||||
<li <?= $this->app->checkMenuSelection('user', 'sessions') ?>>
|
||||
<?= $this->url->link(t('Persistent connections'), 'user', 'sessions', array('user_id' => $user['id'])) ?>
|
||||
</li>
|
||||
<li <?= $this->app->checkMenuSelection('user', 'passwordReset') ?>>
|
||||
<?= $this->url->link(t('Password reset history'), 'user', 'passwordReset', array('user_id' => $user['id'])) ?>
|
||||
</li>
|
||||
<?php endif ?>
|
||||
|
||||
<?= $this->hook->render('template:user:sidebar:information') ?>
|
||||
|
||||
36
app/Validator/Base.php
Normal file
36
app/Validator/Base.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Validator;
|
||||
|
||||
/**
|
||||
* Base Validator
|
||||
*
|
||||
* @package validator
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class Base extends \Kanboard\Core\Base
|
||||
{
|
||||
/**
|
||||
* Execute multiple validators
|
||||
*
|
||||
* @access public
|
||||
* @param array $validators List of validators
|
||||
* @param array $values Form values
|
||||
* @return array $valid, $errors [0] = Success or not, [1] = List of errors
|
||||
*/
|
||||
public function executeValidators(array $validators, array $values)
|
||||
{
|
||||
$result = false;
|
||||
$errors = array();
|
||||
|
||||
foreach ($validators as $method) {
|
||||
list($result, $errors) = $this->$method($values);
|
||||
|
||||
if (! $result) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return array($result, $errors);
|
||||
}
|
||||
}
|
||||
98
app/Validator/PasswordResetValidator.php
Normal file
98
app/Validator/PasswordResetValidator.php
Normal file
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Validator;
|
||||
|
||||
use SimpleValidator\Validator;
|
||||
use SimpleValidator\Validators;
|
||||
use Gregwar\Captcha\CaptchaBuilder;
|
||||
|
||||
/**
|
||||
* Password Reset Validator
|
||||
*
|
||||
* @package validator
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class PasswordResetValidator extends Base
|
||||
{
|
||||
/**
|
||||
* Validate creation
|
||||
*
|
||||
* @access public
|
||||
* @param array $values Form values
|
||||
* @return array $valid, $errors [0] = Success or not, [1] = List of errors
|
||||
*/
|
||||
public function validateCreation(array $values)
|
||||
{
|
||||
return $this->executeValidators(array('validateFields', 'validateCaptcha'), $values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate modification
|
||||
*
|
||||
* @access public
|
||||
* @param array $values Form values
|
||||
* @return array $valid, $errors [0] = Success or not, [1] = List of errors
|
||||
*/
|
||||
public function validateModification(array $values)
|
||||
{
|
||||
$v = new Validator($values, array(
|
||||
new Validators\Required('password', t('The password is required')),
|
||||
new Validators\MinLength('password', t('The minimum length is %d characters', 6), 6),
|
||||
new Validators\Required('confirmation', t('The confirmation is required')),
|
||||
new Validators\Equals('password', 'confirmation', t('Passwords don\'t match')),
|
||||
));
|
||||
|
||||
return array(
|
||||
$v->execute(),
|
||||
$v->getErrors(),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate fields
|
||||
*
|
||||
* @access protected
|
||||
* @param array $values Form values
|
||||
* @return array $valid, $errors [0] = Success or not, [1] = List of errors
|
||||
*/
|
||||
protected function validateFields(array $values)
|
||||
{
|
||||
$v = new Validator($values, array(
|
||||
new Validators\Required('captcha', t('This value is required')),
|
||||
new Validators\Required('username', t('The username is required')),
|
||||
new Validators\MaxLength('username', t('The maximum length is %d characters', 50), 50),
|
||||
));
|
||||
|
||||
return array(
|
||||
$v->execute(),
|
||||
$v->getErrors(),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate captcha
|
||||
*
|
||||
* @access protected
|
||||
* @param array $values Form values
|
||||
* @return boolean
|
||||
*/
|
||||
protected function validateCaptcha(array $values)
|
||||
{
|
||||
$result = true;
|
||||
$errors = array();
|
||||
|
||||
if (! isset($this->sessionStorage->captcha)) {
|
||||
$result = false;
|
||||
} else {
|
||||
$builder = new CaptchaBuilder;
|
||||
$builder->setPhrase($this->sessionStorage->captcha);
|
||||
$result = $builder->testPhrase(isset($values['captcha']) ? $values['captcha'] : '');
|
||||
|
||||
if (! $result) {
|
||||
$errors['captcha'] = array(t('Invalid captcha'));
|
||||
}
|
||||
}
|
||||
|
||||
return array($result, $errors);;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user