death-notifier/src/main/api.php

132 lines
5.8 KiB
PHP

<?php
use com\fwdekker\deathnotifier\ActionDispatcher;
use com\fwdekker\deathnotifier\ActionMethod;
use com\fwdekker\deathnotifier\Config;
use com\fwdekker\deathnotifier\Database;
use com\fwdekker\deathnotifier\EmulateCronAction;
use com\fwdekker\deathnotifier\IllegalArgumentError;
use com\fwdekker\deathnotifier\LoggerUtil;
use com\fwdekker\deathnotifier\mailer\MailManager;
use com\fwdekker\deathnotifier\mailer\ProcessEmailQueueAction;
use com\fwdekker\deathnotifier\mediawiki\MediaWiki;
use com\fwdekker\deathnotifier\Response;
use com\fwdekker\deathnotifier\StartSessionAction;
use com\fwdekker\deathnotifier\tracking\AddTrackingAction;
use com\fwdekker\deathnotifier\tracking\ListTrackingsAction;
use com\fwdekker\deathnotifier\tracking\RemoveTrackingAction;
use com\fwdekker\deathnotifier\tracking\TrackingManager;
use com\fwdekker\deathnotifier\tracking\UpdateTrackingsAction;
use com\fwdekker\deathnotifier\user\GetPublicUserDataAction;
use com\fwdekker\deathnotifier\user\LoginAction;
use com\fwdekker\deathnotifier\user\LogoutAction;
use com\fwdekker\deathnotifier\user\RegisterAction;
use com\fwdekker\deathnotifier\user\ResendVerifyEmailAction;
use com\fwdekker\deathnotifier\user\ResetPasswordAction;
use com\fwdekker\deathnotifier\user\SendPasswordResetAction;
use com\fwdekker\deathnotifier\user\ToggleNotificationsAction;
use com\fwdekker\deathnotifier\user\ChangeEmailAction;
use com\fwdekker\deathnotifier\user\ChangePasswordAction;
use com\fwdekker\deathnotifier\user\UserDeleteAction;
use com\fwdekker\deathnotifier\user\UserManager;
use com\fwdekker\deathnotifier\user\ValidatePasswordResetTokenAction;
use com\fwdekker\deathnotifier\user\VerifyEmailAction;
use com\fwdekker\deathnotifier\Util;
/** @noinspection PhpIncludeInspection Exists after `npm run deploy` */
require_once __DIR__ . "/.vendor/autoload.php";
$logger = LoggerUtil::with_name();
// Wrap everything in try-catch to always return *something* to user
try {
// Preamble
$config = Config::get();
if (hash_equals($config["admin"]["cli_secret"], "REPLACE THIS WITH A SECRET VALUE"))
throw new IllegalArgumentError(
"You must set a CLI secret in the configuration file before running Death Notifier."
);
$db = new Database($config["database"]["filename"]);
$mediawiki = new MediaWiki();
$mail_manager = new MailManager($db->conn);
$user_manager = new UserManager($db->conn);
$tracking_manager = new TrackingManager($db->conn);
$db->auto_install($mail_manager, $user_manager, $tracking_manager);
$db->auto_migrate();
session_start();
$_SESSION["token"] = $_SESSION["token"] ?? Util::generate_csrf_token();
// Set up request handlers
$dispatcher = new ActionDispatcher();
// GET actions
$dispatcher->register_actions([
[ActionMethod::GET, "start-session", new StartSessionAction($user_manager)],
[ActionMethod::GET, "get-user-data", new GetPublicUserDataAction($user_manager)],
[ActionMethod::GET, "list-trackings", new ListTrackingsAction($tracking_manager)],
[ActionMethod::GET, "validate-password-reset-token", new ValidatePasswordResetTokenAction($user_manager)],
]);
// POST actions
$dispatcher->register_actions([
[ActionMethod::POST, "register", new RegisterAction($db->conn, $user_manager, $mail_manager)],
[ActionMethod::POST, "login", new LoginAction($user_manager)],
[ActionMethod::POST, "logout", new LogoutAction()],
[ActionMethod::POST, "user-delete", new UserDeleteAction($user_manager)],
[ActionMethod::POST, "update-email", new ChangeEmailAction($db->conn, $user_manager, $mail_manager)],
[ActionMethod::POST, "verify-email", new VerifyEmailAction($db->conn, $user_manager, $mail_manager)],
[ActionMethod::POST, "resend-verify-email", new ResendVerifyEmailAction($db->conn, $user_manager, $mail_manager)],
[ActionMethod::POST, "toggle-notifications", new ToggleNotificationsAction($db->conn, $user_manager)],
[ActionMethod::POST, "update-password", new ChangePasswordAction($db->conn, $user_manager, $mail_manager)],
[ActionMethod::POST, "send-password-reset", new SendPasswordResetAction($db->conn, $user_manager, $mail_manager)],
[ActionMethod::POST, "reset-password", new ResetPasswordAction($db->conn, $user_manager, $mail_manager)],
[ActionMethod::POST, "add-tracking", new AddTrackingAction($tracking_manager, $mediawiki)],
[ActionMethod::POST, "remove-tracking", new RemoveTrackingAction($tracking_manager)],
]);
// CLI actions
$cli_actions = [
new UpdateTrackingsAction($db->conn, $tracking_manager, $mediawiki, $mail_manager),
new ProcessEmailQueueAction($mail_manager),
];
$dispatcher->register_actions([
[ActionMethod::CLI, "update-trackings", $cli_actions[0]],
[ActionMethod::CLI, "process-email-queue", $cli_actions[1]],
[ActionMethod::CLI, "emulate-cron", new EmulateCronAction($cli_actions)],
]);
// Handle request
if (!isset($_SERVER["REQUEST_METHOD"]))
$response = $dispatcher->handle(ActionMethod::CLI, Util::parse_cli());
else if ($_SERVER["REQUEST_METHOD"] === "GET")
$response = $dispatcher->handle(ActionMethod::GET, $_GET);
else if ($_SERVER["REQUEST_METHOD"] === "POST")
$response = $dispatcher->handle(ActionMethod::POST, Util::parse_post());
else
$response = Response::satisfied();
} catch (Throwable $exception) {
$response = Response::unsatisfied("An unhandled error occurred. Please try again later.");
$logger->error("An unhandled error occurred. Please try again later.", ["cause" => $exception]);
}
// Respond
header("Content-type:application/json;charset=utf-8");
exit(json_encode([
"payload" => $response->payload,
"satisfied" => $response->satisfied,
"token" => $_SESSION["token"],
]));