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>
68 lines
2.9 KiB
C#
68 lines
2.9 KiB
C#
using ColaFlow.Modules.Identity.Application.Services;
|
|
using ColaFlow.Modules.Identity.Domain.Repositories;
|
|
using ColaFlow.Modules.Identity.Infrastructure.Persistence;
|
|
using ColaFlow.Modules.Identity.Infrastructure.Persistence.Repositories;
|
|
using ColaFlow.Modules.Identity.Infrastructure.Services;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Hosting;
|
|
|
|
namespace ColaFlow.Modules.Identity.Infrastructure;
|
|
|
|
public static class DependencyInjection
|
|
{
|
|
public static IServiceCollection AddIdentityInfrastructure(
|
|
this IServiceCollection services,
|
|
IConfiguration configuration,
|
|
IHostEnvironment? environment = null)
|
|
{
|
|
// Only register PostgreSQL DbContext in non-Testing environments
|
|
// In Testing environment, WebApplicationFactory will register InMemory provider
|
|
if (environment == null || environment.EnvironmentName != "Testing")
|
|
{
|
|
// DbContext (using connection string)
|
|
services.AddDbContext<IdentityDbContext>(options =>
|
|
options.UseNpgsql(
|
|
configuration.GetConnectionString("DefaultConnection"),
|
|
b => b.MigrationsAssembly(typeof(IdentityDbContext).Assembly.FullName)));
|
|
}
|
|
|
|
// Tenant Context (Scoped - one instance per request)
|
|
services.AddScoped<ITenantContext, TenantContext>();
|
|
services.AddHttpContextAccessor(); // Required for HttpContext access
|
|
|
|
// Repositories
|
|
services.AddScoped<ITenantRepository, TenantRepository>();
|
|
services.AddScoped<IUserRepository, UserRepository>();
|
|
services.AddScoped<IRefreshTokenRepository, RefreshTokenRepository>();
|
|
services.AddScoped<IUserTenantRoleRepository, UserTenantRoleRepository>();
|
|
services.AddScoped<IEmailVerificationTokenRepository, EmailVerificationTokenRepository>();
|
|
services.AddScoped<IPasswordResetTokenRepository, PasswordResetTokenRepository>();
|
|
|
|
// Application Services
|
|
services.AddScoped<IJwtService, JwtService>();
|
|
services.AddScoped<IPasswordHasher, PasswordHasher>();
|
|
services.AddScoped<IRefreshTokenService, RefreshTokenService>();
|
|
services.AddScoped<ISecurityTokenService, SecurityTokenService>();
|
|
|
|
// Memory cache for rate limiting
|
|
services.AddMemoryCache();
|
|
services.AddSingleton<IRateLimitService, MemoryRateLimitService>();
|
|
|
|
// Email Services
|
|
var emailProvider = configuration["Email:Provider"] ?? "Mock";
|
|
if (emailProvider.Equals("Mock", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
services.AddSingleton<IEmailService, MockEmailService>();
|
|
}
|
|
else
|
|
{
|
|
services.AddScoped<IEmailService, SmtpEmailService>();
|
|
}
|
|
services.AddScoped<IEmailTemplateService, EmailTemplateService>();
|
|
|
|
return services;
|
|
}
|
|
}
|