<?php
/**
* ============================================================================
* ONE-TIME ADMIN ACCOUNT SETUP โ DELETE THIS FILE AFTER USE
* ============================================================================
* This page does NOT require login โ anyone who knows the URL can use it to
* create or reset the admin account. That's by design (so you can recover
* access even with no working login), but it means you must delete this
* file from your server as soon as you're done with it.
*
* Why this file exists: password hashes generated outside of your own PHP
* install aren't 100% guaranteed to verify correctly (bcrypt implementations
* can differ subtly between languages/versions). This script uses YOUR
* server's own PHP password_hash() function, so the hash it creates is
* guaranteed to work with password_verify() on this same server.
* ============================================================================
*/
require_once __DIR__ . '/../includes/functions.php';
$existingCount = (int) db()->query('SELECT COUNT(*) c FROM admin_users')->fetch()['c'];
$success = null;
$error = null;
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (!csrfVerify($_POST['csrf_token'] ?? null)) {
$error = 'Session expired โ please reload this page and try again.';
} else {
$name = trim($_POST['name'] ?? '');
$email = trim($_POST['email'] ?? '');
$password = $_POST['password'] ?? '';
$confirm = $_POST['confirm_password'] ?? '';
if ($name === '' || $email === '' || $password === '') {
$error = 'All fields are required.';
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$error = 'Please enter a valid email address.';
} elseif (strlen($password) < 8) {
$error = 'Password must be at least 8 characters.';
} elseif ($password !== $confirm) {
$error = 'Password confirmation does not match.';
} else {
$hash = password_hash($password, PASSWORD_DEFAULT);
$stmt = db()->prepare('SELECT id FROM admin_users WHERE email = ?');
$stmt->execute([$email]);
$existing = $stmt->fetch();
if ($existing) {
db()->prepare('UPDATE admin_users SET name = ?, password_hash = ? WHERE id = ?')->execute([$name, $hash, $existing['id']]);
} else {
db()->prepare('INSERT INTO admin_users (name, email, password_hash) VALUES (?, ?, ?)')->execute([$name, $email, $hash]);
}
$success = "Admin account for \"$email\" is ready. You can log in now at admin/login.php โ then delete this setup.php file.";
$existingCount = (int) db()->query('SELECT COUNT(*) c FROM admin_users')->fetch()['c'];
}
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Admin Setup ยท PIMS Nepal</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Poppins:wght@500;600;700;800&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.css">
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = { theme: { extend: {
colors: { primary: '#0D6EFD', secondary: '#1E3A8A', accent: '#F59E0B' },
fontFamily: { heading: ['Poppins','sans-serif'], sans: ['Inter','sans-serif'] }
} } }
</script>
<style>body{font-family:'Inter',sans-serif;} .font-heading{font-family:'Poppins',sans-serif;}</style>
</head>
<body class="bg-gradient-to-br from-secondary to-primary min-h-screen flex items-center justify-center px-4 py-10">
<div class="bg-white rounded-2xl shadow-xl w-full max-w-md p-8">
<div class="flex flex-col items-center mb-5">
<img src="../assets/images/pims-logo.png" alt="PIMS Nepal" class="h-14 w-14 object-contain mb-3" />
<h1 class="font-heading font-bold text-xl">Admin Account Setup</h1>
</div>
<div class="mb-5 bg-amber-50 border border-amber-200 text-amber-800 text-sm px-4 py-3 rounded-lg">
<i class="bi bi-exclamation-triangle-fill"></i> This page has no login check. Delete <code>admin/setup.php</code> from your server immediately after creating your account.
</div>
<?php if ($existingCount > 0 && !$success): ?>
<div class="mb-5 bg-blue-50 border border-blue-200 text-blue-800 text-sm px-4 py-3 rounded-lg">
<i class="bi bi-info-circle-fill"></i> An admin account already exists. Submitting this form with an existing email will <strong>reset that account's password</strong>. Use a new email to create an additional admin.
</div>
<?php endif; ?>
<?php if ($success): ?>
<div class="mb-5 bg-green-50 border border-green-200 text-green-700 text-sm px-4 py-3 rounded-lg"><i class="bi bi-check-circle-fill"></i> <?= e($success) ?></div>
<a href="login.php" class="block text-center bg-primary text-white py-3 rounded-lg font-semibold">Go to Login</a>
<?php else: ?>
<?php if ($error): ?>
<div class="mb-4 bg-red-50 border border-red-200 text-red-700 text-sm px-4 py-3 rounded-lg"><i class="bi bi-exclamation-circle-fill"></i> <?= e($error) ?></div>
<?php endif; ?>
<form method="post" class="space-y-4">
<input type="hidden" name="csrf_token" value="<?= e(csrfToken()) ?>" />
<label class="block"><span class="block text-sm font-medium text-gray-700 mb-1.5">Your Name</span>
<input type="text" name="name" required value="<?= e($_POST['name'] ?? 'Admin') ?>" class="w-full px-4 py-2.5 rounded-lg border border-gray-200 focus:outline-none focus:ring-2 focus:ring-primary text-sm" /></label>
<label class="block"><span class="block text-sm font-medium text-gray-700 mb-1.5">Email (this is your login username)</span>
<input type="email" name="email" required value="<?= e($_POST['email'] ?? '') ?>" class="w-full px-4 py-2.5 rounded-lg border border-gray-200 focus:outline-none focus:ring-2 focus:ring-primary text-sm" /></label>
<label class="block"><span class="block text-sm font-medium text-gray-700 mb-1.5">Password (min 8 characters)</span>
<input type="password" name="password" required minlength="8" class="w-full px-4 py-2.5 rounded-lg border border-gray-200 focus:outline-none focus:ring-2 focus:ring-primary text-sm" /></label>
<label class="block"><span class="block text-sm font-medium text-gray-700 mb-1.5">Confirm Password</span>
<input type="password" name="confirm_password" required minlength="8" class="w-full px-4 py-2.5 rounded-lg border border-gray-200 focus:outline-none focus:ring-2 focus:ring-primary text-sm" /></label>
<button class="w-full bg-primary text-white py-3 rounded-lg font-semibold hover:opacity-90">Create / Reset Admin Account</button>
</form>
<?php endif; ?>
</div>
</body>
</html>