Search code examples
phpcodeigniter

Codeigniter 3 applcation bug: unable to send valid link via email message


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.

I was able to do these 2 things separately:

  1. Send a password reset email containing dummy text.
  2. Create a valid password reset link.

I was unable however, to send the email once the reset link was inserted into the email body.

Here is he controller:

class Newpassword 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('changepasword/') . $this->user_email . '/'. $this->reset_token;

                //create reset link
                $this->reset_link = '<a href="' . $this->reset_url . '">password reset link</a>';

                echo $this->reset_link;die();

                $this->body = "Here is your $this->reset_link. \n\nAfter clicking it you will be redirected to a page on the website where you will be able to set a new pasword.";

                // Send mail and rediect
                $this->sendResetMail();             
            } else {
                $this->session->set_flashdata('email_non_existent', "The email you provided does not exist in our database");
            }
           redirect('newpassword');
        }
    }

    public function sendResetMail() {
        // Loading the Email library
        $config['protocol'] = 'sendmail';
        $config['charset'] = 'utf-8';
        $config['mailtype'] = 'html';

        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 atempt to send a pasword reset link to $this->user_email has failed");
        }
    }
}

I have inspected the link, it is valid and the value of the href attribute is as intended, but once I remove echo $this->reset_link;die() I see the attempt to send the email failing:

enter image description here

Where is my mistake?


Solution

  • The email not sending issue can be from multiple reasons:

    1. Codeigniter 3 email library is not configured correctly

    test: use built in email() in php and test if that's working

    1. php not configured correctly to send email
    2. server is not configured for handing over emails
    3. DNS has external mx records and local email is not forwarded out from the server

    test: use external SMTP server (free gmail is fine) and configure like this the ci3 library https://forum.codeigniter.com/thread-75525-post-371979.html#pid371979

    $config['protocol']  = 'smtp';
    $config['smtp_host'] = 'ssl://smtp.googlemail.com';
    $config['smtp_user'] = 'your_email';
    $config['smtp_pass'] = 'your_password';
    $config['smtp_port'] = 465;
    $config['charset']   = 'utf-8';
    $config['mailtype']  = 'html';
    $config['newline']   = "\r\n"; 
    

    if this is not working, check what's the cause by using

    if ($this->email->send(FALSE))
    {
        echo $this->email->print_debugger();
    }
    
    1. server cannot access remote ports firewalls are not opened for this

    test: disable firewall or selinux and test again