/** * 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 value($start, $end) { return (int) $this->app['db']->select('COUNT(uid)')->from('Users')->where([['created_at', U::unixToDb($end), '<='], ['created_at', U::unixToDb($start), '>=']])->scalar(); }
/** * Upgrades the user from temporary to a fully registered account. * * @param array $data user data * * @throws InvalidArgumentException when trying to upgrade a non-temporary account. * * @return bool true if successful */ public function upgradeTemporaryAccount($data) { if (!$this->isTemporary()) { throw new InvalidArgumentException('Cannot upgrade a non-temporary account'); } $updateArray = array_replace($data, ['created_at' => U::unixToDb(time()), 'enabled' => true]); $success = false; $this->grantAllPermissions(); $this->_isUpgrade = true; if ($this->set($updateArray)) { // remove temporary and unverified links $app = $this->getApp(); $app['db']->delete('UserLinks')->where('user_id', $this->id())->where(function ($query) { return $query->where('type', UserLink::TEMPORARY)->orWhere('type', UserLink::VERIFY_EMAIL); })->execute(); // send the user a welcome message $this->sendEmail('welcome'); $success = true; } $this->_isUpgrade = false; $this->enforcePermissions(); return $success; }
/** * Clears out expired user links. * * @return bool */ private function gcUserLinks() { return (bool) $this->app['db']->delete('UserLinks')->where('type', UserLink::FORGOT_PASSWORD)->where('created_at', U::unixToDb(time() - UserLink::$forgotLinkTimeframe), '<')->execute(); }
/** * 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; }