CodeIgniter Forums
What is the reason updating a user's password fails in this application? - Printable Version

+- CodeIgniter Forums (https://forum.codeigniter.com)
+-- Forum: Development (https://forum.codeigniter.com/forumdisplay.php?fid=6)
+--- Forum: CodeIgniter 3.x (https://forum.codeigniter.com/forumdisplay.php?fid=17)
+--- Thread: What is the reason updating a user's password fails in this application? (/showthread.php?tid=78707)



What is the reason updating a user's password fails in this application? - Ajax30 - 02-28-2021

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?