252 lines
10 KiB
PHP
252 lines
10 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
require_once __DIR__ . '/../db.php';
|
|
|
|
function installerEmbedded(): bool {
|
|
return defined('PROJECTKILN_INSTALL_EMBEDDED') && PROJECTKILN_INSTALL_EMBEDDED === true;
|
|
}
|
|
|
|
function installerTableExists(PDO $pdo, string $table): bool {
|
|
$stmt = $pdo->prepare(
|
|
'SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?'
|
|
);
|
|
$stmt->execute([$table]);
|
|
|
|
return (int)$stmt->fetchColumn() > 0;
|
|
}
|
|
|
|
function installerIsInstalled(PDO $pdo): bool {
|
|
if (!installerTableExists($pdo, 'settings')) {
|
|
return false;
|
|
}
|
|
|
|
$stmt = $pdo->prepare(
|
|
"SELECT COUNT(*) FROM settings WHERE setting_name = 'installed' AND LOWER(setting_value) = 'true'"
|
|
);
|
|
$stmt->execute();
|
|
|
|
return (int)$stmt->fetchColumn() > 0;
|
|
}
|
|
|
|
function redirectHome(): never {
|
|
header('Location: ' . (installerEmbedded() ? '?page=home' : '../?page=home'));
|
|
exit;
|
|
}
|
|
|
|
if (installerEmbedded()) {
|
|
$pageStyles[] = 'app/css/login.css';
|
|
}
|
|
|
|
$pdo = db();
|
|
|
|
if (installerIsInstalled($pdo)) {
|
|
redirectHome();
|
|
}
|
|
|
|
$installError = null;
|
|
$formError = null;
|
|
|
|
try {
|
|
require __DIR__ . '/install_db.php';
|
|
require_once __DIR__ . '/../auth.php';
|
|
} catch (Throwable $exception) {
|
|
$installError = $exception->getMessage();
|
|
}
|
|
|
|
if ($installError === null && $_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
$username = trim((string)($_POST['username'] ?? ''));
|
|
$email = strtolower(trim((string)($_POST['email'] ?? '')));
|
|
$password = (string)($_POST['password'] ?? '');
|
|
$passwordConfirm = (string)($_POST['password_confirm'] ?? '');
|
|
|
|
if ($username === '' || $email === '' || $password === '') {
|
|
$formError = 'Please fill in all required fields.';
|
|
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
|
$formError = 'Please enter a valid email address.';
|
|
} elseif (strlen($password) < 8) {
|
|
$formError = 'Password must be at least 8 characters long.';
|
|
} elseif ($password !== $passwordConfirm) {
|
|
$formError = 'Passwords do not match.';
|
|
} else {
|
|
$userId = register($username, $email, $password);
|
|
|
|
if ($userId === null) {
|
|
$formError = 'Admin user could not be created. Check if the email is already used.';
|
|
} else {
|
|
$adminRightStmt = $pdo->prepare("SELECT id FROM rights WHERE name = 'Admin' LIMIT 1");
|
|
$adminRightStmt->execute();
|
|
$adminRightId = (int)$adminRightStmt->fetchColumn();
|
|
|
|
if ($adminRightId <= 0) {
|
|
$formError = 'Admin right is missing after database setup.';
|
|
} else {
|
|
$existingRight = $pdo->prepare(
|
|
'SELECT COUNT(*) FROM user_rights WHERE user_id = ? AND right_id = ?'
|
|
);
|
|
$existingRight->execute([$userId, $adminRightId]);
|
|
|
|
if ((int)$existingRight->fetchColumn() === 0) {
|
|
$assignAdmin = $pdo->prepare(
|
|
'INSERT INTO user_rights (user_id, right_id) VALUES (?, ?)'
|
|
);
|
|
$assignAdmin->execute([$userId, $adminRightId]);
|
|
}
|
|
|
|
$markInstalled = $pdo->prepare(
|
|
"INSERT INTO settings (id, setting_name, setting_value)
|
|
VALUES (2, 'installed', 'true')
|
|
ON DUPLICATE KEY UPDATE setting_name = VALUES(setting_name), setting_value = VALUES(setting_value)"
|
|
);
|
|
$markInstalled->execute();
|
|
|
|
login($email, $password, false);
|
|
redirectHome();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function oldInput(string $name): string {
|
|
return htmlspecialchars((string)($_POST[$name] ?? ''), ENT_QUOTES, 'UTF-8');
|
|
}
|
|
?>
|
|
<?php if (!installerEmbedded()): ?>
|
|
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>ProjectKiln Install</title>
|
|
<link rel="stylesheet" href="../app/bootstrap/css/bootstrap.min.css">
|
|
<link rel="stylesheet" href="../app/fontawesome/css/all.min.css">
|
|
<link rel="stylesheet" href="../app/css/main.css">
|
|
<link rel="stylesheet" href="../app/css/dark_mode.css">
|
|
<link rel="stylesheet" href="../app/css/login.css">
|
|
</head>
|
|
<body>
|
|
<?php endif; ?>
|
|
<main class="container auth-container d-flex align-items-center justify-content-center">
|
|
<div class="card auth-card shadow-lg border">
|
|
<div class="row g-0 h-100">
|
|
<div class="col-lg-6 auth-brand p-5 d-flex flex-column justify-content-center">
|
|
<div class="auth-logo mb-4">
|
|
<i class="fa-solid fa-fire-flame-simple"></i>
|
|
</div>
|
|
|
|
<h1 class="display-5 fw-bold mb-3">
|
|
ProjectKiln Setup
|
|
</h1>
|
|
|
|
<p class="text-secondary mb-0">
|
|
Create the first administrator account to finish the installation.
|
|
</p>
|
|
</div>
|
|
|
|
<div class="col-lg-6 p-5 d-flex flex-column justify-content-center">
|
|
<?php if ($installError !== null): ?>
|
|
<div class="alert alert-danger mb-4">
|
|
<i class="fa-solid fa-circle-exclamation me-2"></i>
|
|
Database setup failed: <?= htmlspecialchars($installError, ENT_QUOTES, 'UTF-8') ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<?php if ($formError !== null): ?>
|
|
<div class="alert alert-danger mb-4">
|
|
<i class="fa-solid fa-circle-exclamation me-2"></i>
|
|
<?= htmlspecialchars($formError, ENT_QUOTES, 'UTF-8') ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<form method="post">
|
|
<div class="mb-3">
|
|
<label class="form-label">Username</label>
|
|
<div class="input-group">
|
|
<span class="input-group-text">
|
|
<i class="fa-solid fa-user"></i>
|
|
</span>
|
|
<input
|
|
type="text"
|
|
name="username"
|
|
class="form-control"
|
|
value="<?= oldInput('username') ?>"
|
|
autocomplete="username"
|
|
required
|
|
<?= $installError !== null ? 'disabled' : '' ?>
|
|
>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label class="form-label">Email Address</label>
|
|
<div class="input-group">
|
|
<span class="input-group-text">
|
|
<i class="fa-solid fa-envelope"></i>
|
|
</span>
|
|
<input
|
|
type="email"
|
|
name="email"
|
|
class="form-control"
|
|
value="<?= oldInput('email') ?>"
|
|
autocomplete="email"
|
|
required
|
|
<?= $installError !== null ? 'disabled' : '' ?>
|
|
>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label class="form-label">Password</label>
|
|
<div class="input-group">
|
|
<span class="input-group-text">
|
|
<i class="fa-solid fa-lock"></i>
|
|
</span>
|
|
<input
|
|
type="password"
|
|
name="password"
|
|
class="form-control"
|
|
autocomplete="new-password"
|
|
minlength="8"
|
|
required
|
|
<?= $installError !== null ? 'disabled' : '' ?>
|
|
>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-4">
|
|
<label class="form-label">Confirm Password</label>
|
|
<div class="input-group">
|
|
<span class="input-group-text">
|
|
<i class="fa-solid fa-key"></i>
|
|
</span>
|
|
<input
|
|
type="password"
|
|
name="password_confirm"
|
|
class="form-control"
|
|
autocomplete="new-password"
|
|
minlength="8"
|
|
required
|
|
<?= $installError !== null ? 'disabled' : '' ?>
|
|
>
|
|
</div>
|
|
</div>
|
|
|
|
<button
|
|
type="submit"
|
|
class="btn btn-primary w-100 auth-submit"
|
|
<?= $installError !== null ? 'disabled' : '' ?>
|
|
>
|
|
<i class="fa-solid fa-user-shield me-2"></i>
|
|
Create Admin
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
<?php if (!installerEmbedded()): ?>
|
|
</body>
|
|
</html>
|
|
<?php endif; ?>
|