request = $request; $this->pdm = new PersistentDataManager(); $this->userRepository = new UserRepository(); $this->userConfirmationRepository = new UserConfirmationRepository(); } public function getSignupForm() { if ($this->request->user() !== null) { return new Redirect([\Container::$routeCollection->getRoute('index'), []], IRedirect::TEMPORARY); } $data = []; return new HtmlContent('signup/signup', $data); } public function signup(): IContent { if ($this->request->user() !== null) { //TODO: return with some error $data = ['success' => true]; return new JsonContent($data); } if (filter_var($this->request->post('email'), FILTER_VALIDATE_EMAIL) === false) { $data = ['error' => 'email_not_valid']; return new JsonContent($data); } $user = $this->userRepository->getByEmail($this->request->post('email')); if ($user !== null) { if ($user->getActive()) { $data = ['error' => 'user_found']; } else { $data = ['error' => 'not_active_user_found']; } return new JsonContent($data); } if (strlen($this->request->post('password')) < 6) { $data = ['error' => 'passwords_too_short']; return new JsonContent($data); } if ($this->request->post('password') !== $this->request->post('password_confirm')) { $data = ['error' => 'passwords_not_match']; return new JsonContent($data); } $user = new User(); $user->setEmail($this->request->post('email')); $user->setPlainPassword($this->request->post('password')); \Container::$dbConnection->startTransaction(); $this->pdm->saveToDb($user); $token = hash('sha256', serialize($user) . random_bytes(10) . microtime()); $confirmation = new UserConfirmation(); $confirmation->setUser($user); $confirmation->setToken($token); $this->pdm->saveToDb($confirmation); \Container::$dbConnection->commit(); $this->sendConfirmationEmail($user->getEmail(), $token); $data = ['success' => true]; return new JsonContent($data); } public function activate() { if ($this->request->user() !== null) { return new Redirect([\Container::$routeCollection->getRoute('index'), []], IRedirect::TEMPORARY); } $confirmation = $this->userConfirmationRepository->getByToken($this->request->query('token')); if ($confirmation === null) { $data = []; return new HtmlContent('signup/activate', $data); } \Container::$dbConnection->startTransaction(); $this->pdm->deleteFromDb($confirmation); $user = $this->userRepository->getById($confirmation->getUserId()); $user->setActive(true); $this->pdm->saveToDb($user); \Container::$dbConnection->commit(); $this->request->setUser($user); return new Redirect([\Container::$routeCollection->getRoute('index'), []], IRedirect::TEMPORARY); } public function cancel() { if ($this->request->user() !== null) { return new Redirect([\Container::$routeCollection->getRoute('index'), []], IRedirect::TEMPORARY); } $confirmation = $this->userConfirmationRepository->getByToken($this->request->query('token')); if ($confirmation === null) { $data = ['success' => false]; return new HtmlContent('signup/cancel', $data); } \Container::$dbConnection->startTransaction(); $this->pdm->deleteFromDb($confirmation); $user = $this->userRepository->getById($confirmation->getUserId()); $this->pdm->deleteFromDb($user); \Container::$dbConnection->commit(); $data = ['success' => true]; return new HtmlContent('signup/cancel', $data); } private function sendConfirmationEmail($email, $token): void { $mail = new Mail(); $mail->addRecipient($email); $mail->setSubject('Welcome to MapGuesser - Activate your account'); $mail->setBodyFromTemplate('signup', [ 'EMAIL' => $email, 'ACTIVATE_LINK' => $this->request->getBase() . '/signup/activate/' . $token, 'CANCEL_LINK' => $this->request->getBase() . '/signup/cancel/' . $token, ]); $mail->send(); } }