/** * The first step in the forgot password sequence. * * @param string $email email address * @param string $ip ip address making the request * @param string $userAgent user agent used to make the request * * @throws AuthException when the step cannot be completed. * * @return bool */ public function step1($email, $ip, $userAgent) { $email = trim(strtolower($email)); if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { throw new AuthException('Please enter a valid email address.'); } $userClass = $this->auth->getUserClass(); $user = $userClass::where('email', $email)->first(); if (!$user || $user->isTemporary()) { throw new AuthException('We could not find a match for that email address.'); } // can only issue a single active forgot token at a time $expiration = U::unixToDb(time() - UserLink::$forgotLinkTimeframe); $nExisting = UserLink::totalRecords(['user_id' => $user->id(), 'type' => UserLink::FORGOT_PASSWORD, 'created_at > "' . $expiration . '"']); if ($nExisting > 0) { return true; } // generate a reset password link $link = $this->buildLink($user->id(), $ip, $userAgent); // and send it return $user->sendEmail('forgot-password', ['ip' => $ip, 'forgot' => $link->link]); }
public function __invoke($app) { $auth = new AuthManager(); $auth->setApp($app); // register authentication strategies $strategies = $app['config']->get('auth.strategies', []); foreach ($strategies as $id => $class) { $auth->registerStrategy($id, $class); } if ($class = $app['config']->get('auth.2fa_strategy')) { $strategy = new $class($auth); $auth->setTwoFactorStrategy($strategy); } // specify storage type if ($class = $app['config']->get('auth.storage')) { $storage = new $class($auth); $auth->setStorage($storage); } return $auth; }
/** * Helper method to start a new user session from this strategy. * * @param UserInterface $user * @param bool $remember whether to enable remember me on this session * * @return User */ protected function signInUser(UserInterface $user, $remember = false) { return $this->auth->signInUser($user, $this->getId(), $remember); }
/** * @param AuthManager $auth */ public function __construct(AuthManager $auth) { $this->auth = $auth; $this->setApp($auth->getApp()); }
/** * Verifies the cookie against an incoming request. * * @param Request $req * @param AuthManager $auth * * @return bool */ public function verify(Request $req, AuthManager $auth) { if (!$this->isValid()) { return false; } // verify the user agent matches the one in the request if ($this->userAgent != $req->agent()) { return false; } // look up the user with a matching email address $userClass = $auth->getUserClass(); $user = $userClass::where('email', $this->email)->first(); if (!$user) { return false; } // hash series for matching with the db $seriesHash = $this->hash($this->series); // First, make sure all of the parameters match, except the token. // We match the token separately to detect if an older session is // being used, in which case we cowardly run away. $expiration = time() - $this->getExpires(); $db = $auth->getApp()['db']; $query = $db->select('token,two_factor_verified')->from('PersistentSessions')->where('email', $this->email)->where('created_at', U::unixToDb($expiration), '>')->where('series', $seriesHash); $persistentSession = $query->one(); if ($query->rowCount() !== 1) { return false; } // if there is a match, sign the user in $tokenHash = $this->hash($this->token); // Same series, but different token, meaning the user is trying // to use an older token. It's most likely an attack, so flush // all sessions. if (!hash_equals($persistentSession['token'], $tokenHash)) { $db->delete('PersistentSessions')->where('email', $this->email)->execute(); return false; } // remove the token once used $db->delete('PersistentSessions')->where('email', $this->email)->where('series', $seriesHash)->where('token', $tokenHash)->execute(); // mark the user as 2fa verified if ($persistentSession['two_factor_verified']) { $user->markTwoFactorVerified(); } return $user; }