summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMinteck <contact@minteck.org>2022-06-06 17:10:14 +0200
committerMinteck <contact@minteck.org>2022-06-06 17:10:14 +0200
commit10b1ace835d908d32f99874facf8811534087d5b (patch)
treeecf068e4ac40f7470ca2b5ac6bd13bd8fbe13ba9
downloadbits-server-10b1ace835d908d32f99874facf8811534087d5b.tar.gz
bits-server-10b1ace835d908d32f99874facf8811534087d5b.tar.bz2
bits-server-10b1ace835d908d32f99874facf8811534087d5b.zip
Initial commit
-rw-r--r--.gitignore3
-rw-r--r--.idea/.gitignore8
-rw-r--r--.idea/BitsServer.iml8
-rw-r--r--.idea/deployment.xml15
-rw-r--r--.idea/discord.xml7
-rw-r--r--.idea/modules.xml8
-rw-r--r--.idea/php.xml4
-rw-r--r--.idea/vcs.xml6
-rw-r--r--Application/TransactionsList/index.php52
-rw-r--r--Authentication/Callback/index.php63
-rw-r--r--Authentication/Disallowed/index.php30
-rw-r--r--Authentication/Start/index.php4
-rw-r--r--Authentication/Success/index.php30
-rw-r--r--Authentication/Test/index.php4
-rw-r--r--Authentication/Username/index.php11
-rw-r--r--Authentication/index.php1
-rw-r--r--Private/AllowedUsers.json4
-rw-r--r--Private/SessionChecker.php25
-rw-r--r--Private/SessionManager.php33
-rw-r--r--index.php2
20 files changed, 318 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..8849011
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+Private/Application.json
+Private/SessionTokens
+Data \ No newline at end of file
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..13566b8
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/BitsServer.iml b/.idea/BitsServer.iml
new file mode 100644
index 0000000..c956989
--- /dev/null
+++ b/.idea/BitsServer.iml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="WEB_MODULE" version="4">
+ <component name="NewModuleRootManager">
+ <content url="file://$MODULE_DIR$" />
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ </component>
+</module> \ No newline at end of file
diff --git a/.idea/deployment.xml b/.idea/deployment.xml
new file mode 100644
index 0000000..8cdf222
--- /dev/null
+++ b/.idea/deployment.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="PublishConfigData" autoUpload="Always" serverName="Minteck.org" filePermissions="511" folderPermissions="511" remoteFilesAllowedToDisappearOnAutoupload="false">
+ <serverData>
+ <paths name="Minteck.org">
+ <serverdata>
+ <mappings>
+ <mapping deploy="/mnt/bits" local="$PROJECT_DIR$" web="/" />
+ </mappings>
+ </serverdata>
+ </paths>
+ </serverData>
+ <option name="myAutoUpload" value="ALWAYS" />
+ </component>
+</project> \ No newline at end of file
diff --git a/.idea/discord.xml b/.idea/discord.xml
new file mode 100644
index 0000000..d8e9561
--- /dev/null
+++ b/.idea/discord.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="DiscordProjectSettings">
+ <option name="show" value="PROJECT_FILES" />
+ <option name="description" value="" />
+ </component>
+</project> \ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..8762b61
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="ProjectModuleManager">
+ <modules>
+ <module fileurl="file://$PROJECT_DIR$/.idea/BitsServer.iml" filepath="$PROJECT_DIR$/.idea/BitsServer.iml" />
+ </modules>
+ </component>
+</project> \ No newline at end of file
diff --git a/.idea/php.xml b/.idea/php.xml
new file mode 100644
index 0000000..7e5d55a
--- /dev/null
+++ b/.idea/php.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="PhpProjectSharedConfiguration" php_language_level="8.1" />
+</project> \ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="VcsDirectoryMappings">
+ <mapping directory="$PROJECT_DIR$" vcs="Git" />
+ </component>
+</project> \ No newline at end of file
diff --git a/Application/TransactionsList/index.php b/Application/TransactionsList/index.php
new file mode 100644
index 0000000..185e94b
--- /dev/null
+++ b/Application/TransactionsList/index.php
@@ -0,0 +1,52 @@
+<?php
+
+function timeAgo($time): string {
+ if (!is_numeric($time)) {
+ $time = strtotime($time);
+ }
+
+ $periods = ["second", "minute", "hour", "day", "week", "month", "year", "age"];
+ $lengths = array("60", "60", "24", "7", "4.35", "12", "100");
+
+ $now = time();
+
+ $difference = $now - $time;
+ if ($difference <= 10 && $difference >= 0) {
+ return $tense = "now";
+ } elseif ($difference > 0) {
+ $tense = "ago";
+ } else {
+ $tense = "later";
+ }
+
+ for ($j = 0; $difference >= $lengths[$j] && $j < count($lengths)-1; $j++) {
+ $difference /= $lengths[$j];
+ }
+
+ $difference = round($difference);
+
+ $period = $periods[$j] . ($difference >1 ? "s" :'');
+ return "{$difference} {$period} {$tense} ";
+}
+
+require_once $_SERVER['DOCUMENT_ROOT'] . "/Private/SessionManager.php";
+header("Content-Type: application/json");
+
+$users = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/Private/Data/Users.json"), true);
+$list = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/Private/Data/Transactions.json"), true);
+$plist = [];
+
+foreach ($list as $item) {
+ $item["author"] = [
+ "id" => $item["author"],
+ "name" => $users[$item["author"]] ?? $item["author"],
+ "avatar" => "https://account.minteck.org/hub/api/rest/avatar/" . $item["author"] . "?dpr=2&size=48"
+ ];
+ $item["date"] = [
+ "absolute" => $item["date"],
+ "relative" => trim(timeAgo($item["date"]))
+ ];
+ $plist[] = $item;
+}
+
+die(json_encode($plist)); \ No newline at end of file
diff --git a/Authentication/Callback/index.php b/Authentication/Callback/index.php
new file mode 100644
index 0000000..3f50e1c
--- /dev/null
+++ b/Authentication/Callback/index.php
@@ -0,0 +1,63 @@
+<?php
+
+header("Content-Type: text/plain");
+// TODO: handle errors
+
+if (!isset($_GET['code'])) {
+ die();
+}
+
+$appdata = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/Private/Application.json"), true);
+
+$crl = curl_init('https://account.minteck.org/hub/api/rest/oauth2/token');
+curl_setopt($crl, CURLOPT_RETURNTRANSFER, true);
+curl_setopt($crl, CURLINFO_HEADER_OUT, true);
+curl_setopt($crl, CURLOPT_POST, true);
+curl_setopt($crl, CURLOPT_HTTPHEADER, [
+ "Authorization: Basic " . base64_encode($appdata["id"] . ":" . $appdata["secret"]),
+ "Content-Type: application/x-www-form-urlencoded",
+ "Accept: application/json"
+]);
+curl_setopt($crl, CURLOPT_POSTFIELDS, "grant_type=authorization_code&redirect_uri=" . urlencode("http" . ($_SERVER['HTTPS'] ? "s" : "") . "://" . $_SERVER['HTTP_HOST'] . "/Authentication/Callback") . "&code=" . $_GET['code']);
+
+$result = curl_exec($crl);
+$result = json_decode($result, true);
+
+curl_close($crl);
+
+if (isset($result["access_token"])) {
+ $crl = curl_init('https://account.minteck.org/hub/api/rest/users/me');
+ curl_setopt($crl, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($crl, CURLINFO_HEADER_OUT, true);
+ curl_setopt($crl, CURLOPT_HTTPHEADER, [
+ "Authorization: Bearer " . $result["access_token"],
+ "Accept: application/json"
+ ]);
+
+ $result = curl_exec($crl);
+ $result = json_decode($result, true);
+
+ if (!file_exists($_SERVER['DOCUMENT_ROOT'] . "/Private/SessionTokens")) mkdir($_SERVER['DOCUMENT_ROOT'] . "/Private/SessionTokens");
+
+ if (in_array($result["id"], json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/Private/AllowedUsers.json"), true))) {
+ $token = bin2hex(random_bytes(32));
+ file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/Private/SessionTokens/" . $token, json_encode($result));
+ session_start();
+ session_set_cookie_params([
+ 'lifetime' => 0,
+ 'path' => '/',
+ 'domain' => "",
+ 'secure' => true,
+ 'httponly' => true,
+ 'samesite' => 'None'
+ ]);
+ setcookie("BITS_SESSION_TOKEN", $token, 0, "/", "", true, true);
+ header("Set-Cookie: BITS_SESSION_TOKEN=" . $token . "; SameSite=None; Path=/; Secure; HttpOnly");
+
+ header("Location: /Authentication/Success");
+ } else {
+ header("Location: /Authentication/Disallowed");
+ }
+
+ die();
+} \ No newline at end of file
diff --git a/Authentication/Disallowed/index.php b/Authentication/Disallowed/index.php
new file mode 100644
index 0000000..bae4da7
--- /dev/null
+++ b/Authentication/Disallowed/index.php
@@ -0,0 +1,30 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport"
+ content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
+ <meta http-equiv="X-UA-Compatible" content="ie=edge">
+ <title>Authentication</title>
+ <style>
+ body {
+ background: #222;
+ color: white;
+ font-family: sans-serif;
+ text-align: center;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ position: fixed;
+ inset: 0;
+ }
+ </style>
+</head>
+<body>
+<div>
+ <h2>Not allowed</h2>
+ <p>You are not allowed to use this application. Please close it now.</p>
+</div>
+</body>
+</html>
+
diff --git a/Authentication/Start/index.php b/Authentication/Start/index.php
new file mode 100644
index 0000000..006752e
--- /dev/null
+++ b/Authentication/Start/index.php
@@ -0,0 +1,4 @@
+<?php
+
+header("Location: https://account.minteck.org/hub/api/rest/oauth2/auth?client_id=" . json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/Private/Application.json"), true)["id"] . "&response_type=code&redirect_uri=http" . ($_SERVER['HTTPS'] ? "s" : "") . "://" . $_SERVER['HTTP_HOST'] . "/Authentication/Callback&scope=Hub&request_credentials=default&access_type=offline");
+die();
diff --git a/Authentication/Success/index.php b/Authentication/Success/index.php
new file mode 100644
index 0000000..882eecc
--- /dev/null
+++ b/Authentication/Success/index.php
@@ -0,0 +1,30 @@
+<?php require_once $_SERVER['DOCUMENT_ROOT'] . "/Private/SessionManager.php"; ?>
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport"
+ content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
+ <meta http-equiv="X-UA-Compatible" content="ie=edge">
+ <title>Authentication</title>
+ <style>
+ body {
+ background: #222;
+ color: white;
+ font-family: sans-serif;
+ text-align: center;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ position: fixed;
+ inset: 0;
+ }
+ </style>
+</head>
+<body>
+ <div>
+ <h2>Success</h2>
+ <p>Authentication succeeded, you will be redirected to the requested application in a few seconds.</p>
+ </div>
+</body>
+</html>
diff --git a/Authentication/Test/index.php b/Authentication/Test/index.php
new file mode 100644
index 0000000..7c0d1fb
--- /dev/null
+++ b/Authentication/Test/index.php
@@ -0,0 +1,4 @@
+<?php
+
+require_once $_SERVER['DOCUMENT_ROOT'] . "/Private/SessionChecker.php";
+header("Content-Type: application/json"); die("{\n \"status\": 0\n}"); \ No newline at end of file
diff --git a/Authentication/Username/index.php b/Authentication/Username/index.php
new file mode 100644
index 0000000..63b4aed
--- /dev/null
+++ b/Authentication/Username/index.php
@@ -0,0 +1,11 @@
+<?php
+
+require_once $_SERVER['DOCUMENT_ROOT'] . "/Private/SessionManager.php"; global $_PROFILE;
+header("Content-Type: application/json");
+
+$a = [
+ "name" => $_PROFILE["name"],
+ "id" => $_PROFILE['id']
+];
+
+die(json_encode($a)); \ No newline at end of file
diff --git a/Authentication/index.php b/Authentication/index.php
new file mode 100644
index 0000000..9fd9e4a
--- /dev/null
+++ b/Authentication/index.php
@@ -0,0 +1 @@
+<?php header("Location: /Authentication/Start") and die(); \ No newline at end of file
diff --git a/Private/AllowedUsers.json b/Private/AllowedUsers.json
new file mode 100644
index 0000000..b94bf28
--- /dev/null
+++ b/Private/AllowedUsers.json
@@ -0,0 +1,4 @@
+[
+ "e2d08242-9107-40fc-834e-28e6000ef1cd",
+ "0204b8a8-4468-4f59-859d-a82e731b1378"
+] \ No newline at end of file
diff --git a/Private/SessionChecker.php b/Private/SessionChecker.php
new file mode 100644
index 0000000..194c398
--- /dev/null
+++ b/Private/SessionChecker.php
@@ -0,0 +1,25 @@
+<?php
+
+global $SessionManagerAllowDisallowed;
+
+if (isset($_COOKIE['BITS_SESSION_TOKEN'])) {
+ if (str_contains($_COOKIE['BITS_SESSION_TOKEN'], ".") || str_contains($_COOKIE['BITS_SESSION_TOKEN'], "/")) {
+ header("Content-Type: application/json"); die("{\n \"status\": 1\n}");
+ }
+
+ if (file_exists($_SERVER['DOCUMENT_ROOT'] . "/Private/SessionTokens/" . str_replace(".", "", str_replace("/", "", $_COOKIE['BITS_SESSION_TOKEN'])))) {
+ $_PROFILE = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/Private/SessionTokens/" . str_replace(".", "", str_replace("/", "", $_COOKIE['BITS_SESSION_TOKEN']))), true);
+
+ if (!in_array($_PROFILE["id"], json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/Private/AllowedUsers.json"), true)) && !$SessionManagerAllowDisallowed) {
+ header("Content-Type: application/json"); die("{\n \"status\": 1\n}");
+ } else {
+ $users = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/Private/Data/Users.json"), true);
+ $users[$_PROFILE["id"]] = $_PROFILE["name"];
+ file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/Private/Data/Users.json", json_encode($users));
+ }
+ } else {
+ header("Content-Type: application/json"); die("{\n \"status\": 1\n}");
+ }
+} else {
+ header("Content-Type: application/json"); die("{\n \"status\": 1\n}");
+} \ No newline at end of file
diff --git a/Private/SessionManager.php b/Private/SessionManager.php
new file mode 100644
index 0000000..bb6c721
--- /dev/null
+++ b/Private/SessionManager.php
@@ -0,0 +1,33 @@
+<?php
+
+if (!file_exists($_SERVER['DOCUMENT_ROOT'] . "/Data")) mkdir($_SERVER['DOCUMENT_ROOT'] . "/Data");
+if (!file_exists($_SERVER['DOCUMENT_ROOT'] . "/Data/Transactions.json")) file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/Data/Transactions.json", "[]");
+if (!file_exists($_SERVER['DOCUMENT_ROOT'] . "/Data/Users.json")) file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/Data/Users.json", "{}");
+
+global $SessionManagerAllowDisallowed;
+
+if (isset($_COOKIE['BITS_SESSION_TOKEN'])) {
+ if (str_contains($_COOKIE['BITS_SESSION_TOKEN'], ".") || str_contains($_COOKIE['BITS_SESSION_TOKEN'], "/")) {
+ header("Location: /Authentication/Start");
+ die();
+ }
+
+ if (file_exists($_SERVER['DOCUMENT_ROOT'] . "/Private/SessionTokens/" . str_replace(".", "", str_replace("/", "", $_COOKIE['BITS_SESSION_TOKEN'])))) {
+ $_PROFILE = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/Private/SessionTokens/" . str_replace(".", "", str_replace("/", "", $_COOKIE['BITS_SESSION_TOKEN']))), true);
+
+ if (!in_array($_PROFILE["id"], json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/Private/AllowedUsers.json"), true)) && !$SessionManagerAllowDisallowed) {
+ header("Location: /Authentication/Disallowed");
+ die();
+ } else {
+ $users = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/Private/Data/Users.json"), true);
+ $users[$_PROFILE["id"]] = $_PROFILE["name"];
+ file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/Private/Data/Users.json", json_encode($users));
+ }
+ } else {
+ header("Location: /Authentication/Start");
+ die();
+ }
+} else {
+ header("Location: /Authentication/Start");
+ die();
+} \ No newline at end of file
diff --git a/index.php b/index.php
new file mode 100644
index 0000000..0ef5364
--- /dev/null
+++ b/index.php
@@ -0,0 +1,2 @@
+<?php
+header("Location: https://git.equestria.dev/equestria.dev/bits-server"); \ No newline at end of file