# 18. Registration Email Verification Flow

Date: 2026-04-20

## What Was Implemented

- Enabled Laravel email verification on the `User` model so the default verification notification is sent through the configured SMTP mailer.
- Replaced the default link-based verification with a CEPI 6-digit email verification code flow delivered through SMTP.
- Verification codes now remain valid for 2 days unless a newer code is issued.
- Updated form-based registration so newly created users are marked with `source_type = form`, logged in, and redirected to the email verification notice inside the same registration screen instead of the dashboard.
- Updated Google authentication so Google-based accounts are created as already verified and marked with `source_type = google_auth`.
- Preserved the existing role and `user_type` behavior so the verification change only affects the registration source and access gating.
- Refreshed the login and registration typography so the auth screens better match the main CEPI landing page scale.

## File Structure Changes

- Added migration:
  - `database/migrations/2026_04_20_110000_add_source_type_to_users_table.php`
  - `database/migrations/2026_04_20_121000_add_email_verification_code_to_users_table.php`
- Updated auth/model files:
  - `app/Models/User.php`
  - `app/Http/Controllers/Auth/RegisteredUserController.php`
  - `app/Http/Controllers/Auth/SocialAuthController.php`
  - `app/Http/Controllers/Auth/EmailVerificationPromptController.php`
  - `app/Http/Controllers/Auth/EmailVerificationNotificationController.php`
  - `app/Http/Controllers/Auth/VerifyEmailController.php`
  - `app/Notifications/Auth/VerifyEmailCodeNotification.php`
  - `resources/views/auth/student-register.blade.php`
  - `resources/views/auth/student-login.blade.php`
  - `resources/views/components/ui/input.blade.php`
  - `resources/views/components/ui/select.blade.php`
  - `resources/views/components/ui/button.blade.php`
  - `routes/auth.php`

## Behavior Notes

- Form registration now follows this sequence:
  1. Create user
  2. Set `source_type = form`
  3. Fire the `Registered` event
  4. Generate and store a 6-digit verification code with expiry
  5. Send the verification code email via SMTP
  6. Redirect the signed-in user to the verification notice page rendered inside the registration layout
- Google authentication now follows this sequence:
  1. Create or restore user
  2. Set `source_type = google_auth` on first Google-based creation
  3. Set `email_verified_at` immediately
  4. Continue directly to the dashboard
- The `/verify-email` route now presents:
  - a code input form
  - a resend code action
  - the CEPI auth branding instead of the default Breeze verification template
- On successful verification, `email_verified_at` is filled but the stored `email_verification_code` and `email_verification_code_expires_at` values are retained for audit/reference instead of being nulled.

## Assumptions Made

- Existing users are backfilled to `source_type = form` because their original registration source cannot be derived safely from current production data.
- If a user originally registers via form and later signs in with Google using the same email address, the original `source_type` is preserved instead of being rewritten.
