postit: persist settings save and apply ApiUrl changes without restart #51

Merged
notazof merged 25 commits from feat/estimate into main 2026-09-06 21:05:58 +01:00
Showing only changes of commit dcd6ad3592 - Show all commits

handles duplicate email at register

Paul Schneider 2026-09-06 19:47:38 +01:00
Signed by: notazof
GPG key ID: 1DD5D838E5343B06

View file

@ -467,8 +467,25 @@ IHtmlLocalizerFactory htmlLocalizerFactory,
if (ModelState.IsValid) if (ModelState.IsValid)
{ {
var existingUser = await _userManager.FindByEmailAsync(model.Email);
if (existingUser is not null)
{
ModelState.AddModelError(nameof(model.Email), _localizer["DuplicateEmail"]);
return View(model);
}
var user = new ApplicationUser { UserName = model.UserName, Email = model.Email }; var user = new ApplicationUser { UserName = model.UserName, Email = model.Email };
var result = await _userManager.CreateAsync(user, model.Password); IdentityResult result;
try
{
result = await _userManager.CreateAsync(user, model.Password);
}
catch (DbUpdateException ex) when (IsDuplicateEmailViolation(ex))
{
_logger.LogWarning(ex, "Registration rejected: duplicate email '{Email}'.", model.Email);
ModelState.AddModelError(nameof(model.Email), _localizer["DuplicateEmail"]);
return View(model);
}
if (result.Succeeded) if (result.Succeeded)
{ {
_logger.LogInformation(3, "User created a new account with password."); _logger.LogInformation(3, "User created a new account with password.");
@ -517,6 +534,21 @@ IHtmlLocalizerFactory htmlLocalizerFactory,
return View(model); return View(model);
} }
private static bool IsDuplicateEmailViolation(Exception exception)
{
for (var current = exception; current is not null; current = current.InnerException)
{
if (current is PostgresException pg
&& pg.SqlState == PostgresErrorCodes.UniqueViolation
&& string.Equals(pg.ConstraintName, "AK_AspNetUsers_Email", StringComparison.Ordinal))
{
return true;
}
}
return false;
}
[Authorize, HttpPost, ValidateAntiForgeryToken] [Authorize, HttpPost, ValidateAntiForgeryToken]
public async Task<IActionResult> SendConfirationEmail() public async Task<IActionResult> SendConfirationEmail()
{ {