103 lines
3.1 KiB
PHP
103 lines
3.1 KiB
PHP
<?php
|
|
defined('BASEPATH') OR exit('No direct script access allowed');
|
|
|
|
class AttendanceWebhook extends CI_Controller {
|
|
|
|
public function __construct()
|
|
{
|
|
parent::__construct();
|
|
|
|
date_default_timezone_set('Asia/Jakarta');
|
|
}
|
|
|
|
public function cdata()
|
|
{
|
|
// =========================
|
|
// AMBIL SN MESIN
|
|
// =========================
|
|
$sn = trim((string) $this->input->get('SN', true));
|
|
if ($sn === '' || !preg_match('/^[A-Za-z0-9._-]{1,100}$/', $sn)) {
|
|
show_error('Serial number perangkat tidak valid.', 400);
|
|
}
|
|
|
|
$allowedSerials = array_filter(array_map('trim', explode(',', (string) app_env('ATTENDANCE_ALLOWED_SERIALS', ''))));
|
|
if (!empty($allowedSerials) && !in_array($sn, $allowedSerials, true)) {
|
|
log_message('error', 'Attendance webhook ditolak untuk SN: ' . $sn);
|
|
show_error('Perangkat tidak terdaftar.', 403);
|
|
}
|
|
|
|
if (ENVIRONMENT === 'production' && empty($allowedSerials)) {
|
|
log_message('error', 'ATTENDANCE_ALLOWED_SERIALS belum dikonfigurasi di production.');
|
|
show_error('Konfigurasi perangkat belum tersedia.', 503);
|
|
}
|
|
|
|
// =========================
|
|
// RAW BODY DARI MESIN
|
|
// =========================
|
|
$body = file_get_contents('php://input', false, null, 0, 1048576);
|
|
if ($body === false) {
|
|
show_error('Payload tidak dapat dibaca.', 400);
|
|
}
|
|
|
|
// =========================
|
|
// LOG DIRECTORY
|
|
// =========================
|
|
$logDir = APPPATH . 'logs/fingerprint/';
|
|
|
|
if (!is_dir($logDir)) {
|
|
mkdir($logDir, 0750, true);
|
|
}
|
|
|
|
// =========================
|
|
// FILE LOG
|
|
// =========================
|
|
$logFile = $logDir . date('Y-m-d') . '.log';
|
|
|
|
// =========================
|
|
// FORMAT LOG HEADER
|
|
// =========================
|
|
$logText = "\n==================================================\n";
|
|
$logText .= "TIME : " . date('Y-m-d H:i:s') . "\n";
|
|
$logText .= "SN : " . $sn . "\n";
|
|
$logText .= "IP : " . $this->input->ip_address() . "\n";
|
|
$logText .= "DATA : \n";
|
|
|
|
// =========================
|
|
// PARSE BARIS ABSENSI
|
|
// =========================
|
|
$lines = explode("\n", trim($body));
|
|
|
|
foreach ($lines as $line) {
|
|
|
|
$line = trim($line);
|
|
|
|
if (empty($line)) {
|
|
continue;
|
|
}
|
|
|
|
$logText .= str_replace(array("\r", "\0"), '', $line) . "\n";
|
|
|
|
// contoh parsing
|
|
$data = explode("\t", $line);
|
|
|
|
/*
|
|
hasil biasanya:
|
|
[0] => PIN/User ID
|
|
[1] => Datetime
|
|
[2] => Status
|
|
*/
|
|
|
|
}
|
|
|
|
// =========================
|
|
// SIMPAN LOG
|
|
// =========================
|
|
file_put_contents($logFile, $logText, FILE_APPEND | LOCK_EX);
|
|
|
|
// =========================
|
|
// RESPONSE KE MESIN
|
|
// =========================
|
|
echo "OK";
|
|
}
|
|
}
|