Support factor hint in web login

This commit is contained in:
LittleSheep 2025-06-29 00:38:00 +08:00
parent d7b443e678
commit ee5d6ef821
4 changed files with 50 additions and 16 deletions

View File

@ -6,7 +6,7 @@
}
<div class="h-full flex items-center justify-center bg-gray-100 dark:bg-gray-900">
<div class="bg-white dark:bg-gray-800 px-8 rounded-lg shadow-md w-full max-w-md">
<div class="bg-white dark:bg-gray-800 p-8 rounded-lg shadow-md w-full max-w-md">
<h1 class="text-2xl font-bold text-center text-gray-900 dark:text-white mb-6">Select Authentication Method</h1>
@if (Model.AuthChallenge == null)
@ -24,16 +24,32 @@
<div class="space-y-4">
@foreach (var factor in Model.AuthFactors)
{
<form method="post" asp-page-handler="SelectFactor" class="w-full">
<div class="mb-4">
<form method="post" asp-page-handler="SelectFactor" class="w-full" id="factor-@factor.Id">
<input type="hidden" name="factorId" value="@factor.Id"/>
@if (factor.Type == AccountAuthFactorType.EmailCode)
{
<div class="mb-3">
<label for="hint-@factor.Id" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
Email to send code to
</label>
<input type="email"
id="hint-@factor.Id"
name="hint"
class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:text-white"
placeholder="Enter your email"
required>
</div>
}
<button type="submit"
class="w-full text-left p-4 bg-gray-50 dark:bg-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 rounded-lg transition-colors">
<div
class="font-medium text-gray-900 dark:text-white">@GetFactorDisplayName(factor.Type)</div>
<div
class="text-sm text-gray-500 dark:text-gray-400">@GetFactorDescription(factor.Type)</div>
<div class="font-medium text-gray-900 dark:text-white">@GetFactorDisplayName(factor.Type)</div>
<div class="text-sm text-gray-500 dark:text-gray-400">@GetFactorDescription(factor.Type)</div>
</button>
</form>
</div>
}
</div>
}

View File

@ -25,7 +25,7 @@ public class SelectFactorModel(
return Page();
}
public async Task<IActionResult> OnPostSelectFactorAsync(Guid factorId)
public async Task<IActionResult> OnPostSelectFactorAsync(Guid factorId, string? hint = null)
{
var challenge = await db.AuthChallenges
.Include(e => e.Account)
@ -40,11 +40,20 @@ public class SelectFactorModel(
// For OTP factors that require code delivery
try
{
await accounts.SendFactorCode(challenge.Account, factor);
}
catch (Exception)
// Validate hint for factors that require it
if (factor.Type == AccountAuthFactorType.EmailCode
&& string.IsNullOrWhiteSpace(hint))
{
ModelState.AddModelError(string.Empty, "An error occurred while sending the verification code.");
ModelState.AddModelError(string.Empty, $"Please provide a {factor.Type.ToString().ToLower().Replace("code", "")} to send the code to.");
await LoadChallengeAndFactors();
return Page();
}
await accounts.SendFactorCode(challenge.Account, factor, hint);
}
catch (Exception ex)
{
ModelState.AddModelError(string.Empty, $"An error occurred while sending the verification code: {ex.Message}");
await LoadChallengeAndFactors();
return Page();
}

View File

@ -6,7 +6,7 @@
}
<div class="h-full flex items-center justify-center bg-gray-100 dark:bg-gray-900">
<div class="bg-white dark:bg-gray-800 p-8 rounded-lg shadow-md w-full max-w-md">
<div class="bg-white dark:bg-gray-800 px-8 pt-8 pb-4 rounded-lg shadow-md w-full max-w-md">
<h1 class="text-2xl font-bold text-center text-gray-900 dark:text-white mb-2">Verify Your Identity</h1>
<p class="text-center text-gray-600 dark:text-gray-300 mb-6">
@switch (Model.FactorType)

View File

@ -285,6 +285,9 @@
.mb-2 {
margin-bottom: calc(var(--spacing) * 2);
}
.mb-3 {
margin-bottom: calc(var(--spacing) * 3);
}
.mb-4 {
margin-bottom: calc(var(--spacing) * 4);
}
@ -452,6 +455,12 @@
.py-12 {
padding-block: calc(var(--spacing) * 12);
}
.pt-8 {
padding-top: calc(var(--spacing) * 8);
}
.pb-4 {
padding-bottom: calc(var(--spacing) * 4);
}
.text-center {
text-align: center;
}