lonnieezell / myth-auth

One-stop Auth package for CodeIgniter 4
MIT License
632 stars 207 forks source link

Attempt to read property 'force_pass_reset' on null #596

Closed udin-ordinari closed 1 year ago

udin-ordinari commented 1 year ago

Hi lonnieezell,

iam trying to use your code with my modification code. but it show error "Attempt to read property 'force_pass_reset' on null"

this is my edited code for attemptlogin

public function attemptLogin()
{
    $rules = ['login' => 'required', 'password' => 'required'];
    if ($this->config->validFields === ['email'])
    {
        $rules['login'] .= '|valid_email';
    }

    if (! $this->validate($rules))
    {
        $this->vars['status']   = 'warning';
        $this->vars['title']    = 'Attention !';
        $this->vars['message']  = $this->validator->getErrors();
        $this->vars['banned']   = FALSE;
    }

    $login    = $this->request->getPost('login');
        $password = $this->request->getPost('password');
        $remember = (bool) $this->request->getPost('remember');

        // Determine credential type
        $type = filter_var($login, FILTER_VALIDATE_EMAIL) ? 'email' : 'username';

        // Try to log them in...
        if (! $this->auth->attempt([$type => $login, 'password' => $password], $remember))
    {
        $this->vars['status']   = 'error';
        $this->vars['title']            = 'Error !';
        $this->vars['message']  = $this->auth->error() ?? lang('Auth.badAttempt');
        $this->vars['banned']   = FALSE;
    }

        // Is the user being forced to reset their password?
        if ($this->auth->user()->force_pass_reset === true)
    {
        $this->vars['status']   = 'info';
        $this->vars['title']            = 'Information !';
        $this->vars['message']  = 'You Have A Reset Password Process Not Yet Completed !';
        $this->vars['banned']   = TRUE;
    }
    else
    {
        $this->vars['status']   = 'success';
        $this->vars['title']            = 'Yaay !';
        $this->vars['message']  = lang('Auth.loginSuccess');
        $this->vars['banned']   = TRUE;
    }

    return $this->response->setJSON($this->vars);
}

how to fix it? thank you for your answer.

udin

manageruz commented 1 year ago

Hi @udin-ordinari Error message Attempt to read property 'force_pass_reset' on null means that $this->auth->user() part of code returns null, which means there is no user instance. All is because of your modified code structure is wrong.

So how to fix it? just check your if statements above. They must have return part code. For example from your code:

if (! $this->validate($rules))
{
    $this->vars['status']   = 'warning';
    $this->vars['title']    = 'Attention !';
    $this->vars['message']  = $this->validator->getErrors();
    $this->vars['banned']   = FALSE;
}

$login    = $this->request->getPost('login');

The execution flow of this code should be stopped if above if statement is false, which will lead to access inside of if statement. The logic must be like if validation fails, code execution should be stopped and immediately returned an error response. But your code will continue even if validation will fail, which is wrong.

Please check the original code for example:

if (! $this->validate($rules)) {
       return redirect()
           ->back()
           ->withInput()
           ->with('errors', $this->validator->getErrors());
}
// code execution will never get to this row,  if validation fails, because we **already returned response inside if statement above**. 
$login    = $this->request->getPost('login');

Hope you get the idea.

manageruz commented 1 year ago

It would be nice to see your posts on "Discussions" part, which is the right place for this.

udin-ordinari commented 1 year ago

It would be nice to see your posts on "Discussions" part, which is the right place for this.

hi manageruz, thank you. yes i should place this question in the discussions page. my mistake.

udin-ordinari commented 1 year ago

Hi @udin-ordinari Error message Attempt to read property 'force_pass_reset' on null means that $this->auth->user() part of code returns null, which means there is no user instance. All is because of your modified code structure is wrong.

So how to fix it? just check your if statements above. They must have return part code. For example from your code:

if (! $this->validate($rules))
{
  $this->vars['status']   = 'warning';
  $this->vars['title']    = 'Attention !';
  $this->vars['message']  = $this->validator->getErrors();
  $this->vars['banned']   = FALSE;
}

$login    = $this->request->getPost('login');

The execution flow of this code should be stopped if above if statement is false, which will lead to access inside of if statement. The logic must be like if validation fails, code execution should be stopped and immediately returned an error response. But your code will continue even if validation will fail, which is wrong.

Please check the original code for example:

if (! $this->validate($rules)) {
       return redirect()
           ->back()
           ->withInput()
           ->with('errors', $this->validator->getErrors());
}
// code execution will never get to this row,  if validation fails, because we **already returned response inside if statement above**. 
$login    = $this->request->getPost('login');

Hope you get the idea.

hi manageruz, thank you for the explanation. i can figure out now.

manageruz commented 1 year ago

I guess you have solved your issue. So closing it as solved. Feel free to reopen it again if you need to.