Forgot password and email confirmations.

This commit is contained in:
Burak Kaan Köse
2026-03-19 16:41:35 +01:00
parent 873a7eca12
commit c2320de5c4
20 changed files with 643 additions and 44 deletions
+41 -7
View File
@@ -225,11 +225,16 @@ public class DialogService : DialogServiceBase, IMailDialogService
RequestedTheme = ThemeService.RootTheme.ToWindowsElementTheme()
};
var result = await HandleDialogPresentationAsync(dialog);
await HandleDialogPresentationAsync(dialog);
return result == ContentDialogResult.Primary
? dialog.Result
: null;
if (!string.IsNullOrWhiteSpace(dialog.ConfirmationEmailAddress))
{
await ShowMessageAsync(
string.Format(Translator.WinoAccount_EmailConfirmationSentDialog_Message, dialog.ConfirmationEmailAddress),
Translator.WinoAccount_EmailConfirmationSentDialog_Title);
}
return null;
}
public async Task<WinoAccount?> ShowWinoAccountLoginDialogAsync()
@@ -241,8 +246,37 @@ public class DialogService : DialogServiceBase, IMailDialogService
var result = await HandleDialogPresentationAsync(dialog);
return result == ContentDialogResult.Primary
? dialog.Result
: null;
if (dialog.EmailConfirmationRequiredDetails != null && !string.IsNullOrWhiteSpace(dialog.PendingConfirmationEmailAddress))
{
var confirmationDialog = new WinoAccountEmailConfirmationRequiredDialog(
_winoAccountProfileService,
dialog.PendingConfirmationEmailAddress,
dialog.EmailConfirmationRequiredDetails)
{
RequestedTheme = ThemeService.RootTheme.ToWindowsElementTheme()
};
await HandleDialogPresentationAsync(confirmationDialog);
if (confirmationDialog.ResendSucceeded)
{
await ShowMessageAsync(
string.Format(Translator.WinoAccount_EmailConfirmationResentDialog_Message, dialog.PendingConfirmationEmailAddress),
Translator.WinoAccount_EmailConfirmationResentDialog_Title);
}
return null;
}
if (!string.IsNullOrWhiteSpace(dialog.PasswordResetEmailAddress))
{
await ShowMessageAsync(
string.Format(Translator.WinoAccount_ForgotPasswordDialog_SuccessMessage, dialog.PasswordResetEmailAddress),
Translator.WinoAccount_ForgotPasswordDialog_SuccessTitle);
return null;
}
return dialog.Result;
}
}
@@ -19,6 +19,10 @@ public static class WinoAccountAuthErrorTranslator
ApiErrorCodes.AccountBanned => Translator.WinoAccount_Error_AccountBanned,
ApiErrorCodes.AccountSuspended => Translator.WinoAccount_Error_AccountSuspended,
ApiErrorCodes.EmailNotConfirmed => Translator.WinoAccount_Error_EmailNotConfirmed,
ApiErrorCodes.EmailConfirmationRequired => Translator.WinoAccount_Error_EmailConfirmationRequired,
ApiErrorCodes.EmailConfirmationResendNotAvailable => Translator.WinoAccount_Error_EmailConfirmationResendNotAvailable,
ApiErrorCodes.EmailConfirmationResendInvalid => Translator.WinoAccount_Error_EmailConfirmationResendInvalid,
ApiErrorCodes.EmailNotRegistered => Translator.WinoAccount_Error_EmailNotRegistered,
ApiErrorCodes.RefreshTokenInvalid => Translator.WinoAccount_Error_RefreshTokenInvalid,
ApiErrorCodes.EmailAlreadyRegistered => Translator.WinoAccount_Error_EmailAlreadyRegistered,
ApiErrorCodes.ExternalLoginEmailRequired => Translator.WinoAccount_Error_ExternalLoginEmailRequired,
@@ -0,0 +1,69 @@
using System;
using System.Text.Json;
using Wino.Mail.Api.Contracts.Auth;
namespace Wino.Mail.WinUI.Services;
internal static class WinoAccountEmailConfirmationHelper
{
public static bool IsEmailConfirmationRequiredError(string? errorCode)
=> string.Equals(errorCode, Wino.Mail.Api.Contracts.Common.ApiErrorCodes.EmailNotConfirmed, StringComparison.Ordinal) ||
string.Equals(errorCode, Wino.Mail.Api.Contracts.Common.ApiErrorCodes.EmailConfirmationRequired, StringComparison.Ordinal);
public static EmailConfirmationRequiredDetailsDto? Parse(JsonElement? details)
{
if (details is not JsonElement element || element.ValueKind is JsonValueKind.Undefined or JsonValueKind.Null)
{
return null;
}
try
{
if (!TryGetString(element, "resendConfirmationEndpoint", out var endpoint) ||
!TryGetString(element, "resendConfirmationTicket", out var ticket) ||
!TryGetDateTimeOffset(element, "resendAvailableAtUtc", out var resendAvailableAtUtc))
{
return null;
}
DateTimeOffset? latestSentUtc = null;
if (element.TryGetProperty("latestConfirmationEmailSentUtc", out var latestSentElement) &&
latestSentElement.ValueKind == JsonValueKind.String &&
DateTimeOffset.TryParse(latestSentElement.GetString(), out var latestParsed))
{
latestSentUtc = latestParsed;
}
return new EmailConfirmationRequiredDetailsDto(endpoint, ticket, latestSentUtc, resendAvailableAtUtc);
}
catch (FormatException)
{
return null;
}
}
private static bool TryGetString(JsonElement element, string propertyName, out string value)
{
value = string.Empty;
if (!element.TryGetProperty(propertyName, out var property) || property.ValueKind != JsonValueKind.String)
{
return false;
}
value = property.GetString() ?? string.Empty;
return !string.IsNullOrWhiteSpace(value);
}
private static bool TryGetDateTimeOffset(JsonElement element, string propertyName, out DateTimeOffset value)
{
value = default;
if (!element.TryGetProperty(propertyName, out var property) || property.ValueKind != JsonValueKind.String)
{
return false;
}
return DateTimeOffset.TryParse(property.GetString(), out value);
}
}