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