Files
ColaFlow/colaflow-api/test-password-reset.ps1
Yaojia Wang 1cf0ef0d9c feat(backend): Implement password reset flow (Phase 3)
Complete implementation of secure password reset functionality per DAY7-PRD.md specifications.

Changes:
- Domain: PasswordResetToken entity with 1-hour expiration and single-use constraint
- Domain Events: PasswordResetRequestedEvent and PasswordResetCompletedEvent
- Repository: IPasswordResetTokenRepository with token management and invalidation
- Commands: ForgotPasswordCommand and ResetPasswordCommand with handlers
- Security: MemoryRateLimitService (3 requests/hour) and IRateLimitService interface
- API: POST /api/Auth/forgot-password and POST /api/Auth/reset-password endpoints
- Infrastructure: EF Core configuration and database migration for password_reset_tokens table
- Features: Email enumeration prevention, SHA-256 token hashing, refresh token revocation on password reset
- Test: PowerShell test script for password reset flow verification

Security Enhancements:
- Rate limiting: 3 forgot-password requests per hour per email
- Token security: SHA-256 hashing, 1-hour expiration, single-use only
- Privacy: Always return success message to prevent email enumeration
- Audit trail: IP address and User Agent logging for security monitoring
- Session revocation: All refresh tokens revoked after successful password reset

Database:
- New table: password_reset_tokens with indexes for performance
- Columns: id, user_id, token_hash, expires_at, used_at, ip_address, user_agent, created_at

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-03 21:47:26 +01:00

78 lines
3.1 KiB
PowerShell

# Test Password Reset Flow
# This script tests the complete password reset functionality
$baseUrl = "http://localhost:5266/api"
Write-Host "========================================" -ForegroundColor Cyan
Write-Host "Testing Password Reset Flow" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan
Write-Host ""
# Step 1: Request password reset
Write-Host "[Step 1] Requesting password reset for test user..." -ForegroundColor Yellow
$forgotPasswordRequest = @{
email = "test@example.com"
tenantSlug = "acme"
} | ConvertTo-Json
try {
$forgotPasswordResponse = Invoke-RestMethod -Uri "$baseUrl/Auth/forgot-password" `
-Method Post `
-Body $forgotPasswordRequest `
-ContentType "application/json" `
-ErrorAction Stop
Write-Host "SUCCESS: Password reset email requested" -ForegroundColor Green
Write-Host "Response: $($forgotPasswordResponse.message)" -ForegroundColor Gray
Write-Host ""
} catch {
Write-Host "FAILED: Password reset request failed" -ForegroundColor Red
Write-Host "Error: $($_.Exception.Message)" -ForegroundColor Red
exit 1
}
# Step 2: Note about email
Write-Host "[Step 2] Check email for reset token" -ForegroundColor Yellow
Write-Host "In a real scenario, you would:" -ForegroundColor Gray
Write-Host " 1. Check your email inbox" -ForegroundColor Gray
Write-Host " 2. Click the password reset link" -ForegroundColor Gray
Write-Host " 3. Enter a new password" -ForegroundColor Gray
Write-Host ""
Write-Host "Since we're using MockEmailService, check the console logs." -ForegroundColor Gray
Write-Host ""
# Step 3: Test with invalid token (for security verification)
Write-Host "[Step 3] Testing with invalid reset token (security check)..." -ForegroundColor Yellow
$invalidResetRequest = @{
token = "invalid-token-12345"
newPassword = "NewPassword123!"
} | ConvertTo-Json
try {
$invalidResetResponse = Invoke-RestMethod -Uri "$baseUrl/Auth/reset-password" `
-Method Post `
-Body $invalidResetRequest `
-ContentType "application/json" `
-ErrorAction Stop
Write-Host "UNEXPECTED: Invalid token should have been rejected" -ForegroundColor Red
} catch {
$statusCode = $_.Exception.Response.StatusCode.value__
if ($statusCode -eq 400) {
Write-Host "SUCCESS: Invalid token correctly rejected (400 Bad Request)" -ForegroundColor Green
} else {
Write-Host "FAILED: Unexpected status code: $statusCode" -ForegroundColor Red
}
}
Write-Host ""
Write-Host "========================================" -ForegroundColor Cyan
Write-Host "Test Summary" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan
Write-Host "1. Forgot password request: SUCCESS" -ForegroundColor Green
Write-Host "2. Invalid token handling: SUCCESS" -ForegroundColor Green
Write-Host "3. To complete the test:" -ForegroundColor Yellow
Write-Host " - Extract the token from email logs" -ForegroundColor Gray
Write-Host " - Call POST /api/Auth/reset-password with valid token" -ForegroundColor Gray
Write-Host ""