/** * Returns an array of the user and token rows for the given token string, or throws an Exception on failure * * @param string $token * @return array * @throws \Dewdrop\Exception */ protected function getUserAndTokenRows($token) { do { if (null === $token) { break; } $tokenTable = new UserPasswordChangeTokensTableGateway(); $tokenRow = $tokenTable->fetchRow($tokenTable->select()->from($tokenTable->getTableName())->where('token = ?', $token)->where('NOT used')); if (null === $tokenRow) { break; } $usersTable = new UsersTableGateway(); $userRow = $usersTable->find($tokenRow->get('user_id')); return ['token' => $tokenRow, 'user' => $userRow]; } while (false); throw new Exception('Invalid token'); }
/** * Generate a password change token and send the given user an email with a link to reset password * * @param UserRowGateway $user * @return Auth */ public function forgotPassword(UserRowGateway $user) { $token = password_hash(openssl_random_pseudo_bytes(64), PASSWORD_BCRYPT); $tokenTableDataGateway = new UserPasswordChangeTokensTableGateway(); $tokenTableDataGateway->insert(['user_id' => $user->getId(), 'token' => $token]); if (!in_array($_SERVER['SERVER_PORT'], ['80', '443'])) { $port = ":{$_SERVER['SERVER_PORT']}"; } else { $port = ''; } if (isset($_SERVER['HTTPS']) && filter_var($_SERVER['HTTPS'], FILTER_VALIDATE_BOOLEAN)) { $scheme = 'https'; } else { $scheme = 'http'; } $resetPasswordUrl = "{$scheme}://{$_SERVER['SERVER_NAME']}{$port}/auth/reset-password?token=" . rawurlencode($token); $mailView = new MailView(); $mailView->assign('resetPasswordUrl', $resetPasswordUrl)->assign('title', $this->title)->setScriptPath(__DIR__ . '/Auth/view-scripts'); $bodyHtml = $mailView->render('forgot-password-email-html.phtml'); $bodyText = $mailView->render('forgot-password-email-text.phtml'); $message = Swift_Message::newInstance(); $message->setSubject('Reset Password')->setFrom("noreply@{$_SERVER['SERVER_NAME']}")->setTo($user->getEmailAddress()); $message->setBody($bodyHtml, 'text/html'); $message->addPart($bodyText, 'text/plain'); $this->app['mailer']->send($message); return $this; }
/** * Look in the DB for a password change token matching the current request. * * @param string $token * @return \Dewdrop\Db\Row|null */ private function findToken($token) { $tokenTable = new UserPasswordChangeTokensTableGateway(); return $tokenTable->fetchRow($tokenTable->select()->from($tokenTable->getTableName())->where('token = ?', $token)->where('used')); }