2023-07-17 19:15:18 +00:00
< ? php declare ( strict_types = 1 );
2023-06-08 15:36:44 +00:00
require 'init.php' ;
2022-09-01 02:21:17 +00:00
$pageAddress = substr ( $_SERVER [ 'REQUEST_URI' ], strlen ( CONF [ 'common' ][ 'prefix' ]) + 1 );
2022-11-20 14:11:54 +00:00
if ( strpos ( $pageAddress , '?' ) !== false ) {
parse_str ( substr ( $pageAddress , strpos ( $pageAddress , '?' ) + 1 ), $_GET );
$pageAddress = substr ( $pageAddress , 0 , strpos ( $pageAddress , '?' ));
2022-09-01 02:21:17 +00:00
}
2022-11-20 14:11:54 +00:00
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 ));
2022-09-01 02:21:17 +00:00
2024-04-09 22:54:27 +00:00
if ( PAGE_ADDRESS === 'config.ini' ) {
header ( 'Content-Type: text/plain' );
echo file_get_contents ( ROOT_PATH . '/config.ini' );
exit ();
}
2024-01-27 23:13:29 +00:00
function pageNotFound () : never {
http_response_code ( 404 );
exit ( _ ( 'Page not found.' ));
}
2023-10-29 13:12:28 +00:00
function getPageInformations ( array $pages , array $pageElements ) : array { // Recursively retrieves page metadata from pages.php
2024-01-27 23:13:29 +00:00
if ( ! isset ( $pages [ 'index' ]) OR $pageElements [ 0 ] === 'index' ) {
if ( count ( $pageElements ) !== 1 )
pageNotFound ();
2022-09-16 22:49:07 +00:00
return [
2024-01-27 23:13:29 +00:00
'titles_lineage' => [ $pages [ $pageElements [ 0 ]][ 'title' ] ? ? pageNotFound ()],
'page_metadata' => $pages [ $pageElements [ 0 ]],
2022-12-20 20:17:03 +00:00
'terminal' => $pageElements [ 0 ] !== 'index'
2022-09-16 22:49:07 +00:00
];
2024-01-27 23:13:29 +00:00
}
2022-09-15 19:23:49 +00:00
$result = $pages [ 'index' ][ 'title' ];
2022-09-09 18:16:48 +00:00
if ( ! isset ( $pageElements [ 1 ]))
2022-09-15 19:23:49 +00:00
unset ( $pages [ 'index' ]);
2022-09-09 18:16:48 +00:00
else
2024-01-27 23:13:29 +00:00
$pages = $pages [ array_shift ( $pageElements )] ? ? [];
2022-09-16 22:49:07 +00:00
$results = getPageInformations ( $pages , $pageElements );
$results [ 'titles_lineage' ][] = $result ;
2022-09-09 18:16:48 +00:00
return $results ;
2022-09-09 18:15:10 +00:00
}
2022-09-16 22:49:07 +00:00
$pageInformations = getPageInformations ( PAGES , PAGE_LINEAGE );
define ( 'TITLES_LINEAGE' , array_reverse ( $pageInformations [ 'titles_lineage' ]));
define ( 'PAGE_METADATA' , $pageInformations [ 'page_metadata' ]);
2022-12-20 20:17:03 +00:00
define ( 'PAGE_TERMINAL' , $pageInformations [ 'terminal' ]);
2022-09-09 18:15:10 +00:00
2023-03-27 22:18:37 +00:00
if ( isset ( $_SERVER [ 'SERVER_NAME' ]) !== true )
exit ( 'Missing <code>$_SERVER[\'SERVER_NAME\']</code>' );
if ( in_array ( $_SERVER [ 'SERVER_NAME' ], CONF [ 'common' ][ 'public_domains' ], true ) !== true )
exit ( 'The current <code>$_SERVER[\'SERVER_NAME\']</code> is not allowed in configuration.' );
define ( 'SERVER_NAME' , $_SERVER [ 'SERVER_NAME' ]);
2023-01-29 20:09:00 +00:00
const SESSION_COOKIE_NAME = 'servnest-session-key' ;
2023-06-19 22:36:58 +00:00
function startSession () : void {
2022-09-09 19:53:31 +00:00
session_start ([
2022-11-26 19:10:37 +00:00
'name' => SESSION_COOKIE_NAME ,
2022-09-09 19:53:31 +00:00
'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 ,
]);
}
2022-12-20 20:17:03 +00:00
if ( isset ( $_COOKIE [ SESSION_COOKIE_NAME ]))
startSession (); // Resume session
2022-09-09 19:53:31 +00:00
2023-01-21 03:14:40 +00:00
if ( isset ( $_SESSION [ 'id' ])) {
2023-10-07 22:50:48 +00:00
if ( ! isset ( query ( 'select' , 'users' , [ 'id' => $_SESSION [ 'id' ]], [ 'id' ])[ 0 ]))
2023-08-17 16:20:08 +00:00
logout ();
2023-06-08 15:36:44 +00:00
2023-03-09 00:35:30 +00:00
// Decrypt display username
2023-01-21 03:14:40 +00:00
if ( ! isset ( $_COOKIE [ 'display-username-decryption-key' ]))
output ( 403 , 'The display username decryption key has not been sent.' );
2023-06-14 20:23:15 +00:00
$decryption_result = sodium_crypto_aead_xchacha20poly1305_ietf_decrypt (
2023-01-21 03:14:40 +00:00
$_SESSION [ 'display-username-cyphertext' ],
2023-02-07 21:25:16 +00:00
'' ,
2023-01-21 03:14:40 +00:00
$_SESSION [ 'display-username-nonce' ],
base64_decode ( $_COOKIE [ 'display-username-decryption-key' ])
2023-06-14 20:23:15 +00:00
);
2023-01-21 03:14:40 +00:00
if ( $decryption_result === false )
output ( 403 , 'Unable to decrypt display username.' );
2023-06-14 20:23:15 +00:00
define ( 'DISPLAY_USERNAME' , htmlspecialchars ( $decryption_result ));
2023-01-21 03:14:40 +00:00
2023-03-09 00:35:30 +00:00
// Enable not already enabled services for this user
2023-10-07 22:50:48 +00:00
$user_services = array_filter ( explode ( ',' , query ( 'select' , 'users' , [ 'id' => $_SESSION [ 'id' ]], [ 'services' ])[ 0 ]));
2023-06-02 21:12:59 +00:00
foreach ( SERVICES_USER as $service )
if ( ! in_array ( $service , $user_services , true ) AND CONF [ 'common' ][ 'services' ][ $service ] === 'enabled' ) {
$user_services [] = $service ;
2022-09-09 19:53:31 +00:00
2023-06-02 21:12:59 +00:00
DB -> prepare ( 'UPDATE users SET services = :services WHERE id = :id' )
-> execute ([ ':services' => implode ( ',' , $user_services ), ':id' => $_SESSION [ 'id' ]]);
2023-03-09 00:35:30 +00:00
2023-06-02 21:12:59 +00:00
if ( $service === 'ht' )
htSetupUserFs ( $_SESSION [ 'id' ]);
}
2022-11-21 23:28:19 +00:00
}
2023-06-19 22:36:58 +00:00
function displayFinalMessage ( ? array $data ) : void {
2022-12-20 20:17:03 +00:00
if ( isset ( $data [ 'final_message' ])) {
echo $data [ 'final_message' ];
unset ( $data [ 'final_message' ]);
}
2022-11-20 00:05:03 +00:00
}
2022-12-20 20:17:03 +00:00
if ( $_POST !== []) {
2023-05-09 23:34:45 +00:00
if ( ! in_array ( CONF [ 'common' ][ 'services' ][ 'auth' ], [ 'enabled' , 'no-registration' ], true ) OR ( in_array ( SERVICE , SERVICES_USER , true ) AND CONF [ 'common' ][ 'services' ][ SERVICE ] !== 'enabled' ))
2023-03-09 00:35:30 +00:00
output ( 503 , _ ( 'This service is currently under maintenance. No action can be taken on it until an administrator finishes repairing it.' ));
// Protect against cross-site request forgery if a POST request is received
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>).' );
2023-03-18 17:40:04 +00:00
if ( ! in_array ( $_SERVER [ 'HTTP_SEC_FETCH_SITE' ], [ 'none' , 'same-origin' ], true ))
output ( 403 , 'The <code>Sec-Fetch-Site</code> HTTP header must be <code>same-origin</code> or <code>none</code> when submitting a POST request to prevent Cross-Site Request Forgery (<abbr>CSRF</abbr>).' );
2023-03-09 00:35:30 +00:00
2023-06-08 15:36:44 +00:00
if ( PAGE_METADATA [ 'require-login' ] ? ? true AND ! isset ( $_SESSION [ 'id' ]))
output ( 403 , _ ( 'You need to be logged in to do this.' ));
2023-03-09 00:35:30 +00:00
2023-04-09 22:50:42 +00:00
if ( file_exists ( ROOT_PATH . '/pg-act/' . PAGE_ADDRESS . '.php' ))
require ROOT_PATH . '/pg-act/' . PAGE_ADDRESS . '.php' ;
2022-12-20 20:17:03 +00:00
}
2022-09-09 19:53:31 +00:00
2023-06-19 22:36:58 +00:00
function displayPage ( ? array $data ) : never {
2023-04-09 22:50:42 +00:00
require ROOT_PATH . '/view.php' ;
2022-09-09 19:53:31 +00:00
exit ();
2022-09-07 16:44:49 +00:00
}
2022-12-20 20:17:03 +00:00
displayPage ( $data ? ? = NULL );