245 lines
9.8 KiB
PHP
245 lines
9.8 KiB
PHP
<?php
|
|
|
|
use php\Database;
|
|
use php\EmailRule;
|
|
use php\EqualsRule;
|
|
use php\IsNotBlankRule;
|
|
use php\IsNotSetRule;
|
|
use php\IsSetRule;
|
|
use php\LengthRule;
|
|
use php\Mailer;
|
|
use php\Mediawiki;
|
|
use php\Response;
|
|
use php\TrackingManager;
|
|
use php\UserManager;
|
|
use php\Util;
|
|
use php\Validator;
|
|
|
|
/** @noinspection PhpIncludeInspection Exists after `npm run deploy` */
|
|
require_once __DIR__ . "/.vendor/autoload.php";
|
|
|
|
|
|
// Preamble
|
|
$_POST = Util::parse_post();
|
|
$config = Util::read_config() ?? Util::http_exit(500);
|
|
$logger = Util::create_logger($config["logger"]);
|
|
$conn = Database::connect($config["database"]["filename"]);
|
|
|
|
$mailer = new Mailer($logger->withName("Mailer"), $config, $conn);
|
|
$mediawiki = new Mediawiki($logger->withName("Mediawiki"));
|
|
$user_manager = new UserManager($conn, $mailer);
|
|
$tracking_manager = new TrackingManager($conn, $mailer, $mediawiki);
|
|
|
|
if (Database::is_empty($conn)) {
|
|
$logger->info("Database does not exist. Creating new database at '{$config["database"]["filename"]}'.");
|
|
$mailer->install();
|
|
$user_manager->install();
|
|
$tracking_manager->install();
|
|
}
|
|
|
|
session_start();
|
|
$_SESSION["token"] = $_SESSION["token"] ?? Util::generate_csrf_token($logger);
|
|
|
|
|
|
// Process request
|
|
$response = null;
|
|
|
|
if (isset($_POST["action"])) {
|
|
// POST requests; alter state
|
|
switch ($_POST["action"]) {
|
|
case "register":
|
|
$response =
|
|
Validator::validate_inputs($_SESSION, ["uuid" => [new IsNotSetRule()]])
|
|
?? Validator::validate_inputs($_POST,
|
|
[
|
|
"token" => [new EqualsRule($_SESSION["token"])],
|
|
"email" => [new IsSetRule(), new EmailRule()],
|
|
"password" => [
|
|
new IsSetRule(),
|
|
new LengthRule(UserManager::MIN_PASSWORD_LENGTH, UserManager::MAX_PASSWORD_LENGTH)
|
|
],
|
|
"password_confirm" => [new IsSetRule()],
|
|
])
|
|
?? $user_manager->register($_POST["email"], $_POST["password"], $_POST["password_confirm"]);
|
|
break;
|
|
case "login":
|
|
$response =
|
|
Validator::validate_inputs($_SESSION, ["uuid" => [new IsNotSetRule()]])
|
|
?? Validator::validate_inputs($_POST,
|
|
[
|
|
"token" => [new EqualsRule($_SESSION["token"])],
|
|
"email" => [new IsSetRule(), new EmailRule()],
|
|
"password" => [
|
|
new IsSetRule(),
|
|
new LengthRule(UserManager::MIN_PASSWORD_LENGTH, UserManager::MAX_PASSWORD_LENGTH)
|
|
],
|
|
]);
|
|
if ($response !== null) break;
|
|
|
|
[$response, $uuid] = $user_manager->check_login($_POST["email"], $_POST["password"]);
|
|
if ($response->satisfied) $_SESSION["uuid"] = $uuid;
|
|
break;
|
|
case "logout":
|
|
$response =
|
|
Validator::validate_inputs($_SESSION, ["uuid" => [new IsSetRule()]])
|
|
?? Validator::validate_inputs($_POST, ["token" => [new EqualsRule($_SESSION["token"])]]);
|
|
if ($response !== null) break;
|
|
|
|
session_destroy();
|
|
session_start();
|
|
$_SESSION["token"] = Util::generate_csrf_token($logger) ?? Util::http_exit(500);
|
|
$response = new Response(payload: null, satisfied: true);
|
|
break;
|
|
case "update-email":
|
|
$response =
|
|
Validator::validate_inputs($_SESSION, ["uuid" => [new IsSetRule()]])
|
|
?? Validator::validate_inputs($_POST,
|
|
[
|
|
"token" => [new EqualsRule($_SESSION["token"])],
|
|
"email" => [new IsSetRule(), new EmailRule()],
|
|
])
|
|
?? $user_manager->set_email($_SESSION["uuid"], $_POST["email"]);
|
|
break;
|
|
case "verify-email":
|
|
$response =
|
|
Validator::validate_inputs($_SESSION, ["uuid" => [new IsSetRule()]])
|
|
?? Validator::validate_inputs($_POST,
|
|
[
|
|
"token" => [new IsSetRule()],
|
|
"email" => [new IsSetRule(), new EmailRule()],
|
|
])
|
|
?? $user_manager->verify_email($_POST["email"], $_POST["token"]);
|
|
break;
|
|
case "resend-verify-email":
|
|
$response =
|
|
Validator::validate_inputs($_SESSION, ["uuid" => [new IsSetRule()]])
|
|
?? Validator::validate_inputs($_POST, ["token" => [new EqualsRule($_SESSION["token"])]])
|
|
?? $user_manager->resend_verify_email($_SESSION["uuid"]);
|
|
break;
|
|
case "update-password":
|
|
$response =
|
|
Validator::validate_inputs($_SESSION, ["uuid" => [new IsSetRule()]])
|
|
?? Validator::validate_inputs($_POST,
|
|
[
|
|
"token" => [new EqualsRule($_SESSION["token"])],
|
|
"password_old" => [
|
|
new IsSetRule(),
|
|
new LengthRule(UserManager::MIN_PASSWORD_LENGTH, UserManager::MAX_PASSWORD_LENGTH)
|
|
],
|
|
"password_new" => [
|
|
new IsSetRule(),
|
|
new LengthRule(UserManager::MIN_PASSWORD_LENGTH, UserManager::MAX_PASSWORD_LENGTH)
|
|
],
|
|
"password_confirm" => [new IsSetRule()],
|
|
])
|
|
?? $user_manager->set_password(
|
|
$_SESSION["uuid"],
|
|
$_POST["password_old"],
|
|
$_POST["password_new"],
|
|
$_POST["password_confirm"]
|
|
);
|
|
break;
|
|
case "user-delete":
|
|
$response =
|
|
Validator::validate_inputs($_SESSION, ["uuid" => [new IsSetRule()]])
|
|
?? Validator::validate_inputs($_POST, ["token" => [new EqualsRule($_SESSION["token"])]])
|
|
?? $user_manager->delete($_SESSION["uuid"]);
|
|
break;
|
|
case "add-tracking":
|
|
$response =
|
|
Validator::validate_inputs($_SESSION, ["uuid" => [new IsSetRule()]])
|
|
?? Validator::validate_inputs($_POST,
|
|
[
|
|
"token" => [new EqualsRule($_SESSION["token"])],
|
|
"person_name" => [
|
|
new IsSetRule(),
|
|
new LengthRule(TrackingManager::MIN_TITLE_LENGTH, TrackingManager::MAX_TITLE_LENGTH),
|
|
new IsNotBlankRule()
|
|
],
|
|
])
|
|
?? $tracking_manager->add_tracking($_SESSION["uuid"], $_POST["person_name"]);
|
|
break;
|
|
case "remove-tracking":
|
|
$response =
|
|
Validator::validate_inputs($_SESSION, ["uuid" => [new IsSetRule()]])
|
|
?? Validator::validate_inputs($_POST,
|
|
[
|
|
"token" => [new EqualsRule($_SESSION["token"])],
|
|
"person_name" => [
|
|
new IsSetRule(),
|
|
new LengthRule(TrackingManager::MIN_TITLE_LENGTH, TrackingManager::MAX_TITLE_LENGTH),
|
|
new IsNotBlankRule()
|
|
],
|
|
])
|
|
?? $tracking_manager->remove_tracking($_SESSION["uuid"], $_POST["person_name"]);
|
|
break;
|
|
default:
|
|
$response = new Response(
|
|
payload: ["target" => null, "message" => "Unknown POST action '{$_POST["action"]}'."],
|
|
satisfied: false
|
|
);
|
|
break;
|
|
}
|
|
} elseif (isset($_GET["action"])) {
|
|
// GET requests; do not alter state
|
|
switch ($_GET["action"]) {
|
|
case "start-session":
|
|
if (!isset($_SESSION["uuid"])) {
|
|
$response = new Response(payload: ["target" => null, "message" => null], satisfied: false);
|
|
break;
|
|
}
|
|
|
|
$response = $user_manager->user_exists($_SESSION["uuid"]);
|
|
if (!$response->satisfied) {
|
|
session_destroy();
|
|
session_start();
|
|
$_SESSION["token"] = Util::generate_csrf_token($logger) ?? Util::http_exit(500);
|
|
}
|
|
break;
|
|
case "get-user-data":
|
|
$response =
|
|
Validator::validate_inputs($_SESSION, ["uuid" => [new IsSetRule()]])
|
|
?? $user_manager->get_user_data($_SESSION["uuid"]);
|
|
break;
|
|
case "list-trackings":
|
|
$response =
|
|
Validator::validate_inputs($_SESSION, ["uuid" => [new IsSetRule()]])
|
|
?? $tracking_manager->list_trackings($_SESSION["uuid"]);
|
|
break;
|
|
default:
|
|
$response = new Response(
|
|
payload: ["target" => null, "message" => "Unknown GET action '{$_GET["action"]}'."],
|
|
satisfied: false
|
|
);
|
|
}
|
|
} elseif ($argc > 1) {
|
|
// CLI
|
|
if (hash_equals($config["admin"]["cli_secret"], "REPLACE THIS WITH A SECRET VALUE"))
|
|
exit("Default value for 'cli_secret' detected. Feature disabled.");
|
|
if (!hash_equals($config["admin"]["cli_secret"], $argv[2]))
|
|
exit("Incorrect value for 'cli_secret'.");
|
|
|
|
switch ($argv[1]) {
|
|
case "update-all-trackings":
|
|
$logger->info("Updating all trackings.");
|
|
$tracking_manager->update_trackings($tracking_manager->list_all_unique_person_names());
|
|
exit("Successfully updated all trackings.");
|
|
case "process-email-queue":
|
|
$logger->info("Processing email queue.");
|
|
$mailer->process_queue();
|
|
exit("Successfully processed email queue.");
|
|
default:
|
|
exit("Unknown CLI action '$argv[1]'.");
|
|
}
|
|
} else {
|
|
// No action given, nothing done, so that's a success
|
|
$response = new Response(payload: null, satisfied: true);
|
|
}
|
|
|
|
header("Content-type:application/json;charset=utf-8");
|
|
exit(json_encode(array(
|
|
"payload" => $response->payload,
|
|
"satisfied" => $response->satisfied,
|
|
"token" => $_SESSION["token"]
|
|
)));
|