[MN-04] Identity: Fix Google Callback Error Handling and Logging #18
@@ -90,11 +90,30 @@
|
||||
</div>
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
[SupplyParameterFromQuery(Name = "error")]
|
||||
public string? ErrorCode { get; set; }
|
||||
|
||||
private LoginModel _loginModel = new();
|
||||
private string? _errorMessage;
|
||||
private bool _isSubmitting;
|
||||
private bool _showPassword;
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(ErrorCode))
|
||||
{
|
||||
_errorMessage = ErrorCode switch
|
||||
{
|
||||
"ExternalLoginFailed" => "Nie udało się zalogować przez Google. Spróbuj ponownie.",
|
||||
"ProvisioningFailed" => "Wystąpił błąd podczas przygotowywania Twojego konta.",
|
||||
"UserAlreadyExists" => "Użytkownik o tym adresie e-mail już istnieje. Zaloguj się tradycyjnie hasłem.",
|
||||
"LockedOut" => "Twoje konto zostało zablokowane. Spróbuj ponownie później.",
|
||||
_ => "Wystąpił nieoczekiwany błąd podczas logowania."
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private async Task HandleLogin()
|
||||
{
|
||||
_isSubmitting = true;
|
||||
|
||||
@@ -355,31 +355,57 @@ app.MapGet("/identity/login/google", (string? returnUrl) =>
|
||||
app.MapGet("/identity/callback/google", async (
|
||||
HttpContext context,
|
||||
SignInManager<NexusUser> signInManager,
|
||||
UserManager<NexusUser> userManager) =>
|
||||
UserManager<NexusUser> userManager,
|
||||
ILogger<Program> logger) =>
|
||||
{
|
||||
var info = await signInManager.GetExternalLoginInfoAsync();
|
||||
if (info == null) return Results.Redirect("/account/login?error=ExternalLoginFailed");
|
||||
if (info == null)
|
||||
{
|
||||
logger.LogWarning("External login info from Google is null.");
|
||||
return Results.Redirect("/account/login?error=ExternalLoginFailed");
|
||||
}
|
||||
|
||||
var result = await signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false);
|
||||
if (result.Succeeded)
|
||||
{
|
||||
logger.LogInformation("User logged in via Google: {Email}", info.Principal.FindFirstValue(ClaimTypes.Email));
|
||||
return Results.Redirect("/");
|
||||
}
|
||||
|
||||
if (result.IsLockedOut)
|
||||
{
|
||||
logger.LogWarning("User account locked out during Google login: {Email}", info.Principal.FindFirstValue(ClaimTypes.Email));
|
||||
return Results.Redirect("/account/login?error=LockedOut");
|
||||
}
|
||||
|
||||
// New user provisioning
|
||||
var email = info.Principal.FindFirstValue(ClaimTypes.Email);
|
||||
if (email != null)
|
||||
{
|
||||
var user = new NexusUser { UserName = email, Email = email, EmailConfirmed = true };
|
||||
var createResult = await userManager.CreateAsync(user);
|
||||
|
||||
if (createResult.Succeeded)
|
||||
{
|
||||
await userManager.AddLoginAsync(user, info);
|
||||
await signInManager.SignInAsync(user, isPersistent: false);
|
||||
logger.LogInformation("New user provisioned via Google: {Email}", email);
|
||||
return Results.Redirect("/");
|
||||
}
|
||||
|
||||
// Log specific errors
|
||||
foreach (var error in createResult.Errors)
|
||||
{
|
||||
logger.LogError("Google provisioning failed for {Email}: {Code} - {Description}", email, error.Code, error.Description);
|
||||
}
|
||||
|
||||
if (createResult.Errors.Any(e => e.Code == "DuplicateEmail" || e.Code == "DuplicateUserName"))
|
||||
{
|
||||
return Results.Redirect("/account/login?error=UserAlreadyExists");
|
||||
}
|
||||
}
|
||||
|
||||
logger.LogError("Google provisioning failed - unknown reason for email {Email}", email);
|
||||
return Results.Redirect("/account/login?error=ProvisioningFailed");
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user