-
Notifications
You must be signed in to change notification settings - Fork 31
Description
I'm trying to solve this problem detailed in the below forum posts:
http://community.dreamfactory.com/t/forgot-password-api/1236/6
http://community.dreamfactory.com/t/password-reset-not-working-after-user-logins/3180
http://community.dreamfactory.com/t/unable-to-change-or-reset-password/4100/
After looking through much of the code, I have found what I believe to be the issue.
Sometimes JWTUtilities::invalidate($token); is called to change a token to blacklisted. This function seems to also remove the token from the map.
Othertimes JWTAuth::invalidate(); is called directly:
df-core/src/Utility/JWTUtilities.php
Line 177 in db355e0
| public static function invalidateTokenByUserId($userId) |
public static function invalidateTokenByUserId($userId)
{
DB::table('token_map')->where('user_id', $userId)->get()->each(function ($map){
try {
JWTAuth::setToken($map->token);
JWTAuth::invalidate();
} catch (TokenExpiredException $e) {
//If the token is expired already then do nothing here.
}
});
return DB::table('token_map')->where('user_id', $userId)->delete();
}I think part of the password reset + blacklisted token issue stems from this. Especially when the error stems from here:
| throw new InternalServerErrorException("Error processing password reset.\n{$ex->getMessage()}"); |
Because invalidateTokenByUserId will get called via the user model at User.setPasswordAttribute($password).
public function setPasswordAttribute($password)
{
if (!empty($password)) {
$password = bcrypt($password);
JWTUtilities::invalidateTokenByUserId($this->id);
// When password is set user account must be confirmed. Confirming user
// account here with confirm_code = null.
// confirm_code = 'y' indicates cases where account is confirmed by user
// using confirmation email.
if (isset($this->attributes['confirm_code']) && $this->attributes['confirm_code'] !== 'y') {
$this->attributes['confirm_code'] = null;
}
}
$this->attributes['password'] = $password;
}