synced-timer/src/index.php

257 lines
8.0 KiB
PHP

<?php
define('L_EXEC', true);
require_once './theme.php';
require_once './strings.php';
require_once './storageHelper.php';
class SyncedTimer
{
private $_serverConfig = array(
"hideIndexPhp" => true
);
private $_themeConfig = array();
private $_translations;
private $_basepath;
private $_resourcePath;
private $_path;
private $_dataFile = "/config/data/data.json";
private $_storageHelper;
public function __construct($translations)
{
session_start();
$this->_translations = $translations;
$this->_storageHelper = new StorageHelper($this->_dataFile);
$this->_calculateBasepath();
$this->_themeConfig["basePath"] = $this->_basepath;
$this->_themeConfig["mainIcon"] = $this->_resourcePath . "static/img/IconSmallSquareOutline.png";
$this->_theme = new LandingpageTheme($this->_themeConfig, $this->_storageHelper, $this->_translations);
$this->_processRequest();
}
private function _processRequest()
{
$this->_updatePermissions();
$this->_checkPagePermissions();
if ($this->_stringEndsWith($this->_path, "submit")) {
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
$this->_redirect('/');
}
switch ($this->_path) {
case '/login/submit':
$this->_handleLoginSubmit();
break;
case '/logout/submit':
unset($_SESSION["auth"]);
$this->_redirect('/');
break;
case '/manage/submit':
$this->_handleManageSubmit();
$this->_redirect('/manage');
break;
default:
$this->_redirect("/");
break;
}
} else {
if ($this->_path === '/logout') {
$this->_redirect('/');
} else {
$paramList = explode('/', ltrim($this->_path, '/'), 2);
$endpoint = $paramList[0];
$username = $paramList[1];
if ($endpoint === "api" && isset($username))
$this->_printJson($username);
else
$this->_theme->printPage($endpoint, $username);
}
}
unset($_SESSION['lastResult']);
}
private function _calculateBasepath()
{
if ($this->_serverConfig['hideIndexPhp']) {
$this->_basepath = str_replace(basename($_SERVER["SCRIPT_NAME"]), '', $_SERVER['SCRIPT_NAME']);
$this->_resourcePath = $this->_basepath;
} else {
$this->_basepath = $_SERVER["SCRIPT_NAME"];
$this->_resourcePath = str_replace(basename($_SERVER["SCRIPT_NAME"]), '', $_SERVER['SCRIPT_NAME']);
}
$this->_basepath = rtrim($this->_basepath, "/ ");
if (($this->_basepath !== '' && strpos($_SERVER['REQUEST_URI'], $this->_basepath) === false) || $_SERVER['REQUEST_URI'] === $this->_basepath)
$this->_path = "/";
else
$this->_path = str_replace($this->_basepath, "", $_SERVER['REQUEST_URI']);
}
private function _redirect($path)
{
header('Location: ' . $this->_basepath . $path);
die();
}
//
// - Page printer (theme)
//
private function _printJson($username)
{
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
$allUserdata = $this->_storageHelper->loadUserdata();
if (array_key_exists($username, $allUserdata)) {
$userdata = $allUserdata[$username];
die(json_encode(array(
"status" => 200,
"data" => array(
"time" => $userdata["time"],
"startedAt" => $userdata["startedAt"],
"header" => $userdata["header"],
"soundEnabled" => $userdata["soundEnabled"],
"repeatEnabled" => $userdata["repeatEnabled"],
)
)));
} else {
http_response_code(404);
die(json_encode(array(
"status" => 404,
"data" => null
)));
}
}
// -----------------------
// - Permission handlers -
// -----------------------
private function _updatePermissions()
{
$_SESSION['permissions'][''] = false;
$_SESSION['permissions']['t'] = true;
$_SESSION['permissions']['api'] = true;
$_SESSION['permissions']['login'] = !$this->_isUserAuthenticated();
$_SESSION['permissions']['logout'] = $this->_isUserAuthenticated();
$_SESSION['permissions']['manage'] = $this->_isUserAuthenticated();
}
private function _checkPagePermissions()
{
$pageRedirectOnInsufficientPermissionsPriority = [
0 => "manage",
1 => "login"
];
$page = explode("/", $this->_path)[1];
if (!isset($_SESSION['permissions'][$page])) {
$this->_redirect('/');
} else if ($_SESSION['permissions'][$page] === false) {
if (!$this->_isUserAuthenticated()) {
$_SESSION['lastResult'] = 'loginRequired';
}
if ($this->_path === '/' || $this->_path === '') {
// if the root is opened, do not throw an error!
unset($_SESSION['lastResult']);
}
// redirect to the first page the user has access to
foreach ($pageRedirectOnInsufficientPermissionsPriority as $page) {
if ($_SESSION['permissions'][$page])
$this->_redirect("/" . $page);
}
die($this->_translations['results']['noPermissionToAnyPage']);
}
}
// -------------------
// - Submit handlers -
// -------------------
private function _handleLoginSubmit()
{
$username = $_POST["username"];
$password = $_POST["password"];
$userData = $this->_storageHelper->loadUserdata();
if (array_key_exists($username, $userData) && password_verify($password, $userData[$username]['password'])) {
$_SESSION["auth"]["loggedIn"] = true;
$_SESSION["auth"]["username"] = $username;
$_SESSION['lastResult'] = "loginSuccess";
$this->_redirect("/manage");
} else {
$_SESSION['lastResult'] = "loginFailed";
$this->_redirect("/login");
}
}
private function _handleManageSubmit()
{
$time = $_POST["time"];
$header = $_POST["header"];
$soundEnabled = $_POST["soundEnabled"] === "on";
$repeatEnabled = $_POST["repeatEnabled"] === "on";
$startedAt = time();
$newData = array(
"time" => intval($time),
"header" => $header,
"soundEnabled" => $soundEnabled,
"repeatEnabled" => $repeatEnabled,
"startedAt" => $startedAt
);
$this->_storageHelper->writeUserdata($_SESSION["auth"]["username"], $newData);
$_SESSION['lastResult'] = "timerSetSuccessfully";
}
// ----------------------------
// - General helper functions -
// ----------------------------
private function _isUserAuthenticated()
{
$authenticated =
isset($_SESSION['auth'])
&& isset($_SESSION['auth']['loggedIn'])
&& $_SESSION['auth']['loggedIn'] === true
&& isset($_SESSION['auth']['username']);
if (!$authenticated && isset($_SESSION['auth'])) {
unset($_SESSION['auth']);
}
return $authenticated;
}
private function _stringStartsWith($haystack, $needle)
{
$length = strlen($needle);
return substr($haystack, 0, $length) === $needle;
}
private function _stringEndsWith($haystack, $needle)
{
$length = strlen($needle);
if (!$length) {
return true;
}
return substr($haystack, -$length) === $needle;
}
}
new SyncedTimer($translations);