diff --git a/footer.php b/footer.php new file mode 100644 index 0000000..156746a --- /dev/null +++ b/footer.php @@ -0,0 +1,11 @@ +
+ +
+
+
+
+ Copyright © 2025 Your Company. +
+
+
+
diff --git a/head.php b/head.php new file mode 100644 index 0000000..753087f --- /dev/null +++ b/head.php @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/header.php b/header.php new file mode 100644 index 0000000..df2ae2d --- /dev/null +++ b/header.php @@ -0,0 +1,74 @@ + + + + + diff --git a/init.php b/init.php new file mode 100644 index 0000000..d026042 --- /dev/null +++ b/init.php @@ -0,0 +1,99 @@ + 0) + { + $varTokenUsers = $c->query( + "SELECT * + from tokens as t + join user as u on u.email = t.email + where + t.token = ? + and ( + t.expires is null + or t.expires > current_timestamp + )", + $strToken); + + $varUser = null; + + if (count($varTokenUsers) == 1) + $varUser = $varTokenUsers[0]; + else return null; + + try + { + $varUserDetails = $c->query( + "SELECT * + from user_info as ui + where + ui.email = ?", + $varUser["email"]); + + if (count($varUserDetails) == 1) + $varUser = array_merge($varUser, $varUserDetails[0]); + } + catch (Exception $x) {} + return $varUser; + } + } + catch (Exception $x) {} + return null; + } + + public static function hasPermission($strPermission) + { + global $c; + $varUser = UserAuth::getUser(); + + if ($varUser == null) + return false; + + $c->query( + "CREATE table if not exists permission ( + id integer primary key autoincrement, + email text not null, + name text not null)"); + + $varPermissions = $c->query( + "SELECT * + from permission + where + email like ? + and ( + name like ? + or name like '*' + )", + $varUser["email"], + $strPermission); + + if (count($varPermissions) > 0) + return true; + + return false; + } + + public static function requirePermission($strPermission) + { + if (!UserAuth::hasPermission($strPermission)) + { + BootstrapRender::message("You do not have permission to do that, please sign into an account that does.", "warning"); + Respond::redirect("/user/signin"); + } + } + } +?> diff --git a/lib/BootstrapRender.php b/lib/BootstrapRender.php new file mode 100644 index 0000000..9a40f56 --- /dev/null +++ b/lib/BootstrapRender.php @@ -0,0 +1,150 @@ + 0) + { + Cookie::set("message", func_get_arg(0)); + + if (func_num_args() > 1) + Cookie::set("messageClass", func_get_arg(1)); + + return; + } + + $strMessage = Cookie::get("message"); + $strMessageClass = Cookie::get("messageClass"); + + if (!isset($strMessageClass) || $strMessageClass == null || strlen($strMessageClass) < 1) + $strMessageClass = "info"; + + ?> + 0): ?> +
+ +
+ + + + + + + +
+
+ +
+ +
+ + /> +
+ +
+ test +
+
+ + + + + +
+ +
+ + + + /> +
+
+ + + + 0): ?> +
+ +
"> + + + + + < + class="btn btn- " + + + > + + + + + + + > + + +
+
+ + diff --git a/lib/TableEditor.php b/lib/TableEditor.php new file mode 100644 index 0000000..e2f0de9 --- /dev/null +++ b/lib/TableEditor.php @@ -0,0 +1,224 @@ +query("SELECT * from {$strTableName}"); + $varKeys = []; + + $strInput = file_get_contents("php://input"); + + if (strlen($strInput) > 0) + { + $a = json_decode($strInput, true); + $output = []; + + foreach ($a as $r) + { + $strColumns = ""; + $strQMarks = ""; + $strSetLns = ""; + $varValues = []; + + foreach ($varColumns as $strCol) + { + $strColumns .= "{$strCol}, "; + $strQMarks .= "?, "; + $strSetLns .= "{$strCol} = ?, "; + $varValues[] = $r[$strCol]; + } + + $strColumns = preg_replace("/, $/", "", $strColumns); + $strQMarks = preg_replace("/, $/", "", $strQMarks); + $strSetLns = preg_replace("/, $/", "", $strSetLns); + + + + if (strlen($r["id"]) < 1) + { + $c->query( + "INSERT into {$strTableName} ({$strColumns}) values ({$strQMarks})", + $varValues); + + continue; + } + + if (intval($r["delete"]) == 1) + { + $c->query("DELETE from {$strTableName} where id = ?", $r["id"]); + continue; + } + + $c->query( + "UPDATE {$strTableName} + set {$strSetLns} + where id = ?", + $varValues, + $r["id"]); + + $output[] = $r; + } + + Respond::json(["message" => "success", "output" => $output]); + } + ?> + + + + + + +
+
+
+ + 0): ?> +
+ + + + $v): ?> + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+ + + +
+
+ + + +
+
+
+ + + diff --git a/pages/user/info.php b/pages/user/info.php new file mode 100644 index 0000000..ab0c2a8 --- /dev/null +++ b/pages/user/info.php @@ -0,0 +1,92 @@ +query( + "CREATE table if not exists user_info ( + id integer primary key autoincrement, + email text not null unique, + user_name text null, + display_name text null)"); + + $varUser = UserAuth::getUser(); + $strUsername = $varUser["user_name"] ?? ""; + $strDisplayName = $varUser["display_name"] ?? ""; + + if ($varUser == null) + Respond::redirect("/"); + + try + { + if (Request::posts("user_name", "display_name")) + { + $strUsername = Request::getPosted("user_name"); + $strDisplayName = Request::getPosted("display_name"); + + if (!preg_match("/^[A-Za-z0-9]{1,}$/", $strUsername)) + throw new Exception("Username must be alphanumeric characters only"); + + $c->query( + "INSERT or replace into user_info (email, user_name, display_name) + select + ?, + ?, + ?", + $varUser["email"], + $strUsername, + $strDisplayName); + + BootstrapRender::message("Profile updated", "success"); + } + } + catch (Exception $x) + { + BootstrapRender::message($x->getMessage(), "danger"); + } +?> + +
+
+ +
+
Edit your account details here.
+
+ +
+ + + +
+ "email", + "label" => "E-Mail Address", + "value" => $varUser["email"], + "disabled" => 1, + ]); ?> + + "user_name", + "label" => "Username", + "value" => $strUsername, + ]); ?> + + "display_name", + "label" => "Display Name", + "value" => $strDisplayName, + ]); ?> + + 0, + "buttons" => [[ + "icon" => "save", + "label" => "Save", + "type" => "submit", + "class" => "outline-success" + ]]]); ?> +
+
+ + +
+
diff --git a/pages/user/list.php b/pages/user/list.php new file mode 100644 index 0000000..587ee6c --- /dev/null +++ b/pages/user/list.php @@ -0,0 +1,6 @@ + + diff --git a/pages/user/permissions.php b/pages/user/permissions.php new file mode 100644 index 0000000..3888096 --- /dev/null +++ b/pages/user/permissions.php @@ -0,0 +1,5 @@ + diff --git a/pages/user/register.php b/pages/user/register.php new file mode 100644 index 0000000..84ad9b1 --- /dev/null +++ b/pages/user/register.php @@ -0,0 +1,100 @@ +query( + "CREATE table if not exists user ( + id integer primary key autoincrement, + email text not null unique, + hash text not null)"); + + $varUsers = $c->query("SELECT * from user where email like ?", $strEmail); + + if (count($varUsers) > 0) + throw new Exception("E-mail address in use"); + + $strHash = sha1($strPassword); + + $c->query( + "INSERT into user (email, hash) values (?, ?)", + $strEmail, + $strHash); + + BootstrapRender::message("Registration was a success, please sign in to continue."); + + Respond::redirect("/user/signin"); + } + + } + catch (Exception $x) + { + BootstrapRender::message($x->getMessage(), "danger"); + } +?> + + + +
+
+
+ + + +
+ + "email", + "label" => "E-Mail Address", + "value" => Request::getPosted("email") + ]); ?> + + "password", + "label" => "Password", + "value" => Request::getPosted("password"), + "type" => "password", + ]); ?> + + "repeat", + "label" => "Repeat Password", + "value" => Request::getPosted("repeat"), + "type" => "password", + ]); ?> + +
+ +
+ +
+
+ + +
+ +
+
+
diff --git a/pages/user/signin.php b/pages/user/signin.php new file mode 100644 index 0000000..b675ef9 --- /dev/null +++ b/pages/user/signin.php @@ -0,0 +1,88 @@ +query( + "SELECT * + from user + where + email like ? + and hash = ?", + $strEmail, + $strHash); + + if (count($varUsers) !== 1) + throw new Exception("Zero or more than one user returned for credentials provided"); + + $strToken = sha1(microtime()); + + $c->query("CREATE table if not exists tokens ( + id integer primary key autoincrement, + email text not null, + token text not null, + expires timestamp null)"); + + $c->query( + "INSERT into tokens (email, token) values (?, ?)", + $strEmail, + $strToken); + + Cookie::set("token", $strToken); + + BootstrapRender::message( + "Successfully signed in", + "info"); + + Respond::redirect("/user/info"); + } + + } + catch (Exception $x) + { + BootstrapRender::message($x->getMessage(), "danger"); + } +?> + + + +
+
+
+ + +
+ "email", + "label" => "E-Mail Address", + "value" => Request::getPosted("email") + ]); ?> + + "password", + "label" => "Password", + "value" => Request::getPosted("password"), + "type" => "password", + ]); ?> + + 0, + "buttons" => [ + ["icon" => "right-to-bracket", "label" => "Continue", "type" => "submit", "class" => "outline-primary"], + ["icon" => "home", "label" => "Home", "href" => "/"] + ]]); ?> + + +
+
+
+
diff --git a/pages/user/signout.php b/pages/user/signout.php new file mode 100644 index 0000000..01c1310 --- /dev/null +++ b/pages/user/signout.php @@ -0,0 +1,29 @@ +query( + "UPDATE tokens + set + expires = current_timestamp + where email = ?", + $varUser["email"]); + } + else + { + $c->query( + "UPDATE tokens + set + expires = current_timestamp + where token = ?", + $varUser["token"]); + } + } + + BootstrapRender::message("You have successfully signed out"); + Respond::redirect("/user/signin"); +?>