Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 66 |
|
0.00% |
0 / 3 |
CRAP | |
0.00% |
0 / 1 |
VerificationController | |
0.00% |
0 / 66 |
|
0.00% |
0 / 3 |
110 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
verifyByCode | |
0.00% |
0 / 52 |
|
0.00% |
0 / 1 |
42 | |||
resend | |
0.00% |
0 / 13 |
|
0.00% |
0 / 1 |
12 |
1 | <?php |
2 | |
3 | namespace App\Http\Controllers\v1\UserAuth; |
4 | |
5 | use App\Http\Controllers\Controller; |
6 | use App\Http\Models\Auth\EmailValidationTokens; |
7 | use App\Http\Models\Auth\User; |
8 | use App\Http\Services\EmailVerificationService; |
9 | use Illuminate\Auth\Access\AuthorizationException; |
10 | use Illuminate\Foundation\Auth\VerifiesEmails; |
11 | use Illuminate\Http\JsonResponse; |
12 | use Illuminate\Http\Request; |
13 | use Illuminate\Support\Facades\Cache; |
14 | use MongoDB\BSON\UTCDateTime; |
15 | |
16 | class VerificationController extends Controller |
17 | { |
18 | use VerifiesEmails; |
19 | |
20 | public function __construct( |
21 | private readonly EmailVerificationService $emailVerificationService |
22 | ) {} |
23 | |
24 | public function verifyByCode(Request $request): JsonResponse |
25 | { |
26 | $validation = [ |
27 | 'email' => 'required|string|email', |
28 | 'verification_code' => 'required|string', |
29 | ]; |
30 | $validatedData = $request->validate($validation); |
31 | |
32 | $user = User::where('email', $validatedData['email'])->first(); |
33 | |
34 | if (!$user) { |
35 | throw new AuthorizationException; |
36 | } |
37 | |
38 | if (!empty($user->email_verified_at)) { |
39 | return response()->json([ |
40 | 'error' => 'Email has already been verified.', |
41 | 'error_type' => 'already_verified', |
42 | ])->setStatusCode(200); |
43 | } |
44 | |
45 | $cacheKey = "verification_code_{$user->id}"; |
46 | $attemptsKey = "verification_attempts_{$user->id}"; |
47 | |
48 | $storedCode = Cache::get($cacheKey); |
49 | $attempts = Cache::get($attemptsKey, 0); |
50 | |
51 | if (!$storedCode) { |
52 | return response()->json([ |
53 | 'error' => "Your code has expired.", |
54 | 'error_type' => 'expired_code', |
55 | 'attempts_left' => 0, |
56 | ], 400); |
57 | } |
58 | |
59 | $verification_code = $validatedData['verification_code']; |
60 | |
61 | if ($attempts >= 5) { |
62 | Cache::forget($cacheKey); |
63 | Cache::forget($attemptsKey); |
64 | return response()->json([ |
65 | 'error' => "You've exceeded the number of attempts.", |
66 | 'error_type' => 'expired_code', |
67 | 'attempts_left' => 0, |
68 | ], 403); |
69 | } |
70 | |
71 | $token = EmailValidationTokens::where('email', $validatedData['email']) |
72 | ->where('used', '!=', true) |
73 | ->latest() |
74 | ->first(); |
75 | |
76 | $token->increment('attempts'); |
77 | Cache::increment($attemptsKey); |
78 | |
79 | if ($verification_code != $storedCode) { |
80 | return response()->json([ |
81 | 'error' => 'Code is invalid or expired.', |
82 | 'error_type' => 'invalid_code', |
83 | 'attempts_left' => 5 - ($attempts + 1), |
84 | ], 400); |
85 | } |
86 | |
87 | Cache::forget($cacheKey); |
88 | Cache::forget($attemptsKey); |
89 | |
90 | $token->used = true; |
91 | $token->save(); |
92 | $user->email_verified_at = new UTCDateTime(now()->getTimestamp() * 1000); |
93 | $user->save(); |
94 | |
95 | $user->sendWelcomeNotification(); |
96 | |
97 | return response()->json(['message' => 'Email has been verified.']); |
98 | } |
99 | |
100 | public function resend(Request $request): JsonResponse |
101 | { |
102 | $data = $request->validate([ |
103 | 'email' => 'required|string|email', |
104 | ]); |
105 | |
106 | $user = User::where('email', $data['email'])->first(); |
107 | |
108 | if (!$user) { |
109 | throw new AuthorizationException; |
110 | } |
111 | |
112 | if (!empty($user->email_verified_at)) { |
113 | return response()->json([ |
114 | 'error' => 'Email has already been verified.', |
115 | 'error_type' => 'already_verified', |
116 | ])->setStatusCode(200); |
117 | } |
118 | |
119 | $this->emailVerificationService->generateToken($data['email']); |
120 | |
121 | return response()->json(['message' => 'We have e-mailed your verification link!']); |
122 | } |
123 | } |