1 <?php namespace BookStack\Services;
5 use Illuminate\Contracts\Mail\Mailer;
6 use Illuminate\Mail\Message;
7 use BookStack\EmailConfirmation;
8 use BookStack\Exceptions\ConfirmationEmailException;
9 use BookStack\Exceptions\UserRegistrationException;
10 use BookStack\Repos\UserRepo;
11 use BookStack\Setting;
14 class EmailConfirmationService
17 protected $emailConfirmation;
20 * EmailConfirmationService constructor.
21 * @param Mailer $mailer
22 * @param EmailConfirmation $emailConfirmation
24 public function __construct(Mailer $mailer, EmailConfirmation $emailConfirmation)
26 $this->mailer = $mailer;
27 $this->emailConfirmation = $emailConfirmation;
31 * Create new confirmation for a user,
32 * Also removes any existing old ones.
34 * @throws ConfirmationEmailException
36 public function sendConfirmation(User $user)
38 if ($user->email_confirmed) {
39 throw new ConfirmationEmailException('Email has already been confirmed, Try logging in.', '/login');
41 $this->deleteConfirmationsByUser($user);
42 $token = $this->getToken();
43 $this->emailConfirmation->create([
44 'user_id' => $user->id,
47 $this->mailer->send('emails/email-confirmation', ['token' => $token], function (Message $message) use ($user) {
48 $appName = setting('app-name', 'BookStack');
49 $message->to($user->email, $user->name)->subject('Confirm your email on ' . $appName . '.');
54 * Gets an email confirmation by looking up the token,
55 * Ensures the token has not expired.
56 * @param string $token
57 * @return EmailConfirmation
58 * @throws UserRegistrationException
60 public function getEmailConfirmationFromToken($token)
62 $emailConfirmation = $this->emailConfirmation->where('token', '=', $token)->first();
64 if ($emailConfirmation === null) {
65 throw new UserRegistrationException('This confirmation token is not valid or has already been used, Please try registering again.', '/register');
68 // If more than a day old
69 if (Carbon::now()->subDay()->gt($emailConfirmation->created_at)) {
70 $this->sendConfirmation($emailConfirmation->user);
71 throw new UserRegistrationException('The confirmation token has expired, A new confirmation email has been sent.', '/register/confirm');
74 return $emailConfirmation;
79 * Delete all email confirmations that belong to a user.
83 public function deleteConfirmationsByUser(User $user)
85 return $this->emailConfirmation->where('user_id', '=', $user->id)->delete();
89 * Creates a unique token within the email confirmation database.
92 protected function getToken()
94 $token = str_random(24);
95 while ($this->emailConfirmation->where('token', '=', $token)->exists()) {
96 $token = str_random(25);