2022-09-13 15:14:49 +02:00
< ? php
namespace Misuzu ;
use Index\Autoloader ;
use Index\Environment ;
2023-01-01 19:06:01 +00:00
use Index\Data\ConnectionFailedException ;
use Index\Data\DbTools ;
2023-01-06 20:50:41 +00:00
use Misuzu\Config\IConfig ;
2023-01-01 20:23:53 +00:00
use Misuzu\Config\DbConfig ;
2022-09-13 15:14:49 +02:00
use Misuzu\Net\IPAddress ;
use Misuzu\Users\User ;
use Misuzu\Users\UserNotFoundException ;
use Misuzu\Users\UserSession ;
use Misuzu\Users\UserSessionNotFoundException ;
define ( 'MSZ_STARTUP' , microtime ( true ));
define ( 'MSZ_ROOT' , __DIR__ );
define ( 'MSZ_CLI' , PHP_SAPI === 'cli' );
define ( 'MSZ_DEBUG' , is_file ( MSZ_ROOT . '/.debug' ));
define ( 'MSZ_PUBLIC' , MSZ_ROOT . '/public' );
define ( 'MSZ_SOURCE' , MSZ_ROOT . '/src' );
define ( 'MSZ_LIBRARIES' , MSZ_ROOT . '/lib' );
define ( 'MSZ_CONFIG' , MSZ_ROOT . '/config' );
define ( 'MSZ_TEMPLATES' , MSZ_ROOT . '/templates' );
2023-01-07 04:15:19 +00:00
define ( 'MSZ_MIGRATIONS' , MSZ_ROOT . '/database' );
2022-09-13 15:14:49 +02:00
2023-01-01 19:06:01 +00:00
define ( 'MSZ_NDX_PATH' , MSZ_LIBRARIES . '/index' );
define ( 'MSZ_NDX_PATH_DEV' , MSZ_LIBRARIES . '/index-dev' );
require_once ( MSZ_DEBUG && is_dir ( MSZ_NDX_PATH_DEV ) ? MSZ_NDX_PATH_DEV : MSZ_NDX_PATH ) . '/index.php' ;
2022-09-13 15:14:49 +02:00
Autoloader :: addNamespace ( __NAMESPACE__ , MSZ_SOURCE );
Environment :: setDebug ( MSZ_DEBUG );
mb_internal_encoding ( 'utf-8' );
date_default_timezone_set ( 'utc' );
set_include_path ( get_include_path () . PATH_SEPARATOR . MSZ_ROOT );
set_exception_handler ( function ( \Throwable $ex ) {
if ( MSZ_CLI ) {
echo ( string ) $ex ;
} else {
http_response_code ( 500 );
ob_clean ();
if ( MSZ_DEBUG ) {
header ( 'Content-Type: text/plain; charset=utf-8' );
echo ( string ) $ex ;
} else {
header ( 'Content-Type: text/html; charset-utf-8' );
echo file_get_contents ( MSZ_TEMPLATES . '/500.html' );
}
}
exit ;
});
require_once 'vendor/autoload.php' ;
require_once 'utility.php' ;
require_once 'src/perms.php' ;
require_once 'src/manage.php' ;
require_once 'src/url.php' ;
require_once 'src/Forum/perms.php' ;
require_once 'src/Forum/forum.php' ;
require_once 'src/Forum/leaderboard.php' ;
require_once 'src/Forum/post.php' ;
require_once 'src/Forum/topic.php' ;
require_once 'src/Forum/validate.php' ;
$dbConfig = parse_ini_file ( MSZ_CONFIG . '/config.ini' , true , INI_SCANNER_TYPED );
if ( empty ( $dbConfig )) {
echo 'Database config is missing.' ;
exit ;
}
2023-01-01 19:06:01 +00:00
define ( 'MSZ_DB_INIT' , 'SET SESSION time_zone = \'+00:00\', sql_mode = \'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION\';' );
2022-09-13 15:14:49 +02:00
2023-01-01 19:06:01 +00:00
$db = DbTools :: create ( $dbConfig [ 'dsn' ]);
$db -> execute ( MSZ_DB_INIT );
$dbConfig = $dbConfig [ 'Database' ] ? ? $dbConfig [ 'Database.mysql-main' ] ? ? [];
2022-09-13 15:14:49 +02:00
DB :: init ( DB :: buildDSN ( $dbConfig ), $dbConfig [ 'username' ] ? ? '' , $dbConfig [ 'password' ] ? ? '' , DB :: ATTRS );
2023-01-01 19:06:01 +00:00
DB :: exec ( MSZ_DB_INIT );
2022-09-13 15:14:49 +02:00
2023-01-01 20:23:53 +00:00
$cfg = new DbConfig ( $db );
$cfg -> reload ();
Config :: init ( $cfg );
2023-01-06 20:50:41 +00:00
Mailer :: init ( $cfg -> getValue ( 'mail.method' , IConfig :: T_STR ), [
'host' => $cfg -> getValue ( 'mail.host' , IConfig :: T_STR ),
'port' => $cfg -> getValue ( 'mail.port' , IConfig :: T_INT , 25 ),
'username' => $cfg -> getValue ( 'mail.username' , IConfig :: T_STR ),
'password' => $cfg -> getValue ( 'mail.password' , IConfig :: T_STR ),
'encryption' => $cfg -> getValue ( 'mail.encryption' , IConfig :: T_STR ),
'sender_name' => $cfg -> getValue ( 'mail.sender.name' , IConfig :: T_STR ),
'sender_addr' => $cfg -> getValue ( 'mail.sender.address' , IConfig :: T_STR ),
2022-09-13 15:14:49 +02:00
]);
// replace this with a better storage mechanism
2023-01-06 20:50:41 +00:00
define ( 'MSZ_STORAGE' , $cfg -> getValue ( 'storage.path' , IConfig :: T_STR , MSZ_ROOT . '/store' ));
2022-09-13 15:14:49 +02:00
if ( ! is_dir ( MSZ_STORAGE ))
mkdir ( MSZ_STORAGE , 0775 , true );
2023-01-06 20:35:03 +00:00
$msz = new MisuzuContext ( $db , $cfg );
2023-01-05 03:20:31 +00:00
2022-09-13 15:14:49 +02:00
if ( MSZ_CLI ) { // Temporary backwards compatibility measure, remove this later
if ( realpath ( $_SERVER [ 'SCRIPT_FILENAME' ]) === __FILE__ ) {
if (( $argv [ 1 ] ? ? '' ) === 'cron' && ( $argv [ 2 ] ? ? '' ) === 'low' )
$argv [ 2 ] = '--slow' ;
array_shift ( $argv );
echo shell_exec ( __DIR__ . '/msz ' . implode ( ' ' , $argv ));
}
return ;
}
// Everything below here should eventually be moved to index.php, probably only initialised when required.
// Serving things like the css/js doesn't need to initialise sessions.
ob_start ();
if ( file_exists ( MSZ_ROOT . '/.migrating' )) {
http_response_code ( 503 );
if ( ! isset ( $_GET [ '_check' ])) {
header ( 'Content-Type: text/html; charset-utf-8' );
echo file_get_contents ( MSZ_TEMPLATES . '/503.html' );
}
exit ;
}
if ( ! is_readable ( MSZ_STORAGE ) || ! is_writable ( MSZ_STORAGE )) {
echo 'Cannot access storage directory.' ;
exit ;
}
2023-01-06 20:35:03 +00:00
IPAddress :: init ( $msz );
2022-09-13 15:14:49 +02:00
if ( ! MSZ_DEBUG ) {
2023-01-01 20:33:32 +00:00
$twigCacheDirSfx = GitInfo :: hash ( true );
if ( empty ( $twigCacheDirSfx ))
$twigCacheDirSfx = md5 ( MSZ_ROOT );
$twigCache = sys_get_temp_dir () . '/msz-tpl-' . $twigCacheDirSfx ;
2022-09-13 15:14:49 +02:00
if ( ! is_dir ( $twigCache ))
mkdir ( $twigCache , 0775 , true );
}
2023-01-06 20:35:03 +00:00
Template :: init ( $msz , $twigCache ? ? null , MSZ_DEBUG );
2022-09-13 15:14:49 +02:00
Template :: set ( 'globals' , [
2023-01-06 20:50:41 +00:00
'site_name' => $cfg -> getValue ( 'site.name' , IConfig :: T_STR , 'Misuzu' ),
'site_description' => $cfg -> getValue ( 'site.desc' , IConfig :: T_STR ),
'site_url' => $cfg -> getValue ( 'site.url' , IConfig :: T_STR ),
2023-01-31 16:21:19 +00:00
'site_chat' => $cfg -> getValue ( 'sockChat.chatPath.normal' , IConfig :: T_STR ),
2023-03-09 21:05:37 +00:00
'eeprom' => [
'path' => $cfg -> getValue ( 'eeprom.path' , IConfig :: T_STR ),
'app' => $cfg -> getValue ( 'eeprom.app' , IConfig :: T_STR ),
],
2022-09-13 15:14:49 +02:00
]);
Template :: addPath ( MSZ_TEMPLATES );
if ( isset ( $_COOKIE [ 'msz_uid' ]) && isset ( $_COOKIE [ 'msz_sid' ])) {
$authToken = ( new AuthToken )
-> setUserId ( filter_input ( INPUT_COOKIE , 'msz_uid' , FILTER_SANITIZE_NUMBER_INT ) ? ? 0 )
-> setSessionToken ( filter_input ( INPUT_COOKIE , 'msz_sid' ) ? ? '' );
if ( $authToken -> isValid ())
setcookie ( 'msz_auth' , $authToken -> pack (), strtotime ( '1 year' ), '/' , msz_cookie_domain (), ! empty ( $_SERVER [ 'HTTPS' ]), true );
setcookie ( 'msz_uid' , '' , - 3600 , '/' , '' , ! empty ( $_SERVER [ 'HTTPS' ]), true );
setcookie ( 'msz_sid' , '' , - 3600 , '/' , '' , ! empty ( $_SERVER [ 'HTTPS' ]), true );
}
if ( ! isset ( $authToken ))
$authToken = AuthToken :: unpack ( filter_input ( INPUT_COOKIE , 'msz_auth' ) ? ? '' );
if ( $authToken -> isValid ()) {
try {
$sessionInfo = $authToken -> getSession ();
if ( $sessionInfo -> hasExpired ()) {
$sessionInfo -> delete ();
} elseif ( $sessionInfo -> getUserId () === $authToken -> getUserId ()) {
$userInfo = $sessionInfo -> getUser ();
if ( ! $userInfo -> isDeleted ()) {
$sessionInfo -> setCurrent ();
$userInfo -> setCurrent ();
2023-01-05 18:33:03 +00:00
$sessionInfo -> bump ( $_SERVER [ 'REMOTE_ADDR' ]);
2022-09-13 15:14:49 +02:00
if ( $sessionInfo -> shouldBumpExpire ())
setcookie ( 'msz_auth' , $authToken -> pack (), $sessionInfo -> getExpiresTime (), '/' , msz_cookie_domain (), ! empty ( $_SERVER [ 'HTTPS' ]), true );
}
}
} catch ( UserNotFoundException $ex ) {
UserSession :: unsetCurrent ();
User :: unsetCurrent ();
} catch ( UserSessionNotFoundException $ex ) {
UserSession :: unsetCurrent ();
User :: unsetCurrent ();
}
if ( UserSession :: hasCurrent ()) {
2023-01-05 18:33:03 +00:00
$userInfo -> bumpActivity ( $_SERVER [ 'REMOTE_ADDR' ]);
2022-09-13 15:14:49 +02:00
} else {
setcookie ( 'msz_auth' , '' , - 9001 , '/' , msz_cookie_domain (), ! empty ( $_SERVER [ 'HTTPS' ]), true );
setcookie ( 'msz_auth' , '' , - 9001 , '/' , '' , ! empty ( $_SERVER [ 'HTTPS' ]), true );
}
}
2023-01-06 20:50:41 +00:00
CSRF :: setGlobalSecretKey ( $cfg -> getValue ( 'csrf.secret' , IConfig :: T_STR , 'soup' ));
2023-01-05 18:33:03 +00:00
CSRF :: setGlobalIdentity (
UserSession :: hasCurrent ()
? UserSession :: getCurrent () -> getToken ()
: ( $_SERVER [ 'REMOTE_ADDR' ] ? ? '::1' )
);
2022-09-13 15:14:49 +02:00
function mszLockdown () : void {
2023-01-01 20:23:53 +00:00
global $misuzuBypassLockdown , $cfg ;
2022-09-13 15:14:49 +02:00
2023-01-06 20:50:41 +00:00
if ( $cfg -> getValue ( 'private.enabled' , IConfig :: T_BOOL )) {
2022-09-13 15:14:49 +02:00
$onLoginPage = $_SERVER [ 'PHP_SELF' ] === url ( 'auth-login' );
$onPasswordPage = parse_url ( $_SERVER [ 'PHP_SELF' ], PHP_URL_PATH ) === url ( 'auth-forgot' );
$misuzuBypassLockdown = ! empty ( $misuzuBypassLockdown ) || $onLoginPage ;
if ( ! $misuzuBypassLockdown ) {
if ( UserSession :: hasCurrent ()) {
2023-01-06 20:50:41 +00:00
$privatePermCat = $cfg -> getValue ( 'private.perm.cat' , IConfig :: T_STR );
$privatePermVal = $cfg -> getValue ( 'private.perm.val' , IConfig :: T_INT );
2022-09-13 15:14:49 +02:00
if ( ! empty ( $privatePermCat ) && $privatePermVal > 0 ) {
if ( ! perms_check_user ( $privatePermCat , User :: getCurrent () -> getId (), $privatePermVal )) {
// au revoir
UserSession :: unsetCurrent ();
User :: unsetCurrent ();
}
}
2023-01-06 20:50:41 +00:00
} elseif ( ! $onLoginPage && ! ( $onPasswordPage && $cfg -> getValue ( 'private.allow_password_reset' , IConfig :: T_BOOL , true ))) {
2022-09-13 15:14:49 +02:00
url_redirect ( 'auth-login' );
exit ;
}
}
}
}
if ( parse_url ( $_SERVER [ 'PHP_SELF' ], PHP_URL_PATH ) !== '/index.php' )
mszLockdown ();
if ( ! empty ( $userInfo ))
Template :: set ( 'current_user' , $userInfo );
$inManageMode = str_starts_with ( $_SERVER [ 'REQUEST_URI' ], '/manage' );
$hasManageAccess = User :: hasCurrent ()
&& ! User :: getCurrent () -> hasActiveWarning ()
&& perms_check_user ( MSZ_PERMS_GENERAL , User :: getCurrent () -> getId (), MSZ_PERM_GENERAL_CAN_MANAGE );
Template :: set ( 'has_manage_access' , $hasManageAccess );
if ( $inManageMode ) {
if ( ! $hasManageAccess ) {
echo render_error ( 403 );
exit ;
}
Template :: set ( 'manage_menu' , manage_get_menu ( User :: getCurrent () -> getId ()));
}