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"] )));