1 | <?php |
||
2 | |||
3 | namespace Fouladgar\MobileVerification\Tokens; |
||
4 | |||
5 | use Exception; |
||
6 | use Fouladgar\MobileVerification\Contracts\MustVerifyMobile; |
||
7 | use Illuminate\Database\ConnectionInterface; |
||
8 | use Illuminate\Database\Query\Builder; |
||
9 | use Illuminate\Support\Carbon; |
||
10 | |||
11 | class DatabaseTokenRepository implements TokenRepositoryInterface |
||
12 | { |
||
13 | /** |
||
14 | * The database connection instance. |
||
15 | * |
||
16 | * @var ConnectionInterface |
||
17 | */ |
||
18 | protected $connection; |
||
19 | |||
20 | /** |
||
21 | * The token database table. |
||
22 | * |
||
23 | * @var string |
||
24 | */ |
||
25 | protected $table; |
||
26 | |||
27 | /** |
||
28 | * The number of seconds a token should last. |
||
29 | * |
||
30 | * @var int |
||
31 | */ |
||
32 | protected $expires; |
||
33 | |||
34 | /** |
||
35 | * @var int |
||
36 | */ |
||
37 | protected $tokenLength; |
||
38 | |||
39 | /** |
||
40 | * Create a new token repository instance. |
||
41 | * |
||
42 | * @param ConnectionInterface $connection |
||
43 | * @param string $table |
||
44 | * @param int $expires |
||
45 | * @param int $tokenLength |
||
46 | */ |
||
47 | public function __construct( |
||
48 | ConnectionInterface $connection, |
||
49 | $table = 'mobile_verification_tokens', |
||
50 | $expires = 5, |
||
51 | $tokenLength = 5 |
||
52 | ) { |
||
53 | $this->table = $table; |
||
54 | $this->expires = $expires; |
||
55 | $this->connection = $connection; |
||
56 | $this->tokenLength = $tokenLength; |
||
57 | } |
||
58 | |||
59 | /** |
||
60 | * {@inheritdoc} |
||
61 | */ |
||
62 | public function create(MustVerifyMobile $user): string |
||
63 | { |
||
64 | $mobile = $user->getMobileForVerification(); |
||
65 | |||
66 | $this->deleteExisting($user); |
||
67 | |||
68 | $token = $this->createNewToken(); |
||
69 | |||
70 | $this->getTable()->insert($this->getPayload($mobile, $token)); |
||
71 | |||
72 | return $token; |
||
73 | } |
||
74 | |||
75 | /** |
||
76 | * Begin a new database query against the table. |
||
77 | * |
||
78 | * @return Builder |
||
79 | */ |
||
80 | protected function getTable(): Builder |
||
81 | { |
||
82 | return $this->connection->table($this->table); |
||
83 | } |
||
84 | |||
85 | /** |
||
86 | * {@inheritdoc} |
||
87 | */ |
||
88 | public function deleteExisting(MustVerifyMobile $user): ?int |
||
89 | { |
||
90 | return optional($this->getTable()->where('mobile', $user->getMobileForVerification()))->delete(); |
||
91 | } |
||
92 | |||
93 | /** |
||
94 | * {@inheritdoc} |
||
95 | */ |
||
96 | public function exists($user, $token): bool |
||
97 | { |
||
98 | /** @var MustVerifyMobile $user */ |
||
99 | $record = (array) $this->getTable() |
||
100 | ->where('mobile', $user->getMobileForVerification()) |
||
101 | ->where('token', $token) |
||
102 | ->first(); |
||
103 | |||
104 | return $record && ! $this->tokenExpired($record['expires_at']); |
||
0 ignored issues
–
show
|
|||
105 | } |
||
106 | |||
107 | /** |
||
108 | * Build the record payload for the table. |
||
109 | * |
||
110 | * @param $mobile |
||
111 | * @param string $token |
||
112 | * |
||
113 | * @throws Exception |
||
114 | * |
||
115 | * @return array |
||
116 | */ |
||
117 | protected function getPayload($mobile, $token): array |
||
118 | { |
||
119 | return ['mobile' => $mobile, 'token' => $token, 'expires_at' => now()->addMinutes($this->expires)]; |
||
120 | } |
||
121 | |||
122 | /** |
||
123 | * Create a new token for the user. |
||
124 | * |
||
125 | * @throws Exception |
||
126 | * |
||
127 | * @return string |
||
128 | */ |
||
129 | protected function createNewToken(): string |
||
130 | { |
||
131 | $tokenLength = config('mobile_verifier.token_length', 5); |
||
132 | |||
133 | return (string) random_int(10 ** ($tokenLength - 1), (10 ** $tokenLength) - 1); |
||
134 | } |
||
135 | |||
136 | /** |
||
137 | * Determine if the token has expired. |
||
138 | * |
||
139 | * @param string $expiresAt |
||
140 | * |
||
141 | * @return bool |
||
142 | */ |
||
143 | protected function tokenExpired($expiresAt): bool |
||
144 | { |
||
145 | return Carbon::parse($expiresAt)->addMinutes($this->expires)->isPast(); |
||
146 | } |
||
147 | } |
||
148 |
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.