1 <?php namespace BookStack\Auth\Access;
3 use BookStack\Auth\User;
4 use BookStack\Exceptions\UserTokenExpiredException;
5 use BookStack\Exceptions\UserTokenNotFoundException;
7 use Illuminate\Database\Connection as Database;
10 class UserTokenService
14 * Name of table where user tokens are stored.
17 protected $tokenTable = 'user_tokens';
20 * Token expiry time in hours.
23 protected $expiryTime = 24;
28 * UserTokenService constructor.
31 public function __construct(Database $db)
37 * Delete all email confirmations that belong to a user.
41 public function deleteByUser(User $user)
43 return $this->db->table($this->tokenTable)
44 ->where('user_id', '=', $user->id)
49 * Get the user id from a token, while check the token exists and has not expired.
50 * @param string $token
52 * @throws UserTokenNotFoundException
53 * @throws UserTokenExpiredException
55 public function checkTokenAndGetUserId(string $token) : int
57 $entry = $this->getEntryByToken($token);
59 if (is_null($entry)) {
60 throw new UserTokenNotFoundException('Token "' . $token . '" not found');
63 if ($this->entryExpired($entry)) {
64 throw new UserTokenExpiredException("Token of id {$token->id} has expired.", $entry->user_id);
67 return $entry->user_id;
71 * Creates a unique token within the email confirmation database.
74 protected function generateToken() : string
76 $token = str_random(24);
77 while ($this->tokenExists($token)) {
78 $token = str_random(25);
84 * Generate and store a token for the given user.
88 protected function createTokenForUser(User $user) : string
90 $token = $this->generateToken();
91 $this->db->table($this->tokenTable)->insert([
92 'user_id' => $user->id,
94 'created_at' => Carbon::now(),
95 'updated_at' => Carbon::now()
101 * Check if the given token exists.
102 * @param string $token
105 protected function tokenExists(string $token) : bool
107 return $this->db->table($this->tokenTable)
108 ->where('token', '=', $token)->exists();
112 * Get a token entry for the given token.
113 * @param string $token
114 * @return object|null
116 protected function getEntryByToken(string $token)
118 return $this->db->table($this->tokenTable)
119 ->where('token', '=', $token)
124 * Check if the given token entry has expired.
125 * @param stdClass $tokenEntry
128 protected function entryExpired(stdClass $tokenEntry) : bool
130 return Carbon::now()->subHours($this->expiryTime)
131 ->gt(new Carbon($tokenEntry->created_at));