servnest/router.php

116 lines
4.5 KiB
PHP

<?php
define('CONF', parse_ini_file(__DIR__ . '/config.ini', true, INI_SCANNER_TYPED));
define('DB', new PDO('sqlite:' . CONF['common']['root_path'] . '/db/niver.db'));
foreach (array_diff(scandir(CONF['common']['root_path'] . '/fn'), array('..', '.')) as $file)
require CONF['common']['root_path'] . '/fn/' . $file;
require 'pages.php';
const LF = "\n";
const PLACEHOLDER_DOMAIN = 'example'; // From RFC2606: Reserved Top Level DNS Names > 2. TLDs for Testing, & Documentation Examples
const PLACEHOLDER_IPV6 = '2001:db8::3'; // From RFC3849: IPv6 Address Prefix Reserved for Documentation
const PLACEHOLDER_IPV4 = '203.0.113.42'; // From RFC5737: IPv4 Address Blocks Reserved for Documentation
if ($_SERVER['REQUEST_URI'] === '/sftpgo-auth.php')
return;
$pageAddress = substr($_SERVER['REQUEST_URI'], strlen(CONF['common']['prefix']) + 1);
if (strpos($pageAddress, '?') !== false) {
parse_str(substr($pageAddress, strpos($pageAddress, '?') + 1), $_GET);
$pageAddress = substr($pageAddress, 0, strpos($pageAddress, '?'));
}
define('PAGE_URL', $pageAddress);
define('PAGE_ADDRESS', $pageAddress . ((substr($pageAddress, -1) === '/' OR $pageAddress === '') ? 'index' : ''));
define('PAGE_LINEAGE', explode('/', PAGE_ADDRESS));
define('SERVICE', dirname(PAGE_ADDRESS));
define('PAGE', basename(PAGE_ADDRESS, '.php'));
function getPageInformations($pages, $pageElements) {
if (!isset($pages['index']) OR $pageElements[0] === 'index')
return [
'titles_lineage' => [$pages[$pageElements[0]]['title'] ?? false],
'page_metadata' => $pages[$pageElements[0]] ?? NULL,
'terminal' => $pageElements[0] !== 'index'
];
$result = $pages['index']['title'];
if (!isset($pageElements[1]))
unset($pages['index']);
else
$pages = $pages[array_shift($pageElements)] ?? false;
$results = getPageInformations($pages, $pageElements);
$results['titles_lineage'][] = $result;
return $results;
}
$pageInformations = getPageInformations(PAGES, PAGE_LINEAGE);
define('TITLES_LINEAGE', array_reverse($pageInformations['titles_lineage']));
define('PAGE_METADATA', $pageInformations['page_metadata']);
define('PAGE_TERMINAL', $pageInformations['terminal']);
if (!TITLES_LINEAGE[array_key_last(TITLES_LINEAGE)]) {
http_response_code(404);
exit('Page not found.');
}
const SESSION_COOKIE_NAME = 'niver-session-key';
function startSession() {
session_start([
'name' => SESSION_COOKIE_NAME,
'sid_length' => 64,
'sid_bits_per_character' => 6,
'cookie_secure' => true,
'cookie_httponly' => true,
'cookie_samesite' => 'Strict',
'cookie_path' => CONF['common']['prefix'] . '/',
'cookie_lifetime' => 432000, // = 60*60*24*5 = 5 days
'gc_maxlifetime' => 10800,
'use_strict_mode' => true,
'use_cookies' => true,
'use_only_cookies' => true,
]);
}
if (isset($_COOKIE[SESSION_COOKIE_NAME]))
startSession(); // Resume session
if (in_array(SERVICE, ['reg', 'ns', 'ht']) AND CONF[SERVICE]['enabled'] !== true)
output(403, 'Ce service est désactivé.');
// Protect against cross-site request forgery if a POST request is received
if ($_POST !== []) {
if (isset($_SERVER['HTTP_SEC_FETCH_SITE']) !== true)
output(403, 'The <code>Sec-Fetch-Site</code> HTTP header is required when submitting a POST request to prevent Cross-Site Request Forgery (<abbr>CSRF</abbr>).');
if ($_SERVER['HTTP_SEC_FETCH_SITE'] !== 'same-origin')
output(403, 'The <code>Sec-Fetch-Site</code> HTTP header must be <code>same-origin</code> when submitting a POST request to prevent Cross-Site Request Forgery (<abbr>CSRF</abbr>).');
}
if (isset($_SERVER['SERVER_NAME']) !== true)
output(500, 'Missing $_SERVER[\'SERVER_NAME\']');
if (in_array($_SERVER['SERVER_NAME'], CONF['common']['public_domains'], true) !== true)
output(500, 'The current server name is not allowed in configuration.');
define('SERVER_NAME', $_SERVER['SERVER_NAME']);
function displayFinalMessage($data) {
if (isset($data['final_message'])) {
echo $data['final_message'];
unset($data['final_message']);
}
}
if ($_POST !== []) {
if (PAGE_METADATA['require-login'] ?? true !== false) {
if (isset($_SESSION['id']) !== true)
output(403, 'Vous devez être connecté·e à un compte pour effectuer cette action.');
if (isset(query('select', 'users', ['id' => $_SESSION['id']], 'id')[0]) !== true)
output(403, 'Ce compte n\'existe plus. Déconnectez-vous pour terminer cette session fantôme.');
}
if (file_exists('pg-act/' . PAGE_ADDRESS . '.php'))
require 'pg-act/' . PAGE_ADDRESS . '.php';
}
function displayPage($data) {
require 'view.php';
exit();
}
displayPage($data ??= NULL);