feat: forgot password/reset password

This commit is contained in:
sam 2024-12-14 16:32:08 +01:00
parent 26b32b40e2
commit 9d33093339
Signed by: sam
GPG key ID: B4EF20DDE721CAA1
17 changed files with 374 additions and 25 deletions

View file

@ -183,6 +183,63 @@ public class EmailAuthController(
return NoContent();
}
[HttpPost("forgot-password")]
public async Task<IActionResult> ForgotPasswordAsync([FromBody] EmailForgotPasswordRequest req)
{
CheckRequirements();
if (!req.Email.Contains('@'))
throw new ApiError.BadRequest("Email is invalid", "email", req.Email);
AuthMethod? authMethod = await db
.AuthMethods.Where(m => m.AuthType == AuthType.Email && m.RemoteId == req.Email)
.FirstOrDefaultAsync();
if (authMethod == null)
return NoContent();
string state = await keyCacheService.GenerateForgotPasswordStateAsync(
req.Email,
authMethod.UserId
);
if (IsRateLimited())
return NoContent();
mailService.QueueResetPasswordEmail(req.Email, state);
return NoContent();
}
[HttpPost("reset-password")]
public async Task<IActionResult> ResetPasswordAsync([FromBody] EmailResetPasswordRequest req)
{
ForgotPasswordState? state = await keyCacheService.GetForgotPasswordStateAsync(req.State);
if (state == null)
throw new ApiError.BadRequest("Unknown state", "state", req.State);
if (
!await db
.AuthMethods.Where(m =>
m.AuthType == AuthType.Email
&& m.RemoteId == state.Email
&& m.UserId == state.UserId
)
.AnyAsync()
)
{
throw new ApiError.BadRequest("Invalid state");
}
ValidationUtils.Validate([("password", ValidationUtils.ValidatePassword(req.Password))]);
User user = await db.Users.FirstAsync(u => u.Id == state.UserId);
await authService.SetUserPasswordAsync(user, req.Password);
await db.SaveChangesAsync();
mailService.QueuePasswordChangedEmail(state.Email);
return NoContent();
}
[HttpPost("add-account")]
[Authorize("*")]
public async Task<IActionResult> AddEmailAddressAsync([FromBody] AddEmailAddressRequest req)