diff options
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | 404.php | 2 | ||||
| -rw-r--r-- | README.md | 9 | ||||
| -rw-r--r-- | account/change_emoteset.php | 2 | ||||
| -rw-r--r-- | account/delete.php | 2 | ||||
| -rw-r--r-- | account/index.php | 24 | ||||
| -rw-r--r-- | account/login/index.php | 14 | ||||
| -rw-r--r-- | account/login/twitch.php | 14 | ||||
| -rw-r--r-- | account/register.php | 25 | ||||
| -rw-r--r-- | account/security.php | 6 | ||||
| -rw-r--r-- | badges.php | 2 | ||||
| -rw-r--r-- | captcha.php | 6 | ||||
| -rw-r--r-- | database.sql | 3 | ||||
| -rw-r--r-- | emotes/delete.php | 2 | ||||
| -rw-r--r-- | emotes/index.php | 16 | ||||
| -rw-r--r-- | emotes/rate.php | 4 | ||||
| -rw-r--r-- | emotes/setmanip.php | 10 | ||||
| -rw-r--r-- | emotes/upload.php | 596 | ||||
| -rw-r--r-- | emotesets.php | 6 | ||||
| -rw-r--r-- | inbox.php | 4 | ||||
| -rw-r--r-- | index.php | 18 | ||||
| -rw-r--r-- | lib/accounts.php | 2 | ||||
| -rw-r--r-- | lib/config.php | 113 | ||||
| -rw-r--r-- | lib/config.sample.php | 74 | ||||
| -rw-r--r-- | lib/partials.php | 16 | ||||
| -rw-r--r-- | report/index.php | 7 | ||||
| -rw-r--r-- | report/list.php | 6 | ||||
| -rw-r--r-- | report/send.php | 4 | ||||
| -rw-r--r-- | rules.php | 4 | ||||
| -rw-r--r-- | software.php | 2 | ||||
| -rw-r--r-- | system/config.php | 430 | ||||
| -rw-r--r-- | system/emotes/index.php | 10 | ||||
| -rw-r--r-- | system/emotes/verdict.php | 4 | ||||
| -rw-r--r-- | system/index.php | 10 | ||||
| -rw-r--r-- | users.php | 10 |
35 files changed, 968 insertions, 491 deletions
@@ -1,6 +1,6 @@ /.vscode userdata/ *.db -config.php +config.json custom_static/ captcha/
\ No newline at end of file @@ -15,7 +15,7 @@ $reason = str_safe($_GET["error_reason"] ?? "Not found", 200); <html> <head> - <title>(Error) <?php echo sprintf("%s - %s", $reason, INSTANCE_NAME) ?></title> + <title>(Error) <?php echo sprintf("%s - %s", $reason, CONFIG['instance']['name']) ?></title> <link rel="stylesheet" href="/static/style.css"> <link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon"> </head> @@ -38,11 +38,10 @@ The main goal of the project is to replicate full functionality of other emote p ### Step-by-step 1. Clone the repository. -2. Import `database.sql` to your database. -3. Copy `src/config.sample.php` to `src/config.php` and set it up. -4. Use reverse proxy *(Nginx, Apache, etc.)* for the project. See [configuration examples](#reverse-proxy-configurations). -5. ??? -6. Profit! It should work. +2. Use reverse proxy *(Nginx, Apache, etc.)* for the project. See [configuration examples](#reverse-proxy-configurations). +3. Go to `/` (or `/system/config.php`) in your browser to configure the instance. +4. ??? +5. Profit! It should work. ### Reverse proxy configurations diff --git a/account/change_emoteset.php b/account/change_emoteset.php index 2452b23..2094b22 100644 --- a/account/change_emoteset.php +++ b/account/change_emoteset.php @@ -21,7 +21,7 @@ if (!isset($_POST["id"])) { $emote_set_id = $_POST["id"]; $user_id = $_SESSION["user_id"]; -$db = new PDO(DB_URL, DB_USER, DB_PASS); +$db = new PDO(CONFIG['database']['url'], CONFIG['database']['user'], CONFIG['database']['pass']); $stmt = $db->prepare("SELECT id FROM acquired_emote_sets WHERE emote_set_id = ? AND user_id = ?"); $stmt->execute([$emote_set_id, $user_id]); diff --git a/account/delete.php b/account/delete.php index 34570a9..0a0bbb6 100644 --- a/account/delete.php +++ b/account/delete.php @@ -9,7 +9,7 @@ if (!isset($_SESSION["user_id"])) { exit; } -$db = new PDO(DB_URL, DB_USER, DB_PASS); +$db = new PDO(CONFIG['database']['url'], CONFIG['database']['user'], CONFIG['database']['pass']); $id = $_SESSION["user_id"]; diff --git a/account/index.php b/account/index.php index 665087a..bb4bff6 100644 --- a/account/index.php +++ b/account/index.php @@ -13,13 +13,13 @@ if (!isset($_SESSION["user_id"], $_SESSION["user_name"])) { exit; } -$db = new PDO(DB_URL, DB_USER, DB_PASS); +$db = new PDO(CONFIG['database']['url'], CONFIG['database']['user'], CONFIG['database']['pass']); if ($_SERVER['REQUEST_METHOD'] == "POST") { - $username = str_safe($_POST["username"] ?? "", ACCOUNT_USERNAME_LENGTH[1]); + $username = str_safe($_POST["username"] ?? "", CONFIG['account']['maxusernamelength']); if (!empty($username) && $username != $_SESSION["user_name"]) { - if (!preg_match(ACCOUNT_USERNAME_REGEX, $username)) { + if (!preg_match(CONFIG['account']['regex'], $username)) { generate_alert("/account", "Bad username"); exit; } @@ -43,8 +43,8 @@ if ($_SERVER['REQUEST_METHOD'] == "POST") { $err = create_image_bundle( $pfp["tmp_name"], $_SERVER["DOCUMENT_ROOT"] . "/static/userdata/avatars/" . $_SESSION["user_id"], - ACCOUNT_PFP_MAX_SIZE[0], - ACCOUNT_PFP_MAX_SIZE[1], + CONFIG['account']['pfpsizex'], + CONFIG['account']['pfpsizey'], true, true ) @@ -61,8 +61,8 @@ if ($_SERVER['REQUEST_METHOD'] == "POST") { $err = create_image_bundle( $banner["tmp_name"], $_SERVER["DOCUMENT_ROOT"] . "/static/userdata/banners/" . $_SESSION["user_id"], - ACCOUNT_BANNER_MAX_SIZE[0], - ACCOUNT_BANNER_MAX_SIZE[1], + CONFIG['account']['bannersizex'], + CONFIG['account']['bannersizey'], true, true ) @@ -79,8 +79,8 @@ if ($_SERVER['REQUEST_METHOD'] == "POST") { $err = create_image_bundle( $badge["tmp_name"], $_SERVER["DOCUMENT_ROOT"] . "/static/userdata/badges/" . $badge_id, - ACCOUNT_BADGE_MAX_SIZE[0], - ACCOUNT_BADGE_MAX_SIZE[1], + CONFIG['account']['badgesizex'], + CONFIG['account']['badgesizey'], true, true ) @@ -104,7 +104,7 @@ if ($_SERVER['REQUEST_METHOD'] == "POST") { <html> <head> - <title>Account management - <?php echo INSTANCE_NAME ?></title> + <title>Account management - <?php echo CONFIG['instance']['name'] ?></title> <link rel="stylesheet" href="/static/style.css"> <link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon"> </head> @@ -293,9 +293,9 @@ if ($_SERVER['REQUEST_METHOD'] == "POST") { let validUsername = ""; username.addEventListener("input", (e) => { - const regex = <?php echo ACCOUNT_USERNAME_REGEX ?>; + const regex = <?php echo CONFIG['account']['regex'] ?>; - if (regex.test(e.target.value) && e.target.value.length <= <?php echo ACCOUNT_USERNAME_LENGTH[1] ?>) { + if (regex.test(e.target.value) && e.target.value.length <= <?php echo CONFIG['account']['maxusernamelength'] ?>) { validUsername = e.target.value; } else { e.target.value = validUsername; diff --git a/account/login/index.php b/account/login/index.php index 7aef703..b4223f2 100644 --- a/account/login/index.php +++ b/account/login/index.php @@ -21,13 +21,13 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") { $password = $_POST["password"]; $remember = intval($_POST["remember"] ?? "0") != 0; - $db = new PDO(DB_URL, DB_USER, DB_PASS); + $db = new PDO(CONFIG['database']['url'], CONFIG['database']['user'], CONFIG['database']['pass']); $stmt = $db->prepare("SELECT secret_key, password FROM users WHERE username = ? AND password IS NOT NULL"); $stmt->execute([$username]); if ($row = $stmt->fetch()) { if (password_verify($password, $row["password"])) { - setcookie("secret_key", $row["secret_key"], $remember ? (time() + ACCOUNT_COOKIE_MAX_LIFETIME) : 0, "/"); + setcookie("secret_key", $row["secret_key"], $remember ? (time() + CONFIG['account']['maxcookielifetime']) : 0, "/"); header("Location: /account"); exit; } else { @@ -44,7 +44,7 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") { <html> <head> - <title>Login - <?php echo INSTANCE_NAME ?></title> + <title>Login - <?php echo CONFIG['instance']['name'] ?></title> <link rel="stylesheet" href="/static/style.css"> <link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon"> </head> @@ -57,7 +57,7 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") { <?php display_alert() ?> <section class="box"> <div class="box navtab"> - <p>Log in to <?php echo INSTANCE_NAME ?></p> + <p>Log in to <?php echo CONFIG['instance']['name'] ?></p> </div> <div class="box content"> <form action="/account/login/" method="post"> @@ -75,7 +75,7 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") { </div> <div> <button type="submit">Log in</button> - <?php if (ACCOUNT_REGISTRATION_ENABLE): ?> + <?php if (CONFIG['account']['registration']): ?> <a href="/account/register.php">Register</a> <?php endif; ?> </div> @@ -83,11 +83,11 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") { </div> </section> - <?php if (TWITCH_REGISTRATION_ENABLE): ?> + <?php if (CONFIG['twitch']['registration']): ?> <section class="box column"> <a href="/account/login/twitch.php" class="button purple big">Login with Twitch</a> <p style="font-size: 12px;">Logging in via Twitch gives you the ability to use - <?php echo INSTANCE_NAME ?> emotes in your Twitch chat. + <?php echo CONFIG['instance']['name'] ?> emotes in your Twitch chat. </p> </section> <?php endif; ?> diff --git a/account/login/twitch.php b/account/login/twitch.php index 23f4ea5..5e61c33 100644 --- a/account/login/twitch.php +++ b/account/login/twitch.php @@ -3,14 +3,14 @@ include_once "{$_SERVER['DOCUMENT_ROOT']}/lib/config.php"; include_once "{$_SERVER['DOCUMENT_ROOT']}/lib/utils.php"; include_once "{$_SERVER['DOCUMENT_ROOT']}/lib/alert.php"; -if (!TWITCH_REGISTRATION_ENABLE) { +if (!CONFIG['twitch']['registration']) { generate_alert("/404.php", "Registration via Twitch is disabled", 405); exit; } session_start(); -$db = new PDO(DB_URL, DB_USER, DB_PASS); +$db = new PDO(CONFIG['database']['url'], CONFIG['database']['user'], CONFIG['database']['pass']); if (isset($_GET["disconnect"], $_SESSION["user_id"])) { $stmt = $db->prepare("SELECT c.id, @@ -37,9 +37,9 @@ if (isset($_GET["disconnect"], $_SESSION["user_id"])) { exit; } -$client_id = TWITCH_CLIENT_ID; -$client_secret = TWITCH_SECRET_KEY; -$redirect_uri = TWITCH_REDIRECT_URI; +$client_id = CONFIG['twitch']['clientid']; +$client_secret = CONFIG['twitch']['clientsecret']; +$redirect_uri = CONFIG['twitch']['redirecturi']; if (isset($_GET["error"])) { header("Location: /account/login"); @@ -113,7 +113,7 @@ $user_name = ""; if ($row = $stmt->fetch()) { if (isset($_SESSION["user_id"]) && $_SESSION["user_id"] != $row["id"]) { - generate_alert("/account", "There is another " . INSTANCE_NAME . " account associated with that Twitch account", 409); + generate_alert("/account", "There is another " . CONFIG['instance']['name'] . " account associated with that Twitch account", 409); exit; } @@ -168,7 +168,7 @@ if ($row = $stmt->fetch()) { $_SESSION["user_id"] = $user_id; $_SESSION["user_name"] = $user_name; -setcookie("secret_key", $user_secret_key, time() + ACCOUNT_COOKIE_MAX_LIFETIME, "/"); +setcookie("secret_key", $user_secret_key, time() + CONFIG['account']['maxcookielifetime'], "/"); $db = null; diff --git a/account/register.php b/account/register.php index 76dc27c..59ea886 100644 --- a/account/register.php +++ b/account/register.php @@ -7,7 +7,7 @@ if (authorize_user()) { exit; } -if (!ACCOUNT_REGISTRATION_ENABLE) { +if (!CONFIG['account']['registration']) { generate_alert("/404.php", "Account registration is disabled", 403); exit; } @@ -24,23 +24,23 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") { $username = $_POST["username"]; $username_length = strlen($username); - if (ACCOUNT_USERNAME_LENGTH[0] > $username_length || $username_length > ACCOUNT_USERNAME_LENGTH[1]) { - generate_alert("/account/register.php", sprintf("Username must be between %d-%d characters long", ACCOUNT_USERNAME_LENGTH[0], ACCOUNT_USERNAME_LENGTH[1])); + if (CONFIG['account']['minusernamelength'] > $username_length || $username_length > CONFIG['account']['maxusernamelength']) { + generate_alert("/account/register.php", sprintf("Username must be between %d-%d characters long", CONFIG['account']['minusernamelength'], CONFIG['account']['maxusernamelength'])); exit; } - if (!preg_match(ACCOUNT_USERNAME_REGEX, $username)) { + if (!preg_match(CONFIG['account']['regex'], $username)) { generate_alert("/account/register.php", "Bad username"); exit; } $password = $_POST["password"]; - if (ACCOUNT_PASSWORD_MIN_LENGTH > strlen($password)) { - generate_alert("/account/register.php", "Password must be at least " . ACCOUNT_PASSWORD_MIN_LENGTH . " characters"); + if (CONFIG['account']['minpasswordlength'] > strlen($password)) { + generate_alert("/account/register.php", "Password must be at least " . CONFIG['account']['minpasswordlength'] . " characters"); exit; } - $db = new PDO(DB_URL, DB_USER, DB_PASS); + $db = new PDO(CONFIG['database']['url'], CONFIG['database']['user'], CONFIG['database']['pass']); $stmt = $db->prepare("SELECT id FROM users WHERE username = ?"); $stmt->execute([$username]); @@ -50,7 +50,7 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") { exit; } - $secret_key = generate_random_string(ACCOUNT_SECRET_KEY_LENGTH); + $secret_key = generate_random_string(CONFIG['account']['secretkeylength']); $password = password_hash($password, PASSWORD_DEFAULT); $id = bin2hex(random_bytes(16)); @@ -58,7 +58,7 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") { $stmt = $db->prepare("INSERT INTO users(id, username, password, secret_key) VALUES (?, ?, ?, ?)"); $stmt->execute([$id, $username, $password, $secret_key]); - setcookie("secret_key", $secret_key, time() + ACCOUNT_COOKIE_MAX_LIFETIME, "/"); + setcookie("secret_key", $secret_key, time() + CONFIG['account']['maxcookielifetime'], "/"); header("Location: /account"); exit; } @@ -67,7 +67,7 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") { <html> <head> - <title>Register an account - <?php echo INSTANCE_NAME ?></title> + <title>Register an account - <?php echo CONFIG['instance']['name'] ?></title> <link rel="stylesheet" href="/static/style.css"> <link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon"> </head> @@ -81,7 +81,7 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") { <?php display_alert() ?> <section class="box"> <div class="box navtab"> - <p>Register an account in <?php echo INSTANCE_NAME ?></p> + <p>Register an account in <?php echo CONFIG['instance']['name'] ?></p> </div> <div class="box content"> <form action="/account/register.php" method="post"> @@ -98,7 +98,8 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") { </div> </form> <p style="font-size: 12px;"> - Since <?php echo INSTANCE_NAME ?> doesn't require email and password reset via email is + Since <?php echo CONFIG['instance']['name'] ?> doesn't require email and password reset via + email is not supported, please remember your passwords! </p> </div> diff --git a/account/security.php b/account/security.php index a0210b5..11738dc 100644 --- a/account/security.php +++ b/account/security.php @@ -10,7 +10,7 @@ if ($_SERVER["REQUEST_METHOD"] != "POST" || !authorize_user(true)) { exit; } -$db = new PDO(DB_URL, DB_USER, DB_PASS); +$db = new PDO(CONFIG['database']['url'], CONFIG['database']['user'], CONFIG['database']['pass']); $stmt = $db->prepare("SELECT * FROM users WHERE id = ?"); $stmt->execute([$_SESSION["user_id"]]); @@ -25,8 +25,8 @@ if ($user["password"] != null && !password_verify($current_password, $user["pass 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"); + if (CONFIG['account']['minpasswordlength'] > strlen($password)) { + generate_alert("/account", "Your password must be at least " . CONFIG['account']['minpasswordlength'] . " characters"); exit; } @@ -3,7 +3,7 @@ include_once "{$_SERVER['DOCUMENT_ROOT']}/lib/utils.php"; include_once "{$_SERVER['DOCUMENT_ROOT']}/lib/config.php"; include_once "{$_SERVER['DOCUMENT_ROOT']}/lib/user.php"; -$db = new PDO(DB_URL, DB_USER, DB_PASS); +$db = new PDO(CONFIG['database']['url'], CONFIG['database']['user'], CONFIG['database']['pass']); $stmt = $db->prepare("SELECT u.id, u.username, diff --git a/captcha.php b/captcha.php index 0b85bf8..3629cd0 100644 --- a/captcha.php +++ b/captcha.php @@ -26,7 +26,7 @@ if ($_SERVER["REQUEST_METHOD"] == "POST" && isset($_POST["answer"])) { $file_folder = $_SERVER["DOCUMENT_ROOT"] . '/static/img/captcha'; -if (!CAPTCHA_ENABLE || ($_SESSION["captcha_solved"] ?? false) || !is_dir($file_folder)) { +if (!CONFIG['captcha']['enable'] || ($_SESSION["captcha_solved"] ?? false) || !is_dir($file_folder)) { $_SESSION["captcha_solved"] = true; echo json_response([ "status_code" => 200, @@ -45,8 +45,8 @@ $filename = basename($filename, ".png"); $_SESSION["captcha_word"] = $filename; $image = generate_image_captcha( - CAPTCHA_SIZE[0], - CAPTCHA_SIZE[1], + CONFIG['captcha']['x'], + CONFIG['captcha']['y'], random_int(1, 3), $filename, $file_folder diff --git a/database.sql b/database.sql index f1aca05..587a1d7 100644 --- a/database.sql +++ b/database.sql @@ -122,7 +122,8 @@ CREATE TABLE IF NOT EXISTS roles ( permission_approve_emotes BOOLEAN NOT NULL DEFAULT false, permission_useredit_own BOOLEAN NOT NULL DEFAULT true, permission_useredit_all BOOLEAN NOT NULL DEFAULT false, - permission_modsystem BOOLEAN NOT NULL DEFAULT false + permission_modsystem BOOLEAN NOT NULL DEFAULT false, + permission_admin BOOLEAN NOT NULL DEFAULT false ); CREATE TABLE IF NOT EXISTS role_assigns( diff --git a/emotes/delete.php b/emotes/delete.php index 159e293..03b6dec 100644 --- a/emotes/delete.php +++ b/emotes/delete.php @@ -16,7 +16,7 @@ if (!isset($_POST["id"])) { $emote_id = $_POST["id"]; $user_id = $_SESSION["user_id"]; -$db = new PDO(DB_URL, DB_USER, DB_PASS); +$db = new PDO(CONFIG['database']['url'], CONFIG['database']['user'], CONFIG['database']['pass']); $stmt = $db->prepare("SELECT uploaded_by, code FROM emotes WHERE id = ?"); $stmt->execute([$emote_id]); diff --git a/emotes/index.php b/emotes/index.php index 80a8c1d..3999d8e 100644 --- a/emotes/index.php +++ b/emotes/index.php @@ -8,7 +8,7 @@ include "{$_SERVER['DOCUMENT_ROOT']}/lib/alert.php"; authorize_user(); -$db = new PDO(DB_URL, DB_USER, DB_PASS); +$db = new PDO(CONFIG['database']['url'], CONFIG['database']['user'], CONFIG['database']['pass']); $user_id = $_SESSION["user_id"] ?? ""; @@ -126,7 +126,7 @@ if (CLIENT_REQUIRES_JSON) { <head> <title><?php - echo ($emote != null ? "Emote " . $emote->get_code() : "Emotes") . ' - ' . INSTANCE_NAME + echo ($emote != null ? "Emote " . $emote->get_code() : "Emotes") . ' - ' . CONFIG['instance']['name'] ?></title> <link rel="stylesheet" href="/static/style.css"> <link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon"> @@ -302,9 +302,9 @@ if (CLIENT_REQUIRES_JSON) { if ($row = $stmt->fetch()) { echo 'You gave <img src="/static/img/icons/ratings/' . $row["rate"] . '.png" width="16" height="16"'; - echo 'title="' . RATING_NAMES[$row["rate"]] . '">'; + echo 'title="' . CONFIG['rating']['names'][$row["rate"]] . '">'; } else { - foreach (RATING_NAMES as $key => $value) { + foreach (CONFIG['rating']['names'] as $key => $value) { echo '<form action="/emotes/rate.php" method="POST">'; echo '<input type="text" name="id" value="' . $emote->get_id() . '"style="display: none;">'; echo "<input type=\"text\" name=\"rate\" value=\"$key\" style=\"display:none;\">"; @@ -316,7 +316,7 @@ if (CLIENT_REQUIRES_JSON) { } } } - if (REPORTS_ENABLE && $_SESSION["user_role"]["permission_report"]) { + if (CONFIG['reports']['enable'] && $_SESSION["user_role"]["permission_report"]) { echo "<a class='button red' href='/report?emote_id={$emote->id}'>Report emote</a>"; } } @@ -348,7 +348,7 @@ if (CLIENT_REQUIRES_JSON) { <tr> <th>Uploader</th> <td><?php - $username = ANONYMOUS_DEFAULT_NAME; + $username = CONFIG['anonymous']['defaultname']; $link = "#"; $show_private_badge = false; $badge = null; @@ -411,11 +411,11 @@ if (CLIENT_REQUIRES_JSON) { echo '</span></td></tr>'; } - if (RATING_ENABLE): ?> + if (CONFIG['rating']['enable']): ?> <tr> <th>Rating</th> <?php - if ($emote->get_rating()["total"] < RATING_EMOTE_MIN_VOTES) { + if ($emote->get_rating()["total"] < CONFIG['rating']['minvotes']) { echo '<td>Not rated (' . $emote->get_rating()["total"] . ')</td>'; } else { diff --git a/emotes/rate.php b/emotes/rate.php index fbea404..2e862f9 100644 --- a/emotes/rate.php +++ b/emotes/rate.php @@ -4,7 +4,7 @@ include_once "{$_SERVER['DOCUMENT_ROOT']}/lib/utils.php"; include_once "{$_SERVER['DOCUMENT_ROOT']}/lib/config.php"; include_once "{$_SERVER['DOCUMENT_ROOT']}/lib/accounts.php"; -if (!RATING_ENABLE) { +if (!CONFIG['rating']['enable']) { generate_alert("/404.php", "Emote ratings are disabled", 403); exit; } @@ -26,7 +26,7 @@ if ($id == 0 || $rate == 0) { exit; } -$db = new PDO(DB_URL, DB_USER, DB_PASS); +$db = new PDO(CONFIG['database']['url'], CONFIG['database']['user'], CONFIG['database']['pass']); // checking if emote exists $stmt = $db->prepare("SELECT id FROM emotes WHERE id = ?"); diff --git a/emotes/setmanip.php b/emotes/setmanip.php index cf8add6..d6a5f4f 100644 --- a/emotes/setmanip.php +++ b/emotes/setmanip.php @@ -18,7 +18,7 @@ if (!isset($_POST["id"], $_POST["action"], $_POST["emote_set_id"])) { exit; } -$db = new PDO(DB_URL, DB_USER, DB_PASS); +$db = new PDO(CONFIG['database']['url'], CONFIG['database']['user'], CONFIG['database']['pass']); // checking emote $emote_id = $_POST["id"]; @@ -62,7 +62,7 @@ switch ($action) { $stmt = $db->prepare("INSERT INTO emote_set_contents(emote_set_id, emote_id, added_by) VALUES (?, ?, ?)"); $stmt->execute([$emote_set_id, $emote_id, $user_id]); - if (ACCOUNT_LOG_ACTIONS) { + if (CONFIG['account']['log']) { $db->prepare("INSERT INTO actions(user_id, action_type, action_payload) VALUES (?, ?, ?)") ->execute([$user_id, "EMOTESET_ADD", json_encode($payload)]); } @@ -82,7 +82,7 @@ switch ($action) { exit; } - if (ACCOUNT_LOG_ACTIONS) { + if (CONFIG['account']['log']) { $db->prepare("INSERT INTO actions(user_id, action_type, action_payload) VALUES (?, ?, ?)") ->execute([$user_id, "EMOTESET_REMOVE", json_encode($payload)]); } @@ -98,7 +98,7 @@ switch ($action) { exit; } - $value = str_safe($_POST["value"], EMOTE_NAME_MAX_LENGTH); + $value = str_safe($_POST["value"], CONFIG['emote']['maxnamelength']); $stmt = $db->prepare("SELECT esc.code AS alias_code, e.code FROM emote_set_contents esc INNER JOIN emotes e ON e.id = esc.emote_id @@ -121,7 +121,7 @@ switch ($action) { $stmt = $db->prepare("UPDATE emote_set_contents SET code = ? WHERE emote_set_id = ? AND emote_id = ?"); $stmt->execute([$value, $emote_set_id, $emote_id]); - if (ACCOUNT_LOG_ACTIONS) { + if (CONFIG['account']['log']) { $db->prepare("INSERT INTO actions(user_id, action_type, action_payload) VALUES (?, ?, ?)") ->execute([$user_id, "EMOTESET_ALIAS", json_encode($payload)]); } diff --git a/emotes/upload.php b/emotes/upload.php index 01ae1ee..e509345 100644 --- a/emotes/upload.php +++ b/emotes/upload.php @@ -4,27 +4,27 @@ include_once "{$_SERVER['DOCUMENT_ROOT']}/lib/config.php"; include_once "{$_SERVER['DOCUMENT_ROOT']}/lib/alert.php"; include_once "{$_SERVER['DOCUMENT_ROOT']}/lib/captcha.php"; -if (!EMOTE_UPLOAD) { +if (!CONFIG['emote']['upload']) { generate_alert("/404.php", "Emote upload is disabled", 403); exit; } authorize_user(); -if (!ANONYMOUS_UPLOAD && isset($_SESSION["user_role"]) && !$_SESSION["user_role"]["permission_upload"]) { +if (!CONFIG['anonymous']['upload'] && isset($_SESSION["user_role"]) && !$_SESSION["user_role"]["permission_upload"]) { generate_alert("/404.php", "Not enough permissions", 403); exit; } $uploaded_by = null; -$uploader_name = ANONYMOUS_DEFAULT_NAME; +$uploader_name = CONFIG['anonymous']['defaultname']; if (isset($_SESSION["user_role"]) && $_SESSION["user_role"]["permission_upload"]) { $uploaded_by = $_SESSION["user_id"] ?? null; - $uploader_name = $_SESSION["user_name"] ?? ANONYMOUS_DEFAULT_NAME; + $uploader_name = $_SESSION["user_name"] ?? CONFIG['anonymous']['defaultname']; } -$db = new PDO(DB_URL, DB_USER, DB_PASS); +$db = new PDO(CONFIG['database']['url'], CONFIG['database']['user'], CONFIG['database']['pass']); function abort_upload(string $path, PDO $db, string $id) { @@ -39,152 +39,152 @@ function abort_upload(string $path, PDO $db, string $id) include "{$_SERVER['DOCUMENT_ROOT']}/lib/utils.php"; include "{$_SERVER['DOCUMENT_ROOT']}/lib/images.php"; -$max_width = EMOTE_MAX_SIZE[0]; -$max_height = EMOTE_MAX_SIZE[1]; +$max_width = CONFIG['emote']['maxsizex']; +$max_height = CONFIG['emote']['maxsizey']; if ($_SERVER['REQUEST_METHOD'] != "POST") { include "{$_SERVER['DOCUMENT_ROOT']}/lib/partials.php"; echo '' ?> - <html> - - <head> - <title>Upload an emote - <?php echo INSTANCE_NAME ?></title> - <link rel="stylesheet" href="/static/style.css"> - <link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon"> - </head> - - <body> - <div class="container"> - <div class="wrapper"> - <?php html_navigation_bar() ?> - <?php display_alert() ?> - - <section class="content row"> - <div class="column small-gap"> - <section class="box"> - <div class="box navtab"> - <div> - <b>Upload a new emote</b> - <p style="font-size:8px;">You can just upload, btw. Anything you want.</p> - </div> - </div> - <div class="box content"> - <form action="/emotes/upload.php" method="POST" enctype="multipart/form-data"> - <h3>Image<span style="color:red;">*</span></h3> - - <input type="file" name="file" id="form-file" accept=".gif,.jpg,.jpeg,.png,.webp" - required> - - <div id="form-manual-files" style="display:none;"> - <input type="file" name="file-1x" id="form-file-1x" - accept=".gif,.jpg,.jpeg,.png,.webp"> - <label class="inline" - for="file-1x"><?php echo sprintf("%dx%d", EMOTE_MAX_SIZE[0] / 4, EMOTE_MAX_SIZE[1] / 4) ?></label> - <input type="file" name="file-2x" id="form-file-2x" - accept=".gif,.jpg,.jpeg,.png,.webp"> - <label class="inline" - for="file-2x"><?php echo sprintf("%dx%d", EMOTE_MAX_SIZE[0] / 2, EMOTE_MAX_SIZE[1] / 2) ?></label> - <input type="file" name="file-3x" id="form-file-3x" - accept=".gif,.jpg,.jpeg,.png,.webp"> - <label class="inline" - for="file-3x"><?php echo sprintf("%dx%d", EMOTE_MAX_SIZE[0], EMOTE_MAX_SIZE[1]) ?></label> - </div> - - <div> - <label for="manual" class="inline">Manual resize</label> - <input type="checkbox" name="manual" value="1" onchange="display_manual_resize()"> - </div> - - <h3>Emote name<span style="color:red;">*</span></h3> - <input type="text" name="code" id="code" required> - - <div> - <label for="visibility" class="inline">Emote visibility: </label> - <select name="visibility" id="form-visibility"> - <option value="1">Public</option> - <option value="0">Unlisted</option> - </select><br> - <p id="form-visibility-description" style="font-size: 10px;">test</p> + <html> + + <head> + <title>Upload an emote - <?php echo CONFIG['instance']['name'] ?></title> + <link rel="stylesheet" href="/static/style.css"> + <link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon"> + </head> + + <body> + <div class="container"> + <div class="wrapper"> + <?php html_navigation_bar() ?> + <?php display_alert() ?> + + <section class="content row"> + <div class="column small-gap"> + <section class="box"> + <div class="box navtab"> + <div> + <b>Upload a new emote</b> + <p style="font-size:8px;">You can just upload, btw. Anything you want.</p> + </div> </div> - - <label for="notes">Approval notes</label> - <textarea name="notes" id="form-notes"></textarea> - - <table class="vertical left font-weight-normal"> - <tr> - <th>Emote source:</th> - <td class="flex"><input class="grow" name="source" id="form-source"></input> - </td> - </tr> - <?php if (TAGS_ENABLE && TAGS_MAX_COUNT != 0): ?> - <tr> - <th>Tags <span class="font-small" style="cursor: help;" title="<?php - echo 'Tags are used for fast search. '; - if (TAGS_MAX_COUNT > 0) { - echo 'You can use ' . TAGS_MAX_COUNT . ' tags. '; - } - echo 'They are space-separated o algo.'; - ?>">[?]</span>: - </th> - <td class="flex"><input class="grow" name="tags" id="form-tags"></input></td> - </tr> - <?php endif; ?> - </table> - - <div> - <label for="tos" class="inline">Do you accept <a href="/rules.php" - target="_BLANK">the - rules</a>?<span style="color:red;">*</span></label> - <input type="checkbox" name="tos" value="1" required> + <div class="box content"> + <form action="/emotes/upload.php" method="POST" enctype="multipart/form-data"> + <h3>Image<span style="color:red;">*</span></h3> + + <input type="file" name="file" id="form-file" accept=".gif,.jpg,.jpeg,.png,.webp" + required> + + <div id="form-manual-files" style="display:none;"> + <input type="file" name="file-1x" id="form-file-1x" + accept=".gif,.jpg,.jpeg,.png,.webp"> + <label class="inline" + for="file-1x"><?php echo sprintf("%dx%d", CONFIG['emote']['maxsizex'] / 4, CONFIG['emote']['maxsizey'] / 4) ?></label> + <input type="file" name="file-2x" id="form-file-2x" + accept=".gif,.jpg,.jpeg,.png,.webp"> + <label class="inline" + for="file-2x"><?php echo sprintf("%dx%d", CONFIG['emote']['maxsizex'] / 2, CONFIG['emote']['maxsizey'] / 2) ?></label> + <input type="file" name="file-3x" id="form-file-3x" + accept=".gif,.jpg,.jpeg,.png,.webp"> + <label class="inline" + for="file-3x"><?php echo sprintf("%dx%d", CONFIG['emote']['maxsizex'], CONFIG['emote']['maxsizey']) ?></label> + </div> + + <div> + <label for="manual" class="inline">Manual resize</label> + <input type="checkbox" name="manual" value="1" onchange="display_manual_resize()"> + </div> + + <h3>Emote name<span style="color:red;">*</span></h3> + <input type="text" name="code" id="code" required> + + <div> + <label for="visibility" class="inline">Emote visibility: </label> + <select name="visibility" id="form-visibility"> + <option value="1">Public</option> + <option value="0">Unlisted</option> + </select><br> + <p id="form-visibility-description" style="font-size: 10px;">test</p> + </div> + + <label for="notes">Approval notes</label> + <textarea name="notes" id="form-notes"></textarea> + + <table class="vertical left font-weight-normal"> + <tr> + <th>Emote source:</th> + <td class="flex"><input class="grow" name="source" id="form-source"></input> + </td> + </tr> + <?php if (CONFIG['tags']['enable'] && CONFIG['tags']['maxcount'] != 0): ?> + <tr> + <th>Tags <span class="font-small" style="cursor: help;" title="<?php + echo 'Tags are used for fast search. '; + if (CONFIG['tags']['maxcount'] > 0) { + echo 'You can use ' . CONFIG['tags']['maxcount'] . ' tags. '; + } + echo 'They are space-separated o algo.'; + ?>">[?]</span>: + </th> + <td class="flex"><input class="grow" name="tags" id="form-tags"></input></td> + </tr> + <?php endif; ?> + </table> + + <div> + <label for="tos" class="inline">Do you accept <a href="/rules.php" + target="_BLANK">the + rules</a>?<span style="color:red;">*</span></label> + <input type="checkbox" name="tos" value="1" required> + </div> + + <button type="submit" id="upload-button">Upload as + <?php echo $uploader_name ?></button> + </form> </div> + </section> - <button type="submit" id="upload-button">Upload as - <?php echo $uploader_name ?></button> - </form> + <?php + if (CONFIG['captcha']['enable'] && (CONFIG['captcha']['force'] || !isset($_SESSION["user_id"]))) { + html_captcha_form(); + } + ?> </div> - </section> - <?php - if (CAPTCHA_ENABLE && (CAPTCHA_FORCE_USERS || !isset($_SESSION["user_id"]))) { - html_captcha_form(); - } - ?> - </div> - - <div class="column small-gap grow" id="emote-showcase" style="display: none;"> - <!-- Emote Preview --> - <section class="box"> - <div class="box navtab"> - Emote Preview - <span id="emote-name"><i>Empty</i></span> - </div> - <div class="box content"> - <div class="emote-showcase items-bottom"> - <div class="emote-image column items-center small-gap"> - <img src="" alt="" class="emote-image-1x"> - <p class="size font-small"></p> + <div class="column small-gap grow" id="emote-showcase" style="display: none;"> + <!-- Emote Preview --> + <section class="box"> + <div class="box navtab"> + Emote Preview - <span id="emote-name"><i>Empty</i></span> </div> - <div class="emote-image column items-center small-gap"> - <img src="" alt="" class="emote-image-2x"> - <p class="size font-small"></p> + <div class="box content"> + <div class="emote-showcase items-bottom"> + <div class="emote-image column items-center small-gap"> + <img src="" alt="" class="emote-image-1x"> + <p class="size font-small"></p> + </div> + <div class="emote-image column items-center small-gap"> + <img src="" alt="" class="emote-image-2x"> + <p class="size font-small"></p> + </div> + <div class="emote-image column items-center small-gap"> + <img src="" alt="" class="emote-image-3x"> + <p class="size font-small"></p> + </div> + </div> + <p style="font-size: 12px;">The result may differ.</p> </div> - <div class="emote-image column items-center small-gap"> - <img src="" alt="" class="emote-image-3x"> - <p class="size font-small"></p> - </div> - </div> - <p style="font-size: 12px;">The result may differ.</p> - </div> - </section> + </section> - <!-- Chat Preview --> - <section class="box"> - <div class="box navtab"> - Chat Preview - </div> - <div class="box content no-gap column chat rounded"> - <?php - $stmt = $db->query("SELECT u.username, + <!-- Chat Preview --> + <section class="box"> + <div class="box navtab"> + Chat Preview + </div> + <div class="box content no-gap column chat rounded"> + <?php + $stmt = $db->query("SELECT u.username, CASE WHEN ub.badge_id IS NOT NULL THEN ub.badge_id WHEN r.badge_id IS NOT NULL THEN r.badge_id @@ -197,194 +197,194 @@ if ($_SERVER['REQUEST_METHOD'] != "POST") { ORDER BY RAND() LIMIT 3 "); - while ($row = $stmt->fetch()) { - echo '<div class="row small-gap items-center chat-message">'; + while ($row = $stmt->fetch()) { + echo '<div class="row small-gap items-center chat-message">'; - if ($row["badge_id"]) { - echo '<img src="/static/userdata/badges/' . $row["badge_id"] . '/1x.webp" alt="" title="" /> '; - } + if ($row["badge_id"]) { + echo '<img src="/static/userdata/badges/' . $row["badge_id"] . '/1x.webp" alt="" title="" /> '; + } - echo '<span style="color: rgb(' . random_int(128, 255) . ', ' . random_int(128, 255) . ', ' . random_int(128, 255) . ')">'; - echo $row["username"]; - echo ': </span>'; + echo '<span style="color: rgb(' . random_int(128, 255) . ', ' . random_int(128, 255) . ', ' . random_int(128, 255) . ')">'; + echo $row["username"]; + echo ': </span>'; - echo '<img src="" alt="" class="emote-image-1x">'; + echo '<img src="" alt="" class="emote-image-1x">'; - echo '</div>'; - } - ?> + echo '</div>'; + } + ?> + </div> + </section> </div> </section> </div> - </section> - </div> - </div> - </body> - - <script> - const max_width = <?php echo EMOTE_MAX_SIZE[0] ?>; - const max_height = <?php echo EMOTE_MAX_SIZE[1] ?>; - - const fileInput = document.getElementById("form-file"); - const showcase = document.getElementById("emote-showcase"); - const reader = new FileReader(); - - let manual = false; - - fileInput.addEventListener("change", (e) => { - if (manual) return; - - showcase.style.display = "flex"; - reader.readAsDataURL(e.target.files[0]); - reader.onload = (e) => { - const image = new Image(); - image.src = e.target.result; - image.onload = () => { - let m = 1; - - for (let i = 3; i > 0; i--) { - place_image(i, m, e, image); - m *= 2; - } - }; - }; - }); + </div> + </body> + + <script> + const max_width = <?php echo CONFIG['emote']['maxsizex'] ?>; + const max_height = <?php echo CONFIG['emote']['maxsizey'] ?>; + + const fileInput = document.getElementById("form-file"); + const showcase = document.getElementById("emote-showcase"); + const reader = new FileReader(); + + let manual = false; + + fileInput.addEventListener("change", (e) => { + if (manual) return; + + showcase.style.display = "flex"; + reader.readAsDataURL(e.target.files[0]); + reader.onload = (e) => { + const image = new Image(); + image.src = e.target.result; + image.onload = () => { + let m = 1; + + for (let i = 3; i > 0; i--) { + place_image(i, m, e, image); + m *= 2; + } + }; + }; + }); - const code = document.getElementById("code"); + const code = document.getElementById("code"); - code.addEventListener("input", (e) => { - const regex = <?php echo EMOTE_NAME_REGEX ?>; + code.addEventListener("input", (e) => { + const regex = <?php echo CONFIG['emote']['nameregex'] ?>; - if (regex.test(e.target.value) && e.target.value.length <= <?php echo EMOTE_NAME_MAX_LENGTH ?>) { - validCode = e.target.value; - } else { - e.target.value = validCode; - } + if (regex.test(e.target.value) && e.target.value.length <= <?php echo CONFIG['emote']['maxnamelength'] ?>) { + validCode = e.target.value; + } else { + e.target.value = validCode; + } - document.getElementById("emote-name").innerHTML = e.target.value ? e.target.value : "<i>Empty</i>"; - }); + document.getElementById("emote-name").innerHTML = e.target.value ? e.target.value : "<i>Empty</i>"; + }); - const visibility = document.getElementById("form-visibility"); - visibility.addEventListener("change", (e) => { - set_form_visibility_description(visibility.value); - }); + const visibility = document.getElementById("form-visibility"); + visibility.addEventListener("change", (e) => { + set_form_visibility_description(visibility.value); + }); - function set_form_visibility_description(visibility) { - const p = document.getElementById("form-visibility-description"); + function set_form_visibility_description(visibility) { + const p = document.getElementById("form-visibility-description"); - if (visibility == 1) { - p.innerHTML = "Emote won't appear on the public list until it passes a moderator's review. It still can be added to chats."; - } else { - p.innerHTML = "Emote doesn't appear on the public list and won't be subject to moderation checks. It still can be added to chats."; - } - } + if (visibility == 1) { + p.innerHTML = "Emote won't appear on the public list until it passes a moderator's review. It still can be added to chats."; + } else { + p.innerHTML = "Emote doesn't appear on the public list and won't be subject to moderation checks. It still can be added to chats."; + } + } - set_form_visibility_description(visibility.value); + set_form_visibility_description(visibility.value); - // Manual resize - function display_manual_resize() { - const manual_files = document.getElementById("form-manual-files"); + // Manual resize + function display_manual_resize() { + const manual_files = document.getElementById("form-manual-files"); - // resetting previous values - const files = document.querySelectorAll("input[type=file]"); + // resetting previous values + const files = document.querySelectorAll("input[type=file]"); - for (let file of files) { - file.value = null; - file.removeAttribute("required"); - } + for (let file of files) { + file.value = null; + file.removeAttribute("required"); + } - const fileImages = document.querySelectorAll(".emote-image img"); + const fileImages = document.querySelectorAll(".emote-image img"); - for (let file of fileImages) { - file.setAttribute("src", ""); - file.setAttribute("width", "0"); - file.setAttribute("height", "0"); - } + for (let file of fileImages) { + file.setAttribute("src", ""); + file.setAttribute("width", "0"); + file.setAttribute("height", "0"); + } - const fileSizes = document.querySelectorAll(".emote-image .size"); + const fileSizes = document.querySelectorAll(".emote-image .size"); - for (let file of fileImages) { - file.innerHTML = ""; - } + for (let file of fileImages) { + file.innerHTML = ""; + } - manual = !manual; + manual = !manual; - if (manual) { - manual_files.style.display = "block"; - fileInput.style.display = "none"; - const elements = document.querySelectorAll("#form-manual-files input[type=file]"); - for (let elem of elements) { - elem.setAttribute("required", "true"); - } - } else { - manual_files.style.display = "none"; - fileInput.style.display = "block"; - fileInput.setAttribute("required", "true"); - } + if (manual) { + manual_files.style.display = "block"; + fileInput.style.display = "none"; + const elements = document.querySelectorAll("#form-manual-files input[type=file]"); + for (let elem of elements) { + elem.setAttribute("required", "true"); + } + } else { + manual_files.style.display = "none"; + fileInput.style.display = "block"; + fileInput.setAttribute("required", "true"); + } - showcase.style.display = "none"; - } + showcase.style.display = "none"; + } - document.getElementById("form-file-1x").addEventListener("change", (e) => { - showcase.style.display = "flex"; - place_image(1, 4, e, null); - }); - - document.getElementById("form-file-2x").addEventListener("change", (e) => { - showcase.style.display = "flex"; - place_image(2, 2, e, null); - }); - - document.getElementById("form-file-3x").addEventListener("change", (e) => { - showcase.style.display = "flex"; - place_image(3, 1, e, null); - }); - - function place_image(image_index, multiplier, e, image) { - let ee = e; - - if (image == null) { - reader.readAsDataURL(e.target.files[0]); - reader.onload = (e) => { - const image = new Image(); - image.src = e.target.result; - image.onload = () => { + document.getElementById("form-file-1x").addEventListener("change", (e) => { + showcase.style.display = "flex"; + place_image(1, 4, e, null); + }); + + document.getElementById("form-file-2x").addEventListener("change", (e) => { + showcase.style.display = "flex"; + place_image(2, 2, e, null); + }); + + document.getElementById("form-file-3x").addEventListener("change", (e) => { + showcase.style.display = "flex"; + place_image(3, 1, e, null); + }); + + function place_image(image_index, multiplier, e, image) { + let ee = e; + + if (image == null) { + reader.readAsDataURL(e.target.files[0]); + reader.onload = (e) => { + const image = new Image(); + image.src = e.target.result; + image.onload = () => { + insert_image(image_index, multiplier, e, image); + }; + } + } else { insert_image(image_index, multiplier, e, image); - }; - } - } else { - insert_image(image_index, multiplier, e, image); - } + } - function insert_image(i, m, e, image) { - const max_w = max_width / multiplier; - const max_h = max_height / multiplier; + function insert_image(i, m, e, image) { + const max_w = max_width / multiplier; + const max_h = max_height / multiplier; - const parentId = `.emote-image-${image_index}x`; - const imgs = document.querySelectorAll(parentId); + const parentId = `.emote-image-${image_index}x`; + const imgs = document.querySelectorAll(parentId); - for (const img of imgs) { - img.setAttribute("src", e.target.result); + for (const img of imgs) { + img.setAttribute("src", e.target.result); - let ratio = Math.min(max_w / image.width, max_h / image.height); + let ratio = Math.min(max_w / image.width, max_h / image.height); - img.setAttribute("width", Math.floor(image.width * ratio)); - img.setAttribute("height", Math.floor(image.height * ratio)); + img.setAttribute("width", Math.floor(image.width * ratio)); + img.setAttribute("height", Math.floor(image.height * ratio)); - const sizeElement = document.querySelector(`.emote-image:has(${parentId}) .size`); - sizeElement.innerHTML = `${img.getAttribute("width")}x${img.getAttribute("height")}`; + const sizeElement = document.querySelector(`.emote-image:has(${parentId}) .size`); + sizeElement.innerHTML = `${img.getAttribute("width")}x${img.getAttribute("height")}`; + } + } } - } - } - </script> + </script> - </html> + </html> - <?php - exit; + <?php + exit; } -if (!CLIENT_REQUIRES_JSON && CAPTCHA_ENABLE && !isset($_SESSION["captcha_solved"])) { +if (!CLIENT_REQUIRES_JSON && CONFIG['captcha']['enable'] && !isset($_SESSION["captcha_solved"])) { generate_alert("/404.php", "You haven't solved captcha yet.", 403); exit; } @@ -401,14 +401,14 @@ if (!$is_manual && !isset($_FILES["file"])) { exit; } -$code = str_safe($_POST["code"] ?? "", EMOTE_NAME_MAX_LENGTH); +$code = str_safe($_POST["code"] ?? "", CONFIG['emote']['maxnamelength']); -if ($code == "" || !preg_match(EMOTE_NAME_REGEX, $code)) { +if ($code == "" || !preg_match(CONFIG['emote']['nameregex'], $code)) { generate_alert("/emotes/upload.php", "Invalid code"); exit; } -$notes = str_safe($_POST["notes"] ?? "", EMOTE_COMMENT_MAX_LENGTH); +$notes = str_safe($_POST["notes"] ?? "", CONFIG['emote']['maxcommentlength']); if (empty($notes)) { $notes = null; } @@ -418,9 +418,9 @@ if (empty($source)) { $source = null; } -$visibility = clamp(intval($_POST["visibility"], EMOTE_VISIBILITY_DEFAULT), 0, 2); +$visibility = clamp(intval($_POST["visibility"], CONFIG['emote']['defaultvisibility']), 0, 2); -if (MOD_EMOTES_APPROVE && $visibility == 1 && EMOTE_VISIBILITY_DEFAULT != 1) { +if (CONFIG['mod']['approve'] && $visibility == 1 && CONFIG['emote']['defaultvisibility'] != 1) { $visibility = 2; } @@ -468,7 +468,7 @@ if ($is_manual) { exit; } - if (EMOTE_STORE_ORIGINAL) { + if (CONFIG['emote']['storeoriginal']) { $ext = get_file_extension($image["tmp_name"]) ?? ""; move_uploaded_file($image["tmp_name"], "$path/original.$ext"); } @@ -477,17 +477,17 @@ if ($is_manual) { $tags = str_safe($_POST["tags"] ?? "", null); $tags_processed = []; -if (!empty($tags) && TAGS_ENABLE) { +if (!empty($tags) && CONFIG['tags']['enable']) { $tags = explode(" ", $tags); $count = 0; foreach ($tags as $tag) { - if (TAGS_MAX_COUNT > 0 && $count >= TAGS_MAX_COUNT) { + if (CONFIG['tags']['maxcount'] > 0 && $count >= CONFIG['tags']['maxcount']) { break; } - if (!preg_match(TAGS_CODE_REGEX, $tag)) { + if (!preg_match(CONFIG['tags']['regex'], $tag)) { continue; } @@ -526,7 +526,7 @@ $emote_data = [ "tags" => $tags_processed ]; -if (ACCOUNT_LOG_ACTIONS && $uploaded_by != null) { +if (CONFIG['account']['log'] && $uploaded_by != null) { $db->prepare("INSERT INTO actions(user_id, action_type, action_payload) VALUES (?, ?, ?)") ->execute([ $uploaded_by, diff --git a/emotesets.php b/emotesets.php index 9d2fa07..e2dae57 100644 --- a/emotesets.php +++ b/emotesets.php @@ -10,7 +10,7 @@ authorize_user(); $id = $_GET["id"] ?? ""; -$db = new PDO(DB_URL, DB_USER, DB_PASS); +$db = new PDO(CONFIG['database']['url'], CONFIG['database']['user'], CONFIG['database']['pass']); // searching requested emoteset $emote_set = null; @@ -75,7 +75,7 @@ $emote_sets = null; // fetching emotes if ($emote_set) { $emote_set = Emoteset::from_array_extended($emote_set, $user_id, $db); -} elseif (!EMOTESET_PUBLIC_LIST) { +} elseif (!CONFIG['emoteset']['public']) { generate_alert("/404.php", "The public list of emotesets is disabled", 403); exit; } else { @@ -120,7 +120,7 @@ if (CLIENT_REQUIRES_JSON) { false => "Emoteset - {$emote_set->name}", }; - echo "$title - " . INSTANCE_NAME; + echo "$title - " . CONFIG['instance']['name']; ?> </title> <link rel="stylesheet" href="/static/style.css"> @@ -8,7 +8,7 @@ if (!authorize_user(true)) { exit; } -$db = new PDO(DB_URL, DB_USER, DB_PASS); +$db = new PDO(CONFIG['database']['url'], CONFIG['database']['user'], CONFIG['database']['pass']); $stmt = $db->prepare("SELECT * FROM inbox_messages WHERE recipient_id = ? ORDER BY sent_at DESC"); $stmt->execute([$_SESSION["user_id"]]); @@ -23,7 +23,7 @@ $stmt->execute([$_SESSION["user_id"]]); <html> <head> - <title>Inbox - <?php echo INSTANCE_NAME ?></title> + <title>Inbox - <?php echo CONFIG['instance']['name'] ?></title> <link rel="stylesheet" href="/static/style.css"> <link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon"> </head> @@ -1,5 +1,11 @@ <?php include_once "{$_SERVER['DOCUMENT_ROOT']}/lib/config.php"; + +if (!file_exists(CFG_PATH)) { + header('Location: /system/config.php'); + exit("You have to set up the instance first!"); +} + include_once "{$_SERVER['DOCUMENT_ROOT']}/lib/accounts.php"; include_once "{$_SERVER['DOCUMENT_ROOT']}/lib/version.php"; @@ -9,7 +15,7 @@ authorize_user(); <html> <head> - <title><?php echo INSTANCE_NAME ?></title> + <title><?php echo CONFIG['instance']['name'] ?></title> <link rel="stylesheet" href="/static/style.css"> <link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon"> </head> @@ -17,20 +23,20 @@ authorize_user(); <body> <div class="container"> <div class="wrapper center big-gap"> - <h1><img src="/static/img/brand/big.webp" alt="<?php echo INSTANCE_NAME; ?>"></h1> + <h1><img src="/static/img/brand/big.webp" alt="<?php echo CONFIG['instance']['name']; ?>"></h1> <div class="items row" style="gap:32px;"> <a href="/emotes">Emotes</a> - <?php if (EMOTESET_PUBLIC_LIST): ?> + <?php if (CONFIG['emoteset']['public']): ?> <a href="/emotesets.php">Emotesets</a> <?php endif; ?> - <?php if (ACCOUNT_PUBLIC_LIST): ?> + <?php if (CONFIG['account']['publiclist']): ?> <a href="/users.php">Users</a> <?php endif; ?> - <?php if (EMOTE_UPLOAD && (ANONYMOUS_UPLOAD || (isset($_SESSION["user_role"]) && $_SESSION["user_role"]["permission_upload"]))) { + <?php if (CONFIG['emote']['upload'] && (CONFIG['anonymous']['upload'] || (isset($_SESSION["user_role"]) && $_SESSION["user_role"]["permission_upload"]))) { echo '<a href="/emotes/upload.php">Upload</a>'; } ?> <a href="/account">Account</a> @@ -44,7 +50,7 @@ authorize_user(); <div class="counter"> <?php - $db = new PDO(DB_URL, DB_USER, DB_PASS); + $db = new PDO(CONFIG['database']['url'], CONFIG['database']['user'], CONFIG['database']['pass']); $results = $db->query("SELECT COUNT(*) FROM emotes WHERE visibility = 1"); $count = $results->fetch()[0]; diff --git a/lib/accounts.php b/lib/accounts.php index 51cb3f6..2ddb796 100644 --- a/lib/accounts.php +++ b/lib/accounts.php @@ -28,7 +28,7 @@ function authorize_user(bool $required = false): bool include_once "config.php"; - $db = new PDO(DB_URL, DB_USER, DB_PASS); + $db = new PDO(CONFIG['database']['url'], CONFIG['database']['user'], CONFIG['database']['pass']); $key = $_SERVER["HTTP_AUTHORIZATION"] ?? $_COOKIE["secret_key"]; diff --git a/lib/config.php b/lib/config.php new file mode 100644 index 0000000..1c6797d --- /dev/null +++ b/lib/config.php @@ -0,0 +1,113 @@ +<?php +$file_path = "{$_SERVER['DOCUMENT_ROOT']}/config.json"; +define('CFG_PATH', $file_path); + +$cfg = [ + 'instance' => [ + 'name' => $_SERVER['HTTP_HOST'] + ], + 'database' => [ + 'name' => '', + 'user' => '', + 'pass' => '', + 'host' => 'localhost', + 'url' => '' + ], + 'anonymous' => [ + 'upload' => false, + 'defaultname' => 'Anonymous' + ], + 'emote' => [ + 'upload' => true, + 'nameregex' => "/^[A-Za-z0-9_]+$/", + 'defaultvisibility' => 2, + 'maxnamelength' => 100, + 'maxcommentlength' => 100, + 'maxsizex' => 128, + 'maxsizey' => 128, + 'storeoriginal' => true + ], + 'rating' => [ + 'enable' => true, + 'names' => "-1=COAL\n1=GEM", + 'minvotes' => 10 + ], + 'tags' => [ + 'enable' => true, + 'regex' => "/^[A-Za-z0-9_]+$/", + 'maxcount' => 10 + ], + 'emoteset' => [ + 'public' => true + ], + 'mod' => [ + 'dashboard' => true, + 'approve' => true + ], + 'reports' => [ + 'enable' => true + ], + 'account' => [ + 'registration' => true, + 'maxcookielifetime' => 86400 * 30, + 'regex' => "/^[A-Za-z0-9_]+$/", + 'minusernamelength' => 2, + 'maxusernamelength' => 20, + 'minpasswordlength' => 10, + 'secretkeylength' => 32, + 'pfpsizex' => 128, + 'pfpsizey' => 128, + 'bannersizex' => 1920, + 'bannersizey' => 1080, + 'badgesizex' => 72, + 'badgesizey' => 72, + 'publiclist' => true, + 'log' => true + ], + 'twitch' => [ + 'registration' => false, + 'clientid' => '', + 'clientsecret' => '', + 'redirecturi' => ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? "https" : "http") . "://$_SERVER[HTTP_HOST]/account/login/twitch.php" + ], + 'captcha' => [ + 'enable' => false, + 'x' => 580, + 'y' => 220, + 'force' => false + ] +]; + +if (file_exists(CFG_PATH)) { + $c = json_decode(file_get_contents(CFG_PATH), true); + foreach ($cfg as $sk => $sv) { + if (!is_array($sv) || !array_key_exists($sk, $c)) { + continue; + } + + foreach ($sv as $k => $v) { + if (array_key_exists($k, $c[$sk])) { + $cfg[$sk][$k] = $c[$sk][$k]; + } + } + } +} + +if (!empty($cfg['database']['host'])) { + $cfg['database']['url'] = "mysql:host={$cfg['database']['host']};dbname={$cfg['database']['name']};port=3306"; +} + +$cfg['rating']['names_string'] = $cfg['rating']['names']; +$n = []; +foreach (explode("\n", $cfg['rating']['names']) as $_ => $v) { + [$k, $v] = explode('=', $v, 2); + $n[intval($k)] = $v; +} +$cfg['rating']['names'] = $n; + +define('CONFIG', $cfg); + +define("INSTANCE_STATIC_FOLDER", "static"); // Static folder. Used only in /404.php. + +// FOR DEVELOPERS +define("CLIENT_REQUIRES_JSON", isset($_SERVER["HTTP_ACCEPT"]) && $_SERVER["HTTP_ACCEPT"] == "application/json");
\ No newline at end of file diff --git a/lib/config.sample.php b/lib/config.sample.php deleted file mode 100644 index 3d30044..0000000 --- a/lib/config.sample.php +++ /dev/null @@ -1,74 +0,0 @@ -<?php -// INSTANCE -define("INSTANCE_NAME", "TinyEmotes"); -define("INSTANCE_STATIC_FOLDER", "static"); // Static folder. Used only in /404.php. - -// DATABASE -define("DB_USER", "ENTER_DATABASE_USER"); // Database user. MANDATORY! -define("DB_PASS", "ENTER_DATABASE_PASSWORD"); // Database password. MANDATORY! -define("DB_HOST", "ENTER_DATABASE_HOST"); // Database host. Can be 'localhost' if it's on the same machine as Tinyemotes. -define("DB_NAME", "ENTER_DATABASE_NAME"); // Database name. -define("DB_URL", 'mysql:host=' . DB_HOST . ';dbname=' . DB_NAME . ';port=3306'); // Database URL. Change it if you don't use MySQL/MariaDB. - -// RATINGS -define("RATING_ENABLE", true); // Enable ratings for emotes. -define("RATING_NAMES", [ - "-1" => "COAL", - "1" => "GEM", -]); // Rating names. The schema is [ "id/rating_point" => "name" ]. -define("RATING_EMOTE_MIN_VOTES", 10); // Minimal amount of votes to display emote rating. - -// UPLOADS -define("ANONYMOUS_UPLOAD", false); // Allow anonymous upload for emotes. -define("ANONYMOUS_DEFAULT_NAME", "Anonymous"); // Default uploader name for anonymous emotes. It's also used when original uploader has been deleted. - -// EMOTES -define("EMOTE_UPLOAD", true); // Enable emote upload. -define("EMOTE_NAME_MAX_LENGTH", 100); // Max length for emote name. -define("EMOTE_COMMENT_MAX_LENGTH", 100); // Max length for emote comment. -define("EMOTE_VISIBILITY_DEFAULT", 2); // Default visibility for emotes. 0 - unlisted, 1 - public, 2 - pending approval (same as unlisted). -define("EMOTE_MAX_SIZE", [128, 128]); // Max size of emote. -define("EMOTE_NAME_REGEX", "/^[A-Za-z0-9_]+$/"); // RegEx filter for emote names. -define("EMOTE_STORE_ORIGINAL", true); // Store original uploads of emotes. - -// TAGS -define("TAGS_ENABLE", true); // Allow emote tagging. -define("TAGS_CODE_REGEX", "/^[A-Za-z0-9_]+$/"); -define("TAGS_MAX_COUNT", 10); // Maximum tags per emote. Set -1 for unlimited amount. - -// EMOTESETS -define("EMOTESET_PUBLIC_LIST", true); // Show emotesets public. - -// MODERATION -define("MOD_SYSTEM_DASHBOARD", true); // Enable system dashboard for moderators (/system). -define("MOD_EMOTES_APPROVE", true); // Enable manual emote approval (/system/emotes). - -// REPORTS -define("REPORTS_ENABLE", true); // Enable emote, user reports. - -// ACCOUNTS -define("ACCOUNT_REGISTRATION_ENABLE", true); // Enable account registration. -define("ACCOUNT_COOKIE_MAX_LIFETIME", 86400 * 30); // Remember user for a month. -define("ACCOUNT_USERNAME_REGEX", "/^[A-Za-z0-9_]+$/"); // RegEx filter for account usernames. -define("ACCOUNT_USERNAME_LENGTH", [2, 20]); // [Min, Max] length for account usernames. -define("ACCOUNT_PASSWORD_MIN_LENGTH", 10); // Minimal length for passwords. -define("ACCOUNT_SECRET_KEY_LENGTH", 32); // The length for secret keys. -define("ACCOUNT_PFP_MAX_SIZE", [128, 128]); // Max dimensions for account pictures. -define("ACCOUNT_BANNER_MAX_SIZE", [1920, 1080]); // Max dimensions for account banners. -define("ACCOUNT_BADGE_MAX_SIZE", [72, 72]); // Max dimensions for account badges. -define("ACCOUNT_PUBLIC_LIST", true); // The public list of accounts. -define("ACCOUNT_LOG_ACTIONS", true); // Log user's actions (emote addition, etc.). - -// TWITCH -define("TWITCH_REGISTRATION_ENABLE", false); // Enable account registration via Twitch. -define("TWITCH_CLIENT_ID", "AAAAAAAAA"); // Client ID of your Twitch application. -define("TWITCH_SECRET_KEY", "BBBBBBBBB"); // Secret key of your Twitch application. -define("TWITCH_REDIRECT_URI", ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? "https" : "http") . "://$_SERVER[HTTP_HOST]/account/login/twitch.php"); // Redirect URI of your Twitch application. - -// CAPTCHA -define("CAPTCHA_ENABLE", true); // Enable built-in captcha. -define("CAPTCHA_SIZE", [580, 220]); // Captcha size. -define("CAPTCHA_FORCE_USERS", false); // Force authorized users to solve captcha. - -// FOR DEVELOPERS -define("CLIENT_REQUIRES_JSON", isset($_SERVER["HTTP_ACCEPT"]) && $_SERVER["HTTP_ACCEPT"] == "application/json");
\ No newline at end of file diff --git a/lib/partials.php b/lib/partials.php index 760923a..979621d 100644 --- a/lib/partials.php +++ b/lib/partials.php @@ -7,26 +7,26 @@ function html_navigation_bar() <section class="navbar"> <a href="/" class="brand" style="color:black;text-decoration:none;"> <img src="/static/img/brand/mini.webp" alt=""> - <h2 style="margin-left:8px;font-size:24px;"><b><?php echo INSTANCE_NAME ?></b></h2> + <h2 style="margin-left:8px;font-size:24px;"><b><?= CONFIG['instance']['name'] ?></b></h2> </a> <div class="links"> <a href="/emotes" class="button">Emotes</a> - <?php if (EMOTESET_PUBLIC_LIST): ?> + <?php if (CONFIG['emoteset']['public']): ?> <a href="/emotesets.php" class="button">Emotesets</a> <?php endif; ?> - <?php if (ACCOUNT_PUBLIC_LIST): ?> + <?php if (CONFIG['account']['publiclist']): ?> <a href="/users.php" class="button">Users</a> <?php endif; ?> - <?php if (EMOTE_UPLOAD && (ANONYMOUS_UPLOAD || (isset($_SESSION["user_role"]) && $_SESSION["user_role"]["permission_upload"]))) { + <?php if (CONFIG['emote']['upload'] && (CONFIG['anonymous']['upload'] || (isset($_SESSION["user_role"]) && $_SESSION["user_role"]["permission_upload"]))) { echo '<a href="/emotes/upload.php" class="button">Upload</a>'; } ?> <a href="/account" class="button">Account</a> <?php if (isset($_SESSION["user_id"])) { - $db = new PDO(DB_URL, DB_USER, DB_PASS); + $db = new PDO(CONFIG['database']['url'], CONFIG['database']['user'], CONFIG['database']['pass']); // getting inbox $stmt = $db->prepare("SELECT COUNT(*) FROM inbox_messages WHERE recipient_id = ? AND has_read = false"); @@ -40,7 +40,7 @@ function html_navigation_bar() $stmt = null; if (isset($_SESSION["user_role"])) { - if (REPORTS_ENABLE && $_SESSION["user_role"]["permission_report"]) { + if (CONFIG['reports']['enable'] && $_SESSION["user_role"]["permission_report"]) { // getting reports $stmt = $db->prepare("SELECT COUNT(*) FROM reports WHERE sender_id = ? AND resolved_by IS NULL"); $stmt->execute([$_SESSION["user_id"]]); @@ -53,10 +53,10 @@ function html_navigation_bar() <?php ; } - if (MOD_SYSTEM_DASHBOARD && ($_SESSION["user_role"]["permission_approve_emotes"] || $_SESSION["user_role"]["permission_report_review"])) { + if (CONFIG['mod']['dashboard'] && ($_SESSION["user_role"]["permission_approve_emotes"] || $_SESSION["user_role"]["permission_report_review"])) { $system_count = 0; - if ($_SESSION["user_role"]["permission_approve_emotes"] && MOD_EMOTES_APPROVE) { + if ($_SESSION["user_role"]["permission_approve_emotes"] && CONFIG['mod']['approve']) { $system_count += intval($db->query("SELECT COUNT(*) FROM emotes WHERE visibility = 2")->fetch()[0]); } diff --git a/report/index.php b/report/index.php index 7b1b259..fe83855 100644 --- a/report/index.php +++ b/report/index.php @@ -5,7 +5,7 @@ include_once "{$_SERVER['DOCUMENT_ROOT']}/lib/partials.php"; include_once "{$_SERVER['DOCUMENT_ROOT']}/lib/utils.php"; include_once "{$_SERVER['DOCUMENT_ROOT']}/lib/alert.php"; -if (!REPORTS_ENABLE) { +if (!CONFIG['reports']['enable']) { generate_alert("/404.php", "Reports are disabled", 403); exit; } @@ -19,7 +19,7 @@ if (isset($_SESSION["user_role"]) && !$_SESSION["user_role"]["permission_report" exit; } -$db = new PDO(DB_URL, DB_USER, DB_PASS); +$db = new PDO(CONFIG['database']['url'], CONFIG['database']['user'], CONFIG['database']['pass']); $report = null; $report_id = $_GET["id"] ?? ""; @@ -58,7 +58,8 @@ if ($contents == "") { <html> <head> - <title><?php echo ($report == null ? "Send a message to MODS" : "A message to MODS") . ' - ' . INSTANCE_NAME ?> + <title> + <?php echo ($report == null ? "Send a message to MODS" : "A message to MODS") . ' - ' . CONFIG['instance']['name'] ?> </title> <link rel="stylesheet" href="/static/style.css"> <link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon"> diff --git a/report/list.php b/report/list.php index 71c233e..94154fe 100644 --- a/report/list.php +++ b/report/list.php @@ -5,7 +5,7 @@ include_once "{$_SERVER['DOCUMENT_ROOT']}/lib/partials.php"; include_once "{$_SERVER['DOCUMENT_ROOT']}/lib/utils.php"; include_once "{$_SERVER['DOCUMENT_ROOT']}/lib/alert.php"; -if (!REPORTS_ENABLE) { +if (!CONFIG['reports']['enable']) { generate_alert("/404.php", "Reports are disabled", 403); exit; } @@ -19,7 +19,7 @@ if (isset($_SESSION["user_role"]) && !$_SESSION["user_role"]["permission_report" exit; } -$db = new PDO(DB_URL, DB_USER, DB_PASS); +$db = new PDO(CONFIG['database']['url'], CONFIG['database']['user'], CONFIG['database']['pass']); $stmt = $db->prepare("SELECT * FROM reports WHERE sender_id = ? ORDER BY sent_at DESC"); $stmt->execute([$_SESSION["user_id"]]); @@ -30,7 +30,7 @@ $reports = $stmt->fetchAll(PDO::FETCH_ASSOC); <html> <head> - <title>Report list - <?php echo INSTANCE_NAME ?></title> + <title>Report list - <?php echo CONFIG['instance']['name'] ?></title> <link rel="stylesheet" href="/static/style.css"> <link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon"> </head> diff --git a/report/send.php b/report/send.php index fe10ba6..fb4a726 100644 --- a/report/send.php +++ b/report/send.php @@ -4,7 +4,7 @@ include_once "{$_SERVER['DOCUMENT_ROOT']}/lib/config.php"; include_once "{$_SERVER['DOCUMENT_ROOT']}/lib/utils.php"; include_once "{$_SERVER['DOCUMENT_ROOT']}/lib/alert.php"; -if (!REPORTS_ENABLE) { +if (!CONFIG['reports']['enable']) { generate_alert("/404.php", "Reports are disabled", 403); exit; } @@ -18,7 +18,7 @@ if (isset($_SESSION["user_role"]) && !$_SESSION["user_role"]["permission_report" exit; } -$db = new PDO(DB_URL, DB_USER, DB_PASS); +$db = new PDO(CONFIG['database']['url'], CONFIG['database']['user'], CONFIG['database']['pass']); if (!isset($_POST["contents"])) { generate_alert("/report", "Not enough POST fields"); @@ -18,7 +18,7 @@ if (is_file($path)) { <html> <head> - <title>The Rules of <?php echo INSTANCE_NAME ?></title> + <title>The Rules of <?php echo CONFIG['instance']['name'] ?></title> <link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon"> <link rel="stylesheet" href="/static/style.css"> </head> @@ -30,7 +30,7 @@ if (is_file($path)) { <div class="content row"> <div class="sidebar" style="min-width: 300px;"></div> <div class="content"> - <h1>The Rules of <?php echo INSTANCE_NAME ?></h1> + <h1>The Rules of <?php echo CONFIG['instance']['name'] ?></h1> <ol> <?php foreach ($contents as $line) { diff --git a/software.php b/software.php index c1f0a75..db9e4af 100644 --- a/software.php +++ b/software.php @@ -22,7 +22,7 @@ $software = [ <html> <head> - <title>Software - <?php echo INSTANCE_NAME ?></title> + <title>Software - <?php echo CONFIG['instance']['name'] ?></title> <link rel="stylesheet" href="/static/style.css"> <link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon"> </head> diff --git a/system/config.php b/system/config.php new file mode 100644 index 0000000..4144b93 --- /dev/null +++ b/system/config.php @@ -0,0 +1,430 @@ +<?php +include_once "{$_SERVER['DOCUMENT_ROOT']}/lib/config.php"; +include_once "{$_SERVER['DOCUMENT_ROOT']}/lib/partials.php"; +include_once "{$_SERVER['DOCUMENT_ROOT']}/lib/alert.php"; +include_once "{$_SERVER['DOCUMENT_ROOT']}/lib/accounts.php"; + +if (file_exists(CFG_PATH) && !authorize_user(true) && !isset($_SESSION['user_role']['permission_admin'])) { + generate_alert('/', 'Unauthorized', 401); + exit(); +} + +if ($_SERVER['REQUEST_METHOD'] === 'POST') { + $c = CONFIG; + $c['rating']['names'] = $c['rating']['names_string']; + unset($c['rating']['names_string']); + + // setting all checkboxes to false + foreach ($c as $sk => $sv) { + foreach ($sv as $k => &$v) { + if (is_bool($v) && !array_key_exists("{$sk}_$k", $_POST)) { + $c[$sk][$k] = false; + } + } + unset($v); + } + + foreach ($_POST as $k => $v) { + $parts = explode('_', $k); + $part_count = count($parts); + if ($part_count != 2) { + continue; + } + $section = $parts[0]; + $key = $parts[1]; + + if (!array_key_exists($section, $c)) { + $c[$section] = []; + } + + if ($v === 'on') { + $v = true; + } + + if (is_numeric($v)) { + $v += 0; + } + + $c[$section][$key] = $v; + } + + if (!file_put_contents(CFG_PATH, json_encode($c, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT))) { + http_response_code(500); + exit("Failed to write the configuration file."); + } + + generate_alert('/system/config.php', 'Saved!', 200); + exit(); +} + +?> +<html> + +<head> + <title>Configuration - <?= CONFIG['instance']['name'] ?></title> + <link rel="stylesheet" href="/static/style.css"> + <link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon"> +</head> + +<body> + <div class="container"> + <div class="wrapper"> + <?php html_navigation_bar() ?> + <section class="content"> + <h1>Instance configuration</h1> + <?php if (!file_exists(CFG_PATH)): ?> + <div class="box"> + <p>This message confirms the instance is nearly ready. The configuration below shows the default + settings. Enter your database credentials to complete the setup.</p> + </div> + <?php endif; ?> + <form action="/system/config.php" method="post"> + <div class="box"> + <div class="box navtab"> + <p>Instance</p> + </div> + <div class="box content"> + <table class="vertical left"> + <tr> + <th>Name</th> + <td><input type="text" name="instance_name" + value="<?= CONFIG['instance']['name'] ?>"></td> + </tr> + </table> + </div> + </div> + + <div class="box"> + <div class="box navtab"> + <p>Database</p> + </div> + <div class="box content"> + <table class="vertical left"> + <tr> + <th>Name</th> + <td><input type="text" name="database_name" + value="<?= CONFIG['database']['name'] ?>" required></td> + </tr> + <tr> + <th>User</th> + <td><input type="text" name="database_user" + value="<?= CONFIG['database']['user'] ?>" required></td> + </tr> + <tr> + <th>Password</th> + <td><input type="password" name="database_pass" + value="<?= CONFIG['database']['pass'] ?>" required></td> + </tr> + <tr> + <th>Host</th> + <td><input type="text" name="database_host" + value="<?= CONFIG['database']['host'] ?>" required></td> + </tr> + </table> + </div> + </div> + + <div class="box"> + <div class="box navtab"> + <p>Emotes</p> + </div> + <div class="box content"> + <table class="vertical left"> + <tr> + <th>Allow emote upload</th> + <td><input type="checkbox" name="emote_upload" value="on" + <?= CONFIG['emote']['upload'] ? 'checked' : '' ?>></td> + </tr> + <tr> + <th>Allow anonymous emote upload</th> + <td><input type="checkbox" name="anonymous_upload" value="on" + <?= CONFIG['anonymous']['upload'] ? 'checked' : '' ?>></td> + </tr> + <tr> + <th>Default uploader name</th> + <td><input type="text" name="anonymous_defaultname" + value="<?= CONFIG['anonymous']['defaultname'] ?>"></td> + </tr> + <tr> + <th>RegEx filter for names</th> + <td><input type="text" name="emote_nameregex" + value="<?= CONFIG['emote']['nameregex'] ?>"></td> + </tr> + <tr> + <th>Default visibility</th> + <td> + <select name="emote_defaultvisibility"> + <option value="0" <?= CONFIG['emote']['defaultvisibility'] == 0 ? 'selected' : '' ?>>Unlisted</option> + <option value="on" <?= CONFIG['emote']['defaultvisibility'] == 1 ? 'selected' : '' ?>>Public</option> + <option value="2" <?= CONFIG['emote']['defaultvisibility'] == 2 ? 'selected' : '' ?>>Pending approval</option> + </select> + </td> + </tr> + <tr> + <th>Max name length</th> + <td><input type="number" name="emote_maxnamelength" + value="<?= CONFIG['emote']['maxnamelength'] ?>"></td> + </tr> + <tr> + <th>Max comment length</th> + <td><input type="number" name="emote_maxcommentlength" + value="<?= CONFIG['emote']['maxcommentlength'] ?>"></td> + </tr> + <tr> + <th>Max size</th> + <td>X: <input type="number" name="emote_maxsizex" + value="<?= CONFIG['emote']['maxsizex'] ?>"> Y: + <input type="number" name="emote_maxsizey" + value="<?= CONFIG['emote']['maxsizey'] ?>"> + </td> + </tr> + <tr> + <th>Store original uploaded file</th> + <td><input type="checkbox" name="emote_storeoriginal" value="on" + <?= CONFIG['emote']['storeoriginal'] ? 'checked' : '' ?>></td> + </tr> + </table> + </div> + </div> + + <div class="box"> + <div class="box navtab"> + <p>Accounts</p> + </div> + <div class="box content"> + <table class="vertical left"> + <tr> + <th>Enable account registration</th> + <td><input type="checkbox" name="account_registration" value="on" + <?= CONFIG['account']['registration'] ? 'checked' : '' ?>></td> + </tr> + <tr> + <th>Max. cookie lifetime <i>(in seconds)</i></th> + <td><input type="number" name="account_maxcookielifetime" + value="<?= CONFIG['account']['maxcookielifetime'] ?>"></td> + </tr> + <tr> + <th>RegEx filter for usernames</th> + <td><input type="text" name="account_regex" + value="<?= CONFIG['account']['regex'] ?>"></td> + </tr> + <tr> + <th>Username length</th> + <td>Min: <input type="number" name="account_minusernamelength" + value="<?= CONFIG['account']['minusernamelength'] ?>"> + Max: <input type="number" name="account_maxusernamelength" + value="<?= CONFIG['account']['maxusernamelength'] ?>"></td> + </tr> + <tr> + <th>Min. password length</th> + <td><input type="number" name="account_minpasswordlength" + value="<?= CONFIG['account']['minpasswordlength'] ?>"></td> + </tr> + <tr> + <th>Secret key length</th> + <td><input type="number" name="account_secretkeylength" + value="<?= CONFIG['account']['secretkeylength'] ?>"></td> + </tr> + <tr> + <th>Profile picture size</th> + <td>X: <input type="number" name="account_pfpsizex" + value="<?= CONFIG['account']['pfpsizex'] ?>"> + Y: <input type="number" name="account_pfpsizey" + value="<?= CONFIG['account']['pfpsizey'] ?>"></td> + </tr> + <tr> + <th>Profile banner size</th> + <td>X: <input type="number" name="account_bannersizex" + value="<?= CONFIG['account']['bannersizex'] ?>"> + Y: <input type="number" name="account_bannersizey" + value="<?= CONFIG['account']['bannersizey'] ?>"></td> + </tr> + <tr> + <th>Badge size</th> + <td>X: <input type="number" name="account_badgesizex" + value="<?= CONFIG['account']['badgesizex'] ?>"> + Y: <input type="number" name="account_badgesizey" + value="<?= CONFIG['account']['badgesizey'] ?>"></td> + </tr> + <tr> + <th>Enable public list</th> + <td><input type="checkbox" name="account_publiclist" value="on" + <?= CONFIG['account']['publiclist'] ? 'checked' : '' ?>></td> + </tr> + <tr> + <th>Log actions</th> + <td><input type="checkbox" name="account_log" value="on" <?= CONFIG['account']['log'] ? 'checked' : '' ?>></td> + </tr> + </table> + </div> + </div> + + <div class="box"> + <div class="box navtab"> + <p>Twitch</p> + </div> + <div class="box content"> + <table class="vertical left"> + <tr> + <th>Enable account registration via Twitch</th> + <td><input type="checkbox" name="twitch_registration" + <?= CONFIG['twitch']['registration'] ? 'checked' : '' ?> value="on"> + </td> + </tr> + <tr> + <th>Client ID</th> + <td><input type="text" name="twitch_clientid" + value="<?= CONFIG['twitch']['clientid'] ?>"> + </td> + </tr> + <tr> + <th>Client secret</th> + <td><input type="password" name="twitch_clientsecret" + value="<?= CONFIG['twitch']['clientsecret'] ?>"> + </td> + </tr> + <tr> + <th>Redirect URI</th> + <td><input type="url" name="twitch_redirecturi" + value="<?= CONFIG['twitch']['redirecturi'] ?>"> + </td> + </tr> + </table> + </div> + </div> + + <div class="box"> + <div class="box navtab"> + <p>CAPTCHA</p> + </div> + <div class="box content"> + <table class="vertical left"> + <tr> + <th>Enable CAPTCHA</th> + <td><input type="checkbox" name="captcha_enable" <?= CONFIG['captcha']['enable'] ? 'checked' : '' ?> value="on"> + </td> + </tr> + <tr> + <th>Force authorized users to solve CAPTCHA</th> + <td><input type="checkbox" name="captcha_force" <?= CONFIG['captcha']['force'] ? 'checked' : '' ?> value="on"> + </td> + </tr> + <tr> + <th>Size</th> + <td>Min: <input type="number" name="captcha_x" + value="<?= CONFIG['captcha']['x'] ?>"> + Max: <input type="number" name="captcha_y" + value="<?= CONFIG['captcha']['y'] ?>"></td> + </tr> + </table> + </div> + </div> + + <div class="box"> + <div class="box navtab"> + <p>Rating</p> + </div> + <div class="box content"> + <table class="vertical left"> + <tr> + <th>Enable rating</th> + <td><input type="checkbox" name="rating_enable" <?= CONFIG['rating']['enable'] ? 'checked' : '' ?> value="on"> + </td> + </tr> + <tr> + <th>Names<sup title="The schema is ['id/rating_point' => 'name']">[?]</sup></th> + <td><textarea name="rating_names"><?= CONFIG['rating']['names_string'] ?></textarea> + </td> + </tr> + <tr> + <th>Minimal amount of votes</th> + <td><input type="number" name="rating_minvotes" + value="<?= CONFIG['rating']['minvotes'] ?>"></td> + </tr> + </table> + </div> + </div> + + <div class="box"> + <div class="box navtab"> + <p>Tags</p> + </div> + <div class="box content"> + <table class="vertical left"> + <tr> + <th>Enable tags</th> + <td><input type="checkbox" name="tags_enable" <?= CONFIG['tags']['enable'] ? 'checked' : '' ?> value="on"> + </td> + </tr> + <tr> + <th>RegEx filter</th> + <td><input type="text" name="tags_regex" value="<?= CONFIG['tags']['regex'] ?>"> + </td> + </tr> + <tr> + <th>Maximum amount of tags per emote.</th> + <td><input type="number" name="tags_maxcount" + value="<?= CONFIG['tags']['maxcount'] ?>"></td> + </tr> + </table> + </div> + </div> + + <div class="box"> + <div class="box navtab"> + <p>Emotesets</p> + </div> + <div class="box content"> + <table class="vertical left"> + <tr> + <th>Show emotesets public</th> + <td><input type="checkbox" name="emoteset_public" <?= CONFIG['emoteset']['public'] ? 'checked' : '' ?> value="on"> + </td> + </tr> + </table> + </div> + </div> + + <div class="box"> + <div class="box navtab"> + <p>Moderation</p> + </div> + <div class="box content"> + <table class="vertical left"> + <tr> + <th>Enable system dashboard for moderators</th> + <td><input type="checkbox" name="mod_dashboard" <?= CONFIG['mod']['dashboard'] ? 'checked' : '' ?> value="on"> + </td> + </tr> + <tr> + <th>Enable manual emote approval</th> + <td><input type="checkbox" name="mod_approve" <?= CONFIG['mod']['approve'] ? 'checked' : '' ?> value="on"> + </td> + </tr> + </table> + </div> + </div> + + <div class="box"> + <div class="box navtab"> + <p>Reports</p> + </div> + <div class="box content"> + <table class="vertical left"> + <tr> + <th>Enable reports</th> + <td><input type="checkbox" name="reports_enable" <?= CONFIG['reports']['enable'] ? 'checked' : '' ?> value="on"> + </td> + </tr> + </table> + </div> + </div> + + <button type="submit">Save</button> + </form> + </section> + </div> + </div> +</body> + +</html>
\ No newline at end of file diff --git a/system/emotes/index.php b/system/emotes/index.php index d172482..79be71f 100644 --- a/system/emotes/index.php +++ b/system/emotes/index.php @@ -5,7 +5,7 @@ include_once "{$_SERVER['DOCUMENT_ROOT']}/lib/alert.php"; include_once "{$_SERVER['DOCUMENT_ROOT']}/lib/config.php"; include_once "{$_SERVER['DOCUMENT_ROOT']}/lib/utils.php"; -if (!MOD_EMOTES_APPROVE) { +if (!CONFIG['mod']['approve']) { generate_alert("/404.php", "Manual emote approval is disabled", 405); exit; } @@ -17,7 +17,7 @@ if (!authorize_user(true) || !$_SESSION["user_role"]["permission_approve_emotes" $current_user_id = $_SESSION["user_id"] ?? ""; -$db = new PDO(DB_URL, DB_USER, DB_PASS); +$db = new PDO(CONFIG['database']['url'], CONFIG['database']['user'], CONFIG['database']['pass']); $emote_results = $db->prepare("SELECT e.*, CASE WHEN up.private_profile = FALSE OR up.id = ? THEN e.uploaded_by ELSE NULL END AS uploaded_by, CASE WHEN up.private_profile = FALSE OR up.id = ? THEN u.username ELSE NULL END AS uploader_name, @@ -65,7 +65,7 @@ if (isset($_GET["id"])) { <html> <head> - <title>System panel - <?php echo INSTANCE_NAME ?></title> + <title>System panel - <?php echo CONFIG['instance']['name'] ?></title> <link rel="stylesheet" href="/static/style.css"> <link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon"> </head> @@ -87,7 +87,7 @@ if (isset($_GET["id"])) { echo '<span style="font-size:10px;"> by '; if ($row["uploader_name"] == null) { - echo ANONYMOUS_DEFAULT_NAME . '*'; + echo CONFIG['anonymous']['defaultname'] . '*'; } else { echo $row["uploader_name"]; } @@ -174,7 +174,7 @@ if (isset($_GET["id"])) { <tr> <th>Uploader</th> <td><?php - $username = ANONYMOUS_DEFAULT_NAME; + $username = CONFIG['anonymous']['defaultname']; $link = "#"; if ($emote["uploader_name"] != null) { diff --git a/system/emotes/verdict.php b/system/emotes/verdict.php index 07e1300..2c53fd0 100644 --- a/system/emotes/verdict.php +++ b/system/emotes/verdict.php @@ -4,7 +4,7 @@ include_once "{$_SERVER['DOCUMENT_ROOT']}/lib/accounts.php"; include_once "{$_SERVER['DOCUMENT_ROOT']}/lib/config.php"; include_once "{$_SERVER['DOCUMENT_ROOT']}/lib/utils.php"; -if (!MOD_EMOTES_APPROVE) { +if (!CONFIG['mod']['approve']) { generate_alert("/404.php", "Manual emote approval is disabled", 405); exit; } @@ -22,7 +22,7 @@ if (!isset($_POST["id"], $_POST["action"])) { $id = str_safe($_POST["id"], 32); $action = $_POST["action"]; -$db = new PDO(DB_URL, DB_USER, DB_PASS); +$db = new PDO(CONFIG['database']['url'], CONFIG['database']['user'], CONFIG['database']['pass']); $stmt = $db->prepare("SELECT id, code, uploaded_by FROM emotes WHERE id = ? AND visibility = 2 LIMIT 1"); $stmt->execute([$id]); diff --git a/system/index.php b/system/index.php index f5c1677..31291be 100644 --- a/system/index.php +++ b/system/index.php @@ -4,7 +4,7 @@ include_once "{$_SERVER['DOCUMENT_ROOT']}/lib/accounts.php"; include_once "{$_SERVER['DOCUMENT_ROOT']}/lib/alert.php"; include_once "{$_SERVER['DOCUMENT_ROOT']}/lib/config.php"; -if (!MOD_SYSTEM_DASHBOARD) { +if (!CONFIG['mod']['dashboard']) { generate_alert("/404.php", "System dashboard is disabled", 405); exit; } @@ -14,14 +14,14 @@ if (!authorize_user(true) || (!$_SESSION["user_role"]["permission_approve_emotes exit; } -$db = new PDO(DB_URL, DB_USER, DB_PASS); +$db = new PDO(CONFIG['database']['url'], CONFIG['database']['user'], CONFIG['database']['pass']); ?> <html> <head> - <title>System panel - <?php echo INSTANCE_NAME ?></title> + <title>System panel - <?php echo CONFIG['instance']['name'] ?></title> <link rel="stylesheet" href="/static/style.css"> <link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon"> </head> @@ -35,7 +35,7 @@ $db = new PDO(DB_URL, DB_USER, DB_PASS); <div class="box navtab">System panel</div> <div class="box content"> <?php - if (MOD_EMOTES_APPROVE && $_SESSION["user_role"]["permission_approve_emotes"]) { + if (CONFIG['mod']['approve'] && $_SESSION["user_role"]["permission_approve_emotes"]) { echo '<a href="/system/emotes">Emotes'; $results = $db->query("SELECT COUNT(*) FROM emotes WHERE visibility = 2")->fetch()[0]; @@ -47,7 +47,7 @@ $db = new PDO(DB_URL, DB_USER, DB_PASS); echo '</a>'; } - if (REPORTS_ENABLE && $_SESSION["user_role"]["permission_report_review"]) { + if (CONFIG['reports']['enable'] && $_SESSION["user_role"]["permission_report_review"]) { echo '<a href="/system/reports">Reports'; $results = $db->query("SELECT COUNT(*) FROM reports WHERE resolved_by IS NULL")->fetch()[0]; @@ -14,10 +14,10 @@ $is_json = isset($_SERVER["HTTP_ACCEPT"]) && $_SERVER["HTTP_ACCEPT"] == "applica $id = $_GET["id"] ?? ""; $alias_id = $_GET["alias_id"] ?? ""; -$db = new PDO(DB_URL, DB_USER, DB_PASS); +$db = new PDO(CONFIG['database']['url'], CONFIG['database']['user'], CONFIG['database']['pass']); if ($id == "" && $alias_id == "") { - if (!ACCOUNT_PUBLIC_LIST) { + if (!CONFIG['account']['publiclist']) { generate_alert("/404.php", "The public list of accounts is disabled", 403); exit; } @@ -58,7 +58,7 @@ if ($id == "" && $alias_id == "") { <html> <head> - <title>User list - <?php echo INSTANCE_NAME ?></title> + <title>User list - <?php echo CONFIG['instance']['name'] ?></title> <link rel="stylesheet" href="/static/style.css"> <link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon"> </head> @@ -272,7 +272,7 @@ if ($is_json) { <html> <head> - <title><?php echo sprintf("%s - %s", $user->username, INSTANCE_NAME) ?></title> + <title><?php echo sprintf("%s - %s", $user->username, CONFIG['instance']['name']) ?></title> <link rel="stylesheet" href="/static/style.css"> <link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon"> </head> @@ -369,7 +369,7 @@ if ($is_json) { <td> <?php foreach ($fav_reactions as $reaction) { - echo $reaction["c"] . ' <img src="/static/img/icons/ratings/' . $reaction["rate"] . '.png" alt="' . RATING_NAMES[$reaction["rate"]] . '" title="' . RATING_NAMES[$reaction["rate"]] . '">'; + echo $reaction["c"] . ' <img src="/static/img/icons/ratings/' . $reaction["rate"] . '.png" alt="' . CONFIG['rating']['names'][$reaction["rate"]] . '" title="' . CONFIG['rating']['names'][$reaction["rate"]] . '">'; } ?> </td> |
