table = $table; $this->hasher = $hasher; $this->hashKey = $hashKey; $this->expires = $expires * 60; $this->connection = $connection; $this->throttle = $throttle; } /** * Create a new token record. * * @param \Illuminate\Contracts\Auth\CanResetPassword $user * @return string */ public function create(CanResetPasswordContract $user) { $email = $user->getEmailForPasswordReset(); $this->deleteExisting($user); // We will create a new, random token for the user so that we can e-mail them // a safe link to the password reset form. Then we will insert a record in // the database so that we can verify the token within the actual reset. $token = $this->createNewToken(); $this->getTable()->insert($this->getPayload($email, $token)); return $token; } /** * Delete all existing reset tokens from the database. * * @param \Illuminate\Contracts\Auth\CanResetPassword $user * @return int */ protected function deleteExisting(CanResetPasswordContract $user) { return $this->getTable()->where('email', $user->getEmailForPasswordReset())->delete(); } /** * Build the record payload for the table. * * @param string $email * @param string $token * @return array */ protected function getPayload($email, $token) { return ['email' => $email, 'token' => $this->hasher->make($token), 'created_at' => new Carbon]; } /** * Determine if a token record exists and is valid. * * @param \Illuminate\Contracts\Auth\CanResetPassword $user * @param string $token * @return bool */ public function exists(CanResetPasswordContract $user, $token) { $record = (array) $this->getTable()->where( 'email', $user->getEmailForPasswordReset() )->first(); return $record && ! $this->tokenExpired($record['created_at']) && $this->hasher->check($token, $record['token']); } /** * Determine if the token has expired. * * @param string $createdAt * @return bool */ protected function tokenExpired($createdAt) { return Carbon::parse($createdAt)->addSeconds($this->expires)->isPast(); } /** * Determine if the given user recently created a password reset token. * * @param \Illuminate\Contracts\Auth\CanResetPassword $user * @return bool */ public function recentlyCreatedToken(CanResetPasswordContract $user) { $record = (array) $this->getTable()->where( 'email', $user->getEmailForPasswordReset() )->first(); return $record && $this->tokenRecentlyCreated($record['created_at']); } /** * Determine if the token was recently created. * * @param string $createdAt * @return bool */ protected function tokenRecentlyCreated($createdAt) { if ($this->throttle <= 0) { return false; } return Carbon::parse($createdAt)->addSeconds( $this->throttle )->isFuture(); } /** * Delete a token record by user. * * @param \Illuminate\Contracts\Auth\CanResetPassword $user * @return void */ public function delete(CanResetPasswordContract $user) { $this->deleteExisting($user); } /** * Delete expired tokens. * * @return void */ public function deleteExpired() { $expiredAt = Carbon::now()->subSeconds($this->expires); $this->getTable()->where('created_at', '<', $expiredAt)->delete(); } /** * Create a new token for the user. * * @return string */ public function createNewToken() { return hash_hmac('sha256', Str::random(40), $this->hashKey); } /** * Get the database connection instance. * * @return \Illuminate\Database\ConnectionInterface */ public function getConnection() { return $this->connection; } /** * Begin a new database query against the table. * * @return \Illuminate\Database\Query\Builder */ protected function getTable() { return $this->connection->table($this->table); } /** * Get the hasher instance. * * @return \Illuminate\Contracts\Hashing\Hasher */ public function getHasher() { return $this->hasher; } }