request->getCookie('token'); // Debug: Log cookie status log_message('debug', 'V2Page checkAuth - token cookie: ' . ($token ? 'EXISTS (length: ' . strlen($token) . ')' : 'NOT FOUND')); log_message('debug', 'V2Page checkAuth - all cookies: ' . json_encode($_COOKIE)); if (!$token) { return false; } try { // Use getenv() directly like Auth controller $key = getenv('JWT_SECRET'); // Debug environment if key missing if (empty($key)) { log_message('error', 'V2Page checkAuth - JWT_SECRET missing. Env vars available: ' . implode(',', array_keys($_ENV))); log_message('error', 'V2Page checkAuth - getenv(JWT_SECRET): ' . (getenv('JWT_SECRET') ? 'FOUND' : 'EMPTY')); return false; } $this->user = JWT::decode($token, new Key($key, 'HS256')); return true; } catch (ExpiredException $e) { log_message('debug', 'V2Page checkAuth - token expired'); return false; } catch (\Exception $e) { log_message('debug', 'V2Page checkAuth - token error: ' . $e->getMessage()); return false; } } /** * Redirect to V2 login if not authenticated */ protected function requireAuth() { if (!$this->checkAuth()) { return redirect()->to(site_url('v2/login')); } return null; } /** * V2 Login Page */ public function login() { // If already authenticated, redirect to dashboard if ($this->checkAuth()) { return redirect()->to(site_url('v2')); } return view('v2/login', [ 'title' => 'V2 Login' ]); } /** * V2 Dashboard */ public function index() { if ($redirect = $this->requireAuth()) return $redirect; return view('v2/dashboard', [ 'title' => 'V2 Dashboard', 'user' => $this->user, 'activePage' => 'dashboard' ]); } /** * API Tester */ public function apiTester() { if ($redirect = $this->requireAuth()) return $redirect; return view('v2/api-tester', [ 'title' => 'API Tester', 'user' => $this->user, 'activePage' => 'api-tester' ]); } /** * Database Browser */ public function dbBrowser() { if ($redirect = $this->requireAuth()) return $redirect; return view('v2/db-browser', [ 'title' => 'DB Browser', 'user' => $this->user, 'activePage' => 'db-browser' ]); } /** * Logs Viewer */ public function logs() { if ($redirect = $this->requireAuth()) return $redirect; return view('v2/logs', [ 'title' => 'Logs', 'user' => $this->user, 'activePage' => 'logs' ]); } /** * Organization Management */ public function organization($type = 'account') { if ($redirect = $this->requireAuth()) return $redirect; // Normalize type $type = strtolower($type); $validTypes = ['account', 'site', 'discipline', 'department', 'workstation']; if (!in_array($type, $validTypes)) { return redirect()->to(site_url('v2/organization/account')); } return view('v2/organization', [ 'title' => 'Organization: ' . ucfirst($type) . 's', 'user' => $this->user, // activePage set below for sub-pages 'activePage' => 'organization-' . $type, 'type' => $type ]); } /** * Value Sets Management */ public function valuesets() { if ($redirect = $this->requireAuth()) return $redirect; return view('v2/valuesets', [ 'title' => 'Value Sets', 'user' => $this->user, 'activePage' => 'valuesets' ]); } /** * Patient List */ public function patients() { if ($redirect = $this->requireAuth()) return $redirect; return view('v2/patients', [ 'title' => 'Patients', 'user' => $this->user, 'activePage' => 'patients' ]); } /** * Patient Create Form */ public function patientCreate() { if ($redirect = $this->requireAuth()) return $redirect; return view('v2/patient-form', [ 'title' => 'New Patient', 'user' => $this->user, 'activePage' => 'patients' ]); } /** * Patient Edit Form */ public function patientEdit($id) { if ($redirect = $this->requireAuth()) return $redirect; // Load patient data $patientModel = new \App\Models\Patient\PatientModel(); $patient = $patientModel->getPatient($id); if (!$patient) { return redirect()->to(site_url('v2/patients')); } return view('v2/patient-form', [ 'title' => 'Edit Patient', 'user' => $this->user, 'activePage' => 'patients', 'patient' => $patient ]); } /** * Patient View/Detail */ public function patientView($id) { if ($redirect = $this->requireAuth()) return $redirect; return view('v2/patient-view', [ 'title' => 'Patient Details', 'user' => $this->user, 'activePage' => 'patients', 'patientId' => $id ]); } /** * JWT Decoder */ public function jwtDecoder() { if ($redirect = $this->requireAuth()) return $redirect; $token = $this->request->getCookie('token'); $decoded = null; $parts = null; if ($token) { $parts = explode('.', $token); if (count($parts) === 3) { $decoded = [ 'header' => json_decode(base64_decode($parts[0]), true), 'payload' => json_decode(base64_decode($parts[1]), true), 'signature' => $parts[2] ]; } } return view('v2/jwt-decoder', [ 'title' => 'JWT Decoder', 'user' => $this->user, 'activePage' => 'jwt-decoder', 'token' => $token, 'decoded' => $decoded ]); } /** * API: Get database tables */ public function getTables() { if (!$this->checkAuth()) { return $this->response->setJSON(['error' => 'Unauthorized'])->setStatusCode(401); } $db = Database::connect(); $tables = $db->listTables(); return $this->response->setJSON(['tables' => $tables]); } /** * API: Get table data */ public function getTableData($table) { if (!$this->checkAuth()) { return $this->response->setJSON(['error' => 'Unauthorized'])->setStatusCode(401); } $db = Database::connect(); // Validate table exists if (!$db->tableExists($table)) { return $this->response->setJSON(['error' => 'Table not found'])->setStatusCode(404); } // Get table structure $fields = $db->getFieldData($table); // Get data (limit 100) $builder = $db->table($table); $data = $builder->limit(100)->get()->getResultArray(); return $this->response->setJSON([ 'table' => $table, 'fields' => $fields, 'data' => $data, 'count' => count($data) ]); } /** * API: Get logs */ public function getLogs() { if (!$this->checkAuth()) { return $this->response->setJSON(['error' => 'Unauthorized'])->setStatusCode(401); } $logPath = WRITEPATH . 'logs/'; $logs = []; if (is_dir($logPath)) { $files = glob($logPath . 'log-*.log'); rsort($files); // Most recent first foreach (array_slice($files, 0, 5) as $file) { $logs[] = [ 'name' => basename($file), 'size' => filesize($file), 'content' => file_get_contents($file) ]; } } return $this->response->setJSON(['logs' => $logs]); } }