404 Not Found'; exit; } // Define base paths and load classes include_once(dirname(dirname(__FILE__)) . "/config/bootstrap.php"); /* * Validate application state before processing request */ // Check prerequisites $prerequisites = new Prerequisites(); $results = $prerequisites->validate(); if (count($prerequisites->getErrors()) > 0) { $prerequisites->generateWebSummary($results); exit; } // Connect to the database try { // SQLite will just create this if it doesn't exist. $db = new PDO("sqlite:" . DB_FILE); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); } catch (PDOException $e) { throw new SetupException( "Database connection failed: " . $e->getMessage(), 'database_connection', 0, $e ); } // Do any necessary database migrations $migrator = new Migrator($db); $migrator->migrate(); // Make sure the initial setup is complete unless we're already heading to setup if (!(preg_match('/setup$/', $path))) { // Make sure required tables (user, settings) are populated $user_count = (int) $db->query("SELECT COUNT(*) FROM user")->fetchColumn(); $settings_count = (int) $db->query("SELECT COUNT(*) FROM settings")->fetchColumn(); // If either required table has no records, redirect to setup. if ($user_count === 0 || $settings_count === 0){ $init = require APP_ROOT . '/config/init.php'; header('Location: ' . $init['base_path'] . 'setup'); exit; }; } /* * Begin processing request */ // Initialize application context with all dependencies global $app; $app = [ 'db' => $db, 'config' => (new ConfigModel($db))->loadFromDatabase(), 'user' => (new UserModel($db))->loadFromDatabase(), ]; // Start a session and generate a CSRF Token Session::start(); Session::generateCsrfToken(); // Remove the base path from the URL if (strpos($path, $app['config']->basePath) === 0) { $path = substr($path, strlen($app['config']->basePath)); } // strip the trailing slash from the resulting route $path = trim($path, '/'); // Set route context for logging Log::setRouteContext("$method $path"); Log::debug("Path requested: {$path}"); // if this is a POST and we aren't in setup, // make sure there's a valid session // if not, redirect to /login or die as appropriate if ($method === 'POST' && $path != 'setup') { if ($path != 'login'){ if (!Session::isValid($_POST['csrf_token'])) { // Invalid session - redirect to /login Log::info('Attempt to POST with invalid session. Redirecting to login.'); header('Location: ' . Util::buildRelativeUrl($app->config->basePath, 'login')); exit; } } else { if (!Session::isValidCsrfToken($_POST['csrf_token'])) { // Just die if the token is invalid on login Log::error("Attempt to log in with invalid CSRF token."); die('Invalid CSRF token'); exit; } } } // Set content type header('Content-Type: text/html; charset=utf-8'); // Render the requested route or throw a 404 $router = new Router(); if (!$router->route($path, $method)){ http_response_code(404); echo "404 - Page Not Found"; exit; }