using Indotalent.Data.Entities; using Indotalent.Infrastructure.Authorization.Identity; using MediatR; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.WebUtilities; using System.Text; namespace Indotalent.Features.Account.Register.Cqrs; public class CreateUserRequest { public string FullName { get; set; } = string.Empty; public string Email { get; set; } = string.Empty; public string Password { get; set; } = string.Empty; public bool IsActive { get; set; } = true; public bool EmailConfirmed { get; set; } = false; } public class CreateUserResponse { public string? Id { get; set; } public string? Email { get; set; } } public record CreateUserCommand(CreateUserRequest Data) : IRequest; public class RegisterHandler : IRequestHandler { private readonly UserManager _userManager; private readonly IEmailSender _emailSender; private readonly IConfiguration _configuration; private readonly IHttpContextAccessor _httpContextAccessor; public RegisterHandler( UserManager userManager, IEmailSender emailSender, IConfiguration configuration, IHttpContextAccessor httpContextAccessor) { _userManager = userManager; _emailSender = emailSender; _configuration = configuration; _httpContextAccessor = httpContextAccessor; } public async Task Handle(CreateUserCommand request, CancellationToken cancellationToken) { var user = new ApplicationUser { UserName = request.Data.Email, Email = request.Data.Email, FullName = request.Data.FullName, IsActive = request.Data.IsActive, EmailConfirmed = request.Data.EmailConfirmed, }; var result = await _userManager.CreateAsync(user, request.Data.Password); if (!result.Succeeded) { var errors = result.Errors.Select(x => x.Description).ToList(); throw new Exception(string.Join(", ", errors)); } var rolesToAdd = ApplicationRoles.AllRoles .Where(role => role != ApplicationRoles.Admin) .ToList(); if (rolesToAdd.Any()) { await _userManager.AddToRolesAsync(user, rolesToAdd); } var requireConfirmation = _configuration.GetValue("IdentitySettings:SignIn:RequireConfirmedAccount"); if (requireConfirmation) { var code = await _userManager.GenerateEmailConfirmationTokenAsync(user); code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code)); var requestHttp = _httpContextAccessor.HttpContext?.Request; var scheme = requestHttp?.Scheme ?? "https"; var host = requestHttp?.Host.Value ?? "localhost:8080"; var callbackUrl = $"{scheme}://{host}/account/confirm-email?userId={user.Id}&code={code}"; var message = $@"

Welcome, {user.FullName}!

Please confirm your account by clicking the link below:

Confirm Account


If the link doesn't work, copy and paste this URL into your browser:

{callbackUrl}

"; await _emailSender.SendConfirmationLinkAsync(user, user.Email!, message); } return new CreateUserResponse { Id = user.Id, Email = user.Email }; } }