load->library('UserSessionService'); } public function index() { if ($this->session->userdata('logged_in')) { redirect('dashboard'); } $notices=array('expired'=>'Masa login Anda telah berakhir. Silakan login kembali.','revoked'=>'Session perangkat telah diakhiri. Silakan login kembali.','device_limit'=>'Login ditolak karena batas perangkat aktif telah tercapai.'); $key=(string)$this->input->get('notice',true); $this->load->view('auth/login',array('auth_notice'=>$notices[$key]??'')); } public function process_login() { if (strtoupper($this->input->method()) !== 'POST') { show_error('Metode request tidak diizinkan.', 405); } $lockedUntil = (int) $this->session->userdata('login_locked_until'); if ($lockedUntil > time()) { $remaining = max(1, (int) ceil(($lockedUntil - time()) / 60)); $this->session->set_flashdata('error', 'Terlalu banyak percobaan login. Coba kembali dalam ' . $remaining . ' menit.'); redirect('auth'); return; } $username = trim((string) $this->input->post('username', true)); $password = (string) $this->input->post('password'); if ($username === '' || $password === '') { $this->session->set_flashdata('error', 'Username dan password wajib diisi.'); redirect('auth'); return; } $user = $this->db->get_where('v_users', ['username' => $username])->row(); $account = $user ? $this->db->get_where('users', array('id' => (int)$user->id))->row() : null; if ($user && (int)$user->role_is_active === 1 && password_verify($password, $user->password)) { $this->session->sess_regenerate(true); try { $loginSecurity = $this->usersessionservice->begin($account ?: $user); } catch (Throwable $exception) { log_message('error', 'Pencatatan session login gagal: ' . $exception->getMessage()); $this->session->set_flashdata('error', 'Login belum dapat diproses karena pencatatan keamanan session gagal.'); redirect('auth'); return; } if (!$loginSecurity['allowed']) { $this->session->set_flashdata('error', $loginSecurity['message']); redirect('auth'); return; } $this->session->unset_userdata(array('login_attempts', 'login_locked_until')); // Decode permissions $permissions = json_decode($user->permissions, true); if (!is_array($permissions)) { $permissions = []; } $role = $this->db->select('is_super_admin')->get_where('roles', array('id' => (int)$user->role_id))->row(); $session_data = [ 'user_id' => $user->id, 'nama' => $user->nama, 'username' => $user->username, 'role' => $user->nama_role, 'role_id' => (int) $user->role_id, 'is_super_admin'=> $role && (int)$role->is_super_admin === 1, 'permissions' => $permissions, 'logged_in' => TRUE, 'email' => $account->email ?? null, 'profile_photo' => $account->profile_photo ?? null, 'auth_login_key'=> $loginSecurity['login_key'], 'auth_started_at'=> $loginSecurity['login_at'], 'auth_expires_at'=> $loginSecurity['expires_at'] ]; $this->session->set_userdata($session_data); // 🔥 LOG LOGIN BERHASIL log_activity( 'Auth', 'login', 'User '.$user->username.' berhasil login', 'success' ); redirect('dashboard'); } else { $this->usersessionservice->recordInvalid($account, $username); $attempts = (int) $this->session->userdata('login_attempts') + 1; $this->session->set_userdata('login_attempts', $attempts); if ($attempts >= 5) { $this->session->set_userdata(array( 'login_attempts' => 0, 'login_locked_until' => time() + 300 )); } // 🔥 LOG LOGIN GAGAL log_activity( 'Auth', 'login_failed', 'Login gagal untuk username: '.$username, 'failed' ); $this->session->set_flashdata('error', 'Username atau password salah.'); redirect('auth'); } } public function logout() { $username = $this->session->userdata('username'); // 🔥 LOG LOGOUT (SEBELUM DESTROY SESSION) log_activity( 'Auth', 'logout', 'User '.$username.' logout', 'success' ); $this->usersessionservice->endCurrent('logged_out', 'Logout oleh pengguna.'); $this->session->sess_destroy(); redirect('auth'); } } ?>