TheInfinityIQ_GCP/src/gcp-backend/GCP.Api/Areas/Identity/Pages/Account/LoginWithRecoveryCode.cshtml.cs
#nullable disable

using System.ComponentModel.DataAnnotations;

using GCP.Api.Data.Entities;

using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace GCP.Api.Areas.Identity.Pages.Account
{
	public class LoginWithRecoveryCodeModel : PageModel
	{
		private readonly SignInManager<User> _signInManager;
		private readonly UserManager<User> _userManager;
		private readonly ILogger<LoginWithRecoveryCodeModel> _logger;

		public LoginWithRecoveryCodeModel(
			SignInManager<User> signInManager,
			UserManager<User> userManager,
			ILogger<LoginWithRecoveryCodeModel> logger)
		{
			_signInManager = signInManager;
			_userManager = userManager;
			_logger = logger;
		}

		[BindProperty]
		public InputModel Input { get; set; }

		public string ReturnUrl { get; set; }

		public class InputModel
		{
			[BindProperty]
			[Required]
			[DataType(DataType.Text)]
			[Display(Name = "Recovery Code")]
			public string RecoveryCode { get; set; }
		}

		public async Task<IActionResult> OnGetAsync(string returnUrl = null)
		{
			// Ensure the user has gone through the username & password screen first
			var user = await _signInManager.GetTwoFactorAuthenticationUserAsync();
			if (user is null)
			{
				throw new InvalidOperationException($"Unable to load two-factor authentication user.");
			}

			ReturnUrl = returnUrl;

			return Page();
		}

		public async Task<IActionResult> OnPostAsync(string returnUrl = null)
		{
			if (!ModelState.IsValid)
			{
				return Page();
			}

			var user = await _signInManager.GetTwoFactorAuthenticationUserAsync();
			if (user is null)
			{
				throw new InvalidOperationException($"Unable to load two-factor authentication user.");
			}

			var recoveryCode = Input.RecoveryCode.Replace(" ", string.Empty);

			var result = await _signInManager.TwoFactorRecoveryCodeSignInAsync(recoveryCode);

			var userId = await _userManager.GetUserIdAsync(user);

			if (result.Succeeded)
			{
				_logger.LogInformation("User with ID '{UserId}' logged in with a recovery code.", user.Id);
				return LocalRedirect(returnUrl ?? Url.Content("~/"));
			}
			if (result.IsLockedOut)
			{
				_logger.LogWarning("User account locked out.");
				return RedirectToPage("./Lockout");
			}
			else
			{
				_logger.LogWarning("Invalid recovery code entered for user with ID '{UserId}' ", user.Id);
				ModelState.AddModelError(string.Empty, "Invalid recovery code entered.");
				return Page();
			}
		}
	}
}
