Sign in , out ,register.

This commit is contained in:
Burak Kaan Köse
2026-03-16 01:33:27 +01:00
parent 921c3bef93
commit 37c1bd3f62
35 changed files with 1195 additions and 30 deletions
@@ -0,0 +1,30 @@
using System;
using SQLite;
namespace Wino.Core.Domain.Entities.Shared;
public class WinoAccount
{
[PrimaryKey]
public Guid Id { get; set; }
public string Email { get; set; } = string.Empty;
public string AccountStatus { get; set; } = string.Empty;
public bool HasPassword { get; set; }
public bool HasGoogleLogin { get; set; }
public bool HasFacebookLogin { get; set; }
public string AccessToken { get; set; } = string.Empty;
public DateTime AccessTokenExpiresAtUtc { get; set; }
public string RefreshToken { get; set; } = string.Empty;
public DateTime RefreshTokenExpiresAtUtc { get; set; }
public DateTime LastAuthenticatedUtc { get; set; }
}
@@ -1,4 +1,5 @@
using System;
#nullable enable
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
@@ -41,7 +42,7 @@ public interface IMailDialogService : IDialogServiceBase
/// Presents a dialog to the user for signature creation/modification.
/// </summary>
/// <returns>Signature information. Null if canceled.</returns>
Task<AccountSignature> ShowSignatureEditorDialog(AccountSignature signatureModel = null);
Task<AccountSignature> ShowSignatureEditorDialog(AccountSignature? signatureModel = null);
/// <summary>
/// Presents a dialog to the user for account alias creation/modification.
@@ -59,7 +60,7 @@ public interface IMailDialogService : IDialogServiceBase
/// </summary>
/// <param name="existingShortcut">Existing shortcut to edit, or null for new shortcut.</param>
/// <returns>Dialog result with shortcut information.</returns>
#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type.
#pragma warning disable CS8625
Task<KeyboardShortcutDialogResult> ShowKeyboardShortcutDialogAsync(KeyboardShortcut existingShortcut = null);
#pragma warning restore CS8625
@@ -68,5 +69,9 @@ public interface IMailDialogService : IDialogServiceBase
/// </summary>
/// <param name="contact">Existing contact to edit, or null for new contact.</param>
/// <returns>Contact information. Null if canceled.</returns>
Task<AccountContact> ShowEditContactDialogAsync(AccountContact contact = null);
Task<AccountContact?> ShowEditContactDialogAsync(AccountContact? contact = null);
Task<WinoAccount?> ShowWinoAccountRegistrationDialogAsync();
Task<WinoAccount?> ShowWinoAccountLoginDialogAsync();
}
@@ -0,0 +1,15 @@
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Wino.Mail.Api.Contracts.Auth;
using Wino.Mail.Api.Contracts.Common;
namespace Wino.Core.Domain.Interfaces;
public interface IWinoAccountApiClient
{
Task<ApiEnvelope<AuthResultDto>> RegisterAsync(string email, string password, CancellationToken cancellationToken = default);
Task<ApiEnvelope<AuthResultDto>> LoginAsync(string email, string password, CancellationToken cancellationToken = default);
Task<ApiEnvelope<AuthResultDto>> RefreshAsync(string refreshToken, CancellationToken cancellationToken = default);
Task<ApiEnvelope<JsonElement>> LogoutAsync(string refreshToken, CancellationToken cancellationToken = default);
}
@@ -0,0 +1,17 @@
#nullable enable
using System.Threading;
using System.Threading.Tasks;
using Wino.Core.Domain.Entities.Shared;
using Wino.Core.Domain.Models.Accounts;
namespace Wino.Core.Domain.Interfaces;
public interface IWinoAccountProfileService
{
Task<WinoAccountOperationResult> RegisterAsync(string email, string password, CancellationToken cancellationToken = default);
Task<WinoAccountOperationResult> LoginAsync(string email, string password, CancellationToken cancellationToken = default);
Task<WinoAccountOperationResult> RefreshAsync(CancellationToken cancellationToken = default);
Task<WinoAccount?> GetActiveAccountAsync();
Task<bool> HasActiveAccountAsync();
Task SignOutAsync(CancellationToken cancellationToken = default);
}
@@ -0,0 +1,25 @@
#nullable enable
using Wino.Core.Domain.Entities.Shared;
namespace Wino.Core.Domain.Models.Accounts;
public sealed class WinoAccountOperationResult
{
public bool IsSuccess { get; init; }
public string? ErrorCode { get; init; }
public WinoAccount? Account { get; init; }
public static WinoAccountOperationResult Success(WinoAccount account)
=> new()
{
IsSuccess = true,
Account = account
};
public static WinoAccountOperationResult Failure(string? errorCode)
=> new()
{
IsSuccess = false,
ErrorCode = errorCode
};
}
@@ -1144,6 +1144,48 @@
"WelcomeWindow_SkipForNow": "Skip for now — I'll set it up later",
"WelcomeWindow_AppDescription": "A fast, focused inbox — redesigned for Windows 11",
"WelcomeWizard_Step1Title": "Welcome",
"WinoAccount_SettingsSection_Title": "Wino Account",
"WinoAccount_SettingsSection_Description": "Create or sign in to a Wino Account using your localhost auth service.",
"WinoAccount_RegisterButton_Title": "Register account",
"WinoAccount_RegisterButton_Description": "Create a Wino Account with email and password.",
"WinoAccount_RegisterButton_Action": "Open registration",
"WinoAccount_LoginButton_Title": "Sign in",
"WinoAccount_LoginButton_Description": "Sign in to an existing Wino Account with email and password.",
"WinoAccount_LoginButton_Action": "Open login",
"WinoAccount_SignOutButton_Title": "Sign out",
"WinoAccount_SignOutButton_Description": "Remove the locally stored Wino Account session.",
"WinoAccount_SignOutButton_Action": "Sign out",
"WinoAccount_RegisterDialog_Title": "Create Wino Account",
"WinoAccount_RegisterDialog_Description": "Register a new Wino Account using the localhost API.",
"WinoAccount_RegisterDialog_PrimaryButton": "Register",
"WinoAccount_LoginDialog_Title": "Sign In to Wino Account",
"WinoAccount_LoginDialog_Description": "Sign in using the localhost API.",
"WinoAccount_EmailLabel": "Email",
"WinoAccount_EmailPlaceholder": "name@example.com",
"WinoAccount_PasswordLabel": "Password",
"WinoAccount_ConfirmPasswordLabel": "Confirm password",
"WinoAccount_Validation_EmailRequired": "Email is required.",
"WinoAccount_Validation_PasswordRequired": "Password is required.",
"WinoAccount_Validation_PasswordMismatch": "Passwords do not match.",
"WinoAccount_Error_InvalidCredentials": "The email address or password is incorrect.",
"WinoAccount_Error_AccountLocked": "This account is temporarily locked.",
"WinoAccount_Error_AccountBanned": "This account has been banned.",
"WinoAccount_Error_AccountSuspended": "This account has been suspended.",
"WinoAccount_Error_RefreshTokenInvalid": "Your session is no longer valid. Please sign in again.",
"WinoAccount_Error_EmailAlreadyRegistered": "This email address is already registered.",
"WinoAccount_Error_ExternalLoginEmailRequired": "An email address is required to complete external sign-in.",
"WinoAccount_Error_ExternalLoginInvalid": "The external sign-in request is invalid.",
"WinoAccount_Error_ExternalAuthStateInvalid": "The external sign-in state is invalid or expired.",
"WinoAccount_Error_ExternalAuthCodeInvalid": "The external sign-in code is invalid or expired.",
"WinoAccount_Error_Forbidden": "You do not have permission to perform this action.",
"WinoAccount_Error_ValidationFailed": "The request is invalid. Please review the entered values.",
"WinoAccount_RegisterSuccessMessage": "Wino Account registration completed for {0}.",
"WinoAccount_LoginSuccessMessage": "Signed in to Wino Account as {0}.",
"WinoAccount_SignOut_SuccessMessage": "Signed out from Wino Account {0}.",
"WinoAccount_SignOut_NoAccountMessage": "There is no active Wino Account to sign out.",
"WinoAccount_Titlebar_SignedOutTitle": "Wino Account",
"WinoAccount_Titlebar_SignedOutDescription": "Sign in or create a Wino Account to manage your Wino session.",
"WinoAccount_Titlebar_SignedInStatus": "Status: {0}",
"WelcomeWizard_Step2Title": "Add Account",
"WelcomeWizard_Step3Title": "Finish Setup",
"ProviderSelection_Title": "Choose your email provider",
+4 -1
View File
@@ -61,6 +61,9 @@
<PackageReference Include="sqlite-net-pcl" />
<PackageReference Include="TimePeriodLibrary.NET" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Wino.Mail.Contracts\Wino.Mail.Contracts.csproj" />
</ItemGroup>
<ItemGroup>
<Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" />
</ItemGroup>
@@ -71,4 +74,4 @@
<!-- Source Generators -->
<ProjectReference Include="..\Wino.SourceGenerators\Wino.SourceGenerators.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
</ItemGroup>
</Project>
</Project>