feat: forgot password/reset password
This commit is contained in:
		
							parent
							
								
									26b32b40e2
								
							
						
					
					
						commit
						9d33093339
					
				
					 17 changed files with 374 additions and 25 deletions
				
			
		|  | @ -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) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue