Files
gravity/จัดการข้อมูล Line KSH-STAFF/admin/setup_2fa.php
T
2026-09-16 23:20:08 +07:00

160 lines
8.2 KiB
PHP

<?php
session_start();
require_once '../includes/db.php';
require_once '../includes/GoogleAuthenticator.php';
if (!isset($_SESSION['admin_logged_in'])) {
header("Location: login.php");
exit;
}
$stmt = $pdo->prepare("SELECT google2fa_secret FROM admin_users WHERE id = ?");
$stmt->execute([$_SESSION['admin_id']]);
$admin = $stmt->fetch();
// If already set up, redirect to dashboard
if (!empty($admin['google2fa_secret'])) {
header("Location: index.php");
exit;
}
$ga = new PHPGangsta_GoogleAuthenticator();
$error = '';
if (!isset($_SESSION['new_2fa_secret'])) {
$_SESSION['new_2fa_secret'] = $ga->createSecret();
}
$secret = $_SESSION['new_2fa_secret'];
$qrCodeUrl = $ga->getQRCodeGoogleUrl('KSH-STAFF-Admin', $secret);
if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['verify_code'])) {
$code = $_POST['code'] ?? '';
if ($ga->verifyCode($secret, $code, 2)) {
// Save to DB
$update = $pdo->prepare("UPDATE admin_users SET google2fa_secret = ? WHERE id = ?");
$update->execute([$secret, $_SESSION['admin_id']]);
unset($_SESSION['new_2fa_secret']);
echo "<script>alert('ตั้งค่า Google Authenticator สำเร็จ'); window.location.href='index.php';</script>";
exit;
} else {
$error = "รหัสไม่ถูกต้อง กรุณาลองใหม่อีกครั้ง";
}
}
?>
<!DOCTYPE html>
<html lang="th">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ตั้งค่า Google Authenticator</title>
<link rel="icon" type="image/png" href="../assets/img/logo.png">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Sarabun:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = {
theme: {
extend: {
fontFamily: {
sans: ['Sarabun', 'sans-serif'],
},
animation: {
shine: 'shine 3s ease-in-out infinite'
},
keyframes: {
shine: {
'0%': { left: '-150%' },
'20%': { left: '150%' },
'100%': { left: '150%' }
}
}
}
}
}
</script>
</head>
<body class="bg-gray-100 min-h-screen flex items-center justify-center font-sans antialiased p-4">
<div class="bg-white rounded-xl shadow-lg p-8 w-full max-w-lg border border-gray-100 text-center">
<div class="relative inline-block overflow-hidden rounded-full w-20 h-20 mx-auto mb-4 shadow-md bg-white p-1">
<img src="../assets/img/logo.png" alt="Logo" class="w-full h-full object-cover rounded-full relative z-10">
<div class="absolute inset-0 z-20 w-1/2 h-full bg-gradient-to-r from-transparent via-white/60 to-transparent -skew-x-12 animate-shine mix-blend-overlay"></div>
</div>
<h3 class="text-blue-600 text-2xl font-bold mb-3">ตั้งค่าความปลอดภัย (2FA)</h3>
<p class="text-gray-600 text-sm mb-6">เนื่องจากเป็นการเข้าสู่ระบบครั้งแรก กรุณาตั้งค่า Google Authenticator เพื่อความปลอดภัยในการเข้าถึงข้อมูล</p>
<div class="flex justify-center mb-6">
<img src="<?= $qrCodeUrl ?>" alt="QR Code" class="rounded-lg border border-gray-200 p-3 shadow-sm bg-white">
</div>
<div class="bg-blue-50 text-blue-800 rounded-lg p-4 text-sm text-left mb-6 shadow-inner">
<ol class="list-decimal list-inside space-y-2 font-medium">
<li>โหลดแอป Google Authenticator</li>
<li>สแกน QR Code ด้านบน</li>
<li>นำรหัส 6 หลักที่ได้มากรอกด้านล่าง</li>
</ol>
</div>
<?php if (!empty($error)): ?>
<div class="text-red-500 text-sm mb-4 font-medium bg-red-50 py-2 rounded-lg"><?= htmlspecialchars($error) ?></div>
<?php endif; ?>
<form method="post" id="otp-form" class="space-y-6">
<div class="flex justify-center gap-2">
<input type="text" maxlength="1" oninput="moveToNext(this, 'otp2')" id="otp1" class="w-12 h-14 text-center text-2xl font-bold border-2 border-gray-300 rounded-lg focus:border-blue-500 focus:ring-4 focus:ring-blue-500/20 outline-none transition" autofocus>
<input type="text" maxlength="1" oninput="moveToNext(this, 'otp3')" onkeydown="moveToPrev(event, this, 'otp1')" id="otp2" class="w-12 h-14 text-center text-2xl font-bold border-2 border-gray-300 rounded-lg focus:border-blue-500 focus:ring-4 focus:ring-blue-500/20 outline-none transition">
<input type="text" maxlength="1" oninput="moveToNext(this, 'otp4')" onkeydown="moveToPrev(event, this, 'otp2')" id="otp3" class="w-12 h-14 text-center text-2xl font-bold border-2 border-gray-300 rounded-lg focus:border-blue-500 focus:ring-4 focus:ring-blue-500/20 outline-none transition">
<input type="text" maxlength="1" oninput="moveToNext(this, 'otp5')" onkeydown="moveToPrev(event, this, 'otp3')" id="otp4" class="w-12 h-14 text-center text-2xl font-bold border-2 border-gray-300 rounded-lg focus:border-blue-500 focus:ring-4 focus:ring-blue-500/20 outline-none transition">
<input type="text" maxlength="1" oninput="moveToNext(this, 'otp6')" onkeydown="moveToPrev(event, this, 'otp4')" id="otp5" class="w-12 h-14 text-center text-2xl font-bold border-2 border-gray-300 rounded-lg focus:border-blue-500 focus:ring-4 focus:ring-blue-500/20 outline-none transition">
<input type="text" maxlength="1" oninput="submitOtp()" onkeydown="moveToPrev(event, this, 'otp5')" id="otp6" class="w-12 h-14 text-center text-2xl font-bold border-2 border-gray-300 rounded-lg focus:border-blue-500 focus:ring-4 focus:ring-blue-500/20 outline-none transition">
</div>
<input type="hidden" name="code" id="code2fa" required>
<button type="submit" name="verify_code" id="submit-btn" class="hidden">ยืนยันรหัสและบันทึก</button>
</form>
<div class="mt-8">
<a href="logout.php" class="text-red-500 hover:text-red-700 text-sm font-medium hover:underline transition">ออกจากระบบ (ตั้งค่าภายหลัง)</a>
</div>
</div>
<script>
function moveToNext(current, nextFieldId) {
if (current.value.length === 1) {
if (nextFieldId) document.getElementById(nextFieldId).focus();
}
}
function moveToPrev(e, current, prevFieldId) {
if (e.key === 'Backspace' && current.value === '') {
if (prevFieldId) document.getElementById(prevFieldId).focus();
}
}
function submitOtp() {
let code = '';
for (let i = 1; i <= 6; i++) {
code += document.getElementById('otp' + i).value;
}
document.getElementById('code2fa').value = code;
if (code.length === 6) {
document.getElementById('submit-btn').click();
}
}
// Handle pasting 6 digits at once
document.getElementById('otp1').addEventListener('paste', function(e) {
let paste = (e.clipboardData || window.clipboardData).getData('text');
if (paste.length === 6 && /^\d+$/.test(paste)) {
for (let i = 0; i < 6; i++) {
document.getElementById('otp' + (i+1)).value = paste[i];
}
submitOtp();
e.preventDefault();
}
});
</script>
</body>
</html>