chore: prepare docker webgis deployment

This commit is contained in:
Andrie
2026-06-11 18:14:21 +07:00
parent d2214ad9c8
commit a90748d9c1
149 changed files with 20844 additions and 5 deletions
@@ -0,0 +1,47 @@
<?php
// api/auth/change_password.php — POST: ganti password akun sendiri
header('Content-Type: application/json');
require_once '../../config.php';
require_once '../../auth/helper.php';
require_once '../../koneksi.php';
require_auth('viewer');
require_csrf();
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
echo json_encode(['status' => 'error', 'message' => 'Method not allowed']);
exit;
}
$new_password = $_POST['new_password'] ?? '';
$confirm = $_POST['confirm_password'] ?? '';
// Validasi policy: min 8 karakter, kombinasi huruf + angka
if (strlen($new_password) < 8) {
echo json_encode(['status' => 'error', 'message' => 'Password minimal 8 karakter']);
exit;
}
if (!preg_match('/[a-zA-Z]/', $new_password) || !preg_match('/[0-9]/', $new_password)) {
echo json_encode(['status' => 'error', 'message' => 'Password harus mengandung huruf dan angka']);
exit;
}
if ($new_password !== $confirm) {
echo json_encode(['status' => 'error', 'message' => 'Konfirmasi password tidak cocok']);
exit;
}
$hash = password_hash($new_password, PASSWORD_BCRYPT);
$user_id = get_user_id();
$stmt = $conn->prepare("UPDATE users SET password = ?, must_change_password = 0 WHERE id = ?");
$stmt->bind_param('si', $hash, $user_id);
if ($stmt->execute()) {
$_SESSION['must_change_password'] = 0;
echo json_encode(['status' => 'success', 'message' => 'Password berhasil diubah']);
} else {
echo json_encode(['status' => 'error', 'message' => 'Gagal menyimpan password']);
}
$stmt->close();
$conn->close();
+105
View File
@@ -0,0 +1,105 @@
<?php
// api/auth/login.php — POST: validasi kredensial + buat sesi
header('Content-Type: application/json');
require_once '../../config.php';
require_once '../../auth/helper.php';
require_once '../../koneksi.php';
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
echo json_encode(['status' => 'error', 'message' => 'Method not allowed']);
exit;
}
$username = trim($_POST['username'] ?? '');
$password = trim($_POST['password'] ?? '');
if (!$username || !$password) {
echo json_encode(['status' => 'error', 'message' => 'Username dan password wajib diisi']);
exit;
}
// Ambil user dari DB (prepared statement — SQL injection safe)
$stmt = $conn->prepare(
"SELECT id, nama_lengkap, password, role, ibadah_id, is_active,
must_change_password, login_attempts, locked_until
FROM users WHERE username = ? LIMIT 1"
);
$stmt->bind_param('s', $username);
$stmt->execute();
$user = $stmt->get_result()->fetch_assoc();
$stmt->close();
if (!$user) {
echo json_encode(['status' => 'error', 'message' => 'Username atau password salah']);
exit;
}
if (!$user['is_active']) {
echo json_encode(['status' => 'error', 'message' => 'Akun dinonaktifkan. Hubungi Administrator.']);
exit;
}
// Cek lockout
if ($user['locked_until'] && strtotime($user['locked_until']) > time()) {
$menit = ceil((strtotime($user['locked_until']) - time()) / 60);
echo json_encode(['status' => 'error', 'message' => "Akun terkunci. Coba lagi dalam {$menit} menit."]);
exit;
}
// Verifikasi password
if (!password_verify($password, $user['password'])) {
$attempts = $user['login_attempts'] + 1;
if ($attempts >= MAX_LOGIN_ATTEMPTS) {
$locked_until = date('Y-m-d H:i:s', time() + LOCKOUT_MINUTES * 60);
$stmt = $conn->prepare("UPDATE users SET login_attempts = ?, locked_until = ? WHERE id = ?");
$stmt->bind_param('isi', $attempts, $locked_until, $user['id']);
} else {
$stmt = $conn->prepare("UPDATE users SET login_attempts = ? WHERE id = ?");
$stmt->bind_param('ii', $attempts, $user['id']);
}
$stmt->execute();
$stmt->close();
$sisa = MAX_LOGIN_ATTEMPTS - $attempts;
$msg = $sisa > 0
? "Username atau password salah. Sisa percobaan: {$sisa}"
: "Akun terkunci " . LOCKOUT_MINUTES . " menit karena terlalu banyak percobaan gagal.";
echo json_encode(['status' => 'error', 'message' => $msg]);
exit;
}
// Login berhasil — reset attempts
$stmt = $conn->prepare("UPDATE users SET login_attempts = 0, locked_until = NULL WHERE id = ?");
$stmt->bind_param('i', $user['id']);
$stmt->execute();
$stmt->close();
// Rotate session ID sebelum menulis data (cegah session fixation)
session_regenerate_id(true);
// Buat sesi
$_SESSION['user_id'] = $user['id'];
$_SESSION['username'] = $username;
$_SESSION['nama'] = $user['nama_lengkap'];
$_SESSION['role'] = $user['role'];
$_SESSION['ibadah_id'] = $user['ibadah_id'];
$_SESSION['must_change_password'] = (int)$user['must_change_password'];
$_SESSION['last_activity'] = time();
// Redirect target: admin → dashboard, operator/viewer → map
$redirect = ($user['role'] === 'administrator') ? '../dashboard.php' : '../index.php';
echo json_encode([
'status' => 'success',
'redirect' => $redirect,
'data' => [
'user_id' => $user['id'],
'nama' => $user['nama_lengkap'],
'role' => $user['role'],
'ibadah_id' => $user['ibadah_id'],
'must_change_password'=> (bool)$user['must_change_password'],
]
]);
$conn->close();
+8
View File
@@ -0,0 +1,8 @@
<?php
// api/auth/logout.php — Hancurkan sesi dan redirect ke login
require_once '../../config.php';
require_once '../../auth/helper.php';
session_destroy();
header('Location: ../../auth/login.php');
exit;