check()) { return redirect()->route('portal.change_login'); } //wenn als Kunde eingeloggt, dann direkt zum Dashboard if (Auth::guard('customers')->check()) { return redirect()->route('portal.dashboard'); } return view('portal.auth.login'); // Erstelle diese View } // Sendet das OTP public function sendOtp(Request $request) { $request->validate(['email' => 'required|email']); $email = $request->input('email'); // 1. Prüfen, ob die E-Mail im System bekannt ist über Kunden-Tabelle) $customer = Customer::firstOrCreate(['email' => $email]); // Erstellt Kunden, wenn nicht vorhanden if ($customer && $customer->language) { \App::setLocale($customer->language); } //add user_shop_domain for back $customer->user_shop_domain = session('user_shop_domain'); $customer->save(); // if (!$customerExists && !$orderExists) { // Oder nur eine Prüfung, je nach Logik if (!$customer) { // Prüfung anhand des Customer-Models throw ValidationException::withMessages([ 'email' => __('auth.failed_customer'), // Generische Fehlermeldung ]); } // 2. Alten Token löschen (optional, aber empfohlen) DB::table('otp_tokens')->where('email', $email)->delete(); // 3. OTP generieren (z.B. 6-stellige Zahl) $otp = random_int(100000, 999999); $expiresAt = Carbon::now()->addMinutes(10); // Gültigkeit z.B. 10 Minuten // 4. OTP (gehasht!) speichern DB::table('otp_tokens')->insert([ 'email' => $email, 'token' => Hash::make((string)$otp), // WICHTIG: Token hashen! 'expires_at' => $expiresAt, 'created_at' => Carbon::now(), ]); // 5. OTP per E-Mail senden (Notification oder Mailable verwenden) try { Mail::to($email)->locale(\App::getLocale())->send(new MailOTPCustomer($otp, $email)); } catch (\Exception $e) { // Logge den Fehler \Log::error('OTP Send Error: ' . $e->getMessage()); // Gib eine Fehlermeldung zurück, ohne Details preiszugeben return back()->withErrors(['email' => 'Konnte E-Mail nicht senden. Bitte versuchen Sie es später erneut.'])->withInput(); } // 6. Zum OTP-Eingabeformular weiterleiten (E-Mail in Session speichern oder als Parameter übergeben) session(['otp_email' => $email]); // Explizit in Session speichern return redirect()->route('portal.login.otp.form', ['email' => $email]); // E-Mail auch als Parameter übergeben } // Zeigt das Formular zur Eingabe des OTP an public function showOtpForm(Request $request, $email = null, $otp = null) { //wenn als Berater eingeloggt, dann zum Login wechseln if (Auth::guard('user')->check()) { return redirect()->route('portal.change_login'); } //wenn als Kunde eingeloggt, dann zum Dashboard wechseln if (Auth::guard('customers')->check()) { return redirect()->route('portal.dashboard'); } // E-Mail aus der Session holen (oder als Request-Parameter erwarten) if ($email) { $email = $email; } else { $email = session('otp_email', $request->query('email')); } if (!$email) { return redirect()->route('portal.login.form')->withErrors(['message' => 'Sitzung abgelaufen oder E-Mail fehlt.']); } // CSRF-Token regenerieren für neue Session $request->session()->regenerateToken(); // Übergebe sowohl 'email' als auch 'otp' an die View return view('portal.auth.verify-otp', ['email' => $email, 'otp_value' => $otp]); // Variable umbenannt zu otp_value für Klarheit } // Validiert das OTP und loggt den Kunden ein public function verifyOtpAndLogin(Request $request) { $request->validate([ 'email' => 'required|email', 'otp' => 'required|numeric|digits:6', // An die Länge deines OTPs anpassen ]); $email = $request->input('email'); $otpInput = $request->input('otp'); // 1. Gespeicherten OTP-Eintrag finden $otpRecord = DB::table('otp_tokens')->where('email', $email)->first(); // 2. Prüfen ob Eintrag existiert, nicht abgelaufen ist und das OTP (Hash) übereinstimmt if (!$otpRecord || Carbon::now()->gt($otpRecord->expires_at) || !Hash::check($otpInput, $otpRecord->token)) { // Ungültiges oder abgelaufenes OTP DB::table('otp_tokens')->where('email', $email)->delete(); // Ungültigen Token löschen return back()->withErrors(['otp' => 'Ungültiges oder abgelaufenes Einmalpasswort.'])->withInput(['email' => $email]); } // 3. Kunden-Objekt finden (basierend auf dem Provider-Model) $customer = Customer::where('email', $email)->first(); // Oder User::where('email', $email)->where('role','customer')->first(); if (!$customer) { // Sollte eigentlich nicht passieren, wenn sendOtp korrekt funktioniert hat DB::table('otp_tokens')->where('email', $email)->delete(); return back()->withErrors(['otp' => __('auth.failed')])->withInput(['email' => $email]); } // 4. Kunden einloggen über den 'customers'-Guard Auth::guard('customers')->login($customer); // Loggt den gefundenen Kunden ein // 5. Explizite Session-Speicherung $request->session()->save(); // 6. OTP-Eintrag löschen DB::table('otp_tokens')->where('email', $email)->delete(); // 7. Session Token regenerieren (statt komplette Session) $request->session()->regenerate(); // 8. customer DB aktualisieren $shopping_user = ShoppingUser::where('billing_email', $email)->latest()->first(); if ($shopping_user) { $data = [ 'name' => $shopping_user->billing_firstname . ' ' . $shopping_user->billing_lastname, 'shopping_user_id' => $shopping_user->id, 'member_id' => $shopping_user->member_id, 'number' => $shopping_user->number, 'language' => session('locale') ?? 'de', ]; $customer->update($data); } else { $data = [ 'name' => __('portal.guest'), 'shopping_user_id' => null, 'member_id' => null, 'number' => null, 'language' => session('locale') ?? 'de', ]; $customer->update($data); } // 10. Zum Kunden-Dashboard weiterleiten return redirect()->intended(route('portal.dashboard')); // intended() leitet zur ursprünglich angefragten Seite weiter } // Logout für Kunden public function logout(Request $request) { $url = Util::getMyMivitaShopUrl(); Auth::guard('customers')->logout(); $request->session()->invalidate(); $request->session()->regenerateToken(); return redirect($url); } // Logout für Berater public function logoutChange(Request $request) { //$url = Util::getMyMivitaShopUrl(); $user_shop_domain = session('user_shop_domain'); $locale = session('locale'); Auth::guard('user')->logout(); $request->session()->invalidate(); $request->session()->regenerateToken(); session(['user_shop_domain' => $user_shop_domain]); session(['locale' => $locale]); return redirect()->route('portal.login.form'); } }