[MN-04] Identity: Fix Google Callback Error Handling and Logging #18
@@ -90,11 +90,30 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
[Parameter]
|
||||||
|
[SupplyParameterFromQuery(Name = "error")]
|
||||||
|
public string? ErrorCode { get; set; }
|
||||||
|
|
||||||
private LoginModel _loginModel = new();
|
private LoginModel _loginModel = new();
|
||||||
private string? _errorMessage;
|
private string? _errorMessage;
|
||||||
private bool _isSubmitting;
|
private bool _isSubmitting;
|
||||||
private bool _showPassword;
|
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()
|
private async Task HandleLogin()
|
||||||
{
|
{
|
||||||
_isSubmitting = true;
|
_isSubmitting = true;
|
||||||
|
|||||||
@@ -355,31 +355,57 @@ app.MapGet("/identity/login/google", (string? returnUrl) =>
|
|||||||
app.MapGet("/identity/callback/google", async (
|
app.MapGet("/identity/callback/google", async (
|
||||||
HttpContext context,
|
HttpContext context,
|
||||||
SignInManager<NexusUser> signInManager,
|
SignInManager<NexusUser> signInManager,
|
||||||
UserManager<NexusUser> userManager) =>
|
UserManager<NexusUser> userManager,
|
||||||
|
ILogger<Program> logger) =>
|
||||||
{
|
{
|
||||||
var info = await signInManager.GetExternalLoginInfoAsync();
|
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);
|
var result = await signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false);
|
||||||
if (result.Succeeded)
|
if (result.Succeeded)
|
||||||
{
|
{
|
||||||
|
logger.LogInformation("User logged in via Google: {Email}", info.Principal.FindFirstValue(ClaimTypes.Email));
|
||||||
return Results.Redirect("/");
|
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
|
// New user provisioning
|
||||||
var email = info.Principal.FindFirstValue(ClaimTypes.Email);
|
var email = info.Principal.FindFirstValue(ClaimTypes.Email);
|
||||||
if (email != null)
|
if (email != null)
|
||||||
{
|
{
|
||||||
var user = new NexusUser { UserName = email, Email = email, EmailConfirmed = true };
|
var user = new NexusUser { UserName = email, Email = email, EmailConfirmed = true };
|
||||||
var createResult = await userManager.CreateAsync(user);
|
var createResult = await userManager.CreateAsync(user);
|
||||||
|
|
||||||
if (createResult.Succeeded)
|
if (createResult.Succeeded)
|
||||||
{
|
{
|
||||||
await userManager.AddLoginAsync(user, info);
|
await userManager.AddLoginAsync(user, info);
|
||||||
await signInManager.SignInAsync(user, isPersistent: false);
|
await signInManager.SignInAsync(user, isPersistent: false);
|
||||||
|
logger.LogInformation("New user provisioned via Google: {Email}", email);
|
||||||
return Results.Redirect("/");
|
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");
|
return Results.Redirect("/account/login?error=ProvisioningFailed");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user