Skip to content

📧 Implement Password Reset Email Notification #78

@kevalyq

Description

@kevalyq

Feature Description

Implement email notification system for password reset feature. Currently, password reset tokens are generated but users never receive the reset link via email (see AuthController.php:131 TODO comment).

Context

User Story

As a user who forgot their password, I want to receive a password reset email so that I can securely reset my password via a time-limited link.

Acceptance Criteria

  • PasswordResetMail Mailable class created
  • Email template (Blade/Markdown) with reset link
  • Integration with AuthController::requestPasswordReset()
  • Queue-based email dispatch (async, non-blocking)
  • Tests for email sending (Mail::fake())
  • Security: Token never logged or exposed
  • Security: Email includes token expiry warning (15 min)
  • DDEV/Mailpit integration documented
  • Rate limiting consideration (already covered in 🔐 Password Reset Feature (Production Test Phase 1) #74)

Technical Requirements

Email Content

Subject: Reset Your SecPal Password

Hi [User Name],

You requested a password reset for your SecPal account.

Click the link below to reset your password (expires in 15 minutes):

[Reset Password Button/Link]

If you didn't request this, please ignore this email.

Security Notice: Never share this link with anyone.

Implementation Notes

Mail Configuration (DDEV + Mailpit):

MAIL_MAILER=smtp
MAIL_HOST=localhost
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS="noreply@secpal.app"
MAIL_FROM_NAME="SecPal"

Queue Configuration:

  • Use database queue driver (already configured)
  • Dispatch email via Mail::to($user)->queue(new PasswordResetMail($token))

Security Checklist:

  • ✅ Token only in email body, never in logs
  • ✅ Use HTTPS for reset link in production
  • ✅ Email expiry warning (15 min matches token TTL)
  • ✅ No PII in email subject

Test Cases

  1. test_password_reset_email_is_sent_when_requested()
  2. test_email_contains_valid_reset_link()
  3. test_email_not_sent_for_invalid_email()
  4. test_email_is_queued_not_sent_immediately()
  5. test_token_not_exposed_in_logs()

Dependencies

Documentation Updates

  • .github/copilot-config.yaml - Add mail configuration section
  • .github/copilot-instructions.md - Add email patterns
  • api/README.md - DDEV Mailpit access instructions

Testing Strategy

TDD Workflow:

  1. Write failing test for email sending
  2. Implement Mailable class
  3. Create email template
  4. Integrate with AuthController
  5. Run tests, iterate until green
  6. Security review

Manual Testing (DDEV):

  1. Request password reset via API
  2. Check Mailpit UI: http://localhost:8026
  3. Verify email content and link
  4. Click reset link, complete flow

Success Metrics

  • ✅ All tests passing (Pest)
  • ✅ Email visible in Mailpit during local testing
  • ✅ No security gaps discovered in review
  • ✅ Documentation complete and accurate
  • ✅ Production Test Report with learnings

Related Issues

Milestone

🎯 v0.1.0 - Core Authentication

Labels

  • type: feature
  • priority: high 🟠
  • component: api
  • effort: M (1-2 hours with TDD)
  • production-test-phase-2 🧪

Assignee

GitHub Copilot (TDD Implementation)


Created: 2025-11-02
Methodology: Production Test Phase 2 (TDD + Gap Discovery)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status

    ✅ Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions