chartboard/app/Controllers/Audit/AuditController.php
2026-03-30 09:51:33 +05:30

136 lines
5.1 KiB
PHP

<?php
namespace App\Controllers\Audit;
use App\Controllers\BaseController;
use App\Models\AuditLogModel;
use App\Models\WorkspaceMemberModel;
class AuditController extends BaseController
{
public function index()
{
$session = $this->session;
$isSuper = (string) $session->get('role') === 'superadmin';
$activeWs = (int) $session->get('active_workspace_id');
$scope = (string) $this->request->getGet('scope');
if (! in_array($scope, ['active', 'global', 'all'], true)) {
$scope = 'active';
}
if (! $isSuper && $scope !== 'active') {
$scope = 'active';
}
$filters = [
'user_id' => (int) $this->request->getGet('user_id'),
'action' => trim((string) $this->request->getGet('action')),
'date_from' => trim((string) $this->request->getGet('date_from')),
'date_to' => trim((string) $this->request->getGet('date_to')),
];
if ($scope === 'global') {
$filters['workspace_id'] = null;
} elseif ($scope === 'all' && $isSuper) {
unset($filters['workspace_id']);
} else {
$filters['workspace_id'] = $activeWs > 0 ? $activeWs : null;
}
$model = new AuditLogModel();
$page = $model->paginateFiltered(25, $filters);
$memberUsers = [];
if ($activeWs > 0) {
$rows = (new WorkspaceMemberModel())
->select('workspace_members.user_id, users.name, users.email')
->join('users', 'users.id = workspace_members.user_id')
->where('workspace_members.workspace_id', $activeWs)
->orderBy('users.name', 'ASC')
->findAll();
foreach ($rows as $r) {
$memberUsers[] = [
'id' => (int) $r['user_id'],
'name' => (string) ($r['name'] ?? ''),
'email' => (string) ($r['email'] ?? ''),
];
}
}
return view('audit/index', [
'title' => 'Audit log | Chart-Board',
'logs' => $page['data'],
'pager' => $page['pager'],
'filters' => $filters,
'scope' => $scope,
'isSuperadmin' => $isSuper,
'memberUsers' => $memberUsers,
'activeWorkspace' => $activeWs,
]);
}
public function detail(int $id)
{
$row = (new AuditLogModel())->findWithUser($id);
if (! $row) {
return $this->response->setJSON(['success' => false, 'message' => 'Not found.'])->setStatusCode(404);
}
$session = $this->session;
$isSuper = (string) $session->get('role') === 'superadmin';
$activeWs = (int) $session->get('active_workspace_id');
$wid = $row['workspace_id'] !== null ? (int) $row['workspace_id'] : null;
if (! $isSuper) {
if ($wid === null || $wid !== $activeWs) {
if ($wid !== null) {
return $this->response->setJSON(['success' => false, 'message' => 'Forbidden.'])->setStatusCode(403);
}
return $this->response->setJSON(['success' => false, 'message' => 'Forbidden.'])->setStatusCode(403);
}
$member = (new WorkspaceMemberModel())
->where('workspace_id', $activeWs)
->where('user_id', (int) $session->get('user_id'))
->first();
if (! $member || (string) ($member['role'] ?? '') !== 'admin') {
return $this->response->setJSON(['success' => false, 'message' => 'Forbidden.'])->setStatusCode(403);
}
}
$old = $this->decodeJson($row['old_value'] ?? null);
$new = $this->decodeJson($row['new_value'] ?? null);
return $this->response->setJSON([
'success' => true,
'log' => [
'id' => (int) $row['id'],
'action' => (string) ($row['action'] ?? ''),
'resource_type' => $row['resource_type'],
'resource_id' => $row['resource_id'],
'user_name' => $row['user_name'] ?? null,
'user_email' => $row['user_email'] ?? null,
'created_at' => (string) ($row['created_at'] ?? ''),
'ip_address' => $row['ip_address'] ?? null,
'user_agent' => $row['user_agent'] ?? null,
'old_value_json' => json_encode($old, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE),
'new_value_json' => json_encode($new, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE),
],
]);
}
private function decodeJson(mixed $raw): mixed
{
if ($raw === null || $raw === '') {
return null;
}
if (is_array($raw)) {
return $raw;
}
$d = json_decode((string) $raw, true);
return is_array($d) ? $d : (string) $raw;
}
}