commit 82660fc9f7cddc95a11672be3ac860ebb9f4a1ee Author: Don Date: Mon Nov 18 22:24:30 2024 +0000 rtnyL omfg diff --git a/index.php b/index.php new file mode 100644 index 0000000..cea709b --- /dev/null +++ b/index.php @@ -0,0 +1,757 @@ += $limit) { + return false; + } + + $rate_limit_data[] = $current_time; + file_put_contents($rate_limit_file, json_encode($rate_limit_data)); + return true; +} + +$accounts_file = '{acc.json}'; +$posts_file = '{posts.json}'; + +$accounts = json_decode(file_get_contents($accounts_file), true); +$posts = json_decode(file_get_contents($posts_file), true); + +$current_user = null; +if (isset($_GET['code'])) { + $token_response = file_get_contents("https://discord.com/api/oauth2/token", false, stream_context_create([ + 'http' => [ + 'method' => 'POST', + 'header' => 'Content-Type: application/x-www-form-urlencoded', + 'content' => http_build_query([ + 'client_id' => $client_id, + 'client_secret' => $client_secret, + 'grant_type' => 'authorization_code', + 'code' => $_GET['code'], + 'redirect_uri' => $redirect_uri + ]) + ] + ])); + $token = json_decode($token_response, true)['access_token']; + + $user_response = file_get_contents('https://discord.com/api/users/@me', false, stream_context_create([ + 'http' => [ + 'method' => 'GET', + 'header' => 'Authorization: Bearer ' . $token + ] + ])); + $user = json_decode($user_response, true); + + $username = $user['username']; + $discriminator = $user['discriminator']; + $display_name = ucfirst(strtolower($username)); + + if (!isset($accounts[$username])) { + $accounts[$username] = [ + 'display_name' => $display_name, + 'bio' => '', + 'profile_picture' => 'https://cdn.discordapp.com/avatars/' . $user['id'] . '/' . $user['avatar'] . '.png', + 'verified' => false, + 'donator' => false, + 'developer' => false, + 'employee' => false, + 'tokens' => [], + 'following' => [], + 'followers' => [] + ]; + } + + $token = generateToken(); + $accounts[$username]['tokens'][] = $token; + setcookie('id', $token, time() + 3600 * 24 * 30, "/"); + + file_put_contents($accounts_file, json_encode($accounts)); + + header('Location: /'); + exit; +} + +if (isset($_GET['logout'])) { + setcookie('id', '', time() - 3600, "/"); + header('Location: /'); + exit; +} + +if (isset($_COOKIE['id'])) { + foreach ($accounts as $username => $account) { + if (in_array($_COOKIE['id'], $account['tokens'])) { + if (isset($account['banned']) && $account['banned']) { + $current_user = null; + break; + } + $current_user = $username; + break; + } + } +} + +// Handle new post submission and replies +if ($current_user && isset($_POST['content'])) { + // Determine if it's a reply or a new post + $is_reply = isset($_POST['replying_to']) && !empty($_POST['replying_to']); + + if ($is_reply) { + $action = 'reply_post'; + $replying_to = $_POST['replying_to']; + } else { + $action = 'new_post'; + $replying_to = null; + } + + if (!checkRateLimit($current_user, $action, 5, 60)) { + echo ''; + die('Please wait before you do that action again.'); + } + + function containsOnlyValidCharacters($string) { + // Prüfen, ob der String nur reguläre und lesbare Zeichen enthält. + // Dies schließt Buchstaben, Zahlen, Satzzeichen und typische Unicode-Zeichen ein. + return preg_match('/^[\p{L}\p{N}\p{P}\p{S}\p{Zs}\p{M}]*$/u', $string); + } + + $content = substr($_POST['content'], 0, 280); + + if (containsOnlyValidCharacters($content)) { + $new_post = [ + 'id' => uniqid(), + 'username' => $current_user, + 'display_name' => $accounts[$current_user]['display_name'], + 'profile_picture' => $accounts[$current_user]['profile_picture'], + 'content' => $content, + 'timestamp' => time(), + 'likes' => 0, + 'replies' => [], + 'replying_to' => $replying_to, + 'image_url' => isset($_POST['image_url']) && preg_match('/\.(jpg|jpeg|png|gif|bmp)$/i', $_POST['image_url']) ? $_POST['image_url'] : null + ]; + $posts[$new_post['id']] = $new_post; + } else { + // Fehlerbehandlung, wenn ungültige Zeichen gefunden wurden + echo "Error: Your tnyL contains invalid characters. Please re-create your tnyL with valid characters!"; + } + + + + // If it's a reply, add the reply ID to the original post + if ($is_reply) { + $posts[$replying_to]['replies'][] = $new_post['id']; + } + + file_put_contents($posts_file, json_encode($posts)); + + header('Location: /'); + exit; +} + + +// Handle post deletion +if ($current_user && isset($_GET['delete'])) { + if (!checkRateLimit($current_user, 'delete_post', 5, 60)) { + echo ''; + die('Please wait before you do that action again.'); + } + + $post_id = $_GET['delete']; + + // Recursive function to delete a post and its replies + function deletePostAndReplies($post_id, &$posts) { + // If the post has replies, delete them first + if (isset($posts[$post_id]['replies']) && !empty($posts[$post_id]['replies'])) { + foreach ($posts[$post_id]['replies'] as $reply_id) { + deletePostAndReplies($reply_id, $posts); // Recursive call + } + } + + // If the post is a reply, remove it from the parent's replies array + if ($posts[$post_id]['replying_to']) { + $parent_id = $posts[$post_id]['replying_to']; + $posts[$parent_id]['replies'] = array_diff($posts[$parent_id]['replies'], [$post_id]); + } + + // Finally, delete the post itself + unset($posts[$post_id]); + } + + if (isset($posts[$post_id]) && ($posts[$post_id]['username'] == $current_user || $current_user == "faelixyz")) { + deletePostAndReplies($post_id, $posts); + file_put_contents($posts_file, json_encode($posts)); + } + + header('Location: /'); + exit; +} + + +// Handle following a user +if ($current_user && isset($_GET['follow'])) { + if (!checkRateLimit($current_user, 'follow_unfollow', 3, 60)) { + echo ''; + die('Please wait before you do that action again.'); + } + + $user_to_follow = $_GET['follow']; + if (isset($accounts[$user_to_follow]) && $current_user != $user_to_follow) { + if (!in_array($user_to_follow, $accounts[$current_user]['following'])) { + $accounts[$current_user]['following'][] = $user_to_follow; + $accounts[$user_to_follow]['followers'][] = $current_user; + file_put_contents($accounts_file, json_encode($accounts)); + } + } + header('Location: /?profile=' . $user_to_follow); + exit; +} + +// Handle unfollowing a user +if ($current_user && isset($_GET['unfollow'])) { + if (!checkRateLimit($current_user, 'follow_unfollow', 3, 60)) { + echo ''; + die('Please wait before you do that action again.'); + } + + $user_to_unfollow = $_GET['unfollow']; + if (isset($accounts[$user_to_unfollow]) && $current_user != $user_to_unfollow) { + if (in_array($user_to_unfollow, $accounts[$current_user]['following'])) { + $accounts[$current_user]['following'] = array_diff($accounts[$current_user]['following'], [$user_to_unfollow]); + $accounts[$user_to_unfollow]['followers'] = array_diff($accounts[$user_to_unfollow]['followers'], [$current_user]); + file_put_contents($accounts_file, json_encode($accounts)); + } + } + header('Location: /?profile=' . $user_to_unfollow); + exit; +} + +// Handle post liking/unliking +if ($current_user && isset($_GET['like'])) { + if (!checkRateLimit($current_user, 'like_unlike', 5, 60)) { + echo ''; + die('Please wait before you do that action again.'); + } + + $post_id = $_GET['like']; + if (isset($posts[$post_id])) { + $liked_by = isset($posts[$post_id]['liked_by']) ? $posts[$post_id]['liked_by'] : []; + if (in_array($current_user, $liked_by)) { + $posts[$post_id]['likes']--; + $liked_by = array_diff($liked_by, [$current_user]); + } else { + $posts[$post_id]['likes']++; + $liked_by[] = $current_user; + } + $posts[$post_id]['liked_by'] = $liked_by; + file_put_contents($posts_file, json_encode($posts)); + } + + header('Location: /'); + exit; +} +// Handle profile editing +if ($current_user && isset($_POST['edit_profile'])) { + if (!checkRateLimit($current_user, 'edit_profile', 3, 60)) { + echo ''; + die('Please wait before you do that action again.'); + } + + if (isset($_POST['display_name'])) { + $accounts[$current_user]['display_name'] = substr($_POST['display_name'], 0, 60); + } + if (isset($_POST['bio'])) { + $accounts[$current_user]['bio'] = substr($_POST['bio'], 0, 60); + } + + file_put_contents($accounts_file, json_encode($accounts)); + + header('Location: /?profile=' . $current_user); + exit; +} + +// Handle banning a user (admin action) +if ($current_user && isset($_POST['ban_user']) && isset($_POST['user_to_ban'])) { + if (!checkRateLimit($current_user, 'ban_user', 1, 300)) { + echo ''; + die('Rate limit exceeded for banning users.'); + } + + $user_to_ban = $_POST['user_to_ban']; + if (isset($accounts[$user_to_ban])) { + $accounts[$user_to_ban]['banned'] = true; + file_put_contents($accounts_file, json_encode($accounts)); + } + header('Location: /'); + exit; +} + +// Handle account deletion +if ($current_user && isset($_POST['delete_account']) && isset($_POST['confirm_delete']) && $_POST['confirm_delete'] == 'yes') { + if (!checkRateLimit($current_user, 'delete_account', 1, 86400)) { + echo ''; + die('Please wait before you do that action again.'); + } + + unset($accounts[$current_user]); + file_put_contents($accounts_file, json_encode($accounts)); + + setcookie('id', '', time() - 3600, "/"); + header('Location: /'); + exit; +} + +// Select suggested posts (excluding replies) +$suggested_posts = []; +if (!empty($posts)) { + $post_ids = array_filter(array_keys($posts), function($post_id) use ($posts) { + $replying_to = $posts[$post_id]['replying_to']; + return $replying_to === null || $replying_to === ''; + }); + + if (count($post_ids) > 0) { + $suggested_posts = array_rand($post_ids, min(5, count($post_ids))); + if (!is_array($suggested_posts)) { + $suggested_posts = [$suggested_posts]; + } + } +} + +function formatTime($timestamp) { + $dt = new DateTime("@$timestamp"); + $dt->setTimezone(new DateTimeZone('Europe/Berlin')); // UTC+2 + return $dt->format('d.m.Y H:i:s'); +} +?> + + + + + + + rtnyL + + + + +
+ +
+
+

Your Account is gone

+

Contact Support.

+ Support +
+
+ + +
+

rtnyL

+
+ + Logged in as: (@) + Logout + + Login with Discord
+ Login with Username and Password + +
+
+ + +
+ +
+ + +
+

s Profile

+ image +

@ + + DevBadge + + + Verified + + + DonatorBadge + + + DevBadge + +

+

+

Followers:

+
+ tnyLs + Replies +
+ + + + + Unfollow + + Follow + + +
+ +
+

+ + by +

+
+ + + + + + +
+
+ image +
+ + @ · +
+
+

+ + + Post image + + +
+
+ image +
+ + @ · +
+
+

+ + + Reply image + + +
+
+ +
+
+ image +
+ + @ · +
+
+

+ + + Post image + + +
+ Like () + + + Delete + +
+
+ + + +

No found.

+ +
+
+ +

Profile not found.

+ + +
+

Settings

+ +

Verification

+

You can request a verification mark. Contact @faelixyz on discord. You just need a social media that has 50 or more followers

+
+

Discord

+

Join the Discord!


+ Join Now
+

Custom Name

+

Please DM @faelixyz on Discord to get a custom name on your rtnyL Account.


+

Account Deletion

+
+ +
+ + +
+
+ + Cancel +
+
+ +
+ + +
+ + +
+

Create new tnyL

+
+ + 0/280 characters + + + +
+
+ +
+

Your Feed

+
+ + + +
+
+ image +
+ + + DevBadge + + + Verified + + + DonateBadge + + + DevBadge + + @ · +
+
+

+ + + Post image + + +
+ Like () + + + Delete + +
+
+ + +

No tnyls found.

+ +
+
+ +
+
+ +

You need to login if you wanna see the tnyls or wanna see a profile.

+

Please note that logging on to this Service "rtnyL", you agree to the Terms of Use and that we use cookies to remember that you are logged in.

+ +
+ + + + + + + + + +