Add last_verification_mail_sent_at column to users table and create action for sending verification mail
ADD
app/Actions/SendVerificationMailAction.php
+<?php
+
+namespace App\Actions;
+
+use App\Exceptions\UserAlreadyVerifiedException;
+use App\Exceptions\UserNotFoundException;
+use App\Exceptions\VerificationMailRateLimitException;
+use App\Mail\VerifyRegistration;
+use App\Models\User;
+use Illuminate\Support\Facades\Mail;
+
+class SendVerificationMailAction
+{
+ public function execute(int $userId): void
+ {
+ $user = User::find($userId);
+
+ if (!$user) {
+ throw new UserNotFoundException();
+ }
+
+ if (!$user->verification_token) {
+ throw new UserAlreadyVerifiedException();
+ }
+
+ $differenceInSeconds = strtotime('now') - strtotime($user->last_verification_mail_sent_at);
+
+ if ($user->last_verification_mail_sent_at && $differenceInSeconds < 300) {
+ throw new VerificationMailRateLimitException();
+ }
+
+ Mail::to($user->email)->queue(new VerifyRegistration($user));
+
+ $user->fill([
+ 'last_verification_mail_sent_at' => date('Y-m-d H:i:s')
+ ])->save();
+ }
+}

ADD
app/Exceptions/UserAlreadyVerifiedException.php
+<?php
+
+namespace App\Exceptions;
+
+use Exception;
+
+class UserAlreadyVerifiedException extends Exception
+{
+ //
+}

ADD
app/Exceptions/UserNotFoundException.php
+<?php
+
+namespace App\Exceptions;
+
+use Exception;
+
+class UserNotFoundException extends Exception
+{
+ //
+}

ADD
app/Exceptions/VerificationMailRateLimitException.php
+<?php
+
+namespace App\Exceptions;
+
+use Exception;
+
+class VerificationMailRateLimitException extends Exception
+{
+ //
+}

MODIFY
app/Http/Controllers/RegisterController.php
app/Http/Controllers/RegisterController.php
namespace App\Http\Controllers;
use App\Actions\StoreSpaceInSessionAction;
+use App\Actions\SendVerificationMailAction;
use App\Models\LoginAttempt;
use Illuminate\Http\Request;
// use App\Http\Controllers\Controller;
-use App\Mail\VerifyRegistration;
use App\Repositories\CurrencyRepository;
use App\Repositories\LoginAttemptRepository;
use App\Repositories\SpaceRepository;
use App\Repositories\UserRepository;
use Illuminate\Support\Facades\Auth;
-use Mail;
class RegisterController extends Controller
{
@@ -49,7 +48,7 @@ class RegisterController extends Controller
$space = $this->spaceRepository->create($request->currency, $user->name . '\'s Space');
$user->spaces()->attach($space->id, ['role' => 'admin']);
- Mail::to($user->email)->queue(new VerifyRegistration($user));
+ (new SendVerificationMailAction())->execute($user->id);
Auth::loginUsingId($user->id);

MODIFY
app/Models/User.php
app/Models/User.php
@@ -13,7 +13,8 @@ class User extends Authenticatable
'name',
'email',
'password',
- 'verification_token'
+ 'verification_token',
+ 'last_verification_mail_sent_at'
];
protected $hidden = [

ADD
database/migrations/2020_07_21_184946_add_last_verification_mail_sent_at_column_to_users_table.php
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class AddLastVerificationMailSentAtColumnToUsersTable extends Migration
+{
+ public function up(): void
+ {
+ Schema::table('users', function (Blueprint $table) {
+ $table->dateTime('last_verification_mail_sent_at')->nullable()->after('verification_token');
+ });
+ }
+
+ public function down(): void
+ {
+ Schema::table('users', function (Blueprint $table) {
+ $table->dropColumn('last_verification_mail_sent_at');
+ });
+ }
+}

Add last_verification_mail_sent_at column to users table and create action for sending verification mail