152 lines
5.0 KiB
C#
152 lines
5.0 KiB
C#
using System;
|
||
using System.Linq;
|
||
using Avalonia.Controls;
|
||
using Avalonia.Interactivity;
|
||
using ChronoFlow.Controller;
|
||
using ChronoFlow.Persistence;
|
||
using ChronoFlow.Security;
|
||
using ChronoFlow.View.Security;
|
||
using Microsoft.Data.Sqlite;
|
||
|
||
namespace ChronoFlow.View;
|
||
|
||
/// <summary>
|
||
/// Das Login-Fenster für Benutzer der Anwendung.
|
||
/// Es prüft die Anmeldedaten, erzwingt ggf. eine Passwortänderung und startet das Hauptfenster.
|
||
/// </summary>
|
||
public partial class LoginWindow : Window
|
||
{
|
||
private readonly LoginController _loginController;
|
||
|
||
/// <summary>
|
||
/// Konstruktor – Initialisiert UI und legt bei Bedarf den Standard-Admin an.
|
||
/// </summary>
|
||
public LoginWindow()
|
||
{
|
||
InitializeComponent();
|
||
_loginController = new LoginController();
|
||
|
||
try
|
||
{
|
||
var service = new SqliteZeiterfassungsService();
|
||
service.ErstelleStandardAdmin(); // Falls noch kein Admin vorhanden, wird ein Default-Admin erstellt.
|
||
}
|
||
catch (SqliteException ex) when (ex.SqliteErrorCode == 5)
|
||
{
|
||
ErrorText.Text = "⚠️ Die Datenbank ist gesperrt. Bitte schließen Sie andere Programme (z. B. DB Browser for SQLite) und starten Sie die App neu.";
|
||
ErrorText.IsVisible = true;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
ErrorText.Text = $"Fehler beim Initialisieren: {ex.Message}";
|
||
ErrorText.IsVisible = true;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Wird aufgerufen, wenn der Benutzer auf „Anmelden“ klickt.
|
||
/// </summary>
|
||
private async void LoginButton_Click(object? sender, RoutedEventArgs e)
|
||
{
|
||
var username = UsernameBox.Text?.Trim();
|
||
var password = PasswordBox.Text?.Trim();
|
||
|
||
// Validierung: Felder dürfen nicht leer sein
|
||
if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password))
|
||
{
|
||
ErrorText.Text = "Bitte Benutzername und Passwort eingeben.";
|
||
ErrorText.IsVisible = true;
|
||
return;
|
||
}
|
||
|
||
SqliteZeiterfassungsService service;
|
||
try
|
||
{
|
||
service = new SqliteZeiterfassungsService();
|
||
}
|
||
catch (SqliteException ex) when (ex.SqliteErrorCode == 5)
|
||
{
|
||
ErrorText.Text = "⚠️ Die Datenbank ist gesperrt. Bitte schließen Sie andere Programme und versuchen Sie es erneut.";
|
||
ErrorText.IsVisible = true;
|
||
return;
|
||
}
|
||
|
||
var benutzerListe = service.LadeAlleBenutzer();
|
||
|
||
// Benutzer mit eingegebenem Namen (case-insensitive) finden
|
||
var matchingUsers = benutzerListe
|
||
.Where(u => u.Username.Equals(username, StringComparison.OrdinalIgnoreCase))
|
||
.ToList();
|
||
|
||
if (matchingUsers.Count == 0)
|
||
{
|
||
ErrorText.Text = "Benutzername nicht gefunden.";
|
||
ErrorText.IsVisible = true;
|
||
return;
|
||
}
|
||
|
||
if (matchingUsers.Count > 1)
|
||
{
|
||
ErrorText.Text = "Interner Fehler: Mehrere Benutzer mit gleichem Namen.";
|
||
ErrorText.IsVisible = true;
|
||
return;
|
||
}
|
||
|
||
var user = matchingUsers.First();
|
||
|
||
// Passwort-Überprüfung mit Hashing
|
||
if (!PasswordHasher.VerifyPassword(password, user.Password))
|
||
{
|
||
ErrorText.Text = "Falsches Passwort. Bitte erneut versuchen.";
|
||
ErrorText.IsVisible = true;
|
||
return;
|
||
}
|
||
|
||
// Benutzer muss Passwort ändern? → Dialog anzeigen
|
||
if (user.MussPasswortAendern)
|
||
{
|
||
var dialog = new PasswortAendernDialog(user);
|
||
var neuesPasswort = await dialog.ShowDialog<string>(this);
|
||
|
||
if (!string.IsNullOrEmpty(neuesPasswort))
|
||
{
|
||
string neuerHash = PasswordHasher.HashPassword(neuesPasswort);
|
||
user.Password = neuerHash;
|
||
user.MussPasswortAendern = false;
|
||
service.UpdateBenutzer(user);
|
||
}
|
||
else
|
||
{
|
||
ErrorText.Text = "Sie müssen ein neues Passwort setzen!";
|
||
ErrorText.IsVisible = true;
|
||
return;
|
||
}
|
||
}
|
||
|
||
try
|
||
{
|
||
// Login-Zeit aktualisieren (für spätere Änderungsbenachrichtigungen)
|
||
var vorher = user.LetzterLogin;
|
||
user.LetzterLogin = DateTime.Now;
|
||
user.VorletzterLogin = vorher;
|
||
service.UpdateLoginZeiten(user);
|
||
|
||
// Hauptfenster öffnen und Login-Fenster schließen
|
||
var main = new MainWindow(user);
|
||
main.Show();
|
||
main.Activate();
|
||
Close();
|
||
}
|
||
catch (SqliteException ex) when (ex.SqliteErrorCode == 5)
|
||
{
|
||
ErrorText.Text = "⚠️ Datenbank gesperrt. Bitte schließen Sie andere Programme und starten Sie die App neu.";
|
||
ErrorText.IsVisible = true;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
ErrorText.Text = $"Interner Fehler beim Starten des Hauptfensters: {ex.Message}";
|
||
ErrorText.IsVisible = true;
|
||
}
|
||
}
|
||
}
|