136 lines
6.1 KiB
PHP
136 lines
6.1 KiB
PHP
<?php
|
||
// ─────────────────────────────────────────────
|
||
// register.php · New user registration
|
||
// ─────────────────────────────────────────────
|
||
require_once __DIR__ . '/auth.php';
|
||
|
||
if (currentUserId()) { header('Location: index.php'); exit; }
|
||
|
||
$siteName = getSetting('site_name', 'Finance Planner');
|
||
$registrationEnabled = getSetting('registration_enabled', '1') === '1';
|
||
$error = '';
|
||
|
||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||
if (!$registrationEnabled) {
|
||
$error = 'Registration is currently disabled.';
|
||
} else {
|
||
$username = trim($_POST['username'] ?? '');
|
||
$displayName = trim($_POST['display_name'] ?? '');
|
||
$password = $_POST['password'] ?? '';
|
||
$confirm = $_POST['confirm_password'] ?? '';
|
||
|
||
if (!$username || !$password) {
|
||
$error = 'Username and password are required.';
|
||
} elseif (!preg_match('/^[a-zA-Z0-9_]{3,30}$/', $username)) {
|
||
$error = 'Username must be 3–30 characters: letters, numbers, underscores only.';
|
||
} elseif (strlen($password) < 6) {
|
||
$error = 'Password must be at least 6 characters.';
|
||
} elseif ($password !== $confirm) {
|
||
$error = 'Passwords do not match.';
|
||
} else {
|
||
try {
|
||
require_once __DIR__ . '/db.php';
|
||
$db = getDB();
|
||
$st = $db->prepare("SELECT id FROM users WHERE username = ?");
|
||
$st->execute([$username]);
|
||
if ($st->fetch()) {
|
||
$error = 'That username is already taken. Please choose another.';
|
||
} else {
|
||
$dn = $displayName ?: $username;
|
||
$hash = password_hash($password, PASSWORD_DEFAULT);
|
||
$db->prepare("INSERT INTO users (username, password_hash, display_name) VALUES (?,?,?)")
|
||
->execute([$username, $hash, $dn]);
|
||
$newId = (int)$db->lastInsertId();
|
||
// Give them a default account to get started
|
||
$db->prepare("INSERT INTO accounts (user_id, name, currency) VALUES (?,?,?)")
|
||
->execute([$newId, 'Main Account', 'GBP']);
|
||
// Auto-login
|
||
$_SESSION['user'] = [
|
||
'id' => $newId,
|
||
'username' => $username,
|
||
'display_name' => $dn,
|
||
'is_admin' => 0,
|
||
];
|
||
header('Location: index.php');
|
||
exit;
|
||
}
|
||
} catch (Exception $e) {
|
||
$error = 'Registration failed. Please try again.';
|
||
}
|
||
}
|
||
}
|
||
}
|
||
?>
|
||
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<title>Register · <?= htmlspecialchars($siteName) ?></title>
|
||
<link rel="stylesheet" href="style.css">
|
||
<style>
|
||
.auth-wrap { display:flex;align-items:center;justify-content:center;min-height:100vh;padding:24px; }
|
||
.auth-card {
|
||
background:var(--surface);border:1px solid var(--border);
|
||
border-radius:var(--radius);padding:36px 30px;max-width:380px;width:100%;
|
||
}
|
||
.auth-logo { font-size:2.5rem;text-align:center;margin-bottom:10px; }
|
||
.auth-card h1 { font-size:1.2rem;text-align:center;margin-bottom:6px; }
|
||
.auth-sub { color:var(--text-dim);font-size:.8rem;text-align:center;margin-bottom:24px; }
|
||
.auth-footer { color:var(--text-muted);font-size:.8rem;text-align:center;margin-top:16px; }
|
||
.auth-footer a { color:var(--accent);text-decoration:none; }
|
||
.field-hint { font-size:.7rem;color:var(--text-muted);margin-top:3px; }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="auth-wrap">
|
||
<div class="auth-card">
|
||
<div class="auth-logo">💷</div>
|
||
<h1><?= htmlspecialchars($siteName) ?></h1>
|
||
<p class="auth-sub">Create your free account</p>
|
||
|
||
<?php if (!$registrationEnabled): ?>
|
||
<div class="alert alert-err">
|
||
Registration is currently disabled.<br>
|
||
Please contact the site administrator.
|
||
</div>
|
||
<div class="auth-footer"><a href="login.php">← Back to Login</a></div>
|
||
<?php else: ?>
|
||
|
||
<?php if ($error): ?>
|
||
<div class="alert alert-err"><?= htmlspecialchars($error) ?></div>
|
||
<?php endif; ?>
|
||
|
||
<form method="POST" action="register.php">
|
||
<div class="form-group">
|
||
<label>Username <span style="color:var(--red)">*</span></label>
|
||
<input type="text" name="username"
|
||
value="<?= htmlspecialchars($_POST['username'] ?? '') ?>"
|
||
placeholder="e.g. jane_doe" autocomplete="username" autofocus required>
|
||
<div class="field-hint">3–30 characters · letters, numbers, underscores</div>
|
||
</div>
|
||
<div class="form-group">
|
||
<label>Display Name <span style="color:var(--text-muted)">(optional)</span></label>
|
||
<input type="text" name="display_name"
|
||
value="<?= htmlspecialchars($_POST['display_name'] ?? '') ?>"
|
||
placeholder="e.g. Jane">
|
||
</div>
|
||
<div class="form-group">
|
||
<label>Password <span style="color:var(--red)">*</span></label>
|
||
<input type="password" name="password"
|
||
placeholder="Minimum 6 characters" autocomplete="new-password" required>
|
||
</div>
|
||
<div class="form-group">
|
||
<label>Confirm Password <span style="color:var(--red)">*</span></label>
|
||
<input type="password" name="confirm_password"
|
||
placeholder="Repeat password" autocomplete="new-password" required>
|
||
</div>
|
||
<button type="submit" class="btn btn-primary btn-full">Create Account</button>
|
||
</form>
|
||
|
||
<div class="auth-footer">Already have an account? <a href="login.php">Sign in →</a></div>
|
||
<?php endif; ?>
|
||
</div>
|
||
</div>
|
||
</body>
|
||
</html>
|