db = \Config\Database::connect(); } /** * Write one audit entry. * * @param array{ * action: string, * entity_type?: string, * entity_id?: string|int, * abha_id?: string, * patient_id?: int, * request?: array, * response?: array, * outcome?: string, * error_message?: string, * actor_user_id?: int, * actor_name?: string, * } $data */ public function log(array $data): void { try { if (! $this->db->tableExists('abdm_audit_logs')) { return; } $httpRequest = \Config\Services::request(); $session = \Config\Services::session(); $actorUserId = (int) ($data['actor_user_id'] ?? $session->get('user_id') ?? 0); $actorName = trim((string) ($data['actor_name'] ?? $session->get('full_name') ?? $session->get('name') ?? '')); // Serialise request / response to JSON; never store raw binary data $requestJson = isset($data['request']) ? json_encode($data['request'], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) : null; $responseJson = isset($data['response']) ? json_encode($data['response'], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) : null; $entityId = (string) ($data['entity_id'] ?? ''); $patientId = (int) ($data['patient_id'] ?? 0); $this->db->table('abdm_audit_logs')->insert([ 'actor_user_id' => $actorUserId > 0 ? $actorUserId : null, 'actor_name' => $actorName !== '' ? $actorName : null, 'action' => (string) ($data['action'] ?? 'unknown'), 'entity_type' => (string) ($data['entity_type'] ?? ''), 'entity_id' => $entityId !== '' ? $entityId : null, 'abha_id' => trim((string) ($data['abha_id'] ?? '')) ?: null, 'patient_id' => $patientId > 0 ? $patientId : null, 'request_json' => $requestJson, 'response_json' => $responseJson, 'ip_address' => $httpRequest->getIPAddress(), 'user_agent' => mb_substr((string) $httpRequest->getUserAgent(), 0, 255), 'outcome' => (string) ($data['outcome'] ?? 'success'), 'error_message' => trim((string) ($data['error_message'] ?? '')) ?: null, 'created_at' => Time::now('Asia/Kolkata')->toDateTimeString(), ]); } catch (\Throwable) { // Fail-open: audit failure must never break the main application flow } } }