MIF_E31231313/Website/s_gizi/app/Http/Controllers/Admin/AuthController.php

183 lines
5.9 KiB
PHP

<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Auth\Events\PasswordReset;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Password;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Str;
use Illuminate\Validation\Rules\Password as PasswordRule;
use Illuminate\View\View;
class AuthController extends Controller
{
public function showLogin(): View
{
return view('auth.admin-login');
}
public function login(Request $request): RedirectResponse
{
$validated = $request->validate([
'login' => ['required', 'string', 'max:255'],
'password' => ['required', 'string', 'min:8'],
]);
$key = $this->throttleKey($request);
if (RateLimiter::tooManyAttempts($key, 5)) {
return back()
->withInput($request->only('login'))
->withErrors(['login' => 'Terlalu banyak percobaan login. Coba lagi dalam 5 menit.']);
}
$identifier = trim($validated['login']);
$user = User::query()
->where(function ($query) use ($identifier) {
$query->where('email', $identifier)
->orWhere('phone', $this->normalizePhone($identifier));
})
->whereIn('role', ['super_admin', 'admin_operasional', 'ahli_gizi', 'nutritionist', 'ahli gizi'])
->first();
if (! $user) {
RateLimiter::hit($key, 300);
return back()->withInput($request->only('login'))->withErrors([
'login' => 'Email tidak ditemukan.',
]);
}
if (! $user->password || ! Hash::check($validated['password'], $user->password)) {
RateLimiter::hit($key, 300);
return back()->withInput($request->only('login'))->withErrors([
'login' => 'Password salah.',
]);
}
if (($user->account_status ?? 'Aktif') !== 'Aktif' || ($user->status ?? 'aktif') === 'nonaktif') {
RateLimiter::hit($key, 300);
return back()->withInput($request->only('login'))->withErrors([
'login' => 'Akun dinonaktifkan.',
]);
}
RateLimiter::clear($key);
Auth::login($user, false);
$request->session()->regenerate();
$request->session()->put('admin_last_activity', time());
$user->update([
'last_login_at' => now(),
'last_active_at' => now(),
'last_login_ip' => $request->ip(),
'last_login_user_agent' => Str::limit((string) $request->userAgent(), 500, ''),
]);
if (in_array($user->role, ['ahli_gizi', 'nutritionist', 'ahli gizi'], true)) {
$user->nutritionist?->forceFill([
'is_online' => true,
'last_active_at' => now(),
])->saveQuietly();
return redirect()->intended(route('nutritionist.dashboard'));
}
return redirect()->intended(route('admin.dashboard'));
}
public function logout(Request $request): RedirectResponse
{
$user = Auth::user();
if ($user?->nutritionist) {
$user->nutritionist->forceFill([
'is_online' => false,
'last_active_at' => now(),
])->saveQuietly();
}
Auth::logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return redirect()->route('admin.login')->with('status', 'Anda berhasil logout.');
}
public function showForgotPassword(): View
{
return view('auth.admin-forgot-password');
}
public function sendResetLink(Request $request): RedirectResponse
{
$request->validate(['email' => ['required', 'email']]);
$status = Password::sendResetLink($request->only('email'));
return $status === Password::RESET_LINK_SENT
? back()->with('status', 'Link reset password sudah dikirim jika email terdaftar.')
: back()->withErrors(['email' => 'Email tidak ditemukan.']);
}
public function showResetPassword(Request $request, string $token): View
{
return view('auth.admin-reset-password', [
'token' => $token,
'email' => $request->query('email'),
]);
}
public function resetPassword(Request $request): RedirectResponse
{
$request->validate([
'token' => ['required'],
'email' => ['required', 'email'],
'password' => ['required', 'confirmed', PasswordRule::min(8)],
]);
$status = Password::reset(
$request->only('email', 'password', 'password_confirmation', 'token'),
function (User $user, string $password) {
$user->forceFill([
'password' => $password,
'remember_token' => Str::random(60),
])->save();
event(new PasswordReset($user));
}
);
return $status === Password::PASSWORD_RESET
? redirect()->route('admin.login')->with('status', 'Password berhasil diperbarui.')
: back()->withErrors(['email' => 'Token reset password tidak valid.']);
}
private function throttleKey(Request $request): string
{
return Str::lower((string) $request->input('login')).'|'.$request->ip();
}
private function normalizePhone(string $phone): string
{
$digits = preg_replace('/\D+/', '', $phone) ?? '';
if ($digits === '') {
return $phone;
}
if (str_starts_with($digits, '0')) {
$digits = '62'.substr($digits, 1);
}
if (! str_starts_with($digits, '62')) {
$digits = '62'.$digits;
}
return '+'.$digits;
}
}