]> BookStack Code Mirror - bookstack/blob - app/Services/EmailConfirmationService.php
Trying to make the tests green.
[bookstack] / app / Services / EmailConfirmationService.php
1 <?php namespace BookStack\Services;
2
3 use BookStack\Notifications\ConfirmEmail;
4 use BookStack\Repos\UserRepo;
5 use Carbon\Carbon;
6 use BookStack\Exceptions\ConfirmationEmailException;
7 use BookStack\Exceptions\UserRegistrationException;
8 use BookStack\User;
9 use Illuminate\Database\Connection as Database;
10
11 class EmailConfirmationService
12 {
13     protected $db;
14     protected $users;
15
16     /**
17      * EmailConfirmationService constructor.
18      * @param Database $db
19      * @param UserRepo $users
20      */
21     public function __construct(Database $db, UserRepo $users)
22     {
23         $this->db = $db;
24         $this->users = $users;
25     }
26
27     /**
28      * Create new confirmation for a user,
29      * Also removes any existing old ones.
30      * @param User $user
31      * @throws ConfirmationEmailException
32      */
33     public function sendConfirmation(User $user)
34     {
35         if ($user->email_confirmed) {
36             throw new ConfirmationEmailException(trans('errors.email_already_confirmed'), '/login');
37         }
38
39         $this->deleteConfirmationsByUser($user);
40         $token = $this->createEmailConfirmation($user);
41
42         $user->notify(new ConfirmEmail($token));
43     }
44
45     /**
46      * Creates a new email confirmation in the database and returns the token.
47      * @param User $user
48      * @return string
49      */
50     public function createEmailConfirmation(User $user)
51     {
52         $token = $this->getToken();
53         $this->db->table('email_confirmations')->insert([
54             'user_id' => $user->id,
55             'token' => $token,
56             'created_at' => Carbon::now(),
57             'updated_at' => Carbon::now()
58         ]);
59         return $token;
60     }
61
62     /**
63      * Gets an email confirmation by looking up the token,
64      * Ensures the token has not expired.
65      * @param string $token
66      * @return array|null|\stdClass
67      * @throws UserRegistrationException
68      */
69     public function getEmailConfirmationFromToken($token)
70     {
71         $emailConfirmation = $this->db->table('email_confirmations')->where('token', '=', $token)->first();
72
73         // If not found show error
74         if ($emailConfirmation === null) {
75             throw new UserRegistrationException(trans('errors.email_confirmation_invalid'), '/register');
76         }
77
78         // If more than a day old
79         if (Carbon::now()->subDay()->gt(new Carbon($emailConfirmation->created_at))) {
80             $user = $this->users->getById($emailConfirmation->user_id);
81             $this->sendConfirmation($user);
82             throw new UserRegistrationException(trans('errors.email_confirmation_expired'), '/register/confirm');
83         }
84
85         $emailConfirmation->user = $this->users->getById($emailConfirmation->user_id);
86         return $emailConfirmation;
87     }
88
89     /**
90      * Delete all email confirmations that belong to a user.
91      * @param User $user
92      * @return mixed
93      */
94     public function deleteConfirmationsByUser(User $user)
95     {
96         return $this->db->table('email_confirmations')->where('user_id', '=', $user->id)->delete();
97     }
98
99     /**
100      * Creates a unique token within the email confirmation database.
101      * @return string
102      */
103     protected function getToken()
104     {
105         $token = str_random(24);
106         while ($this->db->table('email_confirmations')->where('token', '=', $token)->exists()) {
107             $token = str_random(25);
108         }
109         return $token;
110     }
111
112
113 }