166 lines
4.9 KiB
Text
166 lines
4.9 KiB
Text
@page "/login"
|
|
@inject IAuthService AuthService
|
|
@inject CustomAuthStateProvider AuthStateProvider
|
|
@inject NavigationManager Navigation
|
|
@inject ISettingsService SettingsService
|
|
|
|
@rendermode InteractiveServer
|
|
|
|
<PageTitle>@T("Anmelden - Author Buddy", "Login - Author Buddy")</PageTitle>
|
|
|
|
<div class="auth-page">
|
|
<div class="auth-card">
|
|
<h2>@T("Anmelden", "Login")</h2>
|
|
|
|
@if (!show2FA)
|
|
{
|
|
<div class="form-group">
|
|
<label for="username">@T("Benutzername:", "Username:")</label>
|
|
<input id="username" @bind="username" @onkeydown="HandleKeyDown" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="password">@T("Passwort:", "Password:")</label>
|
|
<input id="password" type="password" @bind="password" @onkeydown="HandleKeyDown" />
|
|
</div>
|
|
<div class="auth-actions">
|
|
<button @onclick="DoLogin" disabled="@isBusy">@T("Anmelden", "Login")</button>
|
|
<a href="/register">@T("Registrieren", "Register")</a>
|
|
</div>
|
|
}
|
|
else
|
|
{
|
|
<p>@T("Gib den 6-stelligen Code aus deiner Authenticator-App ein:", "Enter the 6-digit code from your authenticator app:")</p>
|
|
<div class="form-group">
|
|
<label for="code">@T("2FA-Code:", "2FA code:")</label>
|
|
<input id="code" @bind="twoFactorCode" maxlength="6" @onkeydown="HandleKeyDown" />
|
|
</div>
|
|
<div class="auth-actions">
|
|
<button @onclick="Verify2FA" disabled="@isBusy">@T("Bestätigen", "Verify")</button>
|
|
</div>
|
|
}
|
|
|
|
@if (!string.IsNullOrEmpty(errorMessage))
|
|
{
|
|
<div class="auth-error">@errorMessage</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
|
|
@code {
|
|
private string _language = "de";
|
|
private string username = string.Empty;
|
|
private string password = string.Empty;
|
|
private string twoFactorCode = string.Empty;
|
|
private string errorMessage = string.Empty;
|
|
private bool isBusy;
|
|
private bool show2FA;
|
|
|
|
private string T(string de, string en) => _language == "en" ? en : de;
|
|
|
|
protected override async Task OnInitializedAsync()
|
|
{
|
|
_language = await SettingsService.GetLanguageAsync() ?? "de";
|
|
|
|
if (AuthService.IsLoggedIn)
|
|
{
|
|
Navigation.NavigateTo("/");
|
|
return;
|
|
}
|
|
|
|
var users = await SettingsService.GetUsersAsync();
|
|
if (users.Count == 0)
|
|
{
|
|
Navigation.NavigateTo("/register");
|
|
}
|
|
}
|
|
|
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
|
{
|
|
if (firstRender && AuthService.IsLoggedIn)
|
|
Navigation.NavigateTo("/");
|
|
}
|
|
|
|
private async Task HandleKeyDown(KeyboardEventArgs e)
|
|
{
|
|
if (e.Key == "Enter")
|
|
{
|
|
if (show2FA)
|
|
await Verify2FA();
|
|
else
|
|
await DoLogin();
|
|
}
|
|
}
|
|
|
|
private async Task DoLogin()
|
|
{
|
|
if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password))
|
|
{
|
|
errorMessage = T("Bitte Benutzername und Passwort eingeben.", "Please enter username and password.");
|
|
return;
|
|
}
|
|
|
|
isBusy = true;
|
|
errorMessage = string.Empty;
|
|
|
|
try
|
|
{
|
|
var result = await AuthService.LoginAsync(username, password);
|
|
if (AuthService.Is2FARequired)
|
|
{
|
|
show2FA = true;
|
|
password = string.Empty;
|
|
}
|
|
else if (result)
|
|
{
|
|
AuthStateProvider.NotifyStateChanged();
|
|
Navigation.NavigateTo("/");
|
|
}
|
|
else
|
|
{
|
|
errorMessage = T("Benutzername oder Passwort falsch.", "Invalid username or password.");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
errorMessage = $"{T("Fehler:", "Error:")} {ex.Message}";
|
|
}
|
|
finally
|
|
{
|
|
isBusy = false;
|
|
}
|
|
}
|
|
|
|
private async Task Verify2FA()
|
|
{
|
|
if (string.IsNullOrWhiteSpace(twoFactorCode) || twoFactorCode.Length != 6)
|
|
{
|
|
errorMessage = T("Bitte gib einen gültigen 6-stelligen Code ein.", "Please enter a valid 6-digit code.");
|
|
return;
|
|
}
|
|
|
|
isBusy = true;
|
|
errorMessage = string.Empty;
|
|
|
|
try
|
|
{
|
|
var result = await AuthService.Verify2FAAsync(twoFactorCode);
|
|
if (result)
|
|
{
|
|
AuthStateProvider.NotifyStateChanged();
|
|
Navigation.NavigateTo("/");
|
|
}
|
|
else
|
|
{
|
|
errorMessage = T("Ungültiger Code. Bitte versuche es erneut.", "Invalid code. Please try again.");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
errorMessage = $"{T("Fehler:", "Error:")} {ex.Message}";
|
|
}
|
|
finally
|
|
{
|
|
isBusy = false;
|
|
}
|
|
}
|
|
}
|