/** * Start password reset * * @param string $username Username of a user * @return void * * @validate $username NotEmpty */ public function startPasswordResetAction($username) { $user = $this->frontendUserRepository->findOneByUsername($username); // Forbid password reset if there is no password or password property, // e.g. if the user has not completed a special registration process // or is supposed to authenticate in some other way $password = ObjectAccess::getPropertyPath($user, 'password'); if ($password === NULL) { $this->logger->error('Failed to initiate password reset for user "' . $username . '": no password present'); $this->addLocalizedFlashMessage('resetPassword.failed.nopassword', NULL, FlashMessage::ERROR); $this->redirect('showPasswordResetForm'); } $hash = md5(GeneralUtility::generateRandomBytes(64)); $token = array('uid' => $user->getUid(), 'hmac' => $this->hashService->generateHmac($password)); $tokenLifetime = $this->getSettingValue('passwordReset.token.lifetime'); // Remove possibly existing reset tokens and store new one $this->tokenCache->flushByTag($user->getUid()); $this->tokenCache->set($hash, $token, array($user->getUid()), $tokenLifetime); $expiryDate = new \DateTime(sprintf('now + %d seconds', $tokenLifetime)); $hashUri = $this->uriBuilder->setTargetPageUid($this->getSettingValue('passwordReset.page'))->setUseCacheHash(FALSE)->setCreateAbsoluteUri(TRUE)->uriFor('showPasswordResetForm', array('hash' => $hash)); /** @var \PAGEmachine\Hairu\Domain\DTO\PasswordResetRequestTransferObject $passwordResetRequestTransferObject */ $passwordResetRequestTransferObject = GeneralUtility::makeInstance('PAGEmachine\\Hairu\\Domain\\DTO\\PasswordResetRequestTransferObject'); $passwordResetRequestTransferObject->setUser($user); $passwordResetRequestTransferObject->setHash($hash); $passwordResetRequestTransferObject->setHashUri($hashUri); $passwordResetRequestTransferObject->setExpiryDate($expiryDate); $actionVariables = array('user' => $user, 'hash' => $hash, 'hashUri' => $hashUri, 'expiryDate' => $expiryDate); $this->view->assignMultiple($actionVariables); /** @var \TYPO3\CMS\Core\Mail\MailMessage $message */ $message = $this->objectManager->get('TYPO3\\CMS\\Core\\Mail\\MailMessage'); $message->setFrom($this->getSettingValue('passwordReset.mail.from'))->setTo($user->getEmail())->setSubject($this->getSettingValue('passwordReset.mail.subject')); $this->request->setFormat('txt'); $message->setBody($this->view->render('passwordResetMail'), 'text/plain'); $this->request->setFormat('html'); $message->addPart($this->view->render('passwordResetMail'), 'text/html'); $mailSent = FALSE; $passwordResetRequestTransferObject->setMessage($message); $this->emitBeforePasswordResetMailSendSignal($passwordResetRequestTransferObject); try { $mailSent = $message->send(); } catch (\Swift_SwiftException $e) { $this->logger->error($e->getMessage()); } if ($mailSent) { $this->addLocalizedFlashMessage('resetPassword.started', NULL, FlashMessage::INFO); } else { $this->addLocalizedFlashMessage('resetPassword.failed.sending', NULL, FlashMessage::ERROR); } $this->redirect('showPasswordResetForm'); }