Adds support for cloudflare turnstile

This commit is contained in:
2022-12-31 13:33:23 -05:00
parent 877951dd4e
commit d6e2767713
5 changed files with 78 additions and 16 deletions

View File

@@ -1,11 +1,51 @@
<?php
require_once "api.php";
if (array_key_exists("username", $_POST) and array_key_exists("type", $_POST) and array_key_exists("password", $_POST)) { // Used to login or signup and get the cookie
if (array_key_exists("username", $_POST) and array_key_exists("type", $_POST) and array_key_exists("password", $_POST) and array_key_exists("token", $_POST)) { // Used to login or signup and get the cookie
// Selects the correct options for the password hashing
$jsonInfo = file_get_contents($_SERVER["DOCUMENT_ROOT"] . "/config.json");
$jsonInfo = json_decode($jsonInfo, true);
$OPTIONS = $jsonInfo["passwordOptions"];
$USER = $_POST["username"];
$TOKEN = $OGPOST["token"];
// Checks if the captcha was done
$SECRET = $jsonInfo["turnstileSecret"];
if ($SECRET !== "") {
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => "https://challenges.cloudflare.com/turnstile/v0/siteverify",
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
"secret" => $SECRET,
"response" => $TOKEN,
"remoteip" => $address
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
CURLOPT_RETURNTRANSFER => true
]);
$err = curl_error($ch);
// Checks for an error
if ($err) {
echo "Captcha failed.";
http_response_code(400);
exit();
}
$response = curl_exec($ch);
curl_close($ch);
if ($response === false) {
echo "Captcha failed.";
http_response_code(400);
exit();
}
$response = json_decode($response, true);
// Checks if it was a success
if (!array_key_exists("success", $response) or $response["success"] == False) {
echo "Captcha failed.";
http_response_code(400);
exit();
}
}
header("Access-Control-Allow-Origin: *"); // Will allow it from any origin to allow for space 3 to work in any domain
// Will check if the ip address has passed its throttle point
$jsonInfo = file_get_contents($_SERVER["DOCUMENT_ROOT"] . "/config.json");
@@ -34,7 +74,7 @@ if (array_key_exists("username", $_POST) and array_key_exists("type", $_POST) an
$RESULT = dbRequest2("SELECT * FROM users WHERE username='$USER'", "password");
if ($RESULT) {
$RESULT = $RESULT[0];
if (! str_starts_with($RESULT, "$2y$")) { # Checks if it is a plain text password that still needs to get hashed and if it does it gets hashed.
if (!str_starts_with($RESULT, "$2y$")) { # Checks if it is a plain text password that still needs to get hashed and if it does it gets hashed.
$RESULT2 = $RESULT;
$RESULT = password_hash($RESULT, PASSWORD_BCRYPT);
dbEdit("users", [["password", $RESULT]], ["password", $RESULT2], 0);
@@ -47,7 +87,7 @@ if (array_key_exists("username", $_POST) and array_key_exists("type", $_POST) an
writeLog(2, "$USERNAME created by $address");
}
writeLog(0, "$USERNAME was logged in by $address");
$Time = time() + 3600*12;
$Time = time() + 3600 * 12;
$Cookie = $USERNAME;
$Cookie .= rand();
$Cookie = sanitize(substr(sha1($Cookie), 5));
@@ -72,4 +112,4 @@ if (array_key_exists("username", $_POST) and array_key_exists("type", $_POST) an
} else {
http_response_code(400);
echo "Invalid command";
}
}

View File

@@ -1,2 +1,2 @@
#REMOVE LINE 1 WHEN DONE - please fill out all details for the json file as a config and rename to config.json
{ "api": "youtube api key", "database": { "username": "", "name": "", "password": "", "backupLocation": Where the backups should be stored, "backupLength" : how long the backups should be stored }, "developer": true/false Reminder that there should be no quotation marks(This should be a boolean), "throttle":the amount of requests allowed per time period, "throttleTime":The number of seconds allowed for the throttle time period, "fanStart" : Tells the pi when to start the fan, "fanStop": Tells the pi when to stop the fan}
{ "api": "youtube api key", "database": { "username": "", "name": "", "password": "", "backupLocation": Where the backups should be stored, "backupLength" : how long the backups should be stored }, "developer": true/false Reminder that there should be no quotation marks(This should be a boolean), "throttle":the amount of login requests allowed per time period, "throttleTime":The number of seconds allowed for the throttle time period, "fanStart" : Tells the pi when to start the fan, "fanStop": Tells the pi when to stop the fan, "turnstileSecret": A cloudflare turnstile key for login security, "turnstileClient" : A cloudflare turnstile key for login security}

View File

@@ -1,3 +1,16 @@
let turnstile_token = "";
// Used to rended the turnstile
turnstileCb = function () {
if (sitekey !== "") {
turnstile.render('#challenge', {
sitekey,
theme: 'dark',
callback: function(token) {
turnstile_token = token;
},
});
}
};
$(document).ready(function() {
$("#login").button();
$("#login").click(function() { // Used to login/Signup and will redirect to the user menu with a succesful login
@@ -18,6 +31,7 @@ $(document).ready(function() {
location.replace("/usermenu/index.php");
}
} else {
turnstile.reset();
JQerror(ajax.responseText);
}
$("#login").button("enable")
@@ -31,6 +45,6 @@ $(document).ready(function() {
ajax.open("POST", "/api/login.php");
ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
var username = $("#username").val()
ajax.send(`type='${type}'&password='${$("#password").val()}'&username='${username}'`);
ajax.send(`type='${type}'&password='${$("#password").val()}'&username='${username}'&token=${turnstile_token}`);
});
});

View File

@@ -13,14 +13,19 @@
setcookie("user", "", time() - 300);
$USERNAME = Null;
}
$jsonInfo = file_get_contents($_SERVER["DOCUMENT_ROOT"] . "/config.json");
$jsonInfo = json_decode($jsonInfo, true);
$SITEKEY = $jsonInfo["turnstileSitekey"];
echo "<script>const sitekey='$SITEKEY'</script>";
?>
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js?onload=turnstileCb" async defer></script>
</head>
<body>
<?php
include 'include/menu.php';
echo "<div class='main'>
<script type='text/javascript' src='javascript/login.js'></script>";
<script type='text/javascript' src='javascript/login.js' async defer ></script>";
?>
<h1>Login or Signup Here</h1>
<?php
@@ -28,14 +33,15 @@
echo "You have logged out<br><br>";
}
// If logged out a login form will come
echo '<label for="username">Username:</label><br>
<input type="text" id="username" name="username"/><br>
<label for="password">Password:</label><br>
<input type="password" id="password" name="password"/><br>
<input type="checkbox" id="signup" name="signup" value="True">
<label for="signup">Check this to signup</label><br>
<button style="size:50px" id="login">Login/Signup</button>
<p style="color:red" id="status"></p>';
echo "<label for='username'>Username:</label><br>
<input type='text' id='username' name='username'/><br>
<label for='password'>Password:</label><br>
<input type='password' id='password' name='password'/><br>
<input type='checkbox' id='signup' name='signup' value='True'>
<label for='signup'>Check this to signup</label><br>
<div id='challenge'></div>
<button style='size:50px' id='login'>Login/Signup</button>
<p style='color:red' id='status'></p>";
?>
</div>
</body>

View File

@@ -16,7 +16,7 @@ import datetime
import sys
import glob
import string
whitelist = set(string.ascii_letters + string.digits + "/" + "@" + ".")
whitelist = set(string.ascii_letters + string.digits + "/" + "@" + "." + "-" + "_")
try:
import docker
dockerClient = docker.from_env()
@@ -85,6 +85,8 @@ try:
[["fanStop"], int(os.getenv("WEBSITE_FAN_STOP", '35'))],
[["matomoDomain"], os.getenv("MATOMO_DOMAIN", 'example.com')],
[["matomoSiteId"], int(os.getenv("MATOMO_SITE_ID", '1'))],
[["turnstileSecret"], os.getenv("TURNSTILE_SECRET", '')],
[["turnstileSitekey"], os.getenv("TURNSTILE_SITEKEY", '')],
]
if os.path.exists(location + "/config.json"):
configuration = readFile(location + "/config.json")