Files
D1041231092-webgis-povertymap/core/Auth.php
T
2026-06-11 12:30:23 +07:00

150 lines
5.0 KiB
PHP

<?php
// core/Auth.php
class Auth {
private static ?array $user = null;
public static function init(): void {
if (session_status() === PHP_SESSION_NONE) {
session_name(SESSION_NAME);
session_set_cookie_params([
'lifetime' => SESSION_LIFETIME,
'path' => '/',
'secure' => false,
'httponly' => true,
'samesite' => 'Lax'
]);
session_start();
}
}
public static function attempt(string $username, string $password): bool {
$db = Database::getInstance();
$user = $db->fetchOne(
"SELECT u.*, r.slug as role_slug, r.nama as role_nama
FROM users u
JOIN roles r ON u.id_role = r.id
WHERE (u.username = ? OR u.email = ?) AND u.is_active = 1",
[$username, $username]
);
if ($user && password_verify($password, $user['password'])) {
// Update last login
$db->update('users', ['last_login' => date('Y-m-d H:i:s')], 'id = ?', [$user['id']]);
// Store in session
$_SESSION['user_id'] = $user['id'];
$_SESSION['user_name'] = $user['nama'];
$_SESSION['user_role'] = $user['role_slug'];
$_SESSION['user_email'] = $user['email'];
$_SESSION['id_kelurahan'] = $user['id_kelurahan'];
$_SESSION['login_time'] = time();
// Log activity
self::logActivity($user['id'], $user['nama'], $user['role_slug'], 'Login', 'auth', 'Login ke sistem');
return true;
}
return false;
}
public static function check(): bool {
return isset($_SESSION['user_id']) && !empty($_SESSION['user_id']);
}
public static function user(): ?array {
if (!self::check()) return null;
if (self::$user !== null) return self::$user;
$db = Database::getInstance();
self::$user = $db->fetchOne(
"SELECT u.*, r.slug as role_slug, r.nama as role_nama,
k.nama as kelurahan_nama, kec.nama as kecamatan_nama,
ri.id as rumah_ibadah_id, ri.nama as rumah_ibadah_nama,
ri.lat as ri_lat, ri.lng as ri_lng, ri.radius_meter as ri_radius
FROM users u
JOIN roles r ON u.id_role = r.id
LEFT JOIN kelurahan k ON u.id_kelurahan = k.id
LEFT JOIN kecamatan kec ON k.id_kecamatan = kec.id
LEFT JOIN rumah_ibadah ri ON ri.id_user = u.id
WHERE u.id = ?",
[$_SESSION['user_id']]
);
return self::$user;
}
public static function id(): ?int {
return self::check() ? (int)$_SESSION['user_id'] : null;
}
public static function role(): ?string {
return $_SESSION['user_role'] ?? null;
}
public static function is(string ...$roles): bool {
return in_array(self::role(), $roles);
}
public static function logout(): void {
if (self::check()) {
self::logActivity(
$_SESSION['user_id'],
$_SESSION['user_name'],
$_SESSION['user_role'],
'Logout', 'auth', 'Logout dari sistem'
);
}
$_SESSION = [];
session_destroy();
self::$user = null;
}
public static function require(string ...$roles): void {
self::init();
if (!self::check()) {
header('Location: ' . APP_URL . '/login');
exit;
}
if (!empty($roles) && !self::is(...$roles)) {
header('Location: ' . APP_URL . '/forbidden');
exit;
}
}
public static function redirectIfLoggedIn(): void {
if (self::check()) {
header('Location: ' . self::getDashboardUrl());
exit;
}
}
public static function getDashboardUrl(): string {
return match(self::role()) {
'superadmin' => APP_URL . '/admin/dashboard',
'verifikator' => APP_URL . '/verifikator/dashboard',
'rumah_ibadah' => APP_URL . '/rumah-ibadah/dashboard',
'dinsos' => APP_URL . '/dinsos/dashboard',
'walikota' => APP_URL . '/walikota/dashboard',
default => APP_URL . '/'
};
}
public static function logActivity(int $userId, string $namaUser, string $role, string $aksi, string $modul, string $deskripsi = ''): void {
try {
$db = Database::getInstance();
$db->insert('aktivitas_sistem', [
'id_user' => $userId,
'nama_user' => $namaUser,
'role' => $role,
'aksi' => $aksi,
'modul' => $modul,
'deskripsi' => $deskripsi,
'ip_address' => $_SERVER['REMOTE_ADDR'] ?? '',
'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? ''
]);
} catch (Exception $e) {
// Silent fail for logging
}
}
}