diff options
| author | Connor Thomson <blumatrikz@gmail.com> | 2026-09-20 21:01:48 -0700 |
|---|---|---|
| committer | Connor Thomson <blumatrikz@gmail.com> | 2026-09-20 21:01:48 -0700 |
| commit | 1b35cf3f1124b161ebde5e9e3a2c74c8ea2821d0 (patch) | |
| tree | 5f1255ab93943e50685d712a6d49b7ca8e2b484b | |
| parent | 81cabf40f9063f72f04df9b720d7f0e25a185741 (diff) | |
Add status and more
| -rwxr-xr-x | admin/admin.php | 89 | ||||
| -rwxr-xr-x | admin/index.php | 34 | ||||
| -rwxr-xr-x | html/account.html | 1 | ||||
| -rwxr-xr-x | html/admin.html | 69 | ||||
| -rwxr-xr-x | html/forbidden.html | 21 | ||||
| -rwxr-xr-x | html/profile.html | 21 | ||||
| -rwxr-xr-x | html/unknown-user.html | 21 | ||||
| -rwxr-xr-x | php/header.php | 3 | ||||
| -rwxr-xr-x | php/render.php | 8 | ||||
| -rw-r--r-- | php/user.php | 49 | ||||
| -rwxr-xr-x | profile/index.php | 43 | ||||
| -rwxr-xr-x | signin/signin.php | 5 | ||||
| -rwxr-xr-x | signup/signup.php | 5 | ||||
| -rwxr-xr-x | signup/verify/verify.php | 9 |
14 files changed, 366 insertions, 12 deletions
diff --git a/admin/admin.php b/admin/admin.php new file mode 100755 index 0000000..0a00cf3 --- /dev/null +++ b/admin/admin.php @@ -0,0 +1,89 @@ +<?php +/* + * GNUfault.org - GNUfault's website + * Copyright (C) 2026 Connor Thomson + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +define('ROOT', rtrim($_SERVER['DOCUMENT_ROOT'], '/') . '/'); + +require_once ROOT . '/php/user.php'; + +if (!is_admin()) { + http_response_code(403); + + echo "Forbidden"; + exit; +} + +if ($_SERVER["REQUEST_METHOD"] != "POST") { + header("Location: /admin"); + exit; +} + +$action = isset($_POST['action']) ? $_POST['action'] : ''; +$username = isset($_POST['username']) ? $_POST['username'] : ''; + +try { + if (!find_user($username)) { + echo "User not found."; + exit; + } + + if ($action == 'password') { + $password = $_POST['password']; + $confirmpassword = $_POST['confirmpassword']; + + if ($confirmpassword != $password) { + echo "Passwords do not match!"; + exit; + } + + $sql = "UPDATE users SET password = :password WHERE username = :username"; + + query($sql, [ + 'password' => password_hash($password, PASSWORD_DEFAULT), + 'username' => $username + ]); + } elseif ($action == 'status') { + $status = isset($_POST['status']) ? $_POST['status'] : ''; + + if (!in_array($status, USER_STATUSES, true)) { + echo "That is not a status!"; + exit; + } + + $sql = "UPDATE users SET status = :status WHERE username = :username"; + + query($sql, [ + 'status' => $status, + 'username' => $username + ]); + } elseif ($action == 'remove') { + $sql = "DELETE FROM users WHERE username = :username"; + + query($sql, ['username' => $username]); + } else { + echo "That is not something I can do."; + exit; + } +} catch (\PDOException $e) { + echo "Error: " . $e->getMessage(); + exit; +} + +header("Location: /admin"); + +?> diff --git a/admin/index.php b/admin/index.php new file mode 100755 index 0000000..29c8873 --- /dev/null +++ b/admin/index.php @@ -0,0 +1,34 @@ +<?php +/* + * GNUfault.org - GNUfault's website + * Copyright (C) 2026 Connor Thomson + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +define('ROOT', rtrim($_SERVER['DOCUMENT_ROOT'], '/') . '/'); + +require_once ROOT . '/php/render.php'; +require_once ROOT . '/php/user.php'; + +if (!is_admin()) { + http_response_code(403); + + render_content(ROOT . '/html/forbidden.html'); + exit; +} + +render_content(ROOT . '/html/admin.html'); + +?> diff --git a/html/account.html b/html/account.html index 0a4da65..ccba599 100755 --- a/html/account.html +++ b/html/account.html @@ -20,6 +20,7 @@ <input class="toggle" type="checkbox" id="account"> <label class="username" for="account">{{username}}</label> <div class="menu"> + <a href="/profile?username={{profile}}">Profile</a> <a href="/signout">Sign-out</a> </div> </div> diff --git a/html/admin.html b/html/admin.html new file mode 100755 index 0000000..8ae34e2 --- /dev/null +++ b/html/admin.html @@ -0,0 +1,69 @@ +<!-- + GNUfault.org - GNUfault's website + Copyright (C) 2026 Connor Thomson + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. +--> + +<h2>Admin Panel</h2> +<hr> + +<h3>Change user's password</h3> +<form class="login" action="admin.php" method="POST"> + <input type="hidden" name="action" value="password"> + <div class="group"> + <label for="password-username">Username:</label> + <input class="input" type="text" id="password-username" name="username" required> + </div> + <div class="group"> + <label for="password">New password:</label> + <input class="input" type="password" id="password" name="password" required> + </div> + <div class="group"> + <label for="confirmpassword">Confirm new password:</label> + <input class="input" type="password" id="confirmpassword" name="confirmpassword" required> + </div> + <button class="button" type="submit">Send</button> +</form> +<br> + +<h3>Change user's status</h3> +<form class="login" action="admin.php" method="POST"> + <input type="hidden" name="action" value="status"> + <div class="group"> + <label for="status-username">Username:</label> + <input class="input" type="text" id="status-username" name="username" required> + </div> + <div class="group"> + <label for="status">Status:</label> + <select class="input" id="status" name="status"> + <option value="none">none</option> + <option value="member">member</option> + <option value="mod">mod</option> + <option value="admin">admin</option> + </select> + </div> + <button class="button" type="submit">Send</button> +</form> +<br> + +<h3>Remove user</h3> +<form class="login" action="admin.php" method="POST"> + <input type="hidden" name="action" value="remove"> + <div class="group"> + <label for="remove-username">Username:</label> + <input class="input" type="text" id="remove-username" name="username" required> + </div> + <button class="button" type="submit">Send</button> +</form> diff --git a/html/forbidden.html b/html/forbidden.html new file mode 100755 index 0000000..791fa4e --- /dev/null +++ b/html/forbidden.html @@ -0,0 +1,21 @@ +<!-- + GNUfault.org - GNUfault's website + Copyright (C) 2026 Connor Thomson + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. +--> + +<h2>403 Forbidden</h2> +<hr> +<p>You do not have permission to view this page.</p> diff --git a/html/profile.html b/html/profile.html new file mode 100755 index 0000000..d86b5ac --- /dev/null +++ b/html/profile.html @@ -0,0 +1,21 @@ +<!-- + GNUfault.org - GNUfault's website + Copyright (C) 2026 Connor Thomson + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. +--> + +<h2>{{username}}</h2> +<hr> +<p>Status: {{status}}</p> diff --git a/html/unknown-user.html b/html/unknown-user.html new file mode 100755 index 0000000..93bf3a2 --- /dev/null +++ b/html/unknown-user.html @@ -0,0 +1,21 @@ +<!-- + GNUfault.org - GNUfault's website + Copyright (C) 2026 Connor Thomson + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. +--> + +<h2>User not found</h2> +<hr> +<p>There is nobody signed up under that name.</p> diff --git a/php/header.php b/php/header.php index 8648b2a..0fd46df 100755 --- a/php/header.php +++ b/php/header.php @@ -26,7 +26,8 @@ if ($username === null) { $account = import(ROOT . '/html/guest.html'); } else { $account = replace(ROOT . '/html/account.html', [ - '{{username}}' => htmlspecialchars($username, ENT_QUOTES, 'UTF-8') + '{{username}}' => htmlspecialchars($username, ENT_QUOTES, 'UTF-8'), + '{{profile}}' => rawurlencode($username) ]); } diff --git a/php/render.php b/php/render.php index 902d81b..e4986e2 100755 --- a/php/render.php +++ b/php/render.php @@ -20,13 +20,13 @@ require_once ROOT . '/php/replace.php'; require_once ROOT . '/php/execute.php'; -function render_content(string $page) { +function render_page(string $content) { $device = 'desktop'; $targets = [ '{{stylesheets}}' => import(ROOT . '/html/stylesheets.html'), '{{header}}' => execute(ROOT . '/php/header.php'), - '{{content}}' => import($page), + '{{content}}' => $content, '{{footer}}' => execute(ROOT . '/php/footer.php'), '{{device}}' => $device ]; @@ -36,4 +36,8 @@ function render_content(string $page) { echo $main_html . "\n"; } +function render_content(string $page) { + render_page(import($page)); +} + ?> diff --git a/php/user.php b/php/user.php new file mode 100644 index 0000000..8a424e5 --- /dev/null +++ b/php/user.php @@ -0,0 +1,49 @@ +<?php +/* + * GNUfault.org - GNUfault's website + * Copyright (C) 2026 Connor Thomson + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +require_once ROOT . '/php/session.php'; +require_once ROOT . '/php/database.php'; + +const USER_STATUSES = ['none', 'member', 'mod', 'admin']; + +function find_user(string $username): ?array { + $sql = "SELECT id, username, status FROM users WHERE username = :username"; + + return fetch_row($sql, ['username' => $username]); +} + +function current_user(): ?array { + $user_id = get_user_id(); + + if ($user_id === null) { + return null; + } + + $sql = "SELECT id, username, status FROM users WHERE id = :id"; + + return fetch_row($sql, ['id' => $user_id]); +} + +function is_admin(): bool { + $user = current_user(); + + return $user !== null && $user['status'] === 'admin'; +} + +?> diff --git a/profile/index.php b/profile/index.php new file mode 100755 index 0000000..89d8637 --- /dev/null +++ b/profile/index.php @@ -0,0 +1,43 @@ +<?php +/* + * GNUfault.org - GNUfault's website + * Copyright (C) 2026 Connor Thomson + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +define('ROOT', rtrim($_SERVER['DOCUMENT_ROOT'], '/') . '/'); + +require_once ROOT . '/php/render.php'; +require_once ROOT . '/php/user.php'; + +$username = isset($_GET['username']) ? $_GET['username'] : ''; + +$user = find_user($username); + +if (!$user) { + http_response_code(404); + + render_content(ROOT . '/html/unknown-user.html'); + exit; +} + +$content = replace(ROOT . '/html/profile.html', [ + '{{username}}' => htmlspecialchars($user['username'], ENT_QUOTES, 'UTF-8'), + '{{status}}' => htmlspecialchars($user['status'], ENT_QUOTES, 'UTF-8') +]); + +render_page($content); + +?> diff --git a/signin/signin.php b/signin/signin.php index 6e88336..f7f3c23 100755 --- a/signin/signin.php +++ b/signin/signin.php @@ -28,7 +28,7 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") { $remember = isset($_POST['remember']); try { - $sql = "SELECT id, username, password, verification_code FROM users WHERE username = :username"; + $sql = "SELECT id, username, password, status FROM users WHERE username = :username"; $user = fetch_row($sql, ['username' => $username]); } catch (\PDOException $e) { @@ -36,13 +36,12 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") { exit; } - // The same message either way, so it does not say which usernames exist if (!$user || !password_verify($password, $user['password'])) { echo "Username or password is not correct!"; exit; } - if ($user['verification_code'] != '0001') { + if ($user['status'] == 'none') { set_user_id((int)$user['id']); header("Location: /signup/verify"); diff --git a/signup/signup.php b/signup/signup.php index a41454a..7648adf 100755 --- a/signup/signup.php +++ b/signup/signup.php @@ -39,13 +39,14 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") { $code = rand(1000, 9999); try { - $sql = "INSERT INTO users (username, email, password, verification_code) VALUES (:username, :email, :password, :code)"; + $sql = "INSERT INTO users (username, email, password, verification_code, status) VALUES (:username, :email, :password, :code, :status)"; $user_id = insert_row($sql, [ 'username' => $username, 'email' => $email, 'password' => $hashed_password, - 'code' => $code + 'code' => $code, + 'status' => 'none' ]); set_user_id($user_id); diff --git a/signup/verify/verify.php b/signup/verify/verify.php index 592915f..9e22132 100755 --- a/signup/verify/verify.php +++ b/signup/verify/verify.php @@ -47,7 +47,7 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") { exit; } - if ($real_code == '0001') { + if ($user['status'] == 'none') { echo "Account is already verifed"; exit; } @@ -58,11 +58,12 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") { } try { - $sql = "UPDATE users SET verification_code = :code WHERE id = :id"; + $sql = "UPDATE users SET verification_code = :code, status = :status WHERE id = :id"; $statement = query($sql, [ - 'code' => '0001', - 'id' => $user_id + 'code' => '0000', + 'status' => 'member', + 'id' => $user_id ]); if ($statement->rowCount() == 0) { |
