aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMinteck <nekostarfan@gmail.com>2021-08-08 18:27:46 +0200
committerMinteck <nekostarfan@gmail.com>2021-08-08 18:27:46 +0200
commita20dff82a7e2602738f847fa4f1428af3235aafc (patch)
treee607db59fd59561c055a1b68b29d1cf3c6c99d4e
parentc69d44149f544cc80fbe32c26dc4c34266d97bf6 (diff)
downloadmain-a20dff82a7e2602738f847fa4f1428af3235aafc.tar.gz
main-a20dff82a7e2602738f847fa4f1428af3235aafc.tar.bz2
main-a20dff82a7e2602738f847fa4f1428af3235aafc.zip
Updating... the update... that updates
-rw-r--r--.gitignore3
-rw-r--r--.idea/workspace.xml36
-rw-r--r--README.md5
-rw-r--r--about/index.php42
-rw-r--r--admin/.htpasswd1
-rw-r--r--admin/api/getIpLocation.php38
-rw-r--r--admin/index.php11
-rw-r--r--admin/panes/audit.php226
-rw-r--r--admin/panes/shortens.php41
-rw-r--r--admin/private/ipcache.json1
-rw-r--r--contact/index.php1
-rw-r--r--includes/header.php5
-rw-r--r--static/admin/audit.svg11
-rw-r--r--static/admin/locked.svg11
-rw-r--r--static/admin/shortens.svg4
-rw-r--r--version.txt2
16 files changed, 370 insertions, 68 deletions
diff --git a/.gitignore b/.gitignore
index fd22534..bb83a7f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,4 +4,5 @@ archive/get
admin/private/app.json
includes/telemetry.json
includes/blog/data
-admin/private/tokens \ No newline at end of file
+admin/private/tokens
+admin/private/ipcache.json \ No newline at end of file
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 296a9ca..dfd8e4d 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -2,20 +2,21 @@
<project version="4">
<component name="ChangeListManager">
<list default="true" id="efd4dd1a-d09c-4a08-b9ea-ac28a5f96210" name="Default Changelist" comment="">
+ <change afterPath="$PROJECT_DIR$/admin/api/getIpLocation.php" afterDir="false" />
+ <change afterPath="$PROJECT_DIR$/admin/panes/audit.php" afterDir="false" />
+ <change afterPath="$PROJECT_DIR$/admin/panes/shortens.php" afterDir="false" />
+ <change afterPath="$PROJECT_DIR$/admin/private/ipcache.json" afterDir="false" />
+ <change afterPath="$PROJECT_DIR$/static/admin/audit.svg" afterDir="false" />
+ <change afterPath="$PROJECT_DIR$/static/admin/locked.svg" afterDir="false" />
+ <change afterPath="$PROJECT_DIR$/static/admin/shortens.svg" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.gitignore" beforeDir="false" afterPath="$PROJECT_DIR$/.gitignore" afterDir="false" />
- <change beforePath="$PROJECT_DIR$/admin/private/tokens/092748b16bc37807a0ddcb9a3061818fe57bf621f9d92d3b99cea22913483b26" beforeDir="false" />
- <change beforePath="$PROJECT_DIR$/admin/private/tokens/0ef3e11aa75cdcbbf764fd08858141827090ac8f21236ce7b9e51ca1883e549f" beforeDir="false" />
- <change beforePath="$PROJECT_DIR$/admin/private/tokens/1acd958a4ae7af3dbba3b3f5c82f6a4692addd25e1391a67744991666825657c" beforeDir="false" />
- <change beforePath="$PROJECT_DIR$/admin/private/tokens/4932a554ff2b4b5144e8105f8b6034ebc1b3435113bbe250241c8f9b99e1bb73" beforeDir="false" />
- <change beforePath="$PROJECT_DIR$/admin/private/tokens/54b725f6df47930897151c6ac40dfaa17a889d22ce0e5096d0f2fb13e7bea4cb" beforeDir="false" />
- <change beforePath="$PROJECT_DIR$/admin/private/tokens/624d84a92ba3cc4861b0885b5fcf2dc2a69bb8618f527804aa43cfdf25c4f218" beforeDir="false" />
- <change beforePath="$PROJECT_DIR$/admin/private/tokens/6594c1e8fecccb12d4807b20afc6550219d61a28079f379a4a39d199b9b78e35" beforeDir="false" />
- <change beforePath="$PROJECT_DIR$/admin/private/tokens/875869103da9b9e46cc6165cb51bafceb4df669ad07cda025173511886303951" beforeDir="false" />
- <change beforePath="$PROJECT_DIR$/admin/private/tokens/b4fe5fa51384d94213728bd5f68a9524b494105609002b5c7c095c968857fbf6" beforeDir="false" />
- <change beforePath="$PROJECT_DIR$/admin/private/tokens/bbc64f86da832df652c4f2c9e61c11ddee1a94d29f4397954c89efb8c584e082" beforeDir="false" />
- <change beforePath="$PROJECT_DIR$/admin/private/tokens/c9a9ea0efba6ff1c8e28882db1bbf0c7bb73e35740a42304d40c0a98fc18fe23" beforeDir="false" />
- <change beforePath="$PROJECT_DIR$/admin/private/tokens/cfd37ab50076706e20d0f4a19673fd93c957e4c18942e21f983e261ffd05f47c" beforeDir="false" />
- <change beforePath="$PROJECT_DIR$/admin/private/tokens/d53be3c6c4128f456d0d59a5071b9a3f3ed5a0845f7e52d677f5730851cc8919" beforeDir="false" />
+ <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/README.md" beforeDir="false" afterPath="$PROJECT_DIR$/README.md" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/about/index.php" beforeDir="false" afterPath="$PROJECT_DIR$/about/index.php" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/admin/index.php" beforeDir="false" afterPath="$PROJECT_DIR$/admin/index.php" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/contact/index.php" beforeDir="false" afterPath="$PROJECT_DIR$/contact/index.php" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/includes/header.php" beforeDir="false" afterPath="$PROJECT_DIR$/includes/header.php" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/version.txt" beforeDir="false" afterPath="$PROJECT_DIR$/version.txt" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
@@ -66,7 +67,7 @@
<property name="WebServerToolWindowPanel.toolwindow.show.permissions" value="false" />
<property name="WebServerToolWindowPanel.toolwindow.show.size" value="false" />
<property name="add_unversioned_files" value="$PROJECT_DIR$/admin/private/header.php&#10;D:/Projets/Minteck.ro.lt/admin/private/footer.php" />
- <property name="last_opened_file_path" value="$PROJECT_DIR$/includes/blog/data" />
+ <property name="last_opened_file_path" value="$PROJECT_DIR$/admin/panes" />
<property name="list.type.of.created.stylesheet" value="CSS" />
<property name="nodejs_package_manager_path" value="npm" />
<property name="settings.editor.selected.configurable" value="reference.settings.deploy.options" />
@@ -74,11 +75,11 @@
</component>
<component name="RecentsManager">
<key name="CopyFile.RECENT_KEYS">
+ <recent name="$PROJECT_DIR$/admin/panes" />
+ <recent name="$PROJECT_DIR$/admin/api" />
<recent name="$PROJECT_DIR$/includes/blog/data" />
<recent name="$PROJECT_DIR$/includes" />
<recent name="$PROJECT_DIR$/admin/NeutronManage" />
- <recent name="$PROJECT_DIR$/admin/panes" />
- <recent name="$PROJECT_DIR$/admin/api" />
</key>
<key name="MoveFile.RECENT_KEYS">
<recent name="D:\Projets\Minteck.ro.lt\admin\panes" />
@@ -153,7 +154,8 @@
<workItem from="1628105268614" duration="609000" />
<workItem from="1628335662043" duration="2109000" />
<workItem from="1628417033420" duration="2437000" />
- <workItem from="1628420373945" duration="251000" />
+ <workItem from="1628420373945" duration="287000" />
+ <workItem from="1628426128888" duration="10094000" />
</task>
<servers />
</component>
diff --git a/README.md b/README.md
index 11cd6de..f9498bd 100644
--- a/README.md
+++ b/README.md
@@ -17,6 +17,11 @@ www-data ALL=(ALL:ALL) NOPASSWD: /usr/bin/lshw
(replacing `www-data` by the name of the user that runs your Web server)
+### Groups
+Add your server user (usually `www-data`) to the following groups:
+* `syslog` (required to write /var/log)
+* `adm` (required to read /var/log)
+
### Dependencies
Install the following packages:
* `lm-sensors`
diff --git a/about/index.php b/about/index.php
index adbd01c..07cbb33 100644
--- a/about/index.php
+++ b/about/index.php
@@ -309,48 +309,6 @@ ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCsQFXfZUN/jlEk0SaJ7RO/68JuLrVPA3lxkRWkmsMm
</div>
</details>
</li>
- <li>
- <details>
- <summary><?= l("E-mail PGP public key", "Clé PGP publique pour les e-mail") ?></summary>
- <p><b>minteckthefurry@protonmail.com</b> (<?= l("also see: <a href='/contact'>Contact me</a>", "voir aussi : <a href='/contact'>Me contacter</a>") ?>)<?= l("", " ") ?>:</p>
- <div class="code">
- -----BEGIN PGP PUBLIC KEY BLOCK-----<br>
- Version: OpenPGP.js v4.10.10<br>
- Comment: https://openpgpjs.org<br>
- <br>
- xsBNBGCEgK8BCACw8ujCuOUUS5N+d+sNhxXWNeEN6vXKfE6z9Chm5SEhEwxm<br>
- lJ4FfZdOEAXqmehHGGWx9MQ33rD1/4vnRwgyWs97BoTp6ndJPRUK3C4/6mlr<br>
- wbOmAOHgE6p0svdZKrHpE6Ps0o2O63PbxjB7zu94yW0yuLkdUYGbnHy6aVqt<br>
- 9OkSN2Oo1O5JV6OSNCR6OqMuydeHQ3lKfy9EdxQGOzkycQWfeBvCPvFW1Jq8<br>
- inKqyzqKTVUcj3OUVPMagwtv0EyA1XDvq1XNNX+nbUYZtJzyRS3PhD090tLT<br>
- Qk7b0w4ix3Uf/Ttju4Vu5MRlew5eIj8XvQrQTr4hDpuJCJ1zCALXMixzABEB<br>
- AAHNP21pbnRlY2t0aGVmdXJyeUBwcm90b25tYWlsLmNvbSA8bWludGVja3Ro<br>
- ZWZ1cnJ5QHByb3Rvbm1haWwuY29tPsLAjQQQAQgAIAUCYISArwYLCQcIAwIE<br>
- FQgKAgQWAgEAAhkBAhsDAh4BACEJEN3C/JeTXMwxFiEEI3rcbvZVUrPszPjM<br>
- 3cL8l5NczDFrXQf7BvUWgj5lxSx6Webzfs6N3h0DvbV8BLopYI/7T2ih+Rmd<br>
- ptABrBr2S0xAqY3/G5feacKiHsVQEF1B8yDIDurdg08Uo3io/oJutl0V1RIJ<br>
- bmw1QBq38W+K9WDdy099GNGM6sl+26YK8KPRBpXPemHE3r6cWAMgHKux7pIy<br>
- RoPSrKthB6CFhgLfEhObs3/1SBwRpVPV1OnNbT4bZcESbQ21fHS+kYFlmUuP<br>
- DTuW2N5UWP6OItOl6znHAV5Ydns3Sw1XwaOVfno2oBL4apgDyoG/7G9qeBqv<br>
- M3azfw3pazaHqMthfnO9+Kujv0wIi1njg1i+vJZnsWdBMGBpRPS6TaW9ds7A<br>
- TQRghICvAQgApoOuOyZuoX3Y5Ue7bL+76olL7cbqzzKxKw0xQo9Pnj/ggYl8<br>
- Y0unL22/yB6mCe2nep/OEYkS/YT5pDCykvW8HhNQKZjp1qoQbGUUw8hWzXjv<br>
- VTtmnvTtp7TzrHDG3uydsRpCHYaO8EqTpwYF318vMyExEYReyQuXHdWuor/Q<br>
- 7WRMGcjGOITS1h+b9TcRnpJoT1eyVWthouQchxOFqUDBnvR956EJ4qstzbv4<br>
- eDD7BWfBcC6xperKOjGnZB92mXsiCgjIBCqNeGyN8DxNlPqFf5UvMuo60Ojj<br>
- lpFytHBCoPlWwxhNsp6ZcQBONajgxBTQ0mFsZ9XLYhMLF/379s9dMwARAQAB<br>
- wsB2BBgBCAAJBQJghICvAhsMACEJEN3C/JeTXMwxFiEEI3rcbvZVUrPszPjM<br>
- 3cL8l5NczDE0xAf/brnaLn7qxRV9KzQL+mYMAGG2Y8Psy0/lVRbWAQ02V4tG<br>
- CLSVM+duj8Z2cH4ss3kduvvBUNpgtfWyabdhoujwCpJGPCNSa+zm7OELmGXB<br>
- bJLEEFBC6Efp+I7V7YxgITCoCSrOPY1L9DjBX3ejz2wT8GfTqVTgVbmSdWvl<br>
- vDfHrFJcAGbetP0fflNyHE1fP4zOnf/T6+BQK5ic+eV3XnnNnf2KY223UDnY<br>
- SWFSQPRF7OlPfeQ2Mcdirh+n2u1tduzOsJLTtqdTgISarOsbTbErjseVEVZP<br>
- TnjqpWrhRwBneTHBpnNJCjMNXZWp417vAg7/bCvtjYgZ1Sdx7KWYNOg7BQ==<br>
- =m9eo<br>
- -----END PGP PUBLIC KEY BLOCK-----
- </div>
- </details>
- </li>
</ul>
<h2><?= l("Website credits", "Crédits du site") ?></h2>
diff --git a/admin/.htpasswd b/admin/.htpasswd
deleted file mode 100644
index b678dd2..0000000
--- a/admin/.htpasswd
+++ /dev/null
@@ -1 +0,0 @@
-test:$apr1$aD1qs9Kn$f1A2MaHyqhBNODYMQC7l91
diff --git a/admin/api/getIpLocation.php b/admin/api/getIpLocation.php
new file mode 100644
index 0000000..fe34438
--- /dev/null
+++ b/admin/api/getIpLocation.php
@@ -0,0 +1,38 @@
+<?php
+
+require_once $_SERVER['DOCUMENT_ROOT'] . "/admin/private/header.api.php";
+
+if (isset($_GET['_']) && strpos($_GET['_'], "/") === false) {
+ $arg = $_GET['_'];
+} else {
+ die();
+}
+
+if (!file_exists($_SERVER['DOCUMENT_ROOT'] . "/admin/private/ipcache.json")) {
+ file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/admin/private/ipcache.json", "[]");
+}
+
+$ipCache = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/admin/private/ipcache.json"), true);
+
+$data = null;
+foreach ($ipCache as $ip => $item) {
+ if ($ip === $_GET['_']) {
+ $data = $item;
+ }
+}
+
+if ($data === null) {
+ $data = unserialize(file_get_contents('http://www.geoplugin.net/php.gp?ip=' . $arg));
+ $ipCache[$_GET['_']] = $data;
+ file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/admin/private/ipcache.json", json_encode($ipCache));
+}
+
+if ($data["geoplugin_status"] === 404) {
+ die("<span class='text-muted'>Local IP address</span>");
+} else {
+ if ($data["geoplugin_inEU"]) {
+ die($data["geoplugin_countryName"] . " <span class='badge text-light border-light' style='border:1px solid;vertical-align: middle;'>EU</span>");
+ } else {
+ die($data["geoplugin_countryName"]);
+ }
+} \ No newline at end of file
diff --git a/admin/index.php b/admin/index.php
index a7b4ced..0473560 100644
--- a/admin/index.php
+++ b/admin/index.php
@@ -155,6 +155,11 @@
<span class="item-text">Files</span>
<img alt="" src="/static/reload.png" class="reloadbtn">
</div>
+ <div class="item" id="activity-audit">
+ <img src="/static/admin/audit.svg" class="item-icon" alt="">
+ <span class="item-text">Security Audit</span>
+ <img alt="" src="/static/reload.png" class="reloadbtn">
+ </div>
<div class="item" id="activity-hardware">
<img src="/static/admin/hardware.svg" class="item-icon" alt="">
<span class="item-text">Hardware</span>
@@ -189,6 +194,10 @@
<img src="/static/admin/telemetry.svg" class="item-icon" alt="">
<span class="item-text">Telemetry</span>
<img alt="" src="/static/reload.png" class="reloadbtn">
+ </div><div class="item" id="activity-shortens">
+ <img src="/static/admin/shortens.svg" class="item-icon" alt="">
+ <span class="item-text">Shortened URLs</span>
+ <img alt="" src="/static/reload.png" class="reloadbtn">
</div>
<div class="item" id="activity-code">
<img src="/static/admin/code.svg" class="item-icon" alt="">
@@ -237,7 +246,9 @@
document.getElementById("activity-hardware").addEventListener("click", (event) => { activity(event.target.id, "/admin/panes/hardware.php", event.target); }, true)
document.getElementById("activity-disk").addEventListener("click", (event) => { activity(event.target.id, "/admin/panes/disk.php", event.target); }, true)
document.getElementById("activity-uptime").addEventListener("click", (event) => { activity(event.target.id, "/admin/panes/uptime.php", event.target); }, true)
+ document.getElementById("activity-audit").addEventListener("click", (event) => { activity(event.target.id, "/admin/panes/audit.php", event.target); }, true)
document.getElementById("activity-version").addEventListener("click", (event) => { activity(event.target.id, "/admin/panes/version.php", event.target); }, true)
+ document.getElementById("activity-shortens").addEventListener("click", (event) => { activity(event.target.id, "/admin/panes/shortens.php", event.target); }, true)
document.getElementById("activity-kartik").addEventListener("click", (event) => { activity(event.target.id, "/admin/panes/kartik.php", event.target); }, true)
document.getElementById("activity-code").addEventListener("click", (event) => { activity(event.target.id, "/admin/panes/code.php", event.target); }, true)
document.getElementById("activity-quotas").addEventListener("click", (event) => { activity(event.target.id, "/admin/panes/quotas.php", event.target); }, true)
diff --git a/admin/panes/audit.php b/admin/panes/audit.php
new file mode 100644
index 0000000..c2a8609
--- /dev/null
+++ b/admin/panes/audit.php
@@ -0,0 +1,226 @@
+<?php require_once $_SERVER['DOCUMENT_ROOT'] . "/admin/private/header.php";/** @var array $_DATA */ ?>
+
+<style>
+ ::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ ::-webkit-scrollbar-track {
+ border-radius: 9999px;
+ background: transparent;
+ }
+
+ ::-webkit-scrollbar-thumb {
+ border-radius: 9999px;
+ background-color: rgba(136, 136, 136, 0.5);
+ transition: background 200ms;
+ }
+
+ ::-webkit-scrollbar-thumb:hover {
+ background-color: rgba(85, 85, 85, 0.75);
+ }
+
+ ::-webkit-scrollbar-thumb:active {
+ background-color: #222;
+ }
+
+ .list-group-item {
+ background: #34373c;
+ }
+
+ table, table * {
+ color: white !important;
+ border-color: #292b2f !important;
+ }
+
+ th {
+ border-top: 0 !important;
+ }
+
+ table a {
+ color: #007bff !important;
+ }
+
+ td.users {
+ width: 20vw;
+ }
+
+ .addr-location {
+ width: 20vw;
+ }
+</style>
+
+<div class="container" style="color:white;padding-top:15vh;padding-bottom:15vh;">
+ <h2 style="text-align:center;">Security Audit</h2>
+ <table class="table table-hover">
+ <thead>
+ <tr>
+ <th>IP address</th>
+ <th>Connections</th>
+ <th>Username(s)</th>
+ <th>Actions</th>
+ </tr>
+ </thead>
+ <tbody><?php
+
+ $ips = [];
+ $data = "";
+ $dir = scandir("/var/log");
+
+ $dir = array_reverse($dir);
+
+ foreach ($dir as $file) {
+ if ($file !== "." && $file !== "..") {
+ if (substr($file, 0, 5) === "auth.") {
+ if (substr($file, -3) === ".gz") {
+ exec("gzip --decompress /var/log/" . $file);
+ $raw = file_get_contents("/var/log/" . substr($file, 0, -3));
+ } else {
+ $raw = file_get_contents("/var/log/" . $file);
+ }
+
+ $data .= "\n" . $raw;
+ }
+ }
+ }
+
+ $lines = explode("\n", strip_tags($data));
+ $lines = array_reverse($lines);
+
+ foreach ($lines as $line) {
+ if (trim($line) !== "" && strpos($line, "sshd") !== false && strpos($line, "error: kex_exchange_identification: Connection closed by remote host") === false && (strpos($line, "]: Connection closed by invalid user ") !== false || strpos($line, "]: Unable to negotiate with ") !== false || strpos($line, "]: Accepted publickey for ") !== false)) {
+ $data = [];
+
+ $parts = explode(": ", $line);
+
+ $data["date"] = $parts[0];
+ array_shift($parts);
+ $data["message"] = implode(": ", $parts);
+
+
+ if (substr($data["message"], 0, 23) === "Accepted publickey for ") { // Successful connection
+ $data["status"] = "ok";
+ $data["ip"] = explode(" ", $data["message"])[5];
+ $data["user"] = explode(" ", $data["message"])[3];
+ }
+
+ if (substr($data["message"], 0, 25) === "Unable to negotiate with ") { // Errored connection
+ $data["status"] = "error";
+ $data["ip"] = explode(" ", $data["message"])[4];
+ $data["user"] = null;
+ }
+
+ if (substr($data["message"], 0, 34) === "Connection closed by invalid user ") { // Invalid connection
+ $data["status"] = "invalid";
+ $data["ip"] = explode(" ", $data["message"])[count(explode(" ", $data["message"])) - 4];
+ $data["user"] = explode(" ", $data["message"])[5];
+ }
+
+ if (!isset($ips[$data["ip"]])) {
+ $ips[$data["ip"]] = [];
+ }
+ if (!isset($ips[$data["ip"]]["connections"])) {
+ $ips[$data["ip"]]["connections"] = [];
+ }
+ $ips[$data["ip"]]["connections"][] = $data;
+ }
+ }
+
+ $index = 1;
+ foreach ($ips as $ip => $info) {
+ if ($ip !== "port") {
+ echo("<tr>
+ <td class='addr-location'><code>" . $ip . "</code><br><span id='iplocation-" . $ip . "'><span class='text-muted'>Please wait...</span></span>");?>
+ <!--suppress JSUnresolvedVariable -->
+ <script>
+
+ setTimeout(() => {
+ document.getElementById("iplocation-<?= $ip ?>").innerHTML = $.ajax({
+ type: "GET",
+ url: "/admin/api/getIpLocation.php?_=<?= $ip ?>",
+ async: false
+ }).responseText;
+ }, <?= $index ?> * 1000);
+
+ </script>
+ <?php
+ if ($ip === $_SERVER['REMOTE_ADDR']) {
+ echo(" <span class='badge text-primary border-primary' style='border:1px solid;vertical-align: middle;'>You</span>");
+ }
+ echo("</td>
+ <td>");
+
+ $success = 0;
+ $invalid = 0;
+ $failed = 0;
+
+ foreach ($info["connections"] as $connection) {
+ if ($connection["status"] === "invalid") {
+ $invalid++;
+ }
+ if ($connection["status"] === "error") {
+ $failed++;
+ }
+ if ($connection["status"] === "ok") {
+ $success++;
+ }
+ }
+ if (count($info["connections"]) === 0) {
+ echo("<span class='text-muted'>Never connected</span>");
+ } else {
+ echo($success . " succeeded, " . $failed . " failed, " . $invalid . " invalid");
+ }
+
+ echo("<br>Last: ");
+
+ if ($info["connections"][0]["status"] === "ok") {
+ echo("<span class='badge text-success border-success' style='border:1px solid;vertical-align: middle;'>Succeeded</span>");
+ }
+
+ if ($info["connections"][0]["status"] === "error") {
+ echo("<span class='badge text-warning border-warning' style='border:1px solid;vertical-align: middle;'>Failed</span>");
+ }
+
+ if ($info["connections"][0]["status"] === "invalid") {
+ echo("<span class='badge text-danger border-danger' style='border:1px solid;vertical-align: middle;'>Invalid</span>");
+ }
+
+ echo("</td>
+ <td class='users'><details><summary>Show full list</summary><ul class='list-group'>");
+
+ $uniqueUsers = [];
+ $connectionsWithUsers = 0;
+
+ foreach ($info["connections"] as $connection) {
+ if (!in_array($connection["user"], $uniqueUsers) && $connection["user"] !== null) {
+ if (isset($uniqueUsers[$connection["user"]])) {
+ $uniqueUsers[$connection["user"]]++;
+ $connectionsWithUsers++;
+ } else {
+ $uniqueUsers[$connection["user"]] = 1;
+ $connectionsWithUsers++;
+ }
+ }
+ }
+
+ foreach ($uniqueUsers as $user => $occurrences) {
+ echo("<li class='list-group-item'><code>" . $user . "</code> <span style='float:right;'>(" . $occurrences . "×, " . round(($occurrences/$connectionsWithUsers)*100, 2) . "%)</span></li>");
+ }
+
+ if (count($uniqueUsers) === 0) {
+ echo("<li class='list-group-item text-muted'>Username was never sent to server</li>");
+ }
+
+ echo("</ul></details></td></td>
+ <td><a href='#'>Details</a> · <a href='https://cleantalk.org/blacklists/report-ip' target='_blank'>Report</a></td>
+ </tr>");
+
+ $index++;
+ }
+ }
+
+ ?></tbody>
+ </table>
+</div>
+
+<?php require_once $_SERVER['DOCUMENT_ROOT'] . "/admin/private/footer.php"; ?> \ No newline at end of file
diff --git a/admin/panes/shortens.php b/admin/panes/shortens.php
new file mode 100644
index 0000000..51afcbb
--- /dev/null
+++ b/admin/panes/shortens.php
@@ -0,0 +1,41 @@
+<?php require_once $_SERVER['DOCUMENT_ROOT'] . "/admin/private/header.php";/** @var array $_DATA */ ?>
+
+<style>
+ ::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ ::-webkit-scrollbar-track {
+ border-radius: 9999px;
+ background: transparent;
+ }
+
+ ::-webkit-scrollbar-thumb {
+ border-radius: 9999px;
+ background-color: rgba(136, 136, 136, 0.5);
+ transition: background 200ms;
+ }
+
+ ::-webkit-scrollbar-thumb:hover {
+ background-color: rgba(85, 85, 85, 0.75);
+ }
+
+ ::-webkit-scrollbar-thumb:active {
+ background-color: #222;
+ }
+
+ .list-group-item {
+ background: #34373c;
+ }
+</style>
+
+<div class="container" style="color:white;padding-top:15vh;padding-bottom:15vh;">
+ <h2 style="text-align:center;">Shortened URLs</h2>
+
+ <ul class="list-group" style="margin-top:20px;">
+ <li class="list-group-item">English (primary) <span style="float:right;"><a href="/admin/panes/editor.php?file=conduct.en&name=Code%20of%20Conduct%20-%20English&context=code">Edit</a> · <a href="/code-of-conduct/?en" target="_blank">View</a></span></li>
+ <li class="list-group-item">French <span style="float:right;"><a href="/admin/panes/editor.php?file=conduct.fr&name=Code%20of%20Conduct%20-%20French&context=code">Edit</a> · <a href="/code-of-conduct/?fr" target="_blank">View</a></span></li>
+ </ul>
+</div>
+
+<?php require_once $_SERVER['DOCUMENT_ROOT'] . "/admin/private/footer.php"; ?> \ No newline at end of file
diff --git a/admin/private/ipcache.json b/admin/private/ipcache.json
new file mode 100644
index 0000000..028bb8d
--- /dev/null
+++ b/admin/private/ipcache.json
@@ -0,0 +1 @@
+{"127.0.0.1":{"geoplugin_request":"127.0.0.1","geoplugin_status":404,"geoplugin_delay":"1ms","geoplugin_credit":"Some of the returned data includes GeoLite data created by MaxMind, available from <a href=\\'http:\/\/www.maxmind.com\\'>http:\/\/www.maxmind.com<\/a>.","geoplugin_city":null,"geoplugin_region":null,"geoplugin_regionCode":null,"geoplugin_regionName":null,"geoplugin_areaCode":null,"geoplugin_dmaCode":null,"geoplugin_countryCode":null,"geoplugin_countryName":null,"geoplugin_inEU":0,"geoplugin_euVATrate":false,"geoplugin_continentCode":null,"geoplugin_continentName":null,"geoplugin_latitude":null,"geoplugin_longitude":null,"geoplugin_locationAccuracyRadius":null,"geoplugin_timezone":null,"geoplugin_currencyCode":null,"geoplugin_currencySymbol":null,"geoplugin_currencySymbol_UTF8":"","geoplugin_currencyConverter":"0"},"92.152.77.195":{"geoplugin_request":"92.152.77.195","geoplugin_status":200,"geoplugin_delay":"1ms","geoplugin_credit":"Some of the returned data includes GeoLite data created by MaxMind, available from <a href=\\'http:\/\/www.maxmind.com\\'>http:\/\/www.maxmind.com<\/a>.","geoplugin_city":"Orl\u00e9ans","geoplugin_region":"Centre-Val de Loire","geoplugin_regionCode":"45","geoplugin_regionName":"Loiret","geoplugin_areaCode":"","geoplugin_dmaCode":"","geoplugin_countryCode":"FR","geoplugin_countryName":"France","geoplugin_inEU":1,"geoplugin_euVATrate":20,"geoplugin_continentCode":"EU","geoplugin_continentName":"Europe","geoplugin_latitude":"47.9047","geoplugin_longitude":"1.9076","geoplugin_locationAccuracyRadius":"5","geoplugin_timezone":"Europe\/Paris","geoplugin_currencyCode":"EUR","geoplugin_currencySymbol":"&#8364;","geoplugin_currencySymbol_UTF8":"\u20ac","geoplugin_currencyConverter":"0.8501"},"190.2.132.224":{"geoplugin_request":"190.2.132.224","geoplugin_status":200,"geoplugin_delay":"1ms","geoplugin_credit":"Some of the returned data includes GeoLite data created by MaxMind, available from <a href=\\'http:\/\/www.maxmind.com\\'>http:\/\/www.maxmind.com<\/a>.","geoplugin_city":"Naaldwijk","geoplugin_region":"South Holland","geoplugin_regionCode":"ZH","geoplugin_regionName":"South Holland","geoplugin_areaCode":"","geoplugin_dmaCode":"","geoplugin_countryCode":"NL","geoplugin_countryName":"Netherlands","geoplugin_inEU":1,"geoplugin_euVATrate":21,"geoplugin_continentCode":"EU","geoplugin_continentName":"Europe","geoplugin_latitude":"51.9934","geoplugin_longitude":"4.2158","geoplugin_locationAccuracyRadius":"1000","geoplugin_timezone":"Europe\/Amsterdam","geoplugin_currencyCode":"EUR","geoplugin_currencySymbol":"&#8364;","geoplugin_currencySymbol_UTF8":"\u20ac","geoplugin_currencyConverter":"0.8501"},"86.196.89.109":{"geoplugin_request":"86.196.89.109","geoplugin_status":200,"geoplugin_delay":"2ms","geoplugin_credit":"Some of the returned data includes GeoLite data created by MaxMind, available from <a href=\\'http:\/\/www.maxmind.com\\'>http:\/\/www.maxmind.com<\/a>.","geoplugin_city":"Orl\u00e9ans","geoplugin_region":"Centre-Val de Loire","geoplugin_regionCode":"45","geoplugin_regionName":"Loiret","geoplugin_areaCode":"","geoplugin_dmaCode":"","geoplugin_countryCode":"FR","geoplugin_countryName":"France","geoplugin_inEU":1,"geoplugin_euVATrate":20,"geoplugin_continentCode":"EU","geoplugin_continentName":"Europe","geoplugin_latitude":"47.9047","geoplugin_longitude":"1.9076","geoplugin_locationAccuracyRadius":"10","geoplugin_timezone":"Europe\/Paris","geoplugin_currencyCode":"EUR","geoplugin_currencySymbol":"&#8364;","geoplugin_currencySymbol_UTF8":"\u20ac","geoplugin_currencyConverter":"0.8501"},"141.98.10.27":{"geoplugin_request":"141.98.10.27","geoplugin_status":206,"geoplugin_delay":"0ms","geoplugin_credit":"Some of the returned data includes GeoLite data created by MaxMind, available from <a href=\\'http:\/\/www.maxmind.com\\'>http:\/\/www.maxmind.com<\/a>.","geoplugin_city":"","geoplugin_region":"","geoplugin_regionCode":"","geoplugin_regionName":"","geoplugin_areaCode":"","geoplugin_dmaCode":"","geoplugin_countryCode":"LT","geoplugin_countryName":"Lithuania","geoplugin_inEU":1,"geoplugin_euVATrate":21,"geoplugin_continentCode":"EU","geoplugin_continentName":"Europe","geoplugin_latitude":"56","geoplugin_longitude":"24","geoplugin_locationAccuracyRadius":"200","geoplugin_timezone":"Europe\/Vilnius","geoplugin_currencyCode":"EUR","geoplugin_currencySymbol":"&#8364;","geoplugin_currencySymbol_UTF8":"\u20ac","geoplugin_currencyConverter":"0.8501"},"82.65.121.132":{"geoplugin_request":"82.65.121.132","geoplugin_status":200,"geoplugin_delay":"2ms","geoplugin_credit":"Some of the returned data includes GeoLite data created by MaxMind, available from <a href=\\'http:\/\/www.maxmind.com\\'>http:\/\/www.maxmind.com<\/a>.","geoplugin_city":"Paris","geoplugin_region":"\u00cele-de-France","geoplugin_regionCode":"75","geoplugin_regionName":"Paris","geoplugin_areaCode":"","geoplugin_dmaCode":"","geoplugin_countryCode":"FR","geoplugin_countryName":"France","geoplugin_inEU":1,"geoplugin_euVATrate":20,"geoplugin_continentCode":"EU","geoplugin_continentName":"Europe","geoplugin_latitude":"48.8579","geoplugin_longitude":"2.3491","geoplugin_locationAccuracyRadius":"200","geoplugin_timezone":"Europe\/Paris","geoplugin_currencyCode":"EUR","geoplugin_currencySymbol":"&#8364;","geoplugin_currencySymbol_UTF8":"\u20ac","geoplugin_currencyConverter":"0.8501"},"209.141.47.35":{"geoplugin_request":"209.141.47.35","geoplugin_status":200,"geoplugin_delay":"1ms","geoplugin_credit":"Some of the returned data includes GeoLite data created by MaxMind, available from <a href=\\'http:\/\/www.maxmind.com\\'>http:\/\/www.maxmind.com<\/a>.","geoplugin_city":"Las Vegas","geoplugin_region":"Nevada","geoplugin_regionCode":"NV","geoplugin_regionName":"Nevada","geoplugin_areaCode":"","geoplugin_dmaCode":"839","geoplugin_countryCode":"US","geoplugin_countryName":"United States","geoplugin_inEU":0,"geoplugin_euVATrate":false,"geoplugin_continentCode":"NA","geoplugin_continentName":"North America","geoplugin_latitude":"36.1685","geoplugin_longitude":"-115.1164","geoplugin_locationAccuracyRadius":"1000","geoplugin_timezone":"America\/Los_Angeles","geoplugin_currencyCode":"USD","geoplugin_currencySymbol":"&#36;","geoplugin_currencySymbol_UTF8":"$","geoplugin_currencyConverter":"1"},"125.160.65.57":{"geoplugin_request":"125.160.65.57","geoplugin_status":200,"geoplugin_delay":"2ms","geoplugin_credit":"Some of the returned data includes GeoLite data created by MaxMind, available from <a href=\\'http:\/\/www.maxmind.com\\'>http:\/\/www.maxmind.com<\/a>.","geoplugin_city":"Balikpapan","geoplugin_region":"East Kalimantan","geoplugin_regionCode":"KI","geoplugin_regionName":"East Kalimantan","geoplugin_areaCode":"","geoplugin_dmaCode":"","geoplugin_countryCode":"ID","geoplugin_countryName":"Indonesia","geoplugin_inEU":0,"geoplugin_euVATrate":false,"geoplugin_continentCode":"AS","geoplugin_continentName":"Asia","geoplugin_latitude":"-1.2551","geoplugin_longitude":"116.8428","geoplugin_locationAccuracyRadius":"100","geoplugin_timezone":"Asia\/Makassar","geoplugin_currencyCode":"IDR","geoplugin_currencySymbol":"&#82;&#112;","geoplugin_currencySymbol_UTF8":"Rp","geoplugin_currencyConverter":"14444.5"},"37.239.53.5":{"geoplugin_request":"37.239.53.5","geoplugin_status":206,"geoplugin_delay":"1ms","geoplugin_credit":"Some of the returned data includes GeoLite data created by MaxMind, available from <a href=\\'http:\/\/www.maxmind.com\\'>http:\/\/www.maxmind.com<\/a>.","geoplugin_city":"","geoplugin_region":"","geoplugin_regionCode":"","geoplugin_regionName":"","geoplugin_areaCode":"","geoplugin_dmaCode":"","geoplugin_countryCode":"IQ","geoplugin_countryName":"Iraq","geoplugin_inEU":0,"geoplugin_euVATrate":false,"geoplugin_continentCode":"AS","geoplugin_continentName":"Asia","geoplugin_latitude":"33","geoplugin_longitude":"44","geoplugin_locationAccuracyRadius":"50","geoplugin_timezone":"Asia\/Baghdad","geoplugin_currencyCode":"IQD","geoplugin_currencySymbol":"ID","geoplugin_currencySymbol_UTF8":"ID","geoplugin_currencyConverter":"1464.2007"},"188.157.253.48":{"geoplugin_request":"188.157.253.48","geoplugin_status":200,"geoplugin_delay":"2ms","geoplugin_credit":"Some of the returned data includes GeoLite data created by MaxMind, available from <a href=\\'http:\/\/www.maxmind.com\\'>http:\/\/www.maxmind.com<\/a>.","geoplugin_city":"Szigetszentmiklos","geoplugin_region":"Pest megye","geoplugin_regionCode":"PE","geoplugin_regionName":"Pest megye","geoplugin_areaCode":"","geoplugin_dmaCode":"","geoplugin_countryCode":"HU","geoplugin_countryName":"Hungary","geoplugin_inEU":1,"geoplugin_euVATrate":27,"geoplugin_continentCode":"EU","geoplugin_continentName":"Europe","geoplugin_latitude":"47.3485","geoplugin_longitude":"19.0476","geoplugin_locationAccuracyRadius":"5","geoplugin_timezone":"Europe\/Budapest","geoplugin_currencyCode":"HUF","geoplugin_currencySymbol":"&#70;&#116;","geoplugin_currencySymbol_UTF8":"Ft","geoplugin_currencyConverter":"300.8604"}} \ No newline at end of file
diff --git a/contact/index.php b/contact/index.php
index 8e1d91d..b4b36dc 100644
--- a/contact/index.php
+++ b/contact/index.php
@@ -17,7 +17,6 @@
<ul>
<li><b><img alt="" src="/static/contacts/email.png" class="os-logo"> Email</b> — <a href="mailto:nekostarfan@gmail.com" target="_blank">nekostarfan@gmail.com</a></li>
- <li><b><img alt="" src="/static/contacts/email.png" class="os-logo"> Email</b> — <a href="mailto:minteckthefurry@protonmail.com" target="_blank">minteckthefurry@protonmail.com</a> — <?= l("slow to answer, recommended to report security flaws (encrypted)", "long à répondre, recommandé pour signaler des failles de sécurité (chiffré)") ?></li>
<li><b><img alt="" src="/static/contacts/twitter.png" class="os-logo"> Twitter</b> — <a href="https://twitter.com/_Minteck" target="_blank">@_Minteck</a> — DMs open!</li>
<li><b><img alt="" src="/static/contacts/reddit.png" class="os-logo"> Reddit</b> — <a href="https://reddit.com/u/Minteck" target="_blank">u/Minteck</a> — DMs open!</li>
<li><b><img alt="" src="/static/contacts/discord.png" class="os-logo"> Discord</b> — @Minteck#2245 — <?= l("please contact only if we're friends", "merci de me contacter uniquement si nous sommes amis") ?></li>
diff --git a/includes/header.php b/includes/header.php
index 36d0fc1..ab9b33e 100644
--- a/includes/header.php
+++ b/includes/header.php
@@ -1,10 +1,5 @@
<?php
-if ($_SERVER['REMOTE_ADDR'] !== "92.152.77.195") {
- header("Location: https://minteck-projects.alwaysdata.net");
- die();
-}
-
$lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
function l($en, $fr = null) {
diff --git a/static/admin/audit.svg b/static/admin/audit.svg
new file mode 100644
index 0000000..28329a3
--- /dev/null
+++ b/static/admin/audit.svg
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <!-- Generator: Sketch 61.2 (89653) - https://sketch.com -->
+ <title>ic_fluent_lock_shield_24_regular</title>
+ <desc>Created with Sketch.</desc>
+ <g id="🔍-Product-Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+ <g id="ic_fluent_lock_shield_24_regular" fill="#212121" fill-rule="nonzero">
+ <path d="M10,2 C12.209139,2 14,3.790861 14,6 L14,8 L15.75,8 C16.9926407,8 18,9.00735931 18,10.25 L18.0004007,11 C17.6815037,11.0000464 17.3626075,11.1095735 17.1037583,11.3286192 L16.9965667,11.4293133 C16.8328394,11.5997975 16.6677813,11.7518594 16.5008649,11.8859925 L16.5,10.25 C16.5,9.83578644 16.1642136,9.5 15.75,9.5 L4.25,9.5 C3.83578644,9.5 3.5,9.83578644 3.5,10.25 L3.5,19.75 C3.5,20.1642136 3.83578644,20.5 4.25,20.5 L14.138441,20.500838 C14.5460214,21.0773904 15.0606188,21.5790012 15.6783073,22.0004684 L4.25,22 C3.00735931,22 2,20.9926407 2,19.75 L2,10.25 C2,9.00735931 3.00735931,8 4.25,8 L6,8 L6,6 C6,3.790861 7.790861,2 10,2 Z M18.2837159,12.1223125 C19.275757,13.1576093 20.3751344,13.6666667 21.6,13.6666667 C21.7932997,13.6666667 21.9545749,13.8094925 21.9918734,13.9993605 L22,14.0833333 L22,16.5843822 C22,19.2663174 20.6869938,21.0895546 18.1264911,21.978618 C18.0443844,22.0071273 17.9556156,22.0071273 17.8735089,21.978618 C15.3983563,21.1191901 14.0889199,19.3868286 14.0043743,16.8497106 L14,16.5843822 L14,14.0833333 C14,13.8532147 14.1790861,13.6666667 14.4,13.6666667 C15.6233801,13.6666667 16.7233292,13.1575173 17.717822,12.1219826 C17.874143,11.9592104 18.1275699,11.9593581 18.2837159,12.1223125 Z M10.000125,13.5 C10.8285521,13.5 11.500125,14.1715729 11.500125,15 C11.500125,15.8284271 10.8285521,16.5 10.000125,16.5 C9.17169788,16.5 8.500125,15.8284271 8.500125,15 C8.500125,14.1715729 9.17169788,13.5 10.000125,13.5 Z M10,3.5 C8.61928813,3.5 7.5,4.61928813 7.5,6 L7.5,8 L12.5,8 L12.5,6 C12.5,4.61928813 11.3807119,3.5 10,3.5 Z" id="🎨-Color"></path>
+ </g>
+ </g>
+</svg> \ No newline at end of file
diff --git a/static/admin/locked.svg b/static/admin/locked.svg
new file mode 100644
index 0000000..ec23676
--- /dev/null
+++ b/static/admin/locked.svg
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <!-- Generator: Sketch 59.1 (86144) - https://sketch.com -->
+ <title>ic_fluent_lock_24_regular</title>
+ <desc>Created with Sketch.</desc>
+ <g id="🔍-Product-Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+ <g id="ic_fluent_lock_24_regular" fill="#212121" fill-rule="nonzero">
+ <path d="M12,2 C14.209139,2 16,3.790861 16,6 L16,8 L17.75,8 C18.9926407,8 20,9.00735931 20,10.25 L20,19.75 C20,20.9926407 18.9926407,22 17.75,22 L6.25,22 C5.00735931,22 4,20.9926407 4,19.75 L4,10.25 C4,9.00735931 5.00735931,8 6.25,8 L8,8 L8,6 C8,3.790861 9.790861,2 12,2 Z M17.75,9.5 L6.25,9.5 C5.83578644,9.5 5.5,9.83578644 5.5,10.25 L5.5,19.75 C5.5,20.1642136 5.83578644,20.5 6.25,20.5 L17.75,20.5 C18.1642136,20.5 18.5,20.1642136 18.5,19.75 L18.5,10.25 C18.5,9.83578644 18.1642136,9.5 17.75,9.5 Z M12.000125,13.5 C12.8285521,13.5 13.500125,14.1715729 13.500125,15 C13.500125,15.8284271 12.8285521,16.5 12.000125,16.5 C11.1716979,16.5 10.500125,15.8284271 10.500125,15 C10.500125,14.1715729 11.1716979,13.5 12.000125,13.5 Z M12,3.5 C10.6192881,3.5 9.5,4.61928813 9.5,6 L9.5,8 L14.5,8 L14.5,6 C14.5,4.61928813 13.3807119,3.5 12,3.5 Z" id="🎨-Color"></path>
+ </g>
+ </g>
+</svg> \ No newline at end of file
diff --git a/static/admin/shortens.svg b/static/admin/shortens.svg
new file mode 100644
index 0000000..f81f6ef
--- /dev/null
+++ b/static/admin/shortens.svg
@@ -0,0 +1,4 @@
+<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+ <path d="M10.5095 9.5H15.25C15.6642 9.5 16 9.16421 16 8.75C16 8.33579 15.6642 8 15.25 8H8.75C8.33579 8 8 8.33579 8 8.75V15.25C8 15.6642 8.33579 16 8.75 16C9.16421 16 9.5 15.6642 9.5 15.25V10.6114L14.7222 15.783C15.0165 16.0744 15.4914 16.0721 15.7828 15.7778C16.0743 15.4835 16.072 15.0086 15.7777 14.7172L10.5095 9.5Z" fill="#212121"/>
+ <path d="M22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12ZM12 20.5C16.6944 20.5 20.5 16.6944 20.5 12C20.5 7.30558 16.6944 3.5 12 3.5C7.30558 3.5 3.5 7.30558 3.5 12C3.5 16.6944 7.30558 20.5 12 20.5Z" fill="#212121"/>
+</svg>
diff --git a/version.txt b/version.txt
index fa5fce0..da15618 100644
--- a/version.txt
+++ b/version.txt
@@ -1 +1 @@
-8.0.0 \ No newline at end of file
+8.1.0 \ No newline at end of file