Files
2026-09-08 18:21:10 +01:00

126 lines
5.2 KiB
PHP

<?php
// Admin: list / add / edit / ban / delete users, reset passwords.
require_once __DIR__ . '/../lib/bootstrap.php';
$me = require_admin();
$d = db();
$msg = ''; $err = '';
$edit = (int)($_GET['edit'] ?? 0);
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
require_csrf();
$act = $_POST['act'] ?? '';
$uid = (int)($_POST['uid'] ?? 0);
if ($act === 'add') {
$n = trim((string)($_POST['username'] ?? ''));
$p = (string)($_POST['pass'] ?? '');
$a = (int)($_POST['is_admin'] ?? 0);
if (!valid_username($n)) $err = 'Bad username (3-16 alnum/underscore).';
elseif (strlen($p) < 4) $err = 'Password too short.';
elseif (username_taken($n)) $err = 'Username taken.';
else { user_create($n, $p, $a); $msg = 'User ' . $n . ' created.'; }
} elseif ($act === 'save' && $uid) {
$u = user_by_id($uid);
if (!$u) $err = 'No such user.';
else {
$tag = mb_substr(trim((string)($_POST['tagline'] ?? '')), 0, 80);
$loc = mb_substr(trim((string)($_POST['location'] ?? '')), 0, 40);
$adm = (int)($_POST['is_admin'] ?? 0);
$ban = (int)($_POST['is_banned'] ?? 0);
// never let an admin strip their own last-admin rights into a lockout
if ($uid === (int)$me['id'] && !$adm) {
$err = 'You cannot remove your own admin rights.';
} else {
$d->prepare("UPDATE users SET tagline=?,location=?,is_admin=?,is_banned=? WHERE id=?")
->execute([$tag, $loc, $adm, $ban, $uid]);
$msg = 'Saved ' . $u['username'] . '.';
$newpw = (string)($_POST['newpass'] ?? '');
if ($newpw !== '') {
if (strlen($newpw) < 4) $err = 'New password too short - not changed.';
else {
$d->prepare("UPDATE users SET pass_hash=? WHERE id=?")
->execute([password_hash($newpw, PASSWORD_DEFAULT), $uid]);
$msg .= ' Password reset.';
}
}
}
}
} elseif ($act === 'del' && $uid) {
if ($uid === (int)$me['id']) $err = 'You cannot delete yourself.';
else {
$u = user_by_id($uid);
$d->prepare("DELETE FROM users WHERE id=?")->execute([$uid]);
$msg = 'Deleted ' . ($u['username'] ?? '#' . $uid) . '.';
$edit = 0;
}
}
}
page_start('Admin: users', ['back' => '/admin/index.php']);
if ($err) p_err($err);
if ($msg) p_ok($msg);
// ---------- edit one user ----------
if ($edit && ($u = user_by_id($edit))) {
p_para('Editing: ' . $u['username'] . ' (#' . $u['id'] . ')');
p_form('/admin/users.php?edit=' . $edit, [
['name' => 'act', 'type' => 'hidden', 'value' => 'save'],
['name' => 'uid', 'type' => 'hidden', 'value' => (string)$u['id']],
['name' => 'tagline', 'label' => 'Tagline', 'value' => $u['tagline'], 'maxlength' => 80],
['name' => 'location', 'label' => 'Location', 'value' => $u['location'], 'maxlength' => 40],
['name' => 'is_admin', 'label' => 'Admin', 'type' => 'select',
'value' => (string)$u['is_admin'], 'options' => ['0' => 'no', '1' => 'yes']],
['name' => 'is_banned', 'label' => 'Banned', 'type' => 'select',
'value' => (string)$u['is_banned'], 'options' => ['0' => 'no', '1' => 'yes']],
['name' => 'newpass', 'label' => 'Reset password (blank=keep)', 'type' => 'password'],
], 'Save user');
p_form('/admin/users.php', [
['name' => 'act', 'type' => 'hidden', 'value' => 'del'],
['name' => 'uid', 'type' => 'hidden', 'value' => (string)$u['id']],
], 'DELETE user');
p_links([['/admin/users.php', 'Back to user list']]);
page_end();
exit;
}
// ---------- list ----------
$q = trim((string)($_POST['q'] ?? $_GET['q'] ?? ''));
$page = max(1, (int)($_GET['p'] ?? 1));
$off = ($page - 1) * PER_PAGE;
if ($q !== '') {
$s = $d->prepare("SELECT * FROM users WHERE username LIKE ? ORDER BY id LIMIT ? OFFSET ?");
$s->execute(['%' . $q . '%', PER_PAGE + 1, $off]);
} else {
$s = $d->prepare("SELECT * FROM users ORDER BY id LIMIT ? OFFSET ?");
$s->execute([PER_PAGE + 1, $off]);
}
$rows = $s->fetchAll();
$more = count($rows) > PER_PAGE;
if ($more) array_pop($rows);
foreach ($rows as $r) {
$tags = ($r['is_admin'] ? ' [admin]' : '') . ($r['is_banned'] ? ' [BANNED]' : '');
p_link('/admin/users.php', '#' . $r['id'] . ' ' . $r['username'] . $tags,
['edit' => $r['id']]);
}
if (!$rows) p_para('No users found.');
p_pager('/admin/users.php', $page, $more, $q !== '' ? ['q' => $q] : []);
p_rule();
p_form('/admin/users.php', [
['name' => 'q', 'label' => 'Search username', 'value' => $q, 'maxlength' => 16],
], 'Search');
p_rule();
p_para('Add a user:');
p_form('/admin/users.php', [
['name' => 'act', 'type' => 'hidden', 'value' => 'add'],
['name' => 'username', 'label' => 'Username', 'maxlength' => 16],
['name' => 'pass', 'label' => 'Password', 'type' => 'password'],
['name' => 'is_admin', 'label' => 'Admin', 'type' => 'select',
'options' => ['0' => 'no', '1' => 'yes']],
], 'Add user');
p_links([['/admin/index.php', 'Admin home']]);
page_end();