diff --git a/app/Http/Controllers/AdminInviteController.php b/app/Http/Controllers/AdminInviteController.php index 9375b561b..01c739509 100644 --- a/app/Http/Controllers/AdminInviteController.php +++ b/app/Http/Controllers/AdminInviteController.php @@ -6,6 +6,7 @@ use App\Models\AdminInvite; use App\Models\User; use App\Rules\ValidUsername; use App\Services\EmailService; +use App\Services\EmailVerificationService; use Illuminate\Auth\Events\Registered; use Illuminate\Contracts\View\View; use Illuminate\Http\JsonResponse; @@ -170,6 +171,8 @@ class AdminInviteController extends Controller if ($invite->skip_email_verification) { $user->email_verified_at = now(); $user->save(); + } else { + EmailVerificationService::send($user); } if (Auth::attempt([ diff --git a/tests/Feature/AdminInviteVerificationEmailTest.php b/tests/Feature/AdminInviteVerificationEmailTest.php new file mode 100644 index 000000000..ba376ff07 --- /dev/null +++ b/tests/Feature/AdminInviteVerificationEmailTest.php @@ -0,0 +1,91 @@ + true]); +}); + +function makeInvite(bool $skipEmailVerification): AdminInvite +{ + $invite = new AdminInvite; + $invite->skip_email_verification = $skipEmailVerification; + $invite->max_uses = 10; + $invite->uses = 0; + $invite->save(); + + return $invite->refresh(); +} + +it('sends a verification email when the invite requires verification', function () { + Mail::fake(); + + $invite = makeInvite(skipEmailVerification: false); + + $this->withoutMiddleware(ThrottleRequests::class) + ->postJson('/api/v1.1/auth/invite/admin/re', [ + 'token' => $invite->invite_code, + 'username' => 'inviteduser', + 'name' => 'Invited User', + 'email' => 'invited.admininvite@gmail.com', + 'password' => 'SecurePass123!', + 'password_confirm' => 'SecurePass123!', + ])->assertRedirect('/'); + + $user = User::where('email', 'invited.admininvite@gmail.com')->first(); + + expect($user)->not->toBeNull() + ->and($user->email_verified_at)->toBeNull(); + + // A verification row + email were produced for the new address. + expect( + EmailVerification::where('user_id', $user->id)->where('email', $user->email)->exists() + )->toBeTrue(); + + Mail::assertSent(ConfirmEmail::class); +}); + +it('auto-verifies and sends no email when the invite skips verification', function () { + Mail::fake(); + + $invite = makeInvite(skipEmailVerification: true); + + $this->withoutMiddleware(ThrottleRequests::class) + ->postJson('/api/v1.1/auth/invite/admin/re', [ + 'token' => $invite->invite_code, + 'username' => 'autoverified', + 'name' => 'Auto Verified', + 'email' => 'auto.admininvite@gmail.com', + 'password' => 'SecurePass123!', + 'password_confirm' => 'SecurePass123!', + ])->assertRedirect('/'); + + $user = User::where('email', 'auto.admininvite@gmail.com')->first(); + + expect($user)->not->toBeNull() + ->and($user->email_verified_at)->not->toBeNull(); + + expect(EmailVerification::where('user_id', $user->id)->exists())->toBeFalse(); + Mail::assertNothingSent(); +});