ChronoFlow/ChronoFlow.View/LoginWindow.axaml.cs
2025-06-29 17:50:02 +02:00

152 lines
5.0 KiB
C#
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
}
}
}