using Femto.Common.Domain; using Femto.Modules.Auth.Application.Dto; using Femto.Modules.Auth.Data; using Femto.Modules.Auth.Models; using Microsoft.EntityFrameworkCore; namespace Femto.Modules.Auth.Application.Interface.Register; internal class RegisterCommandHandler(AuthContext context) : ICommandHandler { public async Task Handle(RegisterCommand request, CancellationToken cancellationToken) { var now = DateTimeOffset.UtcNow; var code = await context .SignupCodes.Where(c => c.Code == request.SignupCode) .Where(c => c.ExpiresAt == null || c.ExpiresAt > now) .Where(c => c.RedeemingUserId == null) .SingleOrDefaultAsync(cancellationToken); if (code is null) throw new DomainError("invalid signup code"); var usernameTaken = await context.Users.AnyAsync( u => u.Username == request.Username, cancellationToken ); if (usernameTaken) throw new DomainError("username taken"); var user = new UserIdentity(request.Username); await context.AddAsync(user, cancellationToken); user.SetPassword(request.Password); code.Redeem(user.Id); return new UserInfo(user); } }