Email vérifié
+Ton adresse email a bien été validée. Tu peux maintenant retourner sur l'application.
+diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7786b82..3ae7203 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -59,6 +59,15 @@ deploy-to-portainer: - apk add --no-cache curl jq gettext script: + - | + export MAIL_MAILER="${MAIL_MAILER:-smtp}" + export MAIL_SCHEME="${MAIL_SCHEME:-null}" + export MAIL_FROM_NAME="${MAIL_FROM_NAME:-$APP_NAME}" + : "${MAIL_HOST:?Missing MAIL_HOST GitLab CI/CD variable}" + : "${MAIL_PORT:?Missing MAIL_PORT GitLab CI/CD variable}" + : "${MAIL_USERNAME:?Missing MAIL_USERNAME GitLab CI/CD variable}" + : "${MAIL_PASSWORD:?Missing MAIL_PASSWORD GitLab CI/CD variable}" + : "${MAIL_FROM_ADDRESS:?Missing MAIL_FROM_ADDRESS GitLab CI/CD variable}" - envsubst < docker-compose.prod.yml > docker-compose.rendered.yml - | diff --git a/app/Http/Controllers/AuthController.php b/app/Http/Controllers/AuthController.php index e646205..740edce 100644 --- a/app/Http/Controllers/AuthController.php +++ b/app/Http/Controllers/AuthController.php @@ -6,9 +6,11 @@ use App\Http\Requests\Auth\LoginRequest; use App\Http\Requests\Auth\RegisterRequest; use App\Models\User; use Hash; +use Illuminate\Auth\Events\Verified; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use Illuminate\Validation\ValidationException; +use Illuminate\View\View; use Symfony\Component\HttpFoundation\Response; class AuthController extends Controller @@ -36,6 +38,8 @@ class AuthController extends Controller $this->resolveDeviceName($data) )->plainTextToken; + $user->sendEmailVerificationNotification(); + return response()->json([ 'token' => $token, 'token_type' => 'Bearer', @@ -79,6 +83,47 @@ class AuthController extends Controller return response()->json($user); } + public function verifyEmail(Request $request, string $id, string $hash): JsonResponse|View + { + $user = User::findOrFail($id); + + if (! hash_equals($hash, sha1($user->getEmailForVerification()))) { + abort(Response::HTTP_FORBIDDEN); + } + + if (! $user->hasVerifiedEmail()) { + $user->markEmailAsVerified(); + + event(new Verified($user)); + } + + if ($request->expectsJson()) { + return response()->json([ + 'message' => __('auth.email_verified'), + ]); + } + + return view('auth.email-verified'); + } + + public function resendEmailVerificationNotification(Request $request): JsonResponse + { + /** @var \App\Models\User $user */ + $user = $request->user(); + + if ($user->hasVerifiedEmail()) { + return response()->json([ + 'message' => __('auth.email_already_verified'), + ]); + } + + $user->sendEmailVerificationNotification(); + + return response()->json([ + 'message' => __('auth.email_verification_sent'), + ]); + } + public function logout(Request $request): JsonResponse { $request->user()?->currentAccessToken()?->delete(); diff --git a/app/Models/User.php b/app/Models/User.php index 9d4b71d..6808feb 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -2,11 +2,12 @@ namespace App\Models; -// use Illuminate\Contracts\Auth\MustVerifyEmail; use App\Enums\UserRole; +use App\Notifications\VerifyEmailNotification; use Filament\Models\Contracts\FilamentUser; use Filament\Models\Contracts\HasName; use Filament\Panel; +use Illuminate\Contracts\Auth\MustVerifyEmail; use Illuminate\Database\Eloquent\Concerns\HasUuids; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -15,7 +16,7 @@ use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; use Laravel\Sanctum\HasApiTokens; -class User extends Authenticatable implements FilamentUser, HasName +class User extends Authenticatable implements FilamentUser, HasName, MustVerifyEmail { /** @use HasFactory<\Database\Factories\UserFactory> */ use HasApiTokens, HasFactory, HasUuids, Notifiable, SoftDeletes; @@ -96,6 +97,11 @@ class User extends Authenticatable implements FilamentUser, HasName return $this->belongsTo(Level::class, 'level_id'); } + public function sendEmailVerificationNotification(): void + { + $this->notify(new VerifyEmailNotification); + } + public function updateLevel(): void { $level = Level::where('xpThreshold', '<=', $this->xp) diff --git a/app/Notifications/VerifyEmailNotification.php b/app/Notifications/VerifyEmailNotification.php new file mode 100644 index 0000000..88bfcfb --- /dev/null +++ b/app/Notifications/VerifyEmailNotification.php @@ -0,0 +1,48 @@ + + */ + public function via(object $notifiable): array + { + return ['mail']; + } + + /** + * Get the mail representation of the notification. + */ + public function toMail(object $notifiable): MailMessage + { + /** @var MustVerifyEmail $notifiable */ + $verificationUrl = URL::temporarySignedRoute( + 'verification.verify', + now()->addMinutes(Config::get('auth.verification.expire', 60)), + [ + 'id' => $notifiable->getKey(), + 'hash' => sha1($notifiable->getEmailForVerification()), + ], + ); + + return (new MailMessage) + ->subject('Vérifie ton adresse email') + ->view('mail.auth.verify-email', [ + 'notifiable' => $notifiable, + 'verificationUrl' => $verificationUrl, + ]); + } +} diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 4e7ad10..1c2f413 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -20,6 +20,14 @@ services: DB_DATABASE: "${DB_DATABASE}" DB_USERNAME: "${DB_USERNAME}" DB_PASSWORD: "${DB_PASSWORD}" + MAIL_MAILER: "${MAIL_MAILER}" + MAIL_SCHEME: "${MAIL_SCHEME}" + MAIL_HOST: "${MAIL_HOST}" + MAIL_PORT: "${MAIL_PORT}" + MAIL_USERNAME: "${MAIL_USERNAME}" + MAIL_PASSWORD: "${MAIL_PASSWORD}" + MAIL_FROM_ADDRESS: "${MAIL_FROM_ADDRESS}" + MAIL_FROM_NAME: "${MAIL_FROM_NAME}" volumes: - storage-data:/var/www/html/storage/app diff --git a/lang/en/auth.php b/lang/en/auth.php index b8a0b6f..5a16e20 100644 --- a/lang/en/auth.php +++ b/lang/en/auth.php @@ -17,5 +17,8 @@ return [ 'password' => 'The provided password is incorrect.', 'throttle' => 'Too many login attempts. Please try again in :seconds seconds.', 'logout_success' => 'You have been deconnecte', + 'email_verified' => 'Email address verified.', + 'email_already_verified' => 'Email address already verified.', + 'email_verification_sent' => 'Verification link sent.', ]; diff --git a/lang/fr/auth.php b/lang/fr/auth.php index d5ad527..9f84dfd 100644 --- a/lang/fr/auth.php +++ b/lang/fr/auth.php @@ -17,5 +17,8 @@ return [ 'password' => 'Email ou mot de passe incorrect', 'throttle' => 'Trop de tentatives veuillez reessayer dans :seconds seconds.', 'logout_success' => 'Vous êtes bien déconnecté', + 'email_verified' => 'Adresse email vérifiée.', + 'email_already_verified' => 'Adresse email déjà vérifiée.', + 'email_verification_sent' => 'Lien de vérification envoyé.', ]; diff --git a/resources/views/auth/email-verified.blade.php b/resources/views/auth/email-verified.blade.php new file mode 100644 index 0000000..fd262b2 --- /dev/null +++ b/resources/views/auth/email-verified.blade.php @@ -0,0 +1,48 @@ + + +
+ + +Ton adresse email a bien été validée. Tu peux maintenant retourner sur l'application.
+| + + | +