Switch to Sasae.

This commit is contained in:
flash 2023-08-31 21:33:34 +00:00
parent 9682fa595a
commit 1da6470928
15 changed files with 503 additions and 410 deletions

View file

@ -3,7 +3,7 @@
"prefer-stable": true, "prefer-stable": true,
"require": { "require": {
"flashwave/index": "dev-master", "flashwave/index": "dev-master",
"twig/twig": "^3.0", "flashwave/sasae": "dev-master",
"erusev/parsedown": "~1.6", "erusev/parsedown": "~1.6",
"chillerlan/php-qrcode": "^4.3", "chillerlan/php-qrcode": "^4.3",
"symfony/mailer": "^6.0", "symfony/mailer": "^6.0",

202
composer.lock generated
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "c76eb19b0eb02b6a9fccb4b63f50d165", "content-hash": "313710f128265bd0f0f9e7687058324b",
"packages": [ "packages": [
{ {
"name": "chillerlan/php-qrcode", "name": "chillerlan/php-qrcode",
@ -348,7 +348,7 @@
"source": { "source": {
"type": "git", "type": "git",
"url": "https://git.flash.moe/flash/index.git", "url": "https://git.flash.moe/flash/index.git",
"reference": "6a38f803f4b3e49296f7472743e7c683c496ec19" "reference": "1172115e699acf44580ffcdcf86c9e3987d2f969"
}, },
"require": { "require": {
"ext-mbstring": "*", "ext-mbstring": "*",
@ -386,7 +386,48 @@
], ],
"description": "Composer package for the common library for my projects.", "description": "Composer package for the common library for my projects.",
"homepage": "https://railgun.sh/index", "homepage": "https://railgun.sh/index",
"time": "2023-08-22T00:04:20+00:00" "time": "2023-08-28T13:58:51+00:00"
},
{
"name": "flashwave/sasae",
"version": "dev-master",
"source": {
"type": "git",
"url": "https://git.flash.moe/flash/sasae.git",
"reference": "739669fc8ce7ea862ed2129cb24976ceebd0f4c7"
},
"require": {
"flashwave/index": "dev-master",
"php": ">=8.2",
"twig/html-extra": "^3.7",
"twig/twig": "^3.7"
},
"require-dev": {
"phpstan/phpstan": "^1.10",
"phpunit/phpunit": "^10.2"
},
"default-branch": true,
"type": "library",
"autoload": {
"psr-4": {
"Sasae\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"bsd-3-clause-clear"
],
"authors": [
{
"name": "flashwave",
"email": "packagist@flash.moe",
"homepage": "https://flash.moe",
"role": "mom"
}
],
"description": "A wrapper for Twig with added common functionality.",
"homepage": "https://railgun.sh/sasae",
"time": "2023-08-24T23:24:45+00:00"
}, },
{ {
"name": "matomo/device-detector", "name": "matomo/device-detector",
@ -1049,16 +1090,16 @@
}, },
{ {
"name": "symfony/polyfill-ctype", "name": "symfony/polyfill-ctype",
"version": "v1.27.0", "version": "v1.28.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git", "url": "https://github.com/symfony/polyfill-ctype.git",
"reference": "5bbc823adecdae860bb64756d639ecfec17b050a" "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a", "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb",
"reference": "5bbc823adecdae860bb64756d639ecfec17b050a", "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1073,7 +1114,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-main": "1.27-dev" "dev-main": "1.28-dev"
}, },
"thanks": { "thanks": {
"name": "symfony/polyfill", "name": "symfony/polyfill",
@ -1111,7 +1152,7 @@
"portable" "portable"
], ],
"support": { "support": {
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0" "source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0"
}, },
"funding": [ "funding": [
{ {
@ -1127,20 +1168,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-11-03T14:55:06+00:00" "time": "2023-01-26T09:26:14+00:00"
}, },
{ {
"name": "symfony/polyfill-intl-idn", "name": "symfony/polyfill-intl-idn",
"version": "v1.27.0", "version": "v1.28.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-intl-idn.git", "url": "https://github.com/symfony/polyfill-intl-idn.git",
"reference": "639084e360537a19f9ee352433b84ce831f3d2da" "reference": "ecaafce9f77234a6a449d29e49267ba10499116d"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/639084e360537a19f9ee352433b84ce831f3d2da", "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/ecaafce9f77234a6a449d29e49267ba10499116d",
"reference": "639084e360537a19f9ee352433b84ce831f3d2da", "reference": "ecaafce9f77234a6a449d29e49267ba10499116d",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1154,7 +1195,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-main": "1.27-dev" "dev-main": "1.28-dev"
}, },
"thanks": { "thanks": {
"name": "symfony/polyfill", "name": "symfony/polyfill",
@ -1198,7 +1239,7 @@
"shim" "shim"
], ],
"support": { "support": {
"source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.27.0" "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.28.0"
}, },
"funding": [ "funding": [
{ {
@ -1214,20 +1255,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-11-03T14:55:06+00:00" "time": "2023-01-26T09:30:37+00:00"
}, },
{ {
"name": "symfony/polyfill-intl-normalizer", "name": "symfony/polyfill-intl-normalizer",
"version": "v1.27.0", "version": "v1.28.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-intl-normalizer.git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git",
"reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6" "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/19bd1e4fcd5b91116f14d8533c57831ed00571b6", "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92",
"reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6", "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1239,7 +1280,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-main": "1.27-dev" "dev-main": "1.28-dev"
}, },
"thanks": { "thanks": {
"name": "symfony/polyfill", "name": "symfony/polyfill",
@ -1282,7 +1323,7 @@
"shim" "shim"
], ],
"support": { "support": {
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.27.0" "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.28.0"
}, },
"funding": [ "funding": [
{ {
@ -1298,20 +1339,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-11-03T14:55:06+00:00" "time": "2023-01-26T09:26:14+00:00"
}, },
{ {
"name": "symfony/polyfill-mbstring", "name": "symfony/polyfill-mbstring",
"version": "v1.27.0", "version": "v1.28.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git", "url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" "reference": "42292d99c55abe617799667f454222c54c60e229"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229",
"reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", "reference": "42292d99c55abe617799667f454222c54c60e229",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1326,7 +1367,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-main": "1.27-dev" "dev-main": "1.28-dev"
}, },
"thanks": { "thanks": {
"name": "symfony/polyfill", "name": "symfony/polyfill",
@ -1365,7 +1406,7 @@
"shim" "shim"
], ],
"support": { "support": {
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0" "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0"
}, },
"funding": [ "funding": [
{ {
@ -1381,20 +1422,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-11-03T14:55:06+00:00" "time": "2023-07-28T09:04:16+00:00"
}, },
{ {
"name": "symfony/polyfill-php72", "name": "symfony/polyfill-php72",
"version": "v1.27.0", "version": "v1.28.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-php72.git", "url": "https://github.com/symfony/polyfill-php72.git",
"reference": "869329b1e9894268a8a61dabb69153029b7a8c97" "reference": "70f4aebd92afca2f865444d30a4d2151c13c3179"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/869329b1e9894268a8a61dabb69153029b7a8c97", "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/70f4aebd92afca2f865444d30a4d2151c13c3179",
"reference": "869329b1e9894268a8a61dabb69153029b7a8c97", "reference": "70f4aebd92afca2f865444d30a4d2151c13c3179",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1403,7 +1444,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-main": "1.27-dev" "dev-main": "1.28-dev"
}, },
"thanks": { "thanks": {
"name": "symfony/polyfill", "name": "symfony/polyfill",
@ -1441,7 +1482,7 @@
"shim" "shim"
], ],
"support": { "support": {
"source": "https://github.com/symfony/polyfill-php72/tree/v1.27.0" "source": "https://github.com/symfony/polyfill-php72/tree/v1.28.0"
}, },
"funding": [ "funding": [
{ {
@ -1457,7 +1498,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-11-03T14:55:06+00:00" "time": "2023-01-26T09:26:14+00:00"
}, },
{ {
"name": "symfony/service-contracts", "name": "symfony/service-contracts",
@ -1542,17 +1583,81 @@
"time": "2023-05-23T14:45:45+00:00" "time": "2023-05-23T14:45:45+00:00"
}, },
{ {
"name": "twig/twig", "name": "twig/html-extra",
"version": "v3.7.0", "version": "v3.7.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/twigphp/Twig.git", "url": "https://github.com/twigphp/html-extra.git",
"reference": "5cf942bbab3df42afa918caeba947f1b690af64b" "reference": "95ceb36e70fa8d07af08cf5135ecbf5e0bd8f386"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/5cf942bbab3df42afa918caeba947f1b690af64b", "url": "https://api.github.com/repos/twigphp/html-extra/zipball/95ceb36e70fa8d07af08cf5135ecbf5e0bd8f386",
"reference": "5cf942bbab3df42afa918caeba947f1b690af64b", "reference": "95ceb36e70fa8d07af08cf5135ecbf5e0bd8f386",
"shasum": ""
},
"require": {
"php": ">=7.1.3",
"symfony/mime": "^5.4|^6.0",
"twig/twig": "^2.7|^3.0"
},
"require-dev": {
"symfony/phpunit-bridge": "^5.4|^6.3"
},
"type": "library",
"autoload": {
"psr-4": {
"Twig\\Extra\\Html\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
}
],
"description": "A Twig extension for HTML",
"homepage": "https://twig.symfony.com",
"keywords": [
"html",
"twig"
],
"support": {
"source": "https://github.com/twigphp/html-extra/tree/v3.7.1"
},
"funding": [
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/twig/twig",
"type": "tidelift"
}
],
"time": "2023-07-29T15:34:56+00:00"
},
{
"name": "twig/twig",
"version": "v3.7.1",
"source": {
"type": "git",
"url": "https://github.com/twigphp/Twig.git",
"reference": "a0ce373a0ca3bf6c64b9e3e2124aca502ba39554"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/a0ce373a0ca3bf6c64b9e3e2124aca502ba39554",
"reference": "a0ce373a0ca3bf6c64b9e3e2124aca502ba39554",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1562,7 +1667,7 @@
}, },
"require-dev": { "require-dev": {
"psr/container": "^1.0|^2.0", "psr/container": "^1.0|^2.0",
"symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0" "symfony/phpunit-bridge": "^5.4.9|^6.3"
}, },
"type": "library", "type": "library",
"autoload": { "autoload": {
@ -1598,7 +1703,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/twigphp/Twig/issues", "issues": "https://github.com/twigphp/Twig/issues",
"source": "https://github.com/twigphp/Twig/tree/v3.7.0" "source": "https://github.com/twigphp/Twig/tree/v3.7.1"
}, },
"funding": [ "funding": [
{ {
@ -1610,7 +1715,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2023-07-26T07:16:09+00:00" "time": "2023-08-28T11:09:02+00:00"
} }
], ],
"packages-dev": [ "packages-dev": [
@ -1680,7 +1785,8 @@
"aliases": [], "aliases": [],
"minimum-stability": "dev", "minimum-stability": "dev",
"stability-flags": { "stability-flags": {
"flashwave/index": 20 "flashwave/index": 20,
"flashwave/sasae": 20
}, },
"prefer-stable": true, "prefer-stable": true,
"prefer-lowest": false, "prefer-lowest": false,

View file

@ -5,6 +5,7 @@ use RuntimeException;
use Misuzu\Auth\AuthTokenBuilder; use Misuzu\Auth\AuthTokenBuilder;
use Misuzu\Auth\AuthTokenCookie; use Misuzu\Auth\AuthTokenCookie;
use Misuzu\Auth\AuthTokenInfo; use Misuzu\Auth\AuthTokenInfo;
use Sasae\SasaeEnvironment;
require_once __DIR__ . '/../misuzu.php'; require_once __DIR__ . '/../misuzu.php';
@ -38,44 +39,6 @@ if(file_exists(MSZ_ROOT . '/.migrating')) {
exit; exit;
} }
if(!MSZ_DEBUG) {
$twigCacheDirSfx = GitInfo::hash(true);
if(empty($twigCacheDirSfx))
$twigCacheDirSfx = md5(MSZ_ROOT);
$twigCache = sys_get_temp_dir() . '/msz-tpl-' . $twigCacheDirSfx;
if(!is_dir($twigCache))
mkdir($twigCache, 0775, true);
}
$globals = $cfg->getValues([
['site.name:s', 'Misuzu'],
'site.desc:s',
'site.url:s',
'eeprom.path:s',
'eeprom.app:s',
['csrf.secret:s', 'soup'],
]);
Template::init($msz, $twigCache ?? null, MSZ_DEBUG);
Template::set('globals', [
'site_name' => $globals['site.name'],
'site_description' => $globals['site.desc'],
'site_url' => $globals['site.url'],
'eeprom' => [
'path' => $globals['eeprom.path'],
'app' => $globals['eeprom.app'],
],
]);
$mszAssetsInfo = json_decode(file_get_contents(MSZ_ASSETS . '/current.json'));
if(!empty($mszAssetsInfo))
Template::set('assets', $mszAssetsInfo);
unset($mszAssetsInfo);
Template::addPath(MSZ_TEMPLATES);
$tokenPacker = $msz->createAuthTokenPacker(); $tokenPacker = $msz->createAuthTokenPacker();
if(filter_has_var(INPUT_COOKIE, 'msz_auth')) if(filter_has_var(INPUT_COOKIE, 'msz_auth'))
@ -156,95 +119,21 @@ if($tokenInfo->hasUserId() && $tokenInfo->hasSessionToken()) {
$msz->getAuthInfo()->setInfo($tokenInfo, $userInfo, $sessionInfo, $userInfoReal); $msz->getAuthInfo()->setInfo($tokenInfo, $userInfo, $sessionInfo, $userInfoReal);
if(!empty($userInfo))
$userInfo = $users->getUser((string)$userInfo->getId(), 'id');
if(!empty($userInfoReal))
$userInfoReal = $users->getUser((string)$userInfoReal->getId(), 'id');
CSRF::init( CSRF::init(
$globals['csrf.secret'], $cfg->getString('csrf.secret', 'soup'),
($msz->isLoggedIn() ? $sessionInfo->getToken() : $_SERVER['REMOTE_ADDR']) ($msz->isLoggedIn() ? $sessionInfo->getToken() : $_SERVER['REMOTE_ADDR'])
); );
if(!empty($userInfo)) { $msz->startTemplating();
Template::set('current_user', $userInfo);
Template::set('current_user_ban_info', $msz->tryGetActiveBan());
}
if(!empty($userInfoReal)) {
Template::set('current_user_real', $userInfoReal);
Template::set('current_user_real_colour', $users->getUserColour($userInfoReal));
}
$inManageMode = str_starts_with($_SERVER['REQUEST_URI'], '/manage');
Template::set('header_menu', $msz->getHeaderMenu($userInfo ?? null));
Template::set('user_menu', $msz->getUserMenu($userInfo ?? null, $inManageMode));
Template::set('display_timings_info', MSZ_DEBUG || $msz->getAuthInfo()->getPerms('global')->check(Perm::G_TIMINGS_VIEW));
if($inManageMode) {
$hasManageAccess = false;
if($msz->isLoggedIn() && !$msz->hasActiveBan()) {
$manageUser = $msz->getActiveUser();
$manageUserId = $manageUser->getId();
$manageGlobalPerms = $msz->getAuthInfo()->getPerms('global');
if($manageGlobalPerms->check(Perm::G_IS_JANITOR)) {
$hasManageAccess = true;
$manageMenu = [
'General' => [
'Overview' => url('manage-general-overview'),
],
];
if($manageGlobalPerms->check(Perm::G_LOGS_VIEW))
$manageMenu['General']['Logs'] = url('manage-general-logs');
if($manageGlobalPerms->check(Perm::G_EMOTES_MANAGE))
$manageMenu['General']['Emoticons'] = url('manage-general-emoticons');
if($manageGlobalPerms->check(Perm::G_CONFIG_MANAGE))
$manageMenu['General']['Settings'] = url('manage-general-settings');
$manageUserPerms = $msz->getAuthInfo()->getPerms('user');
if($manageUserPerms->check(Perm::U_USERS_MANAGE))
$manageMenu['Users & Roles']['Users'] = url('manage-users');
if($manageUserPerms->check(Perm::U_ROLES_MANAGE))
$manageMenu['Users & Roles']['Roles'] = url('manage-roles');
if($manageUserPerms->check(Perm::U_NOTES_MANAGE))
$manageMenu['Users & Roles']['Notes'] = url('manage-users-notes');
if($manageUserPerms->check(Perm::U_WARNINGS_MANAGE))
$manageMenu['Users & Roles']['Warnings'] = url('manage-users-warnings');
if($manageUserPerms->check(Perm::U_BANS_MANAGE))
$manageMenu['Users & Roles']['Bans'] = url('manage-users-bans');
if($manageGlobalPerms->check(Perm::G_NEWS_POSTS_MANAGE))
$manageMenu['News']['Posts'] = url('manage-news-posts');
if($manageGlobalPerms->check(Perm::G_NEWS_CATEGORIES_MANAGE))
$manageMenu['News']['Categories'] = url('manage-news-categories');
if($manageGlobalPerms->check(Perm::G_FORUM_CATEGORIES_MANAGE))
$manageMenu['Forum']['Permission Calculator'] = url('manage-forum-categories');
if($manageGlobalPerms->check(Perm::G_FORUM_TOPIC_REDIRS_MANAGE))
$manageMenu['Forum']['Topic Redirects'] = url('manage-forum-topic-redirs');
if($manageGlobalPerms->check(Perm::G_CL_CHANGES_MANAGE))
$manageMenu['Changelog']['Changes'] = url('manage-changelog-changes');
if($manageGlobalPerms->check(Perm::G_CL_TAGS_MANAGE))
$manageMenu['Changelog']['Tags'] = url('manage-changelog-tags');
Template::set('manage_menu', $manageMenu);
}
}
if(!$hasManageAccess)
Template::throwError(403);
}
$mszRequestPath = $request->getPath(); $mszRequestPath = $request->getPath();
$mszLegacyPathPrefix = MSZ_PUBLIC . '-legacy/'; $mszLegacyPathPrefix = MSZ_PUBLIC . '-legacy/';
$mszLegacyPath = realpath($mszLegacyPathPrefix . $mszRequestPath); $mszLegacyPath = realpath($mszLegacyPathPrefix . $mszRequestPath);
if(!empty($mszLegacyPath) && str_starts_with($mszLegacyPath, $mszLegacyPathPrefix)) { if(!empty($mszLegacyPath) && str_starts_with($mszLegacyPath, $mszLegacyPathPrefix)) {
if(str_starts_with($mszRequestPath, '/manage') && !$msz->hasManageAccess())
Template::throwError(403);
if(is_dir($mszLegacyPath)) if(is_dir($mszLegacyPath))
$mszLegacyPath .= '/index.php'; $mszLegacyPath .= '/index.php';
@ -254,5 +143,5 @@ if(!empty($mszLegacyPath) && str_starts_with($mszLegacyPath, $mszLegacyPathPrefi
} }
} }
$msz->setUpHttp(); $msz->startRouter();
$msz->dispatchHttp($request); $msz->dispatchRouter($request);

View file

@ -172,9 +172,11 @@ class DbConfig implements IConfig {
if(is_string($spec)) { if(is_string($spec)) {
$name = $spec; $name = $spec;
$default = null; $default = null;
$alias = null;
} elseif(is_array($spec) && !empty($spec)) { } elseif(is_array($spec) && !empty($spec)) {
$name = $spec[0]; $name = $spec[0];
$default = $spec[1] ?? null; $default = $spec[1] ?? null;
$alias = $spec[2] ?? null;
} else } else
throw new InvalidArgumentException('$specs array contains an invalid entry.'); throw new InvalidArgumentException('$specs array contains an invalid entry.');
@ -188,6 +190,7 @@ class DbConfig implements IConfig {
'name' => $name, 'name' => $name,
'type' => $type, 'type' => $type,
'default' => $default, 'default' => $default,
'alias' => $alias,
]; ];
} }
@ -201,6 +204,8 @@ class DbConfig implements IConfig {
break; break;
} }
$resultName = $spec['alias'] ?? $spec['name'];
if(!isset($info)) { if(!isset($info)) {
$defaultValue = $spec['default'] ?? null; $defaultValue = $spec['default'] ?? null;
if($spec['type'] !== '') if($spec['type'] !== '')
@ -214,11 +219,11 @@ class DbConfig implements IConfig {
default => throw new RuntimeException('Invalid type letter encountered.'), default => throw new RuntimeException('Invalid type letter encountered.'),
}); });
$results[$spec['name']] = $defaultValue; $results[$resultName] = $defaultValue;
continue; continue;
} }
$results[$spec['name']] = match($spec['type']) { $results[$resultName] = match($spec['type']) {
's' => $info->getString(), 's' => $info->getString(),
'a' => $info->getArray(), 'a' => $info->getArray(),
'i' => $info->getInteger(), 'i' => $info->getInteger(),

View file

@ -8,6 +8,7 @@ use Index\Data\Migration\FsDbMigrationRepo;
use Index\Http\HttpFx; use Index\Http\HttpFx;
use Index\Http\HttpRequest; use Index\Http\HttpRequest;
use Index\Routing\Router; use Index\Routing\Router;
use Sasae\SasaeEnvironment;
use Misuzu\Template; use Misuzu\Template;
use Misuzu\Auth\AuthInfo; use Misuzu\Auth\AuthInfo;
use Misuzu\Auth\AuthTokenPacker; use Misuzu\Auth\AuthTokenPacker;
@ -69,6 +70,7 @@ class MisuzuContext {
private Forum $forum; private Forum $forum;
private Permissions $perms; private Permissions $perms;
private AuthInfo $authInfo; private AuthInfo $authInfo;
private SasaeEnvironment $templating;
public function __construct(IDbConnection $dbConn, IConfig $config) { public function __construct(IDbConnection $dbConn, IConfig $config) {
$this->dbConn = $dbConn; $this->dbConn = $dbConn;
@ -218,10 +220,10 @@ class MisuzuContext {
} }
$userId = (string)$userInfo->getId(); $userId = (string)$userInfo->getId();
if(array_key_exists($userId, $this->activeBansCache)) if(!array_key_exists($userId, $this->activeBansCache))
return $this->activeBansCache[$userId]; $this->activeBansCache[$userId] = $this->bans->tryGetActiveBan($userId);
return $this->activeBansCache[$userId] = $this->bans->tryGetActiveBan($userId); return $this->activeBansCache[$userId];
} }
public function hasActiveBan(UserInfo|string|null $userInfo = null): bool { public function hasActiveBan(UserInfo|string|null $userInfo = null): bool {
@ -241,125 +243,51 @@ class MisuzuContext {
); );
} }
public function getHeaderMenu(?UserInfo $userInfo): array { private ?bool $hasManageAccess = null;
$hasUserInfo = $userInfo?->isDeleted() === false; public function hasManageAccess(): bool {
$menu = []; $this->hasManageAccess ??= $this->authInfo->isLoggedIn() && !$this->hasActiveBan()
&& $this->getAuthInfo()->getPerms('global')->check(Perm::G_IS_JANITOR);
$home = [ return $this->hasManageAccess;
'title' => 'Home',
'url' => url('index'),
'menu' => [],
];
if($hasUserInfo)
$home['menu'][] = [
'title' => 'Members',
'url' => url('user-list'),
];
$home['menu'][] = [
'title' => 'Changelog',
'url' => url('changelog-index'),
];
$home['menu'][] = [
'title' => 'Contact',
'url' => url('info', ['title' => 'contact']),
];
$home['menu'][] = [
'title' => 'Rules',
'url' => url('info', ['title' => 'rules']),
];
$menu[] = $home;
$menu[] = [
'title' => 'News',
'url' => url('news-index'),
];
$forum = [
'title' => 'Forum',
'url' => url('forum-index'),
'menu' => [],
];
if($this->authInfo->getPerms('global')->check(Perm::G_FORUM_LEADERBOARD_VIEW))
$forum['menu'][] = [
'title' => 'Leaderboard',
'url' => url('forum-leaderboard'),
];
$menu[] = $forum;
$chatPath = $this->config->getString('sockChat.chatPath.normal');
if(!empty($chatPath))
$menu[] = [
'title' => 'Chat',
'url' => $chatPath,
];
return $menu;
} }
public function getUserMenu(?UserInfo $userInfo, bool $inBroomCloset): array { public function getWebAssetInfo(): ?object {
$menu = []; return json_decode(file_get_contents(MSZ_ASSETS . '/current.json'));
if($userInfo === null) {
$menu[] = [
'title' => 'Register',
'url' => url('auth-register'),
'icon' => 'fas fa-user-plus fa-fw',
];
$menu[] = [
'title' => 'Log in',
'url' => url('auth-login'),
'icon' => 'fas fa-sign-in-alt fa-fw',
];
} else {
$menu[] = [
'title' => 'Profile',
'url' => url('user-profile', ['user' => $userInfo->getId()]),
'icon' => 'fas fa-user fa-fw',
];
$menu[] = [
'title' => 'Settings',
'url' => url('settings-index'),
'icon' => 'fas fa-cog fa-fw',
];
$menu[] = [
'title' => 'Search',
'url' => url('search-index'),
'icon' => 'fas fa-search fa-fw',
];
if(!$this->hasActiveBan($userInfo) && $this->authInfo->getPerms('global')->check(Perm::G_IS_JANITOR)) {
// restore behaviour where clicking this button switches between
// site version and broom version
if($inBroomCloset)
$menu[] = [
'title' => 'Exit Broom Closet',
'url' => url('index'),
'icon' => 'fas fa-door-open fa-fw',
];
else
$menu[] = [
'title' => 'Enter Broom Closet',
'url' => url('manage-index'),
'icon' => 'fas fa-door-closed fa-fw',
];
} }
$menu[] = [ private ?string $chatUrl = null;
'title' => 'Log out', public function getChatURL(): string {
'url' => url('auth-logout'), $this->chatUrl ??= $this->config->getString('sockChat.chatPath.normal');
'icon' => 'fas fa-sign-out-alt fa-fw', return $this->chatUrl;
];
} }
return $menu; public function startTemplating(): void {
$globals = $this->config->getValues([
['site.name:s', 'Misuzu', 'site_name'],
['site.desc:s', '', 'site_description'],
['site.url:s', '', 'site_url'],
['eeprom.path:s', '', 'eeprom_path'],
['eeprom.app:s', '', 'eeprom_app'],
]);
$authInfo = $this->getAuthInfo();
$globals['assets'] = $this->getWebAssetInfo();
$globals['auth_info'] = $authInfo;
$globals['active_ban_info'] = $this->tryGetActiveBan();
$globals['display_timings_info'] = MSZ_DEBUG
|| $authInfo->getPerms('global')->check(Perm::G_TIMINGS_VIEW);
$templating = new SasaeEnvironment(
MSZ_TEMPLATES,
cache: MSZ_DEBUG ? null : ['Misuzu', GitInfo::hash(true)],
debug: MSZ_DEBUG
);
$templating->addExtension(new MisuzuSasaeExtension($this));
$templating->addGlobal('globals', $globals);
Template::init($templating);
} }
public function setUpHttp(): void { public function startRouter(): void {
$this->router = new HttpFx; $this->router = new HttpFx;
$this->router->use('/', function($response) { $this->router->use('/', function($response) {
$response->setPoweredBy('Misuzu'); $response->setPoweredBy('Misuzu');
@ -369,7 +297,7 @@ class MisuzuContext {
$this->registerHttpRoutes(); $this->registerHttpRoutes();
} }
public function dispatchHttp(?HttpRequest $request = null): void { public function dispatchRouter(?HttpRequest $request = null): void {
$this->router->dispatch($request); $this->router->dispatch($request);
} }

View file

@ -0,0 +1,238 @@
<?php
namespace Misuzu;
use Index\DateTime;
use Misuzu\MisuzuContext;
use Misuzu\Tools;
use Misuzu\Parsers\Parser;
use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
use Twig\TwigFunction;
final class MisuzuSasaeExtension extends AbstractExtension {
private MisuzuContext $ctx;
public function __construct(MisuzuContext $ctx) {
$this->ctx = $ctx;
}
public function getFilters() {
return [
new TwigFilter('country_name', Tools::countryName(...)),
new TwigFilter('parse_text', fn(string $text, int $parser): string => Parser::instance($parser)->parseText($text)),
new TwigFilter('time_format', $this->timeFormat(...)),
];
}
public function getFunctions() {
return [
new TwigFunction('url_construct', 'url_construct'),
new TwigFunction('url', 'url'),
new TwigFunction('csrf_token', CSRF::token(...)),
new TwigFunction('git_commit_hash', GitInfo::hash(...)),
new TwigFunction('git_tag', GitInfo::tag(...)),
new TwigFunction('git_branch', GitInfo::branch(...)),
new TwigFunction('startup_time', fn(float $time = MSZ_STARTUP) => microtime(true) - $time),
new TwigFunction('sql_query_count', $this->ctx->getDbQueryCount(...)),
new TwigFunction('msz_header_menu', $this->getHeaderMenu(...)),
new TwigFunction('msz_user_menu', $this->getUserMenu(...)),
new TwigFunction('msz_manage_menu', $this->getManageMenu(...)),
];
}
public function timeFormat(DateTime|string|int|null $dateTime): string {
if($dateTime === null)
return 'never';
if(is_string($dateTime))
$dateTime = new DateTime($dateTime);
elseif(is_int($dateTime))
$dateTime = DateTime::fromUnixTimeSeconds($dateTime);
$string = '';
$now = DateTime::now();
$isDiffYear = $now->getYear() !== $dateTime->getYear();
if($isDiffYear || $now->getMonth() !== $dateTime->getMonth() || $now->getDay() !== $dateTime->getDay()) {
$string .= $dateTime->format('M jS');
if($isDiffYear)
$string .= $dateTime->format(' Y');
$string .= ', ';
}
$string .= $dateTime->format('G:i ');
$string .= $dateTime->isUTC() ? 'UTC' : $dateTime->format('T');
return $string;
}
public function getHeaderMenu(): array {
$menu = [];
$authInfo = $this->ctx->getAuthInfo();
$home = [
'title' => 'Home',
'url' => url('index'),
'menu' => [],
];
if($authInfo->isLoggedIn())
$home['menu'][] = [
'title' => 'Members',
'url' => url('user-list'),
];
$home['menu'][] = [
'title' => 'Changelog',
'url' => url('changelog-index'),
];
$home['menu'][] = [
'title' => 'Contact',
'url' => url('info', ['title' => 'contact']),
];
$home['menu'][] = [
'title' => 'Rules',
'url' => url('info', ['title' => 'rules']),
];
$menu[] = $home;
$menu[] = [
'title' => 'News',
'url' => url('news-index'),
];
$forum = [
'title' => 'Forum',
'url' => url('forum-index'),
'menu' => [],
];
if($authInfo->getPerms('global')->check(Perm::G_FORUM_LEADERBOARD_VIEW))
$forum['menu'][] = [
'title' => 'Leaderboard',
'url' => url('forum-leaderboard'),
];
$menu[] = $forum;
$chatPath = $this->ctx->getChatURL();
if(!empty($chatPath))
$menu[] = [
'title' => 'Chat',
'url' => $chatPath,
];
return $menu;
}
public function getUserMenu(bool $inBroomCloset, string $manageUrl = ''): array {
$menu = [];
$authInfo = $this->ctx->getAuthInfo();
if($authInfo->isLoggedIn()) {
$userInfo = $authInfo->getUserInfo();
$menu[] = [
'title' => 'Profile',
'url' => url('user-profile', ['user' => $userInfo->getId()]),
'icon' => 'fas fa-user fa-fw',
];
$menu[] = [
'title' => 'Settings',
'url' => url('settings-index'),
'icon' => 'fas fa-cog fa-fw',
];
$menu[] = [
'title' => 'Search',
'url' => url('search-index'),
'icon' => 'fas fa-search fa-fw',
];
if(!$this->ctx->hasActiveBan($userInfo) && $authInfo->getPerms('global')->check(Perm::G_IS_JANITOR)) {
// restore behaviour where clicking this button switches between
// site version and broom version
if($inBroomCloset)
$menu[] = [
'title' => 'Exit Broom Closet',
'url' => $manageUrl === '' ? url('index') : $manageUrl,
'icon' => 'fas fa-door-open fa-fw',
];
else
$menu[] = [
'title' => 'Enter Broom Closet',
'url' => $manageUrl === '' ? url('manage-index') : $manageUrl,
'icon' => 'fas fa-door-closed fa-fw',
];
}
$menu[] = [
'title' => 'Log out',
'url' => url('auth-logout'),
'icon' => 'fas fa-sign-out-alt fa-fw',
];
} else {
$menu[] = [
'title' => 'Register',
'url' => url('auth-register'),
'icon' => 'fas fa-user-plus fa-fw',
];
$menu[] = [
'title' => 'Log in',
'url' => url('auth-login'),
'icon' => 'fas fa-sign-in-alt fa-fw',
];
}
return $menu;
}
public function getManageMenu(): array {
$authInfo = $this->ctx->getAuthInfo();
$globalPerms = $authInfo->getPerms('global');
if(!$authInfo->isLoggedIn() || !$globalPerms->check(Perm::G_IS_JANITOR))
return [];
$menu = [
'General' => [
'Overview' => url('manage-general-overview'),
],
];
if($globalPerms->check(Perm::G_LOGS_VIEW))
$menu['General']['Logs'] = url('manage-general-logs');
if($globalPerms->check(Perm::G_EMOTES_MANAGE))
$menu['General']['Emoticons'] = url('manage-general-emoticons');
if($globalPerms->check(Perm::G_CONFIG_MANAGE))
$menu['General']['Settings'] = url('manage-general-settings');
$userPerms = $authInfo->getPerms('user');
if($userPerms->check(Perm::U_USERS_MANAGE))
$menu['Users & Roles']['Users'] = url('manage-users');
if($userPerms->check(Perm::U_ROLES_MANAGE))
$menu['Users & Roles']['Roles'] = url('manage-roles');
if($userPerms->check(Perm::U_NOTES_MANAGE))
$menu['Users & Roles']['Notes'] = url('manage-users-notes');
if($userPerms->check(Perm::U_WARNINGS_MANAGE))
$menu['Users & Roles']['Warnings'] = url('manage-users-warnings');
if($userPerms->check(Perm::U_BANS_MANAGE))
$menu['Users & Roles']['Bans'] = url('manage-users-bans');
if($globalPerms->check(Perm::G_NEWS_POSTS_MANAGE))
$menu['News']['Posts'] = url('manage-news-posts');
if($globalPerms->check(Perm::G_NEWS_CATEGORIES_MANAGE))
$menu['News']['Categories'] = url('manage-news-categories');
if($globalPerms->check(Perm::G_FORUM_CATEGORIES_MANAGE))
$menu['Forum']['Permission Calculator'] = url('manage-forum-categories');
if($globalPerms->check(Perm::G_FORUM_TOPIC_REDIRS_MANAGE))
$menu['Forum']['Topic Redirects'] = url('manage-forum-topic-redirs');
if($globalPerms->check(Perm::G_CL_CHANGES_MANAGE))
$menu['Changelog']['Changes'] = url('manage-changelog-changes');
if($globalPerms->check(Perm::G_CL_TAGS_MANAGE))
$menu['Changelog']['Tags'] = url('manage-changelog-tags');
return $menu;
}
}

View file

@ -2,46 +2,30 @@
namespace Misuzu; namespace Misuzu;
use InvalidArgumentException; use InvalidArgumentException;
use Twig\Environment as TwigEnvironment; use Sasae\SasaeContext;
use Twig\TwigFunction; use Sasae\SasaeEnvironment;
use Twig_Extensions_Extension_Date;
use Twig\Loader\FilesystemLoader as TwigLoaderFilesystem;
use Misuzu\MisuzuContext; use Misuzu\MisuzuContext;
final class Template { final class Template {
private const FILE_EXT = '.twig'; private const FILE_EXT = '.twig';
private static $loader; private static SasaeEnvironment $env;
private static $env; private static array $vars = [];
private static $vars = [];
public static function init(MisuzuContext $ctx, ?string $cache = null, bool $debug = false): void { public static function init(SasaeEnvironment $env): void {
self::$loader = new TwigLoaderFilesystem; self::$env = $env;
self::$env = new TwigEnvironment(self::$loader, [
'cache' => $cache ?? false,
'strict_variables' => true,
'auto_reload' => $debug,
'debug' => $debug,
]);
self::$env->addExtension(new TwigMisuzu($ctx));
}
public static function addPath(string $path): void {
self::$loader->addPath($path);
} }
public static function addFunction(string $name, callable $body): void { public static function addFunction(string $name, callable $body): void {
self::$env->addFunction(new TwigFunction($name, $body)); self::$env->addFunction($name, $body);
} }
public static function renderRaw(string $file, array $vars = []): string { public static function renderRaw(string $file, array $vars = []): string {
if(!defined('MSZ_TPL_RENDER')) { if(!defined('MSZ_TPL_RENDER'))
define('MSZ_TPL_RENDER', microtime(true)); define('MSZ_TPL_RENDER', microtime(true));
}
if(!str_ends_with($file, self::FILE_EXT)) { if(!str_ends_with($file, self::FILE_EXT))
$file = str_replace('.', DIRECTORY_SEPARATOR, $file) . self::FILE_EXT; $file = str_replace('.', DIRECTORY_SEPARATOR, $file) . self::FILE_EXT;
}
return self::$env->render($file, array_merge(self::$vars, $vars)); return self::$env->render($file, array_merge(self::$vars, $vars));
} }
@ -51,14 +35,13 @@ final class Template {
} }
public static function set($arrayOrKey, $value = null): void { public static function set($arrayOrKey, $value = null): void {
if(is_string($arrayOrKey)) { if(is_string($arrayOrKey))
self::$vars[$arrayOrKey] = $value; self::$vars[$arrayOrKey] = $value;
} elseif(is_array($arrayOrKey)) { elseif(is_array($arrayOrKey))
self::$vars = array_merge(self::$vars, $arrayOrKey); self::$vars = array_merge(self::$vars, $arrayOrKey);
} else { else
throw new InvalidArgumentException('First parameter must be of type array or string.'); throw new InvalidArgumentException('First parameter must be of type array or string.');
} }
}
public static function displayInfo(?string $message, int $statusCode, ?string $template = null): never { public static function displayInfo(?string $message, int $statusCode, ?string $template = null): never {
http_response_code($statusCode); http_response_code($statusCode);

View file

@ -1,70 +0,0 @@
<?php
namespace Misuzu;
use Index\ByteFormat;
use Index\DateTime;
use Index\Environment;
use Misuzu\MisuzuContext;
use Misuzu\Tools;
use Misuzu\Parsers\Parser;
use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
use Twig\TwigFunction;
use Twig\Environment as TwigEnvironment;
final class TwigMisuzu extends AbstractExtension {
private MisuzuContext $ctx;
public function __construct(MisuzuContext $ctx) {
$this->ctx = $ctx;
}
public function getFilters() {
return [
new TwigFilter('country_name', Tools::countryName(...)),
new TwigFilter('parse_text', fn(string $text, int $parser): string => Parser::instance($parser)->parseText($text)),
new TwigFilter('time_format', $this->timeFormat(...)),
];
}
public function getFunctions() {
return [
new TwigFunction('url_construct', 'url_construct'),
new TwigFunction('url', 'url'),
new TwigFunction('csrf_token', CSRF::token(...)),
new TwigFunction('git_commit_hash', GitInfo::hash(...)),
new TwigFunction('git_tag', GitInfo::tag(...)),
new TwigFunction('git_branch', GitInfo::branch(...)),
new TwigFunction('startup_time', fn(float $time = MSZ_STARTUP) => microtime(true) - $time),
new TwigFunction('sql_query_count', $this->ctx->getDbQueryCount(...)),
new TwigFunction('ndx_version', Environment::getIndexVersion(...)),
new TwigFunction('byte_symbol', ByteFormat::format(...)),
];
}
public function timeFormat(DateTime|string|int|null $dateTime): string {
if($dateTime === null)
return 'never';
if(is_string($dateTime))
$dateTime = new DateTime($dateTime);
elseif(is_int($dateTime))
$dateTime = DateTime::fromUnixTimeSeconds($dateTime);
$string = '';
$now = DateTime::now();
$isDiffYear = $now->getYear() !== $dateTime->getYear();
if($isDiffYear || $now->getMonth() !== $dateTime->getMonth() || $now->getDay() !== $dateTime->getDay()) {
$string .= $dateTime->format('M jS');
if($isDiffYear)
$string .= $dateTime->format(' Y');
$string .= ', ';
}
$string .= $dateTime->format('G:i ');
$string .= $dateTime->isUTC() ? 'UTC' : $dateTime->format('T');
return $string;
}
}

View file

@ -13,7 +13,7 @@
<a href="https://git.flash.moe/flashii/misuzu/src/tag/{{ git_tag }}" target="_blank" rel="noreferrer noopener" class="footer__link">{{ git_tag }}</a> <a href="https://git.flash.moe/flashii/misuzu/src/tag/{{ git_tag }}" target="_blank" rel="noreferrer noopener" class="footer__link">{{ git_tag }}</a>
{% endif %} {% endif %}
# <a href="https://git.flash.moe/flashii/misuzu/commit/{{ git_commit_hash(true) }}" target="_blank" rel="noreferrer noopener" class="footer__link">{{ git_commit_hash() }}</a> # <a href="https://git.flash.moe/flashii/misuzu/commit/{{ git_commit_hash(true) }}" target="_blank" rel="noreferrer noopener" class="footer__link">{{ git_commit_hash() }}</a>
{% if display_timings_info %} {% if globals.display_timings_info %}
/ Index {{ ndx_version() }} / Index {{ ndx_version() }}
/ {{ sql_query_count()|number_format }} queries / {{ sql_query_count()|number_format }} queries
/ {{ (startup_time() - startup_time(constant('MSZ_TPL_RENDER')))|number_format(5) }} load / {{ (startup_time() - startup_time(constant('MSZ_TPL_RENDER')))|number_format(5) }} load

View file

@ -1,13 +1,14 @@
{% from 'macros.twig' import avatar %} {% from 'macros.twig' import avatar %}
{% from '_layout/input.twig' import input_checkbox_raw %} {% from '_layout/input.twig' import input_checkbox_raw %}
{% if current_user_real is defined %} {% if globals.auth_info.isImpersonating %}
{% set real_user_info = globals.auth_info.realUserInfo %}
<div class="impersonate"> <div class="impersonate">
<div class="impersonate-content"> <div class="impersonate-content">
<div class="impersonate-user" style="--user-colour: {{ current_user_real_colour }}"> <div class="impersonate-user">
You are <a href="{{ url('user-profile', {'user': current_user_real.id}) }}" class="impersonate-user-link"> You are <a href="{{ url('user-profile', {'user': real_user_info.id}) }}" class="impersonate-user-link">
<div class="avatar impersonate-user-avatar">{{ avatar(current_user_real.id, 20, current_user_real.name) }}</div> <div class="avatar impersonate-user-avatar">{{ avatar(real_user_info.id, 20, real_user_info.name) }}</div>
{{ current_user_real.name }} {{ real_user_info.name }}
</a> </a>
</div> </div>
<div class="impersonate-options"> <div class="impersonate-options">
@ -17,6 +18,10 @@
</div> </div>
{% endif %} {% endif %}
{% set is_in_manage = is_in_manage|default(false) %}
{% set header_menu = msz_header_menu() %}
{% set user_menu = msz_user_menu(is_in_manage, (is_in_manage ? site_link|default('') : manage_link|default(''))) %}
<nav class="header"> <nav class="header">
<div class="header__background"></div> <div class="header__background"></div>
@ -51,9 +56,10 @@
</a> </a>
{% endfor %} {% endfor %}
{% if current_user is defined %} {% if globals.auth_info.isLoggedIn %}
<a href="{{ url('user-profile', {'user': current_user.id}) }}" class="avatar header__desktop__user__avatar" title="{{ current_user.name }}"> {% set user_info = globals.auth_info.userInfo %}
{{ avatar(current_user.id, 60, current_user.name) }} <a href="{{ url('user-profile', {'user': user_info.id}) }}" class="avatar header__desktop__user__avatar" title="{{ user_info.name }}">
{{ avatar(user_info.id, 60, user_info.name) }}
</a> </a>
{% else %} {% else %}
<a href="{{ url('auth-login') }}" class="avatar header__desktop__user__avatar"> <a href="{{ url('auth-login') }}" class="avatar header__desktop__user__avatar">
@ -74,7 +80,12 @@
</a> </a>
<label class="header__mobile__icon header__mobile__avatar" for="toggle-mobile-header"> <label class="header__mobile__icon header__mobile__avatar" for="toggle-mobile-header">
{{ avatar(current_user.id|default(0), 40, current_user.name|default('Log in')) }} {% if globals.auth_info.isLoggedIn %}
{% set user_info = globals.auth_info.userInfo %}
{{ avatar(user_info.id, 40, user_info.name) }}
{% else %}
{{ avatar(0, 40, 'Log in') }}
{% endif %}
</label> </label>
</div> </div>

View file

@ -176,9 +176,9 @@
</div> </div>
</form> </form>
{% if globals.eeprom.path is not empty %} {% if globals.eeprom_path is not empty and globals.eeprom_app is not empty %}
<script type="text/javascript"> <script type="text/javascript">
const peepPath = '{{ globals.eeprom.path }}', peepApp = '{{ globals.eeprom.app }}'; const peepPath = '{{ globals.eeprom_path }}', peepApp = '{{ globals.eeprom_app }}';
</script> </script>
{% endif %} {% endif %}
{% endblock %} {% endblock %}

View file

@ -36,6 +36,8 @@
}, },
] %} ] %}
{% set header_menu = msz_header_menu() %}
{% block main_header %} {% block main_header %}
<div class="landingv2-header"> <div class="landingv2-header">
<div class="landingv2-header-background"></div> <div class="landingv2-header-background"></div>
@ -87,7 +89,7 @@
{% endif %} {% endif %}
# <a href="https://github.com/flashwave/misuzu/commit/{{ git_commit_hash(true) }}" target="_blank" rel="noreferrer noopener">{{ git_commit_hash() }}</a> # <a href="https://github.com/flashwave/misuzu/commit/{{ git_commit_hash(true) }}" target="_blank" rel="noreferrer noopener">{{ git_commit_hash() }}</a>
</div> </div>
{% if display_timings_info %} {% if globals.display_timings_info %}
<div class="landingv2-footer-copyright-line"> <div class="landingv2-footer-copyright-line">
{{ sql_query_count()|number_format }} queries / {{ (startup_time() - startup_time(constant('MSZ_TPL_RENDER')))|number_format(5) }} load / {{ startup_time(constant('MSZ_TPL_RENDER'))|number_format(5) }} template / {{ startup_time()|number_format(5) }} total {{ sql_query_count()|number_format }} queries / {{ (startup_time() - startup_time(constant('MSZ_TPL_RENDER')))|number_format(5) }} load / {{ startup_time(constant('MSZ_TPL_RENDER'))|number_format(5) }} template / {{ startup_time()|number_format(5) }} total
</div> </div>

View file

@ -2,13 +2,14 @@
{% from 'macros.twig' import container_title %} {% from 'macros.twig' import container_title %}
{% from 'manage/macros.twig' import manage_navigation %} {% from 'manage/macros.twig' import manage_navigation %}
{% set is_in_manage = true %}
{% set title = title|default('Broom Closet') %} {% set title = title|default('Broom Closet') %}
{% set site_logo = '/images/logos/imouto-broom.png' %} {% set site_logo = '/images/logos/imouto-broom.png' %}
{% block content %} {% block content %}
<div class="manage"> <div class="manage">
<nav class="manage__sidebar"> <nav class="manage__sidebar">
{{ manage_navigation(manage_menu) }} {{ manage_navigation(msz_manage_menu()) }}
</nav> </nav>
<div class="manage__content"> <div class="manage__content">

View file

@ -6,7 +6,7 @@
{% include '_layout/meta.twig' %} {% include '_layout/meta.twig' %}
<link href="/vendor/fontawesome/css/all.min.css" type="text/css" rel="stylesheet"> <link href="/vendor/fontawesome/css/all.min.css" type="text/css" rel="stylesheet">
<link href="/vendor/highlightjs/styles/tomorrow-night.css" type="text/css" rel="stylesheet"> <link href="/vendor/highlightjs/styles/tomorrow-night.css" type="text/css" rel="stylesheet">
<link href="{{ assets.mszcss|default() }}" type="text/css" rel="stylesheet"> <link href="{{ globals.assets.mszcss|default() }}" type="text/css" rel="stylesheet">
{% if site_background is defined %} {% if site_background is defined %}
<style> <style>
:root { :root {
@ -32,12 +32,12 @@
{% endblock %} {% endblock %}
<div class="main__wrapper"> <div class="main__wrapper">
{% if current_user_ban_info is defined and current_user_ban_info is not null %} {% if globals.active_ban_info is not null %}
<div class="warning warning--red"> <div class="warning warning--red">
<div class="warning__content"> <div class="warning__content">
<p>You have been banned {% if current_user_ban_info.isPermanent %}<strong>permanently</strong>{% else %}for <strong title="{{ current_user_ban_info.expiresTime|date('r') }}">{{ current_user_ban_info.remainingString }}</strong>{% endif %} since <strong><time datetime="{{ current_user_ban_info.createdTime|date('c') }}" title="{{ current_user_ban_info.createdTime|date('r') }}">{{ current_user_ban_info.createdTime|time_format }}</time></strong>.</p> <p>You have been banned {% if globals.active_ban_info.isPermanent %}<strong>permanently</strong>{% else %}for <strong title="{{ globals.active_ban_info.expiresTime|date('r') }}">{{ globals.active_ban_info.remainingString }}</strong>{% endif %} since <strong><time datetime="{{ globals.active_ban_info.createdTime|date('c') }}" title="{{ globals.active_ban_info.createdTime|date('r') }}">{{ globals.active_ban_info.createdTime|time_format }}</time></strong>.</p>
{% if current_user_ban_info.hasPublicReason %} {% if globals.active_ban_info.hasPublicReason %}
<p>Reason: {{ current_user_ban_info.publicReason }}</p> <p>Reason: {{ globals.active_ban_info.publicReason }}</p>
{% endif %} {% endif %}
</div> </div>
</div> </div>
@ -58,6 +58,6 @@
window.addEventListener('DOMContentLoaded', function() { Misuzu(); }); window.addEventListener('DOMContentLoaded', function() { Misuzu(); });
</script> </script>
<script src="/vendor/highlightjs/highlight.pack.js" type="text/javascript"></script> <script src="/vendor/highlightjs/highlight.pack.js" type="text/javascript"></script>
<script src="{{ assets.mszjs|default() }}" type="text/javascript"></script> <script src="{{ globals.assets.mszjs|default() }}" type="text/javascript"></script>
</body> </body>
</html> </html>

View file

@ -47,7 +47,7 @@
{% if perms.edit_avatar %} {% if perms.edit_avatar %}
<ul class="profile__guidelines__section"> <ul class="profile__guidelines__section">
<li class="profile__guidelines__line profile__guidelines__line--header">Avatar</li> <li class="profile__guidelines__line profile__guidelines__line--header">Avatar</li>
<li class="profile__guidelines__line">May not exceed the <span class="profile__guidelines__emphasis">{{ byte_symbol(profile_avatar_info.maxBytes) }}</span> file size limit.</li> <li class="profile__guidelines__line">May not exceed the <span class="profile__guidelines__emphasis">{{ profile_avatar_info.maxBytes|format_filesize }}</span> file size limit.</li>
<li class="profile__guidelines__line">May not be larger than <span class="profile__guidelines__emphasis">{{ profile_avatar_info.maxWidth }}x{{ profile_avatar_info.maxHeight }}</span>.</li> <li class="profile__guidelines__line">May not be larger than <span class="profile__guidelines__emphasis">{{ profile_avatar_info.maxWidth }}x{{ profile_avatar_info.maxHeight }}</span>.</li>
<li class="profile__guidelines__line">Will be centre cropped and scaled to at most <span class="profile__guidelines__emphasis">240x240</span>.</li> <li class="profile__guidelines__line">Will be centre cropped and scaled to at most <span class="profile__guidelines__emphasis">240x240</span>.</li>
<li class="profile__guidelines__line">Animated GIF images are allowed.</li> <li class="profile__guidelines__line">Animated GIF images are allowed.</li>
@ -57,7 +57,7 @@
{% if perms.edit_background %} {% if perms.edit_background %}
<ul class="profile__guidelines__section"> <ul class="profile__guidelines__section">
<li class="profile__guidelines__line profile__guidelines__line--header">Background</li> <li class="profile__guidelines__line profile__guidelines__line--header">Background</li>
<li class="profile__guidelines__line">May not exceed the <span class="profile__guidelines__emphasis">{{ byte_symbol(profile_background_info.maxBytes) }}</span> file size limit.</li> <li class="profile__guidelines__line">May not exceed the <span class="profile__guidelines__emphasis">{{ profile_background_info.maxBytes|format_filesize }}</span> file size limit.</li>
<li class="profile__guidelines__line">May not be larger than <span class="profile__guidelines__emphasis">{{ profile_background_info.maxWidth }}x{{ profile_background_info.maxHeight }}</span>.</li> <li class="profile__guidelines__line">May not be larger than <span class="profile__guidelines__emphasis">{{ profile_background_info.maxWidth }}x{{ profile_background_info.maxHeight }}</span>.</li>
<li class="profile__guidelines__line">GIF images, in general, are only allowed when tiling.</li> <li class="profile__guidelines__line">GIF images, in general, are only allowed when tiling.</li>
</ul> </ul>