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    public function __construct(
16        private readonly EmailService $emailService
17    ) {
18        //
19    }
20
21    public function generateToken($email)
22    {
23        $randomToken = rand(99999, 999999);
24        $expiresAt = now()->addHours(24);
25        $user = User::where('email', $email)->first();
26
27        $cacheKey = "verification_code_{$user->id}";
28        $attemptsKey = "verification_attempts_{$user->id}";
29        $lastSentKey = "last_verification_sent_{$user->id}";
30
31        if (Cache::has($lastSentKey) && Cache::get($lastSentKey) > now()->subMinute()) {
32            $secondsLeft = Cache::get($lastSentKey)->diffInSeconds(now()->subMinute());
33            throw new TooManyRequestsHttpException($secondsLeft, 'Too many requests. Please wait before requesting a new code.');
34        }
35
36        EmailValidationTokens::create([
37            'email' => $email,
38            'token' => $randomToken,
39            'attempts' => 0,
40            'expires_at' => new UTCDateTime($expiresAt->getTimestamp() * 1000),
41        ]);
42
43        Cache::put($cacheKey, $randomToken, now()->addHours(24));
44        Cache::put($attemptsKey, 0, now()->addHours(24));
45        Cache::put($lastSentKey, now(), now()->addMinutes(1));
46
47        $expiration = $expiresAt->format('m/d/Y').' at '.$expiresAt->format('h:i A').' PST';
48
49        $this->emailService->send($email, new EmailVerification($randomToken, $expiration), 'email_verification');
50    }
51}