]> BookStack Code Mirror - bookstack/blob - app/Auth/Access/UserTokenService.php
Start user invite system
[bookstack] / app / Auth / Access / UserTokenService.php
1 <?php namespace BookStack\Auth\Access;
2
3 use BookStack\Auth\User;
4 use BookStack\Exceptions\UserTokenExpiredException;
5 use BookStack\Exceptions\UserTokenNotFoundException;
6 use Carbon\Carbon;
7 use Illuminate\Database\Connection as Database;
8 use stdClass;
9
10 class UserTokenService
11 {
12
13     /**
14      * Name of table where user tokens are stored.
15      * @var string
16      */
17     protected $tokenTable = 'user_tokens';
18
19     /**
20      * Token expiry time in hours.
21      * @var int
22      */
23     protected $expiryTime = 24;
24
25     protected $db;
26
27     /**
28      * UserTokenService constructor.
29      * @param Database $db
30      */
31     public function __construct(Database $db)
32     {
33         $this->db = $db;
34     }
35
36     /**
37      * Delete all email confirmations that belong to a user.
38      * @param User $user
39      * @return mixed
40      */
41     public function deleteByUser(User $user)
42     {
43         return $this->db->table($this->tokenTable)
44             ->where('user_id', '=', $user->id)
45             ->delete();
46     }
47
48     /**
49      * Get the user id from a token, while check the token exists and has not expired.
50      * @param string $token
51      * @return int
52      * @throws UserTokenNotFoundException
53      * @throws UserTokenExpiredException
54      */
55     public function checkTokenAndGetUserId(string $token) : int
56     {
57         $entry = $this->getEntryByToken($token);
58
59         if (is_null($entry)) {
60             throw new UserTokenNotFoundException('Token "' . $token . '" not found');
61         }
62
63         if ($this->entryExpired($entry)) {
64             throw new UserTokenExpiredException("Token of id {$token->id} has expired.", $entry->user_id);
65         }
66
67         return $entry->user_id;
68     }
69
70     /**
71      * Creates a unique token within the email confirmation database.
72      * @return string
73      */
74     protected function generateToken() : string
75     {
76         $token = str_random(24);
77         while ($this->tokenExists($token)) {
78             $token = str_random(25);
79         }
80         return $token;
81     }
82
83     /**
84      * Generate and store a token for the given user.
85      * @param User $user
86      * @return string
87      */
88     protected function createTokenForUser(User $user) : string
89     {
90         $token = $this->generateToken();
91         $this->db->table($this->tokenTable)->insert([
92             'user_id' => $user->id,
93             'token' => $token,
94             'created_at' => Carbon::now(),
95             'updated_at' => Carbon::now()
96         ]);
97         return $token;
98     }
99
100     /**
101      * Check if the given token exists.
102      * @param string $token
103      * @return bool
104      */
105     protected function tokenExists(string $token) : bool
106     {
107         return $this->db->table($this->tokenTable)
108             ->where('token', '=', $token)->exists();
109     }
110
111     /**
112      * Get a token entry for the given token.
113      * @param string $token
114      * @return object|null
115      */
116     protected function getEntryByToken(string $token)
117     {
118         return $this->db->table($this->tokenTable)
119             ->where('token', '=', $token)
120             ->first();
121     }
122
123     /**
124      * Check if the given token entry has expired.
125      * @param stdClass $tokenEntry
126      * @return bool
127      */
128     protected function entryExpired(stdClass $tokenEntry) : bool
129     {
130         return Carbon::now()->subHours($this->expiryTime)
131             ->gt(new Carbon($tokenEntry->created_at));
132     }
133
134 }