From 3a5cad0f5fb9461d06b81903763cf504988e8091 Mon Sep 17 00:00:00 2001 From: ilotterytea Date: Thu, 8 May 2025 01:23:48 +0500 Subject: feat: security section in /account --- database.sql | 10 +++++++++ public/account/index.php | 31 ++++++++++++++++++++++----- public/account/security.php | 51 +++++++++++++++++++++++++++++++++++++++++++++ public/account/signout.php | 24 --------------------- public/static/style.css | 5 ++++- 5 files changed, 91 insertions(+), 30 deletions(-) create mode 100644 public/account/security.php delete mode 100644 public/account/signout.php diff --git a/database.sql b/database.sql index 657264d..4ca437b 100644 --- a/database.sql +++ b/database.sql @@ -7,6 +7,11 @@ CREATE TABLE IF NOT EXISTS users ( last_active_at TIMESTAMP NOT NULL DEFAULT UTC_TIMESTAMP ); +CREATE TABLE IF NOT EXISTS user_preferences ( + id CHAR(32) NOT NULL PRIMARY KEY REFERENCES users(id) ON DELETE CASCADE, + hide_actions BOOLEAN NOT NULL DEFAULT FALSE +); + CREATE TABLE IF NOT EXISTS connections ( id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, user_id CHAR(32) NOT NULL REFERENCES users(id) ON DELETE CASCADE, @@ -127,16 +132,21 @@ CREATE TABLE IF NOT EXISTS actions ( -- CREATING A ROLE FOR USERS INSERT IGNORE INTO roles(id, name) VALUES (1, 'User'); +INSERT IGNORE INTO user_preferences(id) SELECT id FROM users; + -- ------------------------- -- TRIGGERS -- ------------------------- +DROP TRIGGER IF EXISTS create_user; + -- CREATE EMOTESET AND ASSIGN ROLE FOR NEW USER DELIMITER $$ CREATE TRIGGER IF NOT EXISTS create_user AFTER INSERT ON users FOR EACH ROW BEGIN + INSERT INTO user_preferences(id) VALUES (NEW.id); INSERT INTO role_assigns(user_id, role_id) VALUES (NEW.id, 1); INSERT INTO emote_sets(owner_id, name) VALUES (NEW.id, CONCAT(NEW.username, '''s emoteset')); END$$ diff --git a/public/account/index.php b/public/account/index.php index 80af380..7bb19f5 100644 --- a/public/account/index.php +++ b/public/account/index.php @@ -13,9 +13,9 @@ if (!isset($_SESSION["user_id"], $_SESSION["user_name"])) { exit; } -if ($_SERVER['REQUEST_METHOD'] == "POST") { - $db = new PDO(DB_URL, DB_USER, DB_PASS); +$db = new PDO(DB_URL, DB_USER, DB_PASS); +if ($_SERVER['REQUEST_METHOD'] == "POST") { $username = str_safe($_POST["username"] ?? "", ACCOUNT_USERNAME_LENGTH[1]); if (!empty($username) && $username != $_SESSION["user_name"]) { @@ -135,9 +135,30 @@ if ($_SERVER['REQUEST_METHOD'] == "POST") {
-
-

Security

- + +

Security & Privacy

+
+ + + + +
+
+ prepare("SELECT hide_actions FROM user_preferences WHERE id = ?"); + $stmt->execute([$_SESSION["user_id"]]); + if (intval($stmt->fetch()[0]) == 1) { + echo 'checked'; + } + ?>> + +
+
+ + +
+ +
diff --git a/public/account/security.php b/public/account/security.php new file mode 100644 index 0000000..5110f71 --- /dev/null +++ b/public/account/security.php @@ -0,0 +1,51 @@ +prepare("SELECT * FROM users WHERE id = ?"); +$stmt->execute([$_SESSION["user_id"]]); + +$user = $stmt->fetch(); +$current_password = $_POST["password-current"] ?? ""; + +if ($user["password"] != null && !password_verify($current_password, $user["password"])) { + generate_alert("/account", "Password is required to apply changes in 'Security' section"); + exit; +} + +if (!empty($_POST["password-new"])) { + $password = $_POST["password-new"]; + if (ACCOUNT_PASSWORD_MIN_LENGTH > strlen($password)) { + generate_alert("/account", "Your password must be at least " . ACCOUNT_PASSWORD_MIN_LENGTH . " characters"); + exit; + } + + $db->prepare("UPDATE users SET password = ? WHERE id = ?") + ->execute([password_hash($password, PASSWORD_DEFAULT), $user["id"]]); +} + +$hide_actions = (int) (intval($_POST["hide-actions"] ?? "0") == 1); + +$db->prepare("UPDATE user_preferences SET hide_actions = ? WHERE id = ?") + ->execute([$hide_actions, $user["id"]]); + +if (intval($_POST["signout-everywhere"] ?? "0") == 1) { + $db->prepare("UPDATE users SET secret_key = ? WHERE id = ?") + ->execute([generate_random_string(ACCOUNT_SECRET_KEY_LENGTH), $_SESSION["user_id"]]); + + session_unset(); + session_destroy(); + + setcookie("secret_key", "", time() - 1000); +} + +generate_alert("/account", "Your changes have been applied!", 200); \ No newline at end of file diff --git a/public/account/signout.php b/public/account/signout.php deleted file mode 100644 index 66a0cac..0000000 --- a/public/account/signout.php +++ /dev/null @@ -1,24 +0,0 @@ -prepare("UPDATE users SET secret_key = ? WHERE id = ?"); -$stmt->execute([generate_random_string(32), $_SESSION["user_id"]]); - -session_unset(); -session_destroy(); - -setcookie("secret_key", "", time() - 1000); - -$db = null; - -header("Location: /account"); \ No newline at end of file diff --git a/public/static/style.css b/public/static/style.css index 1398a34..3ce86af 100644 --- a/public/static/style.css +++ b/public/static/style.css @@ -74,7 +74,10 @@ input[type=file] { form { display: flex; flex-direction: column; - gap: 4px; +} + +form:has(div) { + gap: 16px; } label { -- cgit v1.2.3