This commit is contained in:
Bruno Rybársky 2024-02-06 16:24:57 +01:00
parent 38895b1502
commit 72bd8b8bd1
15 changed files with 278 additions and 361 deletions

@ -1,67 +1,52 @@
async function doAction(url, requestData, successMessage, failureMessage, silent = false) {
try {
const params = new URLSearchParams();
function doAccountAction(requestData, successMessage, failureMessage, silent=false) { for (const key in requestData) {
return fetch('/account', { params.append(key, requestData[key]);
}
const response = await fetch(url, {
method: 'POST', method: 'POST',
body: requestData, body: params,
}) });
.then(response => {
if (!response.ok) { if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`); throw new Error(`HTTP error! Status: ${response.status}`);
} }
return response.json();
}) const data = await response.json();
.then(data => {
if (!silent) { if (!silent) {
handleResponse(data, successMessage, failureMessage); handleResponse(data, successMessage, failureMessage);
} }
return data; // Returning the response data for further processing
}) return data;
.catch((error) => { } catch (error) {
console.error('Error:', error); console.error('Error:', error);
});
} }
}
function handlePageResponse(data) { function handlePageResponse(data) {
const navbar = document.getElementById("navbar");
const pageArea = document.getElementById("pagearea");
if (data.Navigation) { if (data.Navigation) {
document.getElementById("navbar").innerHTML = data.Navigation; navbar.innerHTML = data.Navigation;
} }
if (data.Page) { if (data.Page) {
document.getElementById("pagearea").innerHTML = data.Page; pageArea.innerHTML = data.Page;
// if(data.PageLocation){
// history.pushState({}, "", data.PageLocation);
// }
} }
} }
function doPageAction(requestData){ function displayList(data, elementId, deleteFunction) {
return fetch('/page', { const tableContainer = document.getElementById(elementId);
method: 'POST',
body: requestData,
})
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return response.json();
})
.then(data => {
handlePageResponse(data);
})
.catch((error) => {
console.error('Error:', error);
});
}
function displayList(data, element_id, delete_function=null) {
const tableContainer = document.getElementById(element_id);
tableContainer.innerHTML = ""; // Clear previous content tableContainer.innerHTML = ""; // Clear previous content
const table = document.createElement("table"); const table = document.createElement("table");
table.classList.add("list-table"); table.classList.add("list-table");
// Create header row
const headerRow = table.insertRow(0); const headerRow = table.insertRow(0);
for (const key in data[0]) { for (const key in data[0]) {
const th = document.createElement("th"); const th = document.createElement("th");
@ -69,13 +54,12 @@ function displayList(data, element_id, delete_function=null) {
headerRow.appendChild(th); headerRow.appendChild(th);
} }
if(typeof delete_function === "function") { if (typeof deleteFunction === "function") {
const th = document.createElement("th"); const th = document.createElement("th");
th.appendChild(document.createTextNode("Delete")); th.appendChild(document.createTextNode("Delete"));
headerRow.appendChild(th); headerRow.appendChild(th);
} }
// Create data rows
for (const line of data) { for (const line of data) {
const dataRow = table.insertRow(); const dataRow = table.insertRow();
for (const key in line) { for (const key in line) {
@ -83,14 +67,12 @@ function displayList(data, element_id, delete_function=null) {
td.appendChild(document.createTextNode(line[key])); td.appendChild(document.createTextNode(line[key]));
dataRow.appendChild(td); dataRow.appendChild(td);
} }
if(typeof delete_function === "function") { if (typeof deleteFunction === "function") {
const td = document.createElement("td"); const td = document.createElement("td");
let delete_button = document.createElement('button'); const deleteButton = document.createElement('button');
delete_button.textContent = "Delete" deleteButton.textContent = "Delete";
delete_button.onclick = function (){ deleteButton.onclick = () => deleteFunction(line.ID);
delete_function(line.ID); td.appendChild(deleteButton);
}
td.appendChild(delete_button);
dataRow.appendChild(td); dataRow.appendChild(td);
} }
} }
@ -98,85 +80,45 @@ function displayList(data, element_id, delete_function=null) {
tableContainer.appendChild(table); tableContainer.appendChild(table);
} }
function handleResponse(data, SuccessMessage, failureMessage) { async function doPageAction(requestData, wantsReturn = false) {
const StatusMessageElement = document.getElementById("StatusMessage"); try {
const response = await fetch('/page', {
method: 'POST',
body: new URLSearchParams(requestData),
});
if (data.Status === 'Success') { if (!response.ok) {
StatusMessageElement.innerText = SuccessMessage; throw new Error(`HTTP error! Status: ${response.status}`);
}
if (wantsReturn) {
return await response.json();
} else { } else {
StatusMessageElement.innerText = failureMessage; const data = await response.json();
handlePageResponse(data);
} }
} catch (error) {
// Show the status message console.error('Error:', error);
StatusMessageElement.style.display = "block";
setTimeout(() => {
// Hide the status message after 3 seconds
StatusMessageElement.style.opacity = "0";
setTimeout(() => {
StatusMessageElement.style.display = "none";
// Reset opacity for future messages
StatusMessageElement.style.opacity = "1";
}, 500);
}, 3000);
} }
function navigateTo(site, page){
const data = new URLSearchParams();
data.append("action", "getPage");
data.append("site", site);
data.append("page", page);
doPageAction(data).then(() => {
localStorage.setItem("currentSite", site);
localStorage.setItem("currentPage", page);
onPageLoad();
// Expected output: "Success!"
});
}
function softReload(){
navigateTo(localStorage.getItem("currentSite"), localStorage.getItem("currentPage"));
}
function refreshNavbar(){
const data = new URLSearchParams();
data.append("action", "getNavigation");
doPageAction(data);
}
function logout() {
const data = new URLSearchParams();
data.append("action", "logout");
doAccountAction(data, "Logout Successful!", "Logout failed.").then(() => {
refreshNavbar();
navigateTo("", localStorage.getItem("defaultPage"));
// Expected output: "Success!"
});
} }
function initAjax() { function initAjax() {
let links = document.querySelectorAll('.navsite_link, .navpage_link'); const links = document.querySelectorAll('.navsite_link, .navpage_link');
// Add click event listener to each link
links.forEach(function (link) { links.forEach(function (link) {
link.addEventListener('click', function (e) { link.addEventListener('click', function (e) {
e.preventDefault(); e.preventDefault();
// Get page and site information
let site = this.dataset.site; let site = this.dataset.site;
let page = this.dataset.page; let page = this.dataset.page;
if (site && page) { if (site && page) {
navigateTo(site, page); navigateTo(site, page);
} }
// You can use this information to update the URL or perform other actions
}); });
}); });
onPageLoad(); onPageLoad();
} }
document.addEventListener('DOMContentLoaded', initAjax);
document.addEventListener('DOMContentLoaded', initAjax);
function onPageLoad(){ function onPageLoad(){
let currentSite = localStorage.getItem("currentSite"); let currentSite = localStorage.getItem("currentSite");
@ -192,7 +134,41 @@ function onPageLoad(){
} }
} }
//Login function navigateTo(site, page){
const data = {
action: "getPage",
site: site,
page: page,
};
let pageActionStatus = doPageAction(data, true);
if(pageActionStatus.Status === "Success") {
localStorage.setItem("currentSite", site);
localStorage.setItem("currentPage", page);
onPageLoad();
}
}
function softReload(){
navigateTo(localStorage.getItem("currentSite"), localStorage.getItem("currentPage"));
}
function refreshNavbar(){
const data = {
action: "getNavigation",
};
doPageAction(data);
}
function logout() {
const data = {
action: "logout",
};
doAction('/account', data, "Logout Successful!", "Logout failed.").then(() => {
refreshNavbar();
navigateTo("", localStorage.getItem("defaultPage"));
});
}
function login() { function login() {
const email = document.getElementById("login_email").value; const email = document.getElementById("login_email").value;
@ -202,13 +178,14 @@ function login() {
softReload(); softReload();
} }
function doLogin(email, password) { async function doLogin(email, password) {
const data = new URLSearchParams(); const data = {
data.append("action", "login"); action: "login",
data.append("email", email); email: email,
data.append("password", password); password: password,
};
doAccountAction(data, "Login Successful!", "Login failed. Please check your credentials."); await doAction('/account', data, "Login Successful!", "Login failed. Please check your credentials.");
} }
function register() { function register() {
@ -218,38 +195,39 @@ function register() {
const password = document.getElementById("register_password").value; const password = document.getElementById("register_password").value;
const activationToken = document.getElementById("register_activationToken").value; const activationToken = document.getElementById("register_activationToken").value;
const data = new URLSearchParams(); const data = {
data.append("action", "register"); action: "register",
data.append("firstname", firstName); firstname: firstName,
data.append("lastname", lastName); lastname: lastName,
data.append("email", email); email: email,
data.append("password", password); password: password,
data.append("activation_token", activationToken); activation_token: activationToken,
};
doRegister(data); doRegister(data);
} }
function doRegister(requestData) { async function doRegister(requestData) {
doAccountAction(requestData, "Registration Successful!", "Registration failed."); await doAction('/account', requestData, "Registration Successful!", "Registration failed.");
} }
//User settings start //User settings start
function changePassword() { function changePassword() {
const oldPassword = document.getElementById("changeOldPassword").value; const oldPassword = document.getElementById("changeOldPassword").value;
const newPassword = document.getElementById("changeNewPassword").value; const newPassword = document.getElementById("changeNewPassword").value;
const data = new URLSearchParams(); const data = {
data.append("action", "change_password"); action: "change_password",
data.append("old_password", oldPassword); old_password: oldPassword,
data.append("new_password", newPassword); new_password: newPassword,
};
doChangePassword(data, "Password change Successful!", "Password change failed."); doChangePassword(data, "Password change Successful!", "Password change failed.");
} }
function doChangePassword(requestData, successMessage, failureMessage) { async function doChangePassword(requestData, successMessage, failureMessage) {
doAccountAction(requestData, successMessage, failureMessage); await doAction('/account', requestData, successMessage, failureMessage);
} }
function updateUserProfile() { function updateUserProfile() {
@ -258,24 +236,26 @@ function updateUserProfile() {
const nickname = document.getElementById("updateNickname").value; const nickname = document.getElementById("updateNickname").value;
const minecraftNick = document.getElementById("updateMinecraftNick").value; const minecraftNick = document.getElementById("updateMinecraftNick").value;
const data = new URLSearchParams(); const data = {
data.append("action", "update_user_profile"); action: "update_user_profile",
data.append("first_name", firstName); first_name: firstName,
data.append("last_name", lastName); last_name: lastName,
data.append("nickname", nickname); nickname: nickname,
data.append("minecraft_nick", minecraftNick); minecraft_nick: minecraftNick,
};
doAccountAction(data, "Profile update Successful!", "Profile update failed."); doAction('/account', data, "Profile update Successful!", "Profile update failed.");
} }
function updateEmail() { function updateEmail() {
const newEmail = document.getElementById("updateNewEmail").value; const newEmail = document.getElementById("updateNewEmail").value;
const data = new URLSearchParams(); const data = {
data.append("action", "update_user_email"); action: "update_user_email",
data.append("email", newEmail); email: newEmail,
};
doAccountAction(data, "Email update Successful!", "Email update failed."); doAction('/account', data, "Email update Successful!", "Email update failed.");
} }
function populateUserInfoFields(userData) { function populateUserInfoFields(userData) {
@ -286,11 +266,12 @@ function populateUserInfoFields(userData) {
document.getElementById("updateNewEmail").value = userData.Email || ""; document.getElementById("updateNewEmail").value = userData.Email || "";
} }
async function getUserInfo() { function getUserInfo() {
const data = new URLSearchParams(); const data = {
data.append("action", "get_user_info"); action: "get_user_info",
};
const result = await doAccountAction(data, "User info retrieved Successfully!", "User info retrieval failed.", true); const result = doAction('/account', data, "User info retrieved Successfully!", "User info retrieval failed.", true);
if (result && result.Status === "Success") { if (result && result.Status === "Success") {
populateUserInfoFields(result.UserInfo); populateUserInfoFields(result.UserInfo);
@ -301,56 +282,58 @@ async function getUserInfo() {
//Admin settings start //Admin settings start
async function addActivationCodes() { function addActivationCodes() {
const count = document.getElementById("activationCodeCount").value; const count = document.getElementById("activationCodeCount").value;
const data = new URLSearchParams(); const data = {
data.append("action", "add_activation_codes"); action: "add_activation_codes",
data.append("count", count); count: count,
};
const result = await doAccountAction(data, "Activation codes added Successfully!", "Activation codes addition failed."); const result = doAction('/account', data, "Activation codes added Successfully!", "Activation codes addition failed.");
displayList(result.ActivationCodes, "codeListTable", deleteActivationCode); displayList(result.ActivationCodes, "codeListTable", deleteActivationCode);
} }
async function listUsers() { function listUsers() {
const data = new URLSearchParams(); const data = {
data.append("action", "list_users"); action: "list_users",
};
const result = await doAccountAction(data, "User list retrieved Successfully!", "User list retrieval failed."); const result = doAction('/account', data, "User list retrieved Successfully!", "User list retrieval failed.");
if (result && result.Status === "Success") { if (result && result.Status === "Success") {
displayList(result.Users, "userListTable", deleteUser); displayList(result.Users, "userListTable", deleteUser);
} }
} }
function listActivationCodes() {
const data = {
action: "list_activation_codes",
};
async function listActivationCodes() { const result = doAction('/account', data, "Activation code list retrieved Successfully!", "Activation code list retrieval failed.");
const data = new URLSearchParams();
data.append("action", "list_activation_codes");
const result = await doAccountAction(data, "Activation code list retrieved Successfully!", "Activation code list retrieval failed.");
displayList(result.ActivationCodes, "codeListTable", deleteActivationCode); displayList(result.ActivationCodes, "codeListTable", deleteActivationCode);
} }
function deleteUser(userId) { function deleteUser(userId) {
const data = {
action: "delete_user",
user_id: userId,
};
const data = new URLSearchParams(); doAction('/account', data, "User deleted Successfully!", "User deletion failed.");
data.append("action", "delete_user");
data.append("user_id", userId);
doAccountAction(data, "User deleted Successfully!", "User deletion failed.");
listUsers(); listUsers();
} }
function deleteActivationCode(activationCode) { function deleteActivationCode(activationCode) {
const data = {
action: "delete_activation_code",
activation_code: activationCode,
};
const data = new URLSearchParams(); doAction('/account', data, "Activation code deleted Successfully!", "Activation code deletion failed.");
data.append("action", "delete_activation_code");
data.append("activation_code", activationCode);
doAccountAction(data, "Activation code deleted Successfully!", "Activation code deletion failed.");
listActivationCodes(); listActivationCodes();
} }
//Admin settings end //Admin settings end

@ -1,4 +1,5 @@
<?php <?php
/** @noinspection PhpIncludeInspection */
require_once 'secrets/config.php'; require_once 'secrets/config.php';
require_once 'lib/config.php'; require_once 'lib/config.php';
require_once 'lib/navigation.php'; require_once 'lib/navigation.php';
@ -7,29 +8,19 @@ require_once 'lib/page.php';
require_once 'lib/endpoint.php'; require_once 'lib/endpoint.php';
require_once 'lib/account.php'; require_once 'lib/account.php';
$routerConfig = array(); $routerConfig = loadRouterConfig();
$routerRequest = array();
loadRouterConfig(); $routerRequest = initRouter();
$canRender = initRouter();
if ($canRender) {
/** @noinspection PhpArrayIsAlwaysEmptyInspection */
/** @noinspection PhpArrayIsAlwaysEmptyInspection */
; session_set_cookie_params(0, '/', "." . $routerRequest["domain"] . "." . $routerRequest["tld"], true, true);
session_start(); session_start();
if (!isLoggedIn()) { if (!isLoggedIn()) {
setDefaultSessionData(); setDefaultSessionData();
} }
/** @noinspection PhpArrayIsAlwaysEmptyInspection */
if ($routerRequest["type"] == "api") { if ($routerRequest["type"] == "api") {
/** @noinspection PhpArrayIsAlwaysEmptyInspection */
echo getEndpoint($routerRequest["page_name"]); echo getEndpoint($routerRequest["page_name"]);
} /** @noinspection PhpArrayIsAlwaysEmptyInspection */ elseif ($routerRequest["type"] == "page") { } elseif ($routerRequest["type"] == "page") {
/** @noinspection PhpArrayIsAlwaysEmptyInspection */ echo getPage($routerRequest["site_name"], $routerRequest["page_name"]);
echo getPage($routerRequest["page_name"]);
}
} }

@ -5,36 +5,36 @@ use Random\RandomException;
function isLoggedIn(): bool function isLoggedIn(): bool
{ {
global $routerConfig; global $routerConfig;
return $_SESSION["ID"] > 0 && !empty($_SESSION["email"]) && $_SESSION["privilege_level"] >= $routerConfig["logged_in_default_permission_level"]; return $_SESSION["ID"] > 0 && !empty($_SESSION["email"]) && $_SESSION["privilege_level"] >= $routerConfig["permissions"]["logged_in_default"];
} }
function isVerified(): bool function isVerified(): bool
{ {
global $routerConfig; global $routerConfig;
return isLoggedIn() && $_SESSION["privilege_level"] >= $routerConfig["verified_permission_level"]; return isLoggedIn() && $_SESSION["privilege_level"] >= $routerConfig["permissions"]["verified"];
} }
function isTrustWorthy(): bool function isTrustWorthy(): bool
{ {
global $routerConfig; global $routerConfig;
return isLoggedIn() && $_SESSION["privilege_level"] >= $routerConfig["trustworthy_permission_level"]; return isLoggedIn() && $_SESSION["privilege_level"] >= $routerConfig["permissions"]["trustworthy"];
} }
function isModerator(): bool function isModerator(): bool
{ {
global $routerConfig; global $routerConfig;
return isLoggedIn() && $_SESSION["privilege_level"] >= $routerConfig["moderator_permission_level"]; return isLoggedIn() && $_SESSION["privilege_level"] >= $routerConfig["permissions"]["moderator"];
} }
function isUserAdmin(): bool function isUserAdmin(): bool
{ {
global $routerConfig; global $routerConfig;
return isLoggedIn() && $_SESSION["privilege_level"] >= $routerConfig["user_admin_permission_level"]; return isLoggedIn() && $_SESSION["privilege_level"] >= $routerConfig["permissions"]["user_admin"];
} }
function isAdmin(): bool function isAdmin(): bool
{ {
global $routerConfig; global $routerConfig;
return isLoggedIn() && $_SESSION["privilege_level"] >= $routerConfig["admin_permission_level"]; return isLoggedIn() && $_SESSION["privilege_level"] >= $routerConfig["permissions"]["admin"];
} }
@ -69,7 +69,7 @@ function setDefaultSessionData(): void
$_SESSION["nickname"] = ""; $_SESSION["nickname"] = "";
$_SESSION["email"] = ""; $_SESSION["email"] = "";
$_SESSION["minecraft_nickname"] = ""; $_SESSION["minecraft_nickname"] = "";
$_SESSION["privilege_level"] = $routerConfig["logged_out_permission_level"]; $_SESSION["privilege_level"] = $routerConfig["permissions"]["logged_out"];
} }
function verifyPassword($userID, $password): bool function verifyPassword($userID, $password): bool
@ -86,17 +86,16 @@ function verifyPassword($userID, $password): bool
return !empty($password_hash) && !empty($password) && password_verify($password, $password_hash); return !empty($password_hash) && !empty($password) && password_verify($password, $password_hash);
} }
function UpdateSession(){ function UpdateSession(): void
{
global $mysqli; global $mysqli;
$stmt = $mysqli->prepare("SELECT FirstName, LastName, Nickname, Email, MinecraftNick, PrivilegeLevel, LastLoginAt, LoginCount, ClassID, FavoriteColor FROM Users WHERE ID = ? AND isActivated = 1"); $stmt = $mysqli->prepare("SELECT FirstName, LastName, Nickname, Email, MinecraftNick, PrivilegeLevel, LastLoginAt, LoginCount, ClassID, FavoriteColor FROM Users WHERE ID = ? AND isActivated = 1");
$stmt->bind_param("i", $_SESSION["ID"]); $stmt->bind_param("i", $_SESSION["ID"]);
$stmt->execute(); $stmt->execute();
$uid = 0;
$first_name = ""; $first_name = "";
$last_name = ""; $last_name = "";
$nickname = ""; $nickname = "";
$password_hash = "";
$email = ""; $email = "";
$minecraft_nickname = ""; $minecraft_nickname = "";
$privilege_level = 0; $privilege_level = 0;
@ -123,7 +122,7 @@ function UpdateSession(){
function doLogin($email, $password): array function doLogin($email, $password): array
{ {
global $mysqli, $routerConfig; global $mysqli;
$found = false; $found = false;
if (!empty($email) && !empty($password)) { if (!empty($email) && !empty($password)) {
$stmt = $mysqli->prepare("SELECT ID, PasswordHash FROM Users WHERE Email = ? AND isActivated = 1"); $stmt = $mysqli->prepare("SELECT ID, PasswordHash FROM Users WHERE Email = ? AND isActivated = 1");
@ -171,7 +170,7 @@ function doRegister($firstname, $lastname, $email, $password, $activation_token)
$passwordHash = password_hash($password, PASSWORD_DEFAULT); $passwordHash = password_hash($password, PASSWORD_DEFAULT);
$stmt = $mysqli->prepare("UPDATE Users SET FirstName=?, LastName=?, Email=?, PasswordHash=?, PrivilegeLevel=?, isActivated=1, ActivationToken='', RegisteredAt=NOW() WHERE ActivationToken = ?"); $stmt = $mysqli->prepare("UPDATE Users SET FirstName=?, LastName=?, Email=?, PasswordHash=?, PrivilegeLevel=?, isActivated=1, ActivationToken='', RegisteredAt=NOW() WHERE ActivationToken = ?");
$privilege_level = $routerConfig["logged_in_default_permission_level"]; $privilege_level = $routerConfig["permissions"]["logged_in_default"];
/** @noinspection SpellCheckingInspection */ /** @noinspection SpellCheckingInspection */
$stmt->bind_param("ssssis", $firstname, $lastname, $email, $passwordHash, $privilege_level, $activation_token); $stmt->bind_param("ssssis", $firstname, $lastname, $email, $passwordHash, $privilege_level, $activation_token);
@ -315,7 +314,7 @@ function getUserInfo(): array
function addActivationCodes($count): array function addActivationCodes($count): array
{ {
global $mysqli, $routerConfig; global $mysqli;
$activationCodes = []; $activationCodes = [];
$output = ["Status" => "Fail"]; // Default Status is "Fail" $output = ["Status" => "Fail"]; // Default Status is "Fail"
@ -347,7 +346,7 @@ function addActivationCodes($count): array
function listUsers(): array function listUsers(): array
{ {
global $mysqli, $routerConfig; global $mysqli;
$output = ["Status" => "Fail"]; // Default Status is "Fail" $output = ["Status" => "Fail"]; // Default Status is "Fail"
if (isUserAdmin()) { if (isUserAdmin()) {
@ -369,7 +368,7 @@ function listUsers(): array
function listActivationCodes(): array function listActivationCodes(): array
{ {
global $mysqli, $routerConfig; global $mysqli;
$output = ["Status" => "Fail"]; // Default Status is "Fail" $output = ["Status" => "Fail"]; // Default Status is "Fail"
if (isUserAdmin()) { if (isUserAdmin()) {
@ -414,7 +413,7 @@ function listActivationCodes(): array
function deleteUser($userID): array function deleteUser($userID): array
{ {
global $mysqli, $routerConfig; global $mysqli;
$status = ["Status" => "Fail"]; $status = ["Status" => "Fail"];
if (!empty($userID) && isUserAdmin()) { if (!empty($userID) && isUserAdmin()) {
$stmt = $mysqli->prepare("DELETE FROM Users WHERE ID = ?"); $stmt = $mysqli->prepare("DELETE FROM Users WHERE ID = ?");
@ -430,7 +429,7 @@ function deleteUser($userID): array
function deleteActivationCode($activationCode): array function deleteActivationCode($activationCode): array
{ {
global $mysqli, $routerConfig; global $mysqli;
$status = ["Status" => "Fail"]; $status = ["Status" => "Fail"];
if (!empty($activationCode) && isUserAdmin()) { if (!empty($activationCode) && isUserAdmin()) {
$stmt = $mysqli->prepare("DELETE FROM Users WHERE ActivationToken = ?"); $stmt = $mysqli->prepare("DELETE FROM Users WHERE ActivationToken = ?");

@ -1,35 +1,30 @@
<?php <?php
function loadRouterConfig(): void function loadRouterConfig(): array
{ {
global $routerConfig;
$routerConfig["default_page"] = "index"; return [
'inlining' => false,
'domain' => 'adlerka',
'tld' => 'top',
'default_page' => 'index',
'default_site' => 'home',
'template_dir' => 'templates/',
'endpoint_dir' => 'endpoints/',
'page_dir' => 'pages/',
'protocol' => 'https://',
'permissions' => [
'logged_out' => 1,
'logged_in_default' => 2,
'verified' => 3,
'trustworthy' => 4,
'moderator' => 5,
'user_admin' => 254,
'admin' => 255,
],
'page' => [
'default_secret' => 1,
'default_permissions' => 255,
$routerConfig["default_site"] = "home"; ]
];
$routerConfig["template_dir"] = "templates/";
$routerConfig["endpoint_dir"] = "endpoints/";
$routerConfig["page_dir"] = "pages/";
$routerConfig["protocol"] = "https://";
$routerConfig["logged_out_permission_level"] = 1;
$routerConfig["logged_in_default_permission_level"] = 2;
$routerConfig["verified_permission_level"] = 3;
$routerConfig["trustworthy_permission_level"] = 4;
$routerConfig["moderator_permission_level"] = 5;
$routerConfig["user_admin_permission_level"] = 254;
$routerConfig["admin_permission_level"] = 255;
$routerConfig["default_page_permission_level"] = 255;
$routerConfig["default_page_secret"] = 1;
} }

@ -21,21 +21,9 @@ function getEndpoint($endpoint_name): string
$endpoint_name = $routerRequest["page_name"]; $endpoint_name = $routerRequest["page_name"];
} }
if($routerRequest["isToApex"]){ $endpoint_file = $routerConfig["endpoint_dir"] . $endpoint_name . ".php";
$subdomain_part = "";
}
else{
$subdomain_part = $routerRequest["subdomain"] . "/";
}
$endpoint_file = $routerConfig["endpoint_dir"] . $subdomain_part . $endpoint_name . ".php"; if (file_exists($endpoint_file)){
$endpoint_file_global = $routerConfig["endpoint_dir"] . "global/" . $endpoint_name . ".php";
if (file_exists($endpoint_file_global)){
$output = runEndpoint($endpoint_file_global);
}
elseif (file_exists($endpoint_file)){
$output = runEndpoint($endpoint_file); $output = runEndpoint($endpoint_file);
} }
else{ else{

@ -1,9 +1,10 @@
<?php <?php
function inlineLocalStylesFromHref($inputString) { function inlineLocalStylesFromHref($inputString): string
{
$pattern = '/<link[^>]*?\srel=["\']?stylesheet["\'].*?\shref=["\']?\/(.*?)["\'][^>]*?>/i'; $pattern = '/<link[^>]*?\srel=["\']?stylesheet["\'].*?\shref=["\']?\/(.*?)["\'][^>]*?>/i';
$outputString = preg_replace_callback($pattern, function($match) { return preg_replace_callback($pattern, function($match) {
$href = $match[1]; $href = $match[1];
$cssFilePath = $_SERVER['DOCUMENT_ROOT'] . '/' . $href; $cssFilePath = $_SERVER['DOCUMENT_ROOT'] . '/' . $href;
$cssContent = file_get_contents($cssFilePath); $cssContent = file_get_contents($cssFilePath);
@ -28,14 +29,13 @@ function inlineLocalStylesFromHref($inputString) {
return "<style>{$cssContent}</style>"; return "<style>{$cssContent}</style>";
}, $inputString); }, $inputString);
return $outputString;
} }
function inlineScriptFromSrc($inputString) { function inlineScriptFromSrc($inputString): string
{
$pattern = '/<script.*?src=["\']\/(.*?)["\'].*?>\s*<\/script>/i'; $pattern = '/<script.*?src=["\']\/(.*?)["\'].*?>\s*<\/script>/i';
$outputString = preg_replace_callback($pattern, function($match) { return preg_replace_callback($pattern, function($match) {
$src = $match[1]; $src = $match[1];
$jsContent = file_get_contents($_SERVER['DOCUMENT_ROOT'] . '/' . $src); $jsContent = file_get_contents($_SERVER['DOCUMENT_ROOT'] . '/' . $src);
@ -43,11 +43,10 @@ function inlineScriptFromSrc($inputString) {
$jsContent = minifyJs($jsContent); $jsContent = minifyJs($jsContent);
return "<script>{$jsContent}</script>"; return "<script>{$jsContent}</script>";
}, $inputString); }, $inputString);
return $outputString;
} }
function minifyCss($css) { function minifyCss($css): string
{
// Remove comments // Remove comments
$css = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $css); $css = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $css);
@ -66,7 +65,8 @@ function minifyCss($css) {
return trim($css); return trim($css);
} }
function minifyJs($js) { function minifyJs($js): string
{
// Remove newlines and tabs // Remove newlines and tabs
$js = str_replace("\t", '', $js); $js = str_replace("\t", '', $js);

@ -7,11 +7,11 @@ function getDynamicPermission($file): int {
$permission_level = $page_tmp["parameters"]["minimal_permission_level"]; $permission_level = $page_tmp["parameters"]["minimal_permission_level"];
if (!is_numeric($permission_level) || $permission_level <= 0) { if (!is_numeric($permission_level) || $permission_level <= 0) {
$permission_level = $routerConfig["default_page_permission_level"]; $permission_level = $routerConfig["page"]["default_permissions"];
} }
} }
catch (Exception){ catch (Exception){
$permission_level = $routerConfig["default_page_permission_level"]; $permission_level = $routerConfig["page"]["default_permissions"];
} finally { } finally {
return $permission_level; return $permission_level;
} }
@ -32,16 +32,11 @@ function generateNavigation(): string
$site_name = str_replace("_", " ", $site_dir); $site_name = str_replace("_", " ", $site_dir);
$site_subdomain = $site_dir . ".";
if ($site_name == $routerConfig["default_site"]) {
$site_subdomain = "";
}
$site_name = ucfirst($site_name); $site_name = ucfirst($site_name);
$site_location = $routerConfig["protocol"] . $site_subdomain . $routerRequest["domain"] . "." . $routerRequest["tld"] . "/" . $routerConfig["default_page"]; $site_location = "/" . $site_dir . "/" . $routerConfig["default_page"];
if ($routerRequest["subdomain"] == $site_dir) { if ($routerRequest["site_name"] == $site_dir) {
//this is the current page //this is the current page
$site_class = "class=\"navsite_link active\""; $site_class = "class=\"navsite_link active\"";
} }
@ -49,17 +44,17 @@ function generateNavigation(): string
$site_class = "class=\"navsite_link\""; $site_class = "class=\"navsite_link\"";
} }
$navpages = ""; $navigation_pages = "";
foreach ($pages_dir as $page_file) { foreach ($pages_dir as $page_file) {
$page_file_tmp = explode(".", $page_file); $page_file_tmp = explode(".", $page_file);
$page_basename = $page_file_tmp[0]; $page_basename = $page_file_tmp[0];
$page_class = "class=\"navpage_link\""; $page_class = "class=\"navpage_link\"";
if ($routerRequest["subdomain"] == $site_dir && $routerRequest["page_name"] == $page_basename) { if ($routerRequest["site_name"] == $site_dir && $routerRequest["page_name"] == $page_basename) {
$page_class = "class=\"navpage_link active\""; $page_class = "class=\"navpage_link active\"";
} }
$page_location = $routerConfig["protocol"] . $site_subdomain . $routerRequest["domain"] . "." . $routerRequest["tld"] . "/" . $page_basename; $page_location = "/" . $site_dir . "/" . $page_basename;
$page_name = str_replace("_", " ", $page_basename); $page_name = str_replace("_", " ", $page_basename);
$page_name = explode(".", $page_name)[0]; $page_name = explode(".", $page_name)[0];
@ -73,23 +68,26 @@ function generateNavigation(): string
$page_required_permission = intval($pageMetadata["parameters"]["minimal_permission_level"]); $page_required_permission = intval($pageMetadata["parameters"]["minimal_permission_level"]);
} }
else{ else{
$page_required_permission = $routerConfig["default_page_permission_level"]; $page_required_permission = $routerConfig["page"]["default_permissions"];
} }
} }
elseif($page_file_tmp[1] == "php"){ elseif($page_file_tmp[1] == "php"){
$page_required_permission = getDynamicPermission($page_file_path); $page_required_permission = getDynamicPermission($page_file_path);
} }
else{ else{
$page_required_permission = $routerConfig["default_page_permission_level"]; $page_required_permission = $routerConfig["page"]["default_permissions"];
} }
if($page_required_permission <= $_SESSION["privilege_level"]) { if($page_required_permission <= $_SESSION["privilege_level"]) {
$navpages .= "<li class='navpage_item' data-site='$site_dir' data-page='$page_basename'><a data-site='$site_dir' data-page='$page_basename' href='$page_location' $page_class>$page_name</a></li>"; $navpage_attributes = "data-site='$site_dir' data-page='$page_basename'";
$navigation_pages .= "<li class='navpage_item' $navpage_attributes ><a $navpage_attributes href='$page_location' $page_class>$page_name</a></li>";
} }
} }
if(!empty($navpages)){ if(!empty($navigation_pages)){
$default_page = $routerConfig["default_page"]; $default_page = $routerConfig["default_page"];
$nav_out .= "<li class='navsite_item' data-page='$default_page' data-site='$site_dir'><a data-page='$default_page' data-site='$site_dir' href='$site_location' $site_class>$site_name</a><ul class='navpage_list'>$navpages</ul></li>"; $navsite_attributes = "data-page='$default_page' data-site='$site_dir'";
$nav_out .= "<li class='navsite_item' ><a $navsite_attributes href='$site_location' $site_class>$site_name</a><ul class='navpage_list'>$navigation_pages</ul></li>";
} }
} }

@ -1,5 +1,4 @@
<?php <?php
require_once "lib/inliner.php";
require_once "lib/dynamic_style.php"; require_once "lib/dynamic_style.php";
require_once "lib/script_data.php"; require_once "lib/script_data.php";
function renderDynamicPage($page_file): array function renderDynamicPage($page_file): array
@ -38,7 +37,7 @@ function renderPage($page_name = null, $site_name = null): array
global $routerRequest; global $routerRequest;
if(!$site_name) { if(!$site_name) {
$site_name = $routerRequest["subdomain"]; $site_name = $routerRequest["site_name"];
} }
if(!$page_name){ if(!$page_name){
@ -70,7 +69,7 @@ function renderPage($page_name = null, $site_name = null): array
$page_required_permission = intval($pageMetadata["parameters"]["minimal_permission_level"]); $page_required_permission = intval($pageMetadata["parameters"]["minimal_permission_level"]);
} }
else{ else{
$page_required_permission = $routerConfig["default_page_permission_level"]; $page_required_permission = $routerConfig["page"]["default_permissions"];
} }
if(!empty($pageMetadata["parameters"]["secret"])){ if(!empty($pageMetadata["parameters"]["secret"])){
@ -82,11 +81,11 @@ function renderPage($page_name = null, $site_name = null): array
$is_secret_page = 0; $is_secret_page = 0;
} }
else{ else{
$is_secret_page = $routerConfig["default_page_secret"]; $is_secret_page = $routerConfig["page"]["default_secret"];
} }
} }
else{ else{
$is_secret_page = $routerConfig["default_page_secret"]; $is_secret_page = $routerConfig["page"]["default_secret"];
} }
@ -117,7 +116,7 @@ function renderPage($page_name = null, $site_name = null): array
} }
function getPage($page_name_in = null, $site_name_in = null): string function getPage($site_name_in = null, $page_name_in = null): string
{ {
$page_tmp = renderPage($page_name_in, $site_name_in); $page_tmp = renderPage($page_name_in, $site_name_in);
@ -142,28 +141,24 @@ function getPage($page_name_in = null, $site_name_in = null): string
"defaultPage" => $routerConfig["default_page"], "defaultPage" => $routerConfig["default_page"],
]); ]);
$navpages = generateNavigation(); $navigation = generateNavigation();
$out = $skeleton; $out = $skeleton;
$out = str_replace("__TEMPLATE__NAV__", $navpages, $out); $out = str_replace("__TEMPLATE__NAV__", $navigation, $out);
$out = str_replace("__TEMPLATE__PAGE__", $page, $out); $out = str_replace("__TEMPLATE__PAGE__", $page, $out);
$out = str_replace("__TEMPLATE__DYNASCRIPT__", $dynamic_script, $out); $out = str_replace("__TEMPLATE__DYNAMIC__SCRIPT__", $dynamic_script, $out);
$out = str_replace("__TEMPLATE__DYNASTYLE__", $dynamic_style, $out); $out = str_replace("__TEMPLATE__DYNAMIC__STYLE__", $dynamic_style, $out);
if($routerConfig["inlining"]) {
require_once "lib/inliner.php";
$out = inlineLocalStylesFromHref($out); $out = inlineLocalStylesFromHref($out);
$out = inlineScriptFromSrc($out); $out = inlineScriptFromSrc($out);
}
return str_replace("__TEMPLATE_PAGE_TITLE__", $page_title, $out); return str_replace("__TEMPLATE_PAGE_TITLE__", $page_title, $out);
} }
function getPageEndpoint($page_name, $site_name) :array function getPageEndpoint($page_name, $site_name) :array
{ {
global $routerRequest, $routerConfig; $page_location = "/" . $site_name . "/" . $page_name;
if(!empty($site_name)){
$subdomain = "$site_name.";
}
else{
$subdomain = "";
}
$page_location = $routerConfig["protocol"] . $subdomain . $routerRequest["domain"] . "." . $routerRequest["tld"] . "/" . $page_name;
$page_tmp = renderPage($page_name, $site_name); $page_tmp = renderPage($page_name, $site_name);
return [ return [
"Status" => "Success", "Status" => "Success",

@ -1,68 +1,36 @@
<?php <?php
function initRouter(): bool function initRouter(): array
{ {
global $routerRequest;
global $routerConfig; global $routerConfig;
$routerRequest = array();
$routerRequest["requestAddress"] = array_slice(explode('.', $_SERVER['HTTP_HOST']), -3, 3); //get the last 3 elements $routerRequest["requestAddress"] = array_slice(explode('.', $_SERVER['HTTP_HOST']), -3, 3); //get the last 3 elements
$needsRedirect = false; $request_uri = explode("/", $_SERVER["QUERY_STRING"]);
if(count($routerRequest["requestAddress"]) < 3){ $request_uri = array_slice($request_uri, -3, 3);
// Root domain accessed directly
$routerRequest["subdomain"] = $routerConfig["default_site"];
$routerRequest["domain"] = basename($routerRequest["requestAddress"][0]);
$routerRequest["tld"] = basename($routerRequest["requestAddress"][1]);
$routerRequest["isToApex"] = true;
$routerRequest["site_name"] = basename($request_uri[1]);
$routerRequest["page_name"] = basename($request_uri[2]);
if (empty($routerRequest["site_name"])) {
$routerRequest["site_name"] = $routerConfig["default_site"];
} }
else {
$routerRequest["subdomain"] = basename($routerRequest["requestAddress"][0]);
$routerRequest["domain"] = basename($routerRequest["requestAddress"][1]);
$routerRequest["tld"] = basename($routerRequest["requestAddress"][2]);
if($routerRequest["subdomain"] == $routerConfig["default_site"]){
$routerRequest["subdomain"] = "";
$needsRedirect = true;
}
}
$routerRequest["page_name"] = basename($_SERVER["QUERY_STRING"]);
if (empty($routerRequest["page_name"])) { if (empty($routerRequest["page_name"])) {
// Page name is empty
$needsRedirect = true;
$routerRequest["page_name"] = $routerConfig["default_page"]; $routerRequest["page_name"] = $routerConfig["default_page"];
} }
if ($needsRedirect) {
if(!empty($routerRequest["subdomain"])){
$sub_domain = $routerRequest["subdomain"] . ".";
}
else{
$sub_domain = "";
}
$redirectAddress = $routerConfig["protocol"] .
$sub_domain .
$routerRequest["domain"] . "." .
$routerRequest["tld"] . "/" .
$routerRequest["page_name"];
// Redirect with default page name
header("Location: $redirectAddress");
return false;
}
else{
if($_SERVER["REQUEST_METHOD"] == "POST"){ if($_SERVER["REQUEST_METHOD"] == "POST"){
$routerRequest["type"] = "api"; $routerRequest["type"] = "api";
} }
if(empty($routerRequest["type"])) { if(empty($routerRequest["type"])) {
$routerRequest["type"] = "page"; $routerRequest["type"] = "page";
} }
return true;
} return $routerRequest;
} }

@ -1,4 +1,4 @@
<page minimal_permission_level="1" secret="no" page_title="Memečká"></page> <page minimal_permission_level="1" secret="no" page_title="Memes"></page>
<header> <header>
<h1 class="title">Adlerka Memes</h1> <h1 class="title">Adlerka Memes</h1>
<p>Skoro ako <a href="https://reddit.com/r/adlerka" target="_blank">r/adlerka</a> - ale lepšie.</p> <p>Skoro ako <a href="https://reddit.com/r/adlerka" target="_blank">r/adlerka</a> - ale lepšie.</p>

@ -1,2 +1,2 @@
<page minimal_permission_level="1" secret="no" page_title="Memečká info"></page> <page minimal_permission_level="1" secret="no" page_title="Memes info"></page>
<h1>Vitaj na oficiálnej stránke Memeov o AdlerkaSMP</h1> <h1>Vitaj na stránke Adlerka memes</h1>

@ -5,8 +5,8 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/assets/3rdparty/fonts/remixicon/remixicon.css"> <link rel="stylesheet" href="/assets/3rdparty/fonts/remixicon/remixicon.css">
<link rel="stylesheet" href="/assets/style.css"> <link rel="stylesheet" href="/assets/style.css">
__TEMPLATE__DYNASCRIPT__ __TEMPLATE__DYNAMIC__SCRIPT__
__TEMPLATE__DYNASTYLE__ __TEMPLATE__DYNAMIC__STYLE__
<script async src="https://umami.brn.systems/script.js" data-website-id="95e93885-5c19-4cab-ba9b-2f746a316a2a"></script> <script async src="https://umami.brn.systems/script.js" data-website-id="95e93885-5c19-4cab-ba9b-2f746a316a2a"></script>
<script async src="/assets/script.js"></script> <script async src="/assets/script.js"></script>
<title>Adlerka __TEMPLATE_PAGE_TITLE__</title> <title>Adlerka __TEMPLATE_PAGE_TITLE__</title>