Files
FlyTeam/SkyTeam/LogInPage.xaml.cs
2026-03-05 12:32:01 +01:00

128 lines
5.2 KiB
C#

using BCrypt.Net;
using MySql.Data.MySqlClient;
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace SkyTeam
{
public partial class LogInPage : Page
{
public LogInPage()
{
InitializeComponent();
}
private void AdminLink_Click(object sender, RoutedEventArgs e)
{
// Quelle: Im Unterricht gemacht
if (Application.Current.MainWindow is MainWindow mainWindow)
{
mainWindow.MainFrame.Navigate(new AdminLoginPage());
}
}
private void LogInButton_Click(object sender, RoutedEventArgs e)
{
string email = BenutzernameTextBox.Text;
string password = PasswortTextBox.Password;
// Quelle: Im Unterricht gemacht
// Basis Validierung auf leere Felder
if (string.IsNullOrEmpty(email) || string.IsNullOrEmpty(password))
{
MessageBox.Show("Bitte Email und Passwort eingeben.");
return;
}
string query = @"
SELECT Id, Vorname, Rolle, PasswortHash
FROM users
WHERE Email = @email";
try
{
using (MySqlConnection conn = new MySqlConnection(DatenbankServices.GetConnection()))
{
conn.Open();
using (MySqlCommand cmd = new MySqlCommand(query, conn))
{
cmd.Parameters.AddWithValue("@email", email);
using (MySqlDataReader reader = cmd.ExecuteReader())
{
if (!reader.Read())
{
MessageBox.Show("Benutzer wurde nicht gefunden.");
return;
}
// Quelle: Stack Overflow "How to verify a BCrypt hash"
// Man kann gehashte Passwörter NICHT direkt im SQL Query vergleichen
// (z.B. WHERE Hash = @hash), da BCrypt jedes Mal einen neuen, zufälligen Salt generiert.
// Wir müssen erst den gespeicherten Hash aus der DB laden und dann die Verify Methode
// der BCrypt-Bibliothek nutzen, um das Klartext passwort damit zu prüfen
string storedHash = reader.GetString("PasswortHash");
if (!BCrypt.Net.BCrypt.Verify(password, storedHash))
{
MessageBox.Show("Falsches Passwort.");
return;
}
// Quelle: AI Assistant (chat gpt)
// Idee: Globales State-Management über eine statische Klasse (SessionManager)
// Kommentar: Anstatt die User ID mühsam über jeden Seitenaufruf hinweg in den Konstruktoren
// weiterzureichen, hat die KI vorgeschlagen, eine statische SessionManager Klasse zu nutzen.
// So sind User-ID, Name und Rolle global für die gesamte Laufzeit abrufbar.
SessionManager.CurrentUserId = reader.GetInt32("Id");
SessionManager.CurrentUserName = reader.GetString("Vorname");
SessionManager.Role = reader.GetString("Rolle");
}
}
((MainWindow)Application.Current.MainWindow)
.MainFrame.Navigate(new NavigationPage());
}
}
catch (Exception ex)
{
MessageBox.Show("Datenbankfehler: " + ex.Message);
}
}
private void anmeldungsButton_Click(object sender, RoutedEventArgs e)
{
// Quelle: Im Unterricht gemacht
((MainWindow)Application.Current.MainWindow)
.MainFrame.Navigate(new RegistrationPage());
}
private void Page_Loaded(object sender, RoutedEventArgs e)
{
// Quelle: Im Unterricht gemacht
// Setzt den Cursor direkt beim Laden der Seite ins Benutzernamen-Feld.
BenutzernameTextBox.Focus();
}
private void BenutzernameTextBox_PreviewKeyDown(object sender, KeyEventArgs e)
{
// Quelle: Stack Overflow "WPF Move focus on enter key"
// Kommentar: Ein UX-Feature (User Experience). Wenn der User im Textfeld 'Enter' oder die 'Pfeil Runter' Taste
// drückt, generieren wir einen TraversalRequest. Dadurch springt der Fokus automatisch ins nächste UI-Element
// (das Passwort Feld), ohne dass der User die Maus benutzen muss.
if (e.Key == Key.Down || e.Key == Key.Enter)
{
TraversalRequest request =
new TraversalRequest(FocusNavigationDirection.Next);
(sender as UIElement).MoveFocus(request);
e.Handled = true;
}
}
}
}