I am working on a
basic blog application in Codeigniter 3.1.8 and Bootstrap 4.
I have added a **registration and login** system to this application. I am current working on a password reset system. It has a 2 steps process:
1. Generating a token and inserting it in the database (`authors`
table).
2. Setting a new password.
Setting a new password fails with a 404 error for some reason I was unable to find out and fix.
The routes:
Code:
$route['default_controller'] = 'posts';
$route['install'] = 'install';
$route['migrate'] = 'migrate';
$route['register'] = 'register';
$route['login'] = 'login';
$route['passwordreset'] = 'passwordreset';
$route['newpasword'] = 'newpasword';
$route['newpasword/(:any)/(:any)'] = 'newpasword/index/$1/$2/';
$route['dashboard'] = 'dashboard';
$route['dashboard/create-post'] = 'dashboard/posts/create';
$route['dashboard/create-page'] = 'dashboard/pages/create';
$route['dashboard/create-category'] = 'dashboard/categories/create';
$route['dashboard/manage-authors'] = 'dashboard/users';
$route['404_override'] = '';
$route['categories/posts/(:any)'] = 'categories/posts/$1';
$route['(:any)'] = 'posts/post/$1';
$route['translate_uri_dashes'] = FALSE;
In the Passwordreset controller I have:
Code:
class Passwordreset extends CI_Controller {
public function __construct()
{
parent::__construct();
}
private $sender_email = "[email protected]";
private $sender_name = "Razvan Zamfir";
private $user_email = '';
private $subject = 'Pasword reset link';
private $reset_token = '';
private $reset_url = '';
private $reset_link = '';
private $body = '';
public function index() {
// Display form
$data = $this->Static_model->get_static_data();
$data['pages'] = $this->Pages_model->get_pages();
$data['tagline'] = 'Reset your password';
$data['categories'] = $this->Categories_model->get_categories();
// Form validation rules
$this->form_validation->set_rules('email', 'Email', 'required|trim|valid_email');
$this->form_validation->set_error_delimiters('<p class="error-message">', '</p>');
if(!$this->form_validation->run()) {
$this->load->view('partials/header', $data);
$this->load->view('auth/passwordreset');
$this->load->view('partials/footer');
} else {
if ($this->Usermodel->email_exists()) {
//Get user email
$this->user_email = $this->input->post('email');
//create token
$this->reset_token = md5(str_shuffle($this->user_email));
//create url
$this->reset_url = base_url('newpasword/') . md5($this->user_email) . '/'. $this->reset_token;
//create reset link
$this->reset_link = '<a href="' . $this->reset_url . '">password reset link</a>';
$this->body = "Here is your <strong>" . $this->reset_link . "</strong>. After clicking it you will be redirected to a page on the website where you will be able to set a new pasword.";
// Update paswword reset token
$this->updateToken($this->user_email, $this->reset_token);
echo $this->body;
} else {
$this->session->set_flashdata('email_non_existent', "The email you provided does not exist in our database");
}
}
}
public function updateToken($user_email, $reset_token) {
$user_email = $this->user_email;
$reset_token = $this->reset_token;
$this->Usermodel->update_token($user_email, $reset_token);
}
public function sendResetMail() {
// Loading the Email library
$config['protocol'] = 'smtp';
$config['smtp_host'] = 'ssl://smtp.googlemail.com';
$config['smtp_user'] = '[email protected]';
$config['smtp_pass'] = '******';
$config['smtp_port'] = 465;
$config['charset'] = 'utf-8';
$config['mailtype'] = 'html';
$config['newline'] = "\r\n";
if(!$this->load->is_loaded('email')){
$this->load->library('email', $config);
} else {
$this->email->initialize($config);
}
// Build the body and meta data of the email message
$this->email->from($this->sender_email, $this->sender_name);
$this->email->to($this->user_email);
$this->email->subject($this->subject);
$this->email->message($this->body);
if($this->email->send()){
$this->session->set_flashdata('reset_mail_confirm', "A pasword reset link was send to the email address $this->user_email");
} else{
$this->session->set_flashdata('reset_mail_fail', "Our attempt to send a pasword reset link to $this->user_email has failed");
}
}
}
The corresponding view (passwordreset.php):
Code:
<?php echo form_open(base_url('passwordreset')); ?>
<div class="form-group <?php if(form_error('email')) echo 'has-error';?>">
<input type="text" name="email" id="email" class="form-control" placeholder="Email">
<?php if(form_error('email')) echo form_error('email'); ?>
</div>
<div class="form-group mb-2">
<input type="submit" value="Reset password" class="btn btn-block btn-md btn-success">
</div>
<?php echo form_close(); ?>
In the Newpasword controller:
Code:
class Newpasword extends CI_Controller {
private $hashed_email = '';
private $token = '';
public function index($hashed_email, $token) {
$data = $this->Static_model->get_static_data();
$data['pages'] = $this->Pages_model->get_pages();
$data['tagline'] = 'New password';
$data['categories'] = $this->Categories_model->get_categories();
$this->hashed_email = $hashed_email;
$this->token = $token;
// Form validation rules
$this->form_validation->set_rules('password', 'Password', 'required|min_length[6]');
$this->form_validation->set_rules('cpassword', 'Confirm password', 'required|matches[password]');
$this->form_validation->set_error_delimiters('<p class="error-message">', '</p>');
if(!$this->form_validation->run()) {
$this->load->view('partials/header', $data);
$this->load->view('auth/newpassword');
$this->load->view('partials/footer');
} else {
// Encrypt new password
$enc_password = password_hash($this->input->post('password'), PASSWORD_DEFAULT);
// Update password column
$this->Usermodel->set_new_password($hashed_email, $token, $enc_password);
}
}
}
The view corresponding to the above controller (newpassword.php):
Code:
<?php echo form_open(base_url('newpassword')); ?>
<div class="form-group <?php if(form_error('password')) echo 'has-error';?>">
<input type="password" name="password" id="password" class="form-control" placeholder="Password">
<?php if(form_error('password')) echo form_error('password'); ?>
</div>
<div class="form-group <?php if(form_error('cpassword')) echo 'has-error';?>">
<input type="password" name="cpassword" id="cpassword" class="form-control" placeholder="Confirm password">
<?php if(form_error('cpassword')) echo form_error('cpassword'); ?>
</div>
<div class="form-group mb-2">
<input type="submit" value="Set password" class="btn btn-block btn-md btn-success">
</div>
<?php echo form_close(); ?>
In the model I have the 2 methods for inserting the token and updating the password:
Code:
public function update_token($user_email, $reset_token) {
$this->db
->where(['email' => $user_email])
// insert token (make it diffrent from NULL)
->update('authors', array('token' => $reset_token));
}
Code:
public function set_new_password($hashed_email, $token, $enc_password) {
$this->db
->where([md5('email') => $hashed_email])
// set new password and reset token to NULL
->update('authors', array('password' => $enc_password, 'token' => NULL));
}
Inserting the token works without problems, but setting a new password fails with a
404 error.
What am I doing wrong?