274 lines
7.7 KiB
PHP
274 lines
7.7 KiB
PHP
<?php
|
|
ini_set('display_errors', 1);
|
|
ini_set('display_startup_errors', 1);
|
|
error_reporting(E_ALL);
|
|
|
|
|
|
require_once 'config.php';
|
|
|
|
if(!isset($config) || empty($config)){
|
|
die("<h1>Configuration error</h1><p>Copy the webdata/config.sample.php file to webdata/config.php and fill out your connection settings.</p>");
|
|
}
|
|
|
|
$projectRoot = $config["general"]["projectRoot"];
|
|
|
|
function getConfig($val, $group = "general"){
|
|
global $config;
|
|
|
|
if(isset($config[$group][ $val ])){
|
|
return $config[$group][$val];
|
|
}
|
|
return false;
|
|
}
|
|
|
|
function database(){
|
|
global $config;
|
|
|
|
$db = new mysqli($config["db"]["host"], $config["db"]["user"], $config["db"]["pass"], $config["db"]["database"]);
|
|
|
|
if($db->connect_error){
|
|
die("Connection failed: " . $db->connect_error);
|
|
}
|
|
|
|
return $db;
|
|
}
|
|
|
|
function filter($data){
|
|
global $db;
|
|
|
|
if(gettype($data) !== "array"){
|
|
$data = trim(htmlentities(strip_tags($data)));
|
|
|
|
return $db->real_escape_string($data);
|
|
}
|
|
else if(gettype($data) == "array"){
|
|
foreach($data as $key => $value){
|
|
$data[$key] = filter($value);
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
function getHtmlHeaders($prepend = ""){
|
|
return "<meta charset='UTF-8'>
|
|
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
|
|
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
|
|
|
|
<link rel='stylesheet' href='".$prepend."css/bootstrap.min.css' type='text/css' />
|
|
<link rel='stylesheet' href='".$prepend."css/index.css' type='text/css' />
|
|
|
|
<script src='".$prepend."js/jquery-3.5.1.min.js'></script>
|
|
<script src='".$prepend."js/popper.min.js'></script>
|
|
<script src='".$prepend."js/bootstrap.min.js'></script>
|
|
<!--<script src='//cdn.jsdelivr.net/npm/marked/marked.min.js'></script>-->
|
|
<script src='".$prepend."js/hammer.js'></script>
|
|
<script src='".$prepend."js/hammer.jquery.js'></script>
|
|
\n";
|
|
}
|
|
|
|
function loginUser($email, $pass, $stayLoggedIn = false) {
|
|
global $db;
|
|
|
|
|
|
$err = [];
|
|
|
|
// get user from database
|
|
$getUserSQL = "SELECT pwd, user_id, user_email FROM user WHERE user_email = '$email' LIMIT 1;";
|
|
$getUserRes = $db->query($getUserSQL);
|
|
|
|
$dbPass = "missingPassword";
|
|
$dbUserId = 0;
|
|
$dbUserName = "Unknown";
|
|
|
|
if($getUserRes->num_rows == 1){
|
|
// Verify password
|
|
list($dbPass, $dbUserId, $dbUserName) = $getUserRes->fetch_row();
|
|
}
|
|
|
|
|
|
if(password_verify(PwdGen($pass), $dbPass)){
|
|
if(!isset($_SESSION)){
|
|
session_start();
|
|
}
|
|
session_regenerate_id();
|
|
|
|
$md5agent = md5($_SERVER['HTTP_USER_AGENT']);
|
|
$userKey = GenKey();
|
|
$shaUserKey = sha1($userKey);
|
|
$expire = $stayLoggedIn?30:0; // if "stay logged in", stay logged in for 30 days.
|
|
|
|
$updateUserSQL = "INSERT INTO user_login (user_id, ckey, ctime, expire, agent) VALUES ('$dbUserId', '$userKey', '".time()."', $expire, '$md5agent');";
|
|
if($db->query($updateUserSQL)){
|
|
$_SESSION['user_id'] = $dbUserId;
|
|
$_SESSION['user_name'] = $dbUserName;
|
|
$_SESSION['user_agent'] = $md5agent;
|
|
$_SESSION['user_key'] = $shaUserKey;
|
|
|
|
if($stayLoggedIn){
|
|
setcookie("auth", $shaUserKey.".".$dbUserId, time() + (30 * 24*60*60), "/", $_SERVER['HTTP_HOST'], isset($_SERVER['HTTPS']), true );
|
|
}
|
|
return true;
|
|
}
|
|
else {
|
|
$err[] = "Failed to login.\n".$db->error;
|
|
}
|
|
}
|
|
else {
|
|
$err[] = "Username and/or Password is wrong.";
|
|
}
|
|
|
|
return $err;
|
|
}
|
|
|
|
function loginFromAuth($auth): bool {
|
|
global $db;
|
|
$db = $db ?? database();
|
|
|
|
$md5agent = md5($_SERVER['HTTP_USER_AGENT']);
|
|
|
|
$cookieSplode = explode('.', $auth);
|
|
if(count($cookieSplode) == 2){
|
|
$tkey = $cookieSplode[0];
|
|
$tuid = $cookieSplode[1];
|
|
$verifyLoginCookieRes = $db->query("SELECT ul.user_id, ul.ckey, ul.ctime, ul.expire, ul.agent, u.full_name FROM user_login ul INNER JOIN user u ON ul.user_id = u.user_id WHERE ul.user_id = '$tuid' ORDER BY ctime DESC");
|
|
while($row = $verifyLoginCookieRes->fetch_assoc()){
|
|
if($row['expire'] == 0){ $row['expire'] = 1; }
|
|
if(
|
|
sha1($row['ckey']) == $tkey &&
|
|
$row['agent'] == $md5agent &&
|
|
($row['ctime']+($row['expire']*24*60*60) > time())
|
|
){
|
|
session_regenerate_id();
|
|
$_SESSION['user_id'] = $row['user_id'];
|
|
$_SESSION['user_name'] = $row['full_name'];
|
|
$_SESSION['user_agent'] = $md5agent;
|
|
$_SESSION['user_key'] = sha1($row['ckey']);
|
|
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
function logoutUser($everywhere = false){
|
|
if(checkLogin()){
|
|
global $db;
|
|
|
|
$logoutSql = "DELETE FROM user_login WHERE user_id = $_SESSION[user_id]";
|
|
if(!$everywhere){ $logoutSql .= " AND agent = '".md5($_SERVER['HTTP_USER_AGENT'])."'"; }
|
|
|
|
$db = $db ?? database();
|
|
$db->query($logoutSql);
|
|
}
|
|
|
|
// Delete session-cookie
|
|
$params = session_get_cookie_params();
|
|
setcookie(session_name(), '', time() - 42000,
|
|
$params["path"], $params["domain"],
|
|
$params["secure"], $params["httponly"]
|
|
);
|
|
|
|
setcookie('auth', '', time() - 42000, "/", $_SERVER['HTTP_HOST'], isset($_SERVER['HTTPS']), true );
|
|
|
|
// Finally, destroy the session.
|
|
session_destroy();
|
|
}
|
|
|
|
function PwdGen($pass, $returnHashed = false): string {
|
|
global $config;
|
|
|
|
$pepper = $config['general']['pepper'] ?? 'IAmBadAtSecurity';
|
|
$pwd_peppered = hash_hmac("sha256", $pass, $pepper);
|
|
if(!$returnHashed){
|
|
return $pwd_peppered;
|
|
}
|
|
|
|
return password_hash($pwd_peppered, PASSWORD_ARGON2ID, ['threads' => 2]);
|
|
}
|
|
|
|
function GenKey($length = 21): string{
|
|
$password = "";
|
|
$possible = "0123456789abcdefghijkmnopqrstuvwxyz";
|
|
|
|
$i = 0;
|
|
|
|
while($i < $length){
|
|
|
|
$char = substr($possible, mt_rand(0, strlen($possible)-1), 1);
|
|
|
|
if(!strstr($password, $char)){
|
|
$password .= $char;
|
|
$i++;
|
|
}
|
|
}
|
|
|
|
return $password;
|
|
}
|
|
|
|
function checkLogin(): bool {
|
|
global $db, $_SESSION, $_COOKIE;
|
|
|
|
if($db == null){
|
|
$db = database();
|
|
}
|
|
|
|
if(!isset($_SESSION)){
|
|
session_start();
|
|
}
|
|
|
|
if(isset($_SESSION['user_id'])){
|
|
$md5agent = md5($_SERVER['HTTP_USER_AGENT']);
|
|
if($md5agent == @$_SESSION['user_agent']){
|
|
$verifyLoginSessionRes = $db->query("SELECT expire, ctime, ckey FROM user_login WHERE user_id = ".$_SESSION['user_id']." and agent = '$md5agent'");
|
|
if($verifyLoginSessionRes->num_rows > 0){
|
|
while ($row = $verifyLoginSessionRes->fetch_assoc()){
|
|
if(
|
|
(sha1($row['ckey']) == $_SESSION['user_key']) &&
|
|
($row['expire'] == 0 || $row['ctime']+($row['expire']*24*60*60) > time())
|
|
){
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(isset($_COOKIE['auth']) && loginFromAuth($_COOKIE['auth'])){
|
|
return true;
|
|
}
|
|
|
|
unset($_SESSION['user_id']);
|
|
return false;
|
|
}
|
|
|
|
function requireLogin(): bool{
|
|
global $config;
|
|
if(checkLogin()){
|
|
return true;
|
|
}
|
|
|
|
$_SESSION['loginRef'] = $_SERVER['PHP_SELF'];
|
|
|
|
header("Location: ".$config["general"]["projectRoot"]."/login.php?return=".str_ireplace('index.php', '', $_SERVER['PHP_SELF']));
|
|
return false;
|
|
}
|
|
|
|
function checkLoginSimple(): bool {
|
|
global $_SESSION;
|
|
|
|
if(!isset($_SESSION)){
|
|
session_start();
|
|
$_SERVER['HTTP_REFERER'] = "";
|
|
}
|
|
|
|
if(isset($_SESSION['user_id'])){
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|