Reset/Forgot Password



# 1 > Functions in Users Controller

In Users Controller,

add the following 'forgot' and 'emailReminder' functions
(modify the from email address to your from email address)

function forgot($key = FALSE){
$this->set('section_admin', NULL);
$this->Session->write('goingTo', false);

if (!empty($this->data)) {
if ($userInfo = $this->User->doesUserExist($this->data['User']['email'])) {
//we have a user let's write a ticket
$hash = $this->User->Ticket->generate($userInfo['User']['id']);
//Let's create an email with the hash
if ($this->emailReminder($userInfo['User']['email'], $hash)) {
$this->Session->setFlash(__('Email sent, please check your email to reset your password', TRUE));
$this->redirect('/login');
} else {
$this->Session->setFlash(__('Error; please call customer service', TRUE));
}
} else {
$this->Session->setFlash(__("No email exists", TRUE));
}
}
}

private function emailReminder($to, $hash){
$domain = Router::url("/", TRUE);

$this->set('hash', $hash);
$this->set('domain', $domain);
$subject = 'Password Reset';
$Email = new CakeEmail();
$Email->transport('smtp');
$Email->to($to);
$vars['hash'] = $hash;
$vars['domain'] = $domain;
$Email->viewVars($vars);
$Email->subject($subject);
$Email->from('your_from_email_address');
$Email->template('reset');
$Email->emailFormat('html');
$sent = $Email->send();
if ($sent) {
return TRUE;
} else {
return FALSE;
}
}

 


# 2 > Functions in User Model

In User Model, add the following function

function doesUserExist($email) {
$user = $this->find('first', array(
'conditions' => array('User.email' => $email)));
if ($user) {
return $user;
} else {
return FALSE;
}
}

# 3 > Functions in Users View

In Users View
-> create forgot.ctp file and add the following code in forgot.ctp file

<style>
input {
font-size:140%;
padding:1%;
width:80%;
margin-left:120px;
}
label {
position:absolute;
}
</style>

<div class="customerLoginCreateAccount forgotForm oneForm">
<h2>Reset your password</h2>
<?php echo $this->Form->create('User'); ?>
<?php echo $this->Form->input('email'); ?>
<div class=""><?php echo $this->Form->end(__('Send me a reset email')); ?></div>

<address>
Follow the instructions in your email to reset your password
</address>
<div class="clr"></div>
</div>

 


# 4 > Tickets Controller

In Controllers, create "TicketsController" and add the following in TicketsController

<?php
App::uses('AppController', 'Controller');
/**
* Tickets Controller
*
* @property Ticket $Ticket
* @property PaginatorComponent $Paginator
*/
class TicketsController extends AppController {

public $components = array('Paginator');

//allows the user to enter the code for the reset
function setup() {
if (!empty($this->data)) {
$this->redirect(array(
'action' => 'reset', $this->data[ 'key' ]
));
}
$layouts = Configure::read('Tickets.UseVendorGridLayouts');
if (!empty($layouts)) {
$this->assignCompanyForDomain();

$this->showCompanyLayout();
}

}

function reset($hash = FALSE, $password = NULL) {
if (empty($hash))
$this->redirect(array('action' => 'setup'));
//let's cleanup the old rows
$this->Ticket->cleanUp();
//let's check the hash and see if we have a match
if (!empty($this->request->data)) {
if ($this->request->data[ 'password' ] == $this->request->data[ 'passwordVerify' ]) {
//passwords are good let's run are change
$password = $this->Auth->password($this->request->data[ 'password' ]);

if ($user_id = $this->Ticket->changePassword($this->request->data[ 'hash' ], $password)) {
//let's try to login
$this->Session->setFlash(__('Your password has been changed', TRUE));

$userInfo = $this->Ticket->User->find('first', array(
'conditions' => array("User.id" => $user_id),
'contain' => array('UserType')
));
$this->Auth->login($userInfo['User']);
$this->redirect('/client/Pages/dashboard');

} else {
$this->Session->setFlash(__('This ticket has expired or is not valid, please create a new one', TRUE));
$this->redirect('/forgot');
}
} else {
$this->Session->setFlash(__('passwords do not match', TRUE));
}
} else {
//put into a hidden variable
$this->request->data[ 'hash' ] = $hash;
}

}
}

# 5 > Ticket Model

In Model, Create "Ticket" model and add the following code in Ticket model

<?php
App::uses('AppModel', 'Model');

class Ticket extends AppModel {

public $validate = array(
'user_id' => array(
'numeric' => array(
'rule' => array('numeric'),

),
),
);

public $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);

function generate($user_id) {
$ticketHash = substr(Security::hash(microtime() * 12345), 0, 12);
$res = $this->save(array(
'hash' => $ticketHash, 'user_id' => $user_id
));
return $ticketHash;
}

function changePassword($hash, $password) {
$this->User->validate = array();
if ($this->data = $this->find('first', array(
'contain' => array('User'),
'conditions' => array('Ticket.hash' => $hash)))) {
$this->data[ 'User' ][ 'password' ] = $password;
$ticket = $this->data;

if ($this->User->save($this->data)) {
//let's clean up our ticket
if ($this->delete($this->data[ 'Ticket' ][ 'id' ])) {
return $ticket['Ticket']['user_id'];
} else {
$this->log('could not delete ticket');
}
} else {
print_r ($this->User->validationErrors);
die ('CANNOT SAVE');
}
} else {
return FALSE;
}
}

function cleanUp() {
$date = date('Y-m-d H:i:s', strtotime("-1 hours"));
//let's cleaned up the expired rows
$found = $this->find('all', array(
'conditions' => array('Ticket.created <' => $date)
));

foreach ($found as $each) {
$this->delete($each[ 'Ticket' ][ 'id' ]);
}
}
}

# 6 > Add Tickets table

In Phpmyadmin -> Choose your database -> Click 'SQL' in menu and add the following code (modify the code by adding your database_name) -> click Go
CREATE TABLE `your_database_name`.`tickets` ( `id` INT NOT NULL , `hash`VARCHAR(255NOT NULL , `user_id` INT NOT NULL , `created` DATETIME NOTNULL , `modified` DATETIME NOT NULL , PRIMARY KEY (`id`)) ENGINE =InnoDB;


# 7 > Add Relations ship in User model

In User model add the following relationship function

var $hasMany = array(
'Ticket' => array('className' => 'Ticket', 'foreignKey' => 'user_id', 'dependent' => FALSE, 'conditions' => '', 'fields' => '', 'order' => '', 'limit' => '', 'offset' => '', 'exclusive' => '', 'finderQuery' => '', 'counterQuery' => ''),


);

 


# 8 > Add reset function

In App->View->Emails->Html, create a file name reset.ctp and add the following in reset.ctp

<?= $this->Element('emailers/reset'); ?>

# 9 > Create reset element

In View->elements,created a folder named 'emailers' and created a file name reset.ctp
and add the following code in reset.ctp

<h3>Password Reset</h3>
<p>
In order to reset your password you can either:
</p>
<p>1-> <a href="<?= $domain; ?>reset/<?= $hash; ?>">click here to use the direct link</a></p>
<p>OR</p>
<p>
2-> copy and paste this key:<br/>
<?= $hash; ?><br/>
and navigate to <?= $domain; ?>reset<br/>
to complete the reset
</p>
<p>
An email reset was initiated from <?= $domain; ?>. If you did not
initiate this request disregard this email and no changes will
be made to your account.
</p>

# 10 > SMTP setup

logon to Control Panel 
-> Create an email ('website_messages@yourwebsite.com')

-> Create a unique password

In App->Config->email.php, modify SMTP section with the following info

 

'transport' => 'Smtp',
'from' => array('website_messages@yourdomain_name' => 'your company name'),
'host' => 'server_name',
'port' => 587,
'timeout' => 30,
'username' => 'website_messages@your_domain_name',
'password' => 'the password you created in control panel',
'client' => null,
'log' => false,

 


Other Instructions

Below are many other instructions that show you how to use your UpdateCase application