PlanTempusApp/PlanTempus.Components/Accounts/Create/CreateAccountHandler.cs

72 lines
2.7 KiB
C#
Raw Normal View History

2025-03-04 17:13:02 +01:00
using Insight.Database;
2025-03-10 15:56:22 +01:00
using Npgsql;
using PlanTempus.Components.Accounts.Exceptions;
2025-03-04 17:13:02 +01:00
using PlanTempus.Core;
2025-03-12 00:13:53 +01:00
using PlanTempus.Core.CommandQueries;
2025-03-10 15:56:22 +01:00
using PlanTempus.Core.Database;
using PlanTempus.Core.Outbox;
2025-03-04 17:13:02 +01:00
namespace PlanTempus.Components.Accounts.Create
2025-03-04 17:13:02 +01:00
{
public class CreateAccountHandler(
2025-03-06 00:05:58 +01:00
IDatabaseOperations databaseOperations,
ISecureTokenizer secureTokenizer,
IOutboxService outboxService) : ICommandHandler<CreateAccountCommand>
2025-03-04 23:54:55 +01:00
{
public async Task<CommandResponse> Handle(CreateAccountCommand command)
2025-03-04 23:54:55 +01:00
{
using var db = databaseOperations.CreateScope(nameof(CreateAccountHandler));
using var transaction = db.Connection.BeginTransaction();
2025-03-04 23:54:55 +01:00
try
{
var securityStamp = Guid.NewGuid().ToString("N");
2025-03-04 23:54:55 +01:00
var sql = @"
INSERT INTO system.accounts(email, password_hash, security_stamp, email_confirmed,
access_failed_count, lockout_enabled, is_active)
2025-03-04 17:13:02 +01:00
VALUES(@Email, @PasswordHash, @SecurityStamp, @EmailConfirmed,
2025-03-04 23:54:55 +01:00
@AccessFailedCount, @LockoutEnabled, @IsActive)
RETURNING id, created_at, email, is_active";
2025-03-04 17:13:02 +01:00
2025-06-26 21:30:32 +02:00
await db.Connection.QuerySqlAsync(sql, new
2025-03-04 23:54:55 +01:00
{
2025-03-12 00:13:53 +01:00
command.Email,
2025-03-04 23:54:55 +01:00
PasswordHash = secureTokenizer.TokenizeText(command.Password),
SecurityStamp = securityStamp,
2025-03-04 23:54:55 +01:00
EmailConfirmed = false,
AccessFailedCount = 0,
LockoutEnabled = false,
2025-03-12 00:13:53 +01:00
command.IsActive,
2025-03-04 23:54:55 +01:00
});
await outboxService.EnqueueAsync(
OutboxMessageTypes.VerificationEmail,
new VerificationEmailPayload
{
Email = command.Email,
UserName = command.Email,
Token = securityStamp
},
db.Connection,
transaction);
transaction.Commit();
return new CommandResponse(command.CorrelationId, command.GetType().Name, command.TransactionId);
2025-03-04 23:54:55 +01:00
}
catch (PostgresException ex) when (ex.SqlState == "23505" && ex.ConstraintName.Equals("accounts_email_key", StringComparison.InvariantCultureIgnoreCase))
2025-03-10 15:56:22 +01:00
{
transaction.Rollback();
2025-03-10 15:56:22 +01:00
db.Error(ex);
throw new EmailAlreadyRegistreredException();
}
2025-03-04 23:54:55 +01:00
catch (Exception ex)
{
transaction.Rollback();
2025-03-04 23:54:55 +01:00
db.Error(ex);
throw;
}
}
}
}