Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
EmailVerificationService
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 2
20
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 generateToken
0.00% covered (danger)
0.00%
0 / 20
0.00% covered (danger)
0.00%
0 / 1
12
1<?php
2
3namespace App\Http\Services;
4
5use App\Http\Models\Auth\EmailValidationTokens;
6use App\Http\Models\Auth\User;
7use App\Mail\EmailVerification;
8use App\Services\Email\EmailService;
9use Illuminate\Support\Facades\Cache;
10use MongoDB\BSON\UTCDateTime;
11use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException;
12
13class EmailVerificationService
14{
15
16    public function __construct(
17        private readonly EmailService $emailService
18    ) {
19        //
20    }
21
22    public function generateToken($email)
23    {
24        $randomToken = rand(99999, 999999);
25        $expiresAt = now()->addHours(24);
26        $user = User::where('email', $email)->first();
27
28        EmailValidationTokens::create([
29            'email' => $email,
30            'token' => $randomToken,
31            'attempts' => 0,
32            'expires_at' => new UTCDateTime($expiresAt->getTimestamp() * 1000),
33        ]);
34
35        $cacheKey = "verification_code_{$user->id}";
36        $attemptsKey = "verification_attempts_{$user->id}";
37        $lastSentKey = "last_verification_sent_{$user->id}";
38
39        if (Cache::has($lastSentKey) && Cache::get($lastSentKey) > now()->subMinute()) {
40            // throw http exception 429
41            $secondsLeft = Cache::get($lastSentKey)->diffInSeconds(now()->subMinute());
42            throw new TooManyRequestsHttpException($secondsLeft, 429);
43        }
44
45        Cache::put($cacheKey, $randomToken, now()->addHours(24));
46        Cache::put($attemptsKey, 0, now()->addHours(24));
47        Cache::put($lastSentKey, now(), now()->addMinutes(1));
48
49        $expiration = $expiresAt->format("m/d/Y") . " at " . $expiresAt->format("h:i A") . " PST";
50
51        $this->emailService->send($email, new EmailVerification($randomToken, $expiration), 'email_verification');
52    }
53}