Adding forgot password functionality.
This commit is contained in:
parent
2cd4bade30
commit
cf2d93f71a
|
@ -10,6 +10,7 @@
|
|||
namespace PHPCI\Controller;
|
||||
|
||||
use b8;
|
||||
use PHPCI\Helper\Email;
|
||||
|
||||
/**
|
||||
* Session Controller - Handles user login / logout.
|
||||
|
@ -88,4 +89,74 @@ class SessionController extends \PHPCI\Controller
|
|||
header('Location: ' . PHPCI_URL);
|
||||
die;
|
||||
}
|
||||
|
||||
public function forgotPassword()
|
||||
{
|
||||
if ($this->request->getMethod() == 'POST') {
|
||||
$email = $this->getParam('email', null);
|
||||
$user = $this->userStore->getByEmail($email);
|
||||
|
||||
if (empty($user)) {
|
||||
$this->view->error = 'No user exists with that email address, please try again.';
|
||||
return $this->view->render();
|
||||
}
|
||||
|
||||
$key = md5(date('Y-m-d') . $user->getHash());
|
||||
$url = PHPCI_URL;
|
||||
$name = $user->getName();
|
||||
$id = $user->getId();
|
||||
|
||||
$message = <<<MSG
|
||||
Hi {$name},
|
||||
|
||||
You have received this email because you, or someone else, has requested a password reset for PHPCI.
|
||||
|
||||
If this was you, please click the following link to reset your password: {$url}session/reset-password/{$id}/{$key}
|
||||
|
||||
Otherwise, please ignore this email and no action will be taken.
|
||||
|
||||
Thank you,
|
||||
|
||||
PHPCI
|
||||
MSG;
|
||||
|
||||
|
||||
$email = new Email();
|
||||
$email->setTo($user->getEmail(), $user->getName());
|
||||
$email->setSubject('Password reset');
|
||||
$email->setBody($message);
|
||||
$email->send();
|
||||
|
||||
$this->view->emailed = true;
|
||||
}
|
||||
|
||||
return $this->view->render();
|
||||
}
|
||||
|
||||
public function resetPassword($id, $key)
|
||||
{
|
||||
$user = $this->userStore->getById($id);
|
||||
$userKey = md5(date('Y-m-d') . $user->getHash());
|
||||
|
||||
if (empty($user) || $key != $userKey) {
|
||||
$this->view->error = 'Invalid password reset request.';
|
||||
return $this->view->render();
|
||||
}
|
||||
|
||||
if ($this->request->getMethod() == 'POST') {
|
||||
$hash = password_hash($this->getParam('password'), PASSWORD_DEFAULT);
|
||||
$user->setHash($hash);
|
||||
|
||||
$_SESSION['user'] = $this->userStore->save($user);
|
||||
$_SESSION['user_id'] = $user->getId();
|
||||
|
||||
header('Location: ' . PHPCI_URL);
|
||||
die;
|
||||
}
|
||||
|
||||
$this->view->id = $id;
|
||||
$this->view->key = $key;
|
||||
|
||||
return $this->view->render();
|
||||
}
|
||||
}
|
||||
|
|
127
PHPCI/Helper/Email.php
Normal file
127
PHPCI/Helper/Email.php
Normal file
|
@ -0,0 +1,127 @@
|
|||
<?php
|
||||
|
||||
namespace PHPCI\Helper;
|
||||
|
||||
use b8\Config;
|
||||
use PHPCI\Helper\MailerFactory;
|
||||
|
||||
class Email
|
||||
{
|
||||
const DEFAULT_FROM = 'PHPCI <no-reply@phptesting.org>';
|
||||
|
||||
protected $to = array();
|
||||
protected $cc = array();
|
||||
protected $subject = 'Email from PHPCI';
|
||||
protected $body = '';
|
||||
protected $isHtml = false;
|
||||
protected $config;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->config = Config::getInstance();
|
||||
}
|
||||
|
||||
public function setTo($email, $name = null)
|
||||
{
|
||||
$this->to[$email] = $name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addCc($email, $name = null)
|
||||
{
|
||||
$this->cc[$email] = $name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setSubject($subject)
|
||||
{
|
||||
$this->subject = $subject;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setBody($body)
|
||||
{
|
||||
$this->body = $body;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setIsHtml($isHtml = false)
|
||||
{
|
||||
$this->isHtml = $isHtml;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function send()
|
||||
{
|
||||
$smtpServer = $this->config->get('phpci.email_settings.smtp_address');
|
||||
|
||||
if (empty($smtpServer)) {
|
||||
return $this->sendViaMail();
|
||||
} else {
|
||||
return $this->sendViaSwiftMailer();
|
||||
}
|
||||
}
|
||||
|
||||
protected function sendViaMail()
|
||||
{
|
||||
$headers = '';
|
||||
|
||||
if ($this->isHtml) {
|
||||
$headers = 'Content-Type: text/html' . PHP_EOL;
|
||||
}
|
||||
|
||||
$headers .= 'From: ' . $this->getFrom() . PHP_EOL;
|
||||
|
||||
$to = array();
|
||||
foreach ($this->to as $email => $name) {
|
||||
$thisTo = $email;
|
||||
|
||||
if (!is_null($name)) {
|
||||
$thisTo = '"' . $name . '" <' . $thisTo . '>';
|
||||
}
|
||||
|
||||
$to[] = $thisTo;
|
||||
}
|
||||
|
||||
$to = implode(', ', $to);
|
||||
|
||||
return mail($to, $this->subject, $this->body, $headers);
|
||||
}
|
||||
|
||||
protected function sendViaSwiftMailer()
|
||||
{
|
||||
$factory = new MailerFactory($this->config->get('phpci'));
|
||||
$mailer = $factory->getSwiftMailerFromConfig();
|
||||
|
||||
$message = \Swift_Message::newInstance($this->subject)
|
||||
->setFrom($this->getFrom())
|
||||
->setTo($this->to)
|
||||
->setBody($this->body);
|
||||
|
||||
if ($this->isHtml) {
|
||||
$message->setContentType('text/html');
|
||||
}
|
||||
|
||||
if (is_array($this->cc) && count($this->cc)) {
|
||||
$message->setCc($this->cc);
|
||||
}
|
||||
|
||||
return $mailer->send($message);
|
||||
}
|
||||
|
||||
protected function getFrom()
|
||||
{
|
||||
$email = $this->config->get('phpci.email_settings.from_address', self::DEFAULT_FROM);
|
||||
|
||||
if (empty($email)) {
|
||||
$email = self::DEFAULT_FROM;
|
||||
}
|
||||
|
||||
return $email;
|
||||
}
|
||||
}
|
88
PHPCI/View/Session.phtml
Normal file
88
PHPCI/View/Session.phtml
Normal file
|
@ -0,0 +1,88 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Log in to PHPCI</title>
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="<?php echo PHPCI_URL ?>assets/css/bootstrap.min.css">
|
||||
<script src="//code.jquery.com/jquery-1.8.1.min.js"></script>
|
||||
<script src="<?php echo PHPCI_URL ?>assets/js/bootstrap.min.js"></script>
|
||||
|
||||
<style type="text/css">
|
||||
|
||||
html {
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
body
|
||||
{
|
||||
background: #224466; /* Old browsers */
|
||||
background: -moz-radial-gradient(center, ellipse cover, #224466 0%, #112233 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%,#224466), color-stop(100%,#112233)); /* Chrome,Safari4+ */
|
||||
background: -webkit-radial-gradient(center, ellipse cover, #224466 0%,#112233 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-radial-gradient(center, ellipse cover, #224466 0%,#112233 100%); /* Opera 12+ */
|
||||
background: -ms-radial-gradient(center, ellipse cover, #224466 0%,#112233 100%); /* IE10+ */
|
||||
background: radial-gradient(ellipse at center, #224466 0%,#112233 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#224466', endColorstr='#112233',GradientType=1 ); /* IE6-9 fallback on horizontal gradient */
|
||||
|
||||
min-height: 100%;
|
||||
|
||||
font-family: Roboto, Arial, Sans-Serif;
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
padding-top: 0px;
|
||||
}
|
||||
|
||||
#login-box
|
||||
{
|
||||
background: #fcfcfc; /* Old browsers */
|
||||
background: -moz-linear-gradient(top, #fcfcfc 50%, #e0e0e0 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(50%,#fcfcfc), color-stop(100%,#e0e0e0)); /* Chrome,Safari4+ */
|
||||
background: -webkit-linear-gradient(top, #fcfcfc 50%,#e0e0e0 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, #fcfcfc 50%,#e0e0e0 100%); /* Opera 11.10+ */
|
||||
background: -ms-linear-gradient(top, #fcfcfc 50%,#e0e0e0 100%); /* IE10+ */
|
||||
background: linear-gradient(to bottom, #fcfcfc 50%,#e0e0e0 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fcfcfc', endColorstr='#e0e0e0',GradientType=0 ); /* IE6-9 */
|
||||
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 0 30px rgba(0,0,0, 0.3);
|
||||
margin: 0 auto;
|
||||
padding: 15px 30px;
|
||||
text-align: left;
|
||||
width: 350px;
|
||||
}
|
||||
|
||||
#logo {
|
||||
background: transparent url('http://www.block8.co.uk/badge-dark-muted.png') no-repeat top left;
|
||||
display: inline-block;
|
||||
height: 26px;
|
||||
margin: 40px auto;
|
||||
width: 90px;
|
||||
}
|
||||
|
||||
#logo:hover {
|
||||
background-image: url('http://www.block8.co.uk/badge-dark.png');
|
||||
}
|
||||
|
||||
#phpci-logo img {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="row" style="margin-top: 10%; text-align: center">
|
||||
<a id="phpci-logo" href="http://www.phptesting.org">
|
||||
<img src="<?php print PHPCI_URL; ?>/assets/img/logo-large.png">
|
||||
</a>
|
||||
<div class="" id="login-box">
|
||||
<?php print $content; ?>
|
||||
</div>
|
||||
|
||||
<a id="logo" href="http://www.block8.co.uk/"></a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
33
PHPCI/View/Session/forgotPassword.phtml
Normal file
33
PHPCI/View/Session/forgotPassword.phtml
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?php if (isset($emailed)): ?>
|
||||
<p class="alert alert-success" style="margin-bottom: 0">
|
||||
We've emailed you a link to reset your password.
|
||||
</p>
|
||||
<?php else: ?>
|
||||
<?php if (empty($error)): ?>
|
||||
<div class="panel panel-success" style="margin-bottom: 0">
|
||||
<div class="panel-heading">
|
||||
<strong>Don't worry!</strong><br>Just enter your email address below and we'll email you a link to reset your password.
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="panel panel-danger" style="margin-bottom: 0">
|
||||
<div class="panel-heading">
|
||||
<?php print $error; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="panel-body">
|
||||
<form class="form" action="<?php print PHPCI_URL; ?>session/forgot-password" method="POST">
|
||||
<div class="form-group">
|
||||
<label for="email">Enter your email address:</label>
|
||||
<input id="email" name="email" class="form-control" required>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<input class="btn btn-success" type="submit" value="Email password reset">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<?php endif; ?>
|
|
@ -1,91 +1,6 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Log in to PHPCI</title>
|
||||
<?php if($failed): ?>
|
||||
<p class="alert alert-danger">Incorrect email address or password</p>
|
||||
<?php endif; ?>
|
||||
<?php print $form; ?>
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="<?php echo PHPCI_URL ?>assets/css/bootstrap.min.css">
|
||||
<script src="//code.jquery.com/jquery-1.8.1.min.js"></script>
|
||||
<script src="<?php echo PHPCI_URL ?>assets/js/bootstrap.min.js"></script>
|
||||
|
||||
<style type="text/css">
|
||||
|
||||
html {
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
body
|
||||
{
|
||||
background: #224466; /* Old browsers */
|
||||
background: -moz-radial-gradient(center, ellipse cover, #224466 0%, #112233 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%,#224466), color-stop(100%,#112233)); /* Chrome,Safari4+ */
|
||||
background: -webkit-radial-gradient(center, ellipse cover, #224466 0%,#112233 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-radial-gradient(center, ellipse cover, #224466 0%,#112233 100%); /* Opera 12+ */
|
||||
background: -ms-radial-gradient(center, ellipse cover, #224466 0%,#112233 100%); /* IE10+ */
|
||||
background: radial-gradient(ellipse at center, #224466 0%,#112233 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#224466', endColorstr='#112233',GradientType=1 ); /* IE6-9 fallback on horizontal gradient */
|
||||
|
||||
min-height: 100%;
|
||||
|
||||
font-family: Roboto, Arial, Sans-Serif;
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
padding-top: 0px;
|
||||
}
|
||||
|
||||
#login-box
|
||||
{
|
||||
background: #fcfcfc; /* Old browsers */
|
||||
background: -moz-linear-gradient(top, #fcfcfc 50%, #e0e0e0 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(50%,#fcfcfc), color-stop(100%,#e0e0e0)); /* Chrome,Safari4+ */
|
||||
background: -webkit-linear-gradient(top, #fcfcfc 50%,#e0e0e0 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, #fcfcfc 50%,#e0e0e0 100%); /* Opera 11.10+ */
|
||||
background: -ms-linear-gradient(top, #fcfcfc 50%,#e0e0e0 100%); /* IE10+ */
|
||||
background: linear-gradient(to bottom, #fcfcfc 50%,#e0e0e0 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fcfcfc', endColorstr='#e0e0e0',GradientType=0 ); /* IE6-9 */
|
||||
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 0 30px rgba(0,0,0, 0.3);
|
||||
margin: 0 auto;
|
||||
padding: 15px 30px;
|
||||
text-align: left;
|
||||
width: 350px;
|
||||
}
|
||||
|
||||
#logo {
|
||||
background: transparent url('http://www.block8.co.uk/badge-dark-muted.png') no-repeat top left;
|
||||
display: inline-block;
|
||||
height: 26px;
|
||||
margin: 40px auto;
|
||||
width: 90px;
|
||||
}
|
||||
|
||||
#logo:hover {
|
||||
background-image: url('http://www.block8.co.uk/badge-dark.png');
|
||||
}
|
||||
|
||||
#phpci-logo img {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="row" style="margin-top: 10%; text-align: center">
|
||||
<a id="phpci-logo" href="http://www.phptesting.org">
|
||||
<img src="<?php print PHPCI_URL; ?>/assets/img/logo-large.png">
|
||||
</a>
|
||||
<div class="" id="login-box">
|
||||
<?php if($failed): ?>
|
||||
<p class="alert alert-danger">Incorrect email address or password</p>
|
||||
<?php endif; ?>
|
||||
<?php print $form; ?>
|
||||
</div>
|
||||
|
||||
<a id="logo" href="http://www.block8.co.uk/"></a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
<a style="margin-top: -22px; font-size: 0.85em; color: #246" class="pull-right" href="<?php print PHPCI_URL; ?>session/forgot-password">Forgotten your password?</a>
|
27
PHPCI/View/Session/resetPassword.phtml
Normal file
27
PHPCI/View/Session/resetPassword.phtml
Normal file
|
@ -0,0 +1,27 @@
|
|||
|
||||
<?php if (empty($error)): ?>
|
||||
<div class="panel panel-success" style="margin-bottom: 0">
|
||||
<div class="panel-heading">
|
||||
Please enter a new password
|
||||
</div>
|
||||
|
||||
<div class="panel-body">
|
||||
<form class="form" action="<?php print PHPCI_URL; ?>session/reset-password/<?php print $id; ?>/<?php print $key; ?>" method="POST">
|
||||
<div class="form-group">
|
||||
<label for="password">New password:</label>
|
||||
<input type="password" id="password" name="password" class="form-control" required>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<input class="btn btn-success" type="submit" value="Change password">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="alert alert-danger" style="margin-bottom: 0">
|
||||
<?php print $error; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
|
Loading…
Reference in a new issue