346 lines
7.7 KiB
PHP
346 lines
7.7 KiB
PHP
<?php
|
|
|
|
namespace App\Controllers\Pages;
|
|
|
|
use CodeIgniter\Controller;
|
|
use Firebase\JWT\JWT;
|
|
use Firebase\JWT\Key;
|
|
use Firebase\JWT\ExpiredException;
|
|
use Config\Database;
|
|
|
|
/**
|
|
* V2 Page Controller
|
|
* Hidden frontend for backend development
|
|
*/
|
|
class V2Page extends Controller
|
|
{
|
|
protected $user = null;
|
|
|
|
/**
|
|
* Check JWT authentication
|
|
*/
|
|
protected function checkAuth()
|
|
{
|
|
$token = $this->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]);
|
|
}
|
|
}
|