Improved templating engine wrapping.
This commit is contained in:
parent
e4c3e4c052
commit
ceb6bece09
86 changed files with 784 additions and 515 deletions
.env.examplecomposer.jsoncomposer.lockmisuzu.phppackage-lock.json
public-legacy
public
src
AssetInfo.php
Auth
Changelog
Colours
Comments
CsrfContext.phpDatabaseContext.phpEmoticons
Forum
Home
Info
LegacyRoutes.phpMessages
MisuzuContext.phpNews
OAuth2
Redirects
AliasRedirectsRoutes.phpIncrementalRedirectsRoutes.phpLandingRedirectsRoutes.phpNamedRedirectsRoutes.phpSocialRedirectsRoutes.php
Routing
Satori
SharpChat
SiteInfo.phpStorage
Template.phpTemplating
Users
WebFinger
templates
tools
12
.env.example
12
.env.example
|
@ -23,3 +23,15 @@ DATABASE_DSN="null:"
|
|||
# But to make things more understandable, the value for Flashii is also included
|
||||
#DOMAIN_ROLES="flashii.net=main; fii.moe=redirect"
|
||||
DOMAIN_ROLES="localhost=main,redirect:/go"
|
||||
|
||||
# Local storage path
|
||||
# This determines where uploaded files are stored. If left unset, the storage folder in the project tree will be used.
|
||||
#STORAGE_PATH_LOCAL="/path/to/storage"
|
||||
|
||||
# Remote storage path
|
||||
# Path on which the storage folder is exposed to the web for NGINX.
|
||||
#STORAGE_PATH_REMOTE="/_storage"
|
||||
|
||||
# Template cache directory
|
||||
# Writeable directory path to which template files are cached.
|
||||
#TEMPLATE_CACHE="/tmp/msz-tpl-cache"
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"require": {
|
||||
"php": ">=8.4",
|
||||
"ext-mbstring": "*",
|
||||
"flashwave/index": "^0.2503",
|
||||
"flashwave/index": "^0.2504",
|
||||
"erusev/parsedown": "~1.7",
|
||||
"chillerlan/php-qrcode": "~5.0",
|
||||
"symfony/mailer": "~7.2",
|
||||
|
|
54
composer.lock
generated
54
composer.lock
generated
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "cd96df7b2981a653c33b100a8b3837cd",
|
||||
"content-hash": "600e14fc77ff00755761d6e9b6add998",
|
||||
"packages": [
|
||||
{
|
||||
"name": "carbonphp/carbon-doctrine-types",
|
||||
|
@ -501,11 +501,11 @@
|
|||
},
|
||||
{
|
||||
"name": "flashwave/index",
|
||||
"version": "v0.2503.260138",
|
||||
"version": "v0.2504.21040",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://patchii.net/flash/index.git",
|
||||
"reference": "ea549dd0eb7cc7e7348bfcfb0e95da880dd2c039"
|
||||
"reference": "42adbe5da8325d66a996e5d69dbb01def80743fc"
|
||||
},
|
||||
"require": {
|
||||
"ext-mbstring": "*",
|
||||
|
@ -554,7 +554,7 @@
|
|||
],
|
||||
"description": "Composer package for the common library for my projects.",
|
||||
"homepage": "https://railgun.sh/index",
|
||||
"time": "2025-03-26T01:40:42+00:00"
|
||||
"time": "2025-04-02T10:41:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "graham-campbell/result-type",
|
||||
|
@ -620,16 +620,16 @@
|
|||
},
|
||||
{
|
||||
"name": "guzzlehttp/guzzle",
|
||||
"version": "7.9.2",
|
||||
"version": "7.9.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/guzzle/guzzle.git",
|
||||
"reference": "d281ed313b989f213357e3be1a179f02196ac99b"
|
||||
"reference": "7b2f29fe81dc4da0ca0ea7d42107a0845946ea77"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/d281ed313b989f213357e3be1a179f02196ac99b",
|
||||
"reference": "d281ed313b989f213357e3be1a179f02196ac99b",
|
||||
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/7b2f29fe81dc4da0ca0ea7d42107a0845946ea77",
|
||||
"reference": "7b2f29fe81dc4da0ca0ea7d42107a0845946ea77",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -726,7 +726,7 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/guzzle/guzzle/issues",
|
||||
"source": "https://github.com/guzzle/guzzle/tree/7.9.2"
|
||||
"source": "https://github.com/guzzle/guzzle/tree/7.9.3"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -742,20 +742,20 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-07-24T11:22:20+00:00"
|
||||
"time": "2025-03-27T13:37:11+00:00"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/promises",
|
||||
"version": "2.0.4",
|
||||
"version": "2.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/guzzle/promises.git",
|
||||
"reference": "f9c436286ab2892c7db7be8c8da4ef61ccf7b455"
|
||||
"reference": "7c69f28996b0a6920945dd20b3857e499d9ca96c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/guzzle/promises/zipball/f9c436286ab2892c7db7be8c8da4ef61ccf7b455",
|
||||
"reference": "f9c436286ab2892c7db7be8c8da4ef61ccf7b455",
|
||||
"url": "https://api.github.com/repos/guzzle/promises/zipball/7c69f28996b0a6920945dd20b3857e499d9ca96c",
|
||||
"reference": "7c69f28996b0a6920945dd20b3857e499d9ca96c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -809,7 +809,7 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/guzzle/promises/issues",
|
||||
"source": "https://github.com/guzzle/promises/tree/2.0.4"
|
||||
"source": "https://github.com/guzzle/promises/tree/2.2.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -825,20 +825,20 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-10-17T10:06:22+00:00"
|
||||
"time": "2025-03-27T13:27:01+00:00"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/psr7",
|
||||
"version": "2.7.0",
|
||||
"version": "2.7.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/guzzle/psr7.git",
|
||||
"reference": "a70f5c95fb43bc83f07c9c948baa0dc1829bf201"
|
||||
"reference": "c2270caaabe631b3b44c85f99e5a04bbb8060d16"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/guzzle/psr7/zipball/a70f5c95fb43bc83f07c9c948baa0dc1829bf201",
|
||||
"reference": "a70f5c95fb43bc83f07c9c948baa0dc1829bf201",
|
||||
"url": "https://api.github.com/repos/guzzle/psr7/zipball/c2270caaabe631b3b44c85f99e5a04bbb8060d16",
|
||||
"reference": "c2270caaabe631b3b44c85f99e5a04bbb8060d16",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -925,7 +925,7 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/guzzle/psr7/issues",
|
||||
"source": "https://github.com/guzzle/psr7/tree/2.7.0"
|
||||
"source": "https://github.com/guzzle/psr7/tree/2.7.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -941,7 +941,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-07-18T11:15:46+00:00"
|
||||
"time": "2025-03-27T12:30:47+00:00"
|
||||
},
|
||||
{
|
||||
"name": "jean85/pretty-package-versions",
|
||||
|
@ -1129,16 +1129,16 @@
|
|||
},
|
||||
{
|
||||
"name": "nesbot/carbon",
|
||||
"version": "3.8.6",
|
||||
"version": "3.9.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/CarbonPHP/carbon.git",
|
||||
"reference": "ff2f20cf83bd4d503720632ce8a426dc747bf7fd"
|
||||
"reference": "6d16a8a015166fe54e22c042e0805c5363aef50d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/ff2f20cf83bd4d503720632ce8a426dc747bf7fd",
|
||||
"reference": "ff2f20cf83bd4d503720632ce8a426dc747bf7fd",
|
||||
"url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/6d16a8a015166fe54e22c042e0805c5363aef50d",
|
||||
"reference": "6d16a8a015166fe54e22c042e0805c5363aef50d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1231,7 +1231,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-02-20T17:33:38+00:00"
|
||||
"time": "2025-03-27T12:57:33+00:00"
|
||||
},
|
||||
{
|
||||
"name": "paragonie/constant_time_encoding",
|
||||
|
|
|
@ -27,4 +27,5 @@ $msz = new MisuzuContext(
|
|||
$_ENV['DOMAIN_ROLES'] ?? 'localhost=main,redirect,storage',
|
||||
$_ENV['STORAGE_PATH_LOCAL'] ?? Misuzu::PATH_STORAGE,
|
||||
$_ENV['STORAGE_PATH_REMOTE'] ?? '/_storage',
|
||||
$_ENV['TEMPLATE_CACHE'] ?? '',
|
||||
);
|
||||
|
|
142
package-lock.json
generated
142
package-lock.json
generated
|
@ -80,14 +80,14 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@swc/core": {
|
||||
"version": "1.10.17",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core/-/core-1.10.17.tgz",
|
||||
"integrity": "sha512-FXZx7jHpiwz4fTuuueWwsvN7VFLSoeS3mcxCTPUNOHs/K2ecaBO+slh5T5Xvt/KGuD2I/2T8G6Zts0maPkt2lQ==",
|
||||
"version": "1.11.16",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core/-/core-1.11.16.tgz",
|
||||
"integrity": "sha512-wgjrJqVUss8Lxqilg0vkiE0tkEKU3mZkoybQM1Ehy+PKWwwB6lFAwKi20cAEFlSSWo8jFR8hRo19ZELAoLDowg==",
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@swc/counter": "^0.1.3",
|
||||
"@swc/types": "^0.1.17"
|
||||
"@swc/types": "^0.1.21"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
|
@ -97,16 +97,16 @@
|
|||
"url": "https://opencollective.com/swc"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@swc/core-darwin-arm64": "1.10.17",
|
||||
"@swc/core-darwin-x64": "1.10.17",
|
||||
"@swc/core-linux-arm-gnueabihf": "1.10.17",
|
||||
"@swc/core-linux-arm64-gnu": "1.10.17",
|
||||
"@swc/core-linux-arm64-musl": "1.10.17",
|
||||
"@swc/core-linux-x64-gnu": "1.10.17",
|
||||
"@swc/core-linux-x64-musl": "1.10.17",
|
||||
"@swc/core-win32-arm64-msvc": "1.10.17",
|
||||
"@swc/core-win32-ia32-msvc": "1.10.17",
|
||||
"@swc/core-win32-x64-msvc": "1.10.17"
|
||||
"@swc/core-darwin-arm64": "1.11.16",
|
||||
"@swc/core-darwin-x64": "1.11.16",
|
||||
"@swc/core-linux-arm-gnueabihf": "1.11.16",
|
||||
"@swc/core-linux-arm64-gnu": "1.11.16",
|
||||
"@swc/core-linux-arm64-musl": "1.11.16",
|
||||
"@swc/core-linux-x64-gnu": "1.11.16",
|
||||
"@swc/core-linux-x64-musl": "1.11.16",
|
||||
"@swc/core-win32-arm64-msvc": "1.11.16",
|
||||
"@swc/core-win32-ia32-msvc": "1.11.16",
|
||||
"@swc/core-win32-x64-msvc": "1.11.16"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@swc/helpers": "*"
|
||||
|
@ -118,9 +118,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@swc/core-darwin-arm64": {
|
||||
"version": "1.10.17",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.10.17.tgz",
|
||||
"integrity": "sha512-LSQhSjESleTc0c45BnVKRacp9Nl4zhJMlV/nmhpFCOv/CqHI5YBDX5c9bPk9jTRNHIf0QH92uTtswt8yN++TCQ==",
|
||||
"version": "1.11.16",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.11.16.tgz",
|
||||
"integrity": "sha512-l6uWMU+MUdfLHCl3dJgtVEdsUHPskoA4BSu0L1hh9SGBwPZ8xeOz8iLIqZM27lTuXxL4KsYH6GQR/OdQ/vhLtg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
@ -134,9 +134,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@swc/core-darwin-x64": {
|
||||
"version": "1.10.17",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.10.17.tgz",
|
||||
"integrity": "sha512-TTaZFS4jLuA3y6+D2HYv4yVGhmjkOGG6KyAwBiJEeoUaazX5MYOyQwaZBPhRGtzHZFrzi4t4jNix4kAkMajPkQ==",
|
||||
"version": "1.11.16",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.11.16.tgz",
|
||||
"integrity": "sha512-TH0IW8Ao1WZ4ARFHIh29dAQHYBEl4YnP74n++rjppmlCjY+8v3s5nXMA7IqxO3b5LVHyggWtU4+46DXTyMJM7g==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
@ -150,9 +150,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@swc/core-linux-arm-gnueabihf": {
|
||||
"version": "1.10.17",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.10.17.tgz",
|
||||
"integrity": "sha512-8P+ESJyGnVdJi0nUcQfxkbTiB/7hnu6N3U72KbvHFBcuroherwzW4DId1XD4RTU2Cjsh1dztZoCcOLY8W9RW1Q==",
|
||||
"version": "1.11.16",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.11.16.tgz",
|
||||
"integrity": "sha512-2IxD9t09oNZrbv37p4cJ9cTHMUAK6qNiShi9s2FJ9LcqSnZSN4iS4hvaaX6KZuG54d58vWnMU7yycjkdOTQcMg==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
|
@ -166,9 +166,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@swc/core-linux-arm64-gnu": {
|
||||
"version": "1.10.17",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.10.17.tgz",
|
||||
"integrity": "sha512-zT21jDQCe+IslzOtw+BD/9ElO/H4qU4fkkOeVQ68PcxuqYS2gwyDxWqa9IGwpzWexYM+Lzi1rAbl/1BM6nGW8Q==",
|
||||
"version": "1.11.16",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.11.16.tgz",
|
||||
"integrity": "sha512-AYkN23DOiPh1bf3XBf/xzZQDKSsgZTxlbyTyUIhprLJpAAAT0ZCGAUcS5mHqydk0nWQ13ABUymodvHoroutNzw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
@ -182,9 +182,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@swc/core-linux-arm64-musl": {
|
||||
"version": "1.10.17",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.10.17.tgz",
|
||||
"integrity": "sha512-C2jaW1X+93HscVcesKYgSuZ9GaKqKcQvwvD+q+4JZkaKF4Zopt/aguc6Tmn/nuavRk0WV8yVCpHXoP7lz/2akA==",
|
||||
"version": "1.11.16",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.11.16.tgz",
|
||||
"integrity": "sha512-n/nWXDRCIhM51dDGELfBcTMNnCiFatE7LDvsbYxb7DJt1HGjaCNvHHCKURb/apJTh/YNtWfgFap9dbsTgw8yPA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
@ -198,9 +198,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@swc/core-linux-x64-gnu": {
|
||||
"version": "1.10.17",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.10.17.tgz",
|
||||
"integrity": "sha512-vfyxqV5gddurG2NVJLemR/68s7GTe0QruozrZiDpNqr9V4VX9t3PadDKMDAvQz6jKrtiqMtshNXQTNRKAKlzFw==",
|
||||
"version": "1.11.16",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.11.16.tgz",
|
||||
"integrity": "sha512-xr182YQrF47n7Awxj+/ruI21bYw+xO/B26KFVnb+i3ezF9NOhqoqTX+33RL1ZLA/uFTq8ksPZO/y+ZVS/odtQA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
@ -214,9 +214,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@swc/core-linux-x64-musl": {
|
||||
"version": "1.10.17",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.10.17.tgz",
|
||||
"integrity": "sha512-8M+nI5MHZGQUnXyfTLsGw85a3oQRXMsFjgMZuOEJO9ZGBIEnYVuWOxENfcP6MmlJmTOW+cJxHnMGhKY+fjcntw==",
|
||||
"version": "1.11.16",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.11.16.tgz",
|
||||
"integrity": "sha512-k2JBfiwWfXCIKrBRjFO9/vEdLSYq0QLJ+iNSLdfrejZ/aENNkbEg8O7O2GKUSb30RBacn6k8HMfJrcPLFiEyCQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
@ -230,9 +230,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@swc/core-win32-arm64-msvc": {
|
||||
"version": "1.10.17",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.10.17.tgz",
|
||||
"integrity": "sha512-iUeIBFM6c/NwsreLFSAH395Dahc+54mSi0Kq//IrZ2Y16VlqCV7VHdOIMrdAyDoBFUvh0jKuLJPWt+jlKGtSLg==",
|
||||
"version": "1.11.16",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.11.16.tgz",
|
||||
"integrity": "sha512-taOb5U+abyEhQgex+hr6cI48BoqSvSdfmdirWcxprIEUBHCxa1dSriVwnJRAJOFI9T+5BEz88by6rgbB9MjbHA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
@ -246,9 +246,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@swc/core-win32-ia32-msvc": {
|
||||
"version": "1.10.17",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.10.17.tgz",
|
||||
"integrity": "sha512-lPXYFvkfYIN8HdNmG6dCnQqgA+rOSTgeAjIhGsYCEyLsYkkhF2FQw34OF6PnWawQ6hOdOE9v6Bw3T4enj3Lb6w==",
|
||||
"version": "1.11.16",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.11.16.tgz",
|
||||
"integrity": "sha512-b7yYggM9LBDiMY+XUt5kYWvs5sn0U3PXSOGvF3CbLufD/N/YQiDcYON2N3lrWHYL8aYnwbuZl45ojmQHSQPcdA==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
|
@ -262,9 +262,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@swc/core-win32-x64-msvc": {
|
||||
"version": "1.10.17",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.10.17.tgz",
|
||||
"integrity": "sha512-KrnkFEWpBmxSe8LixhAZXeeUwTNDVukrPeXJ1PiG+pmb5nI989I9J9IQVIgBv+JXXaK+rmiWjlcIkphaDJJEAA==",
|
||||
"version": "1.11.16",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.11.16.tgz",
|
||||
"integrity": "sha512-/ibq/YDc3B5AROkpOKPGxVkSyCKOg+ml8k11RxrW7FAPy6a9y5y9KPcWIqV74Ahq4RuaMNslTQqHWAGSm0xJsQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
@ -284,9 +284,9 @@
|
|||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/@swc/types": {
|
||||
"version": "0.1.17",
|
||||
"resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.17.tgz",
|
||||
"integrity": "sha512-V5gRru+aD8YVyCOMAjMpWR1Ui577DD5KSJsHP8RAxopAH22jFz6GZd/qxqjO6MJHQhcsjvjOFXyDhyLQUnMveQ==",
|
||||
"version": "0.1.21",
|
||||
"resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.21.tgz",
|
||||
"integrity": "sha512-2YEtj5HJVbKivud9N4bpPBAyZhj4S2Ipe5LkUG94alTpr7in/GU/EARgPAd3BwU+YOmFVJC2+kjqhGRi3r0ZpQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@swc/counter": "^0.1.3"
|
||||
|
@ -302,9 +302,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/acorn": {
|
||||
"version": "8.14.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
|
||||
"integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
|
||||
"version": "8.14.1",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz",
|
||||
"integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
|
@ -314,9 +314,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/autoprefixer": {
|
||||
"version": "10.4.20",
|
||||
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz",
|
||||
"integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==",
|
||||
"version": "10.4.21",
|
||||
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz",
|
||||
"integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
|
@ -333,11 +333,11 @@
|
|||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"browserslist": "^4.23.3",
|
||||
"caniuse-lite": "^1.0.30001646",
|
||||
"browserslist": "^4.24.4",
|
||||
"caniuse-lite": "^1.0.30001702",
|
||||
"fraction.js": "^4.3.7",
|
||||
"normalize-range": "^0.1.2",
|
||||
"picocolors": "^1.0.1",
|
||||
"picocolors": "^1.1.1",
|
||||
"postcss-value-parser": "^4.2.0"
|
||||
},
|
||||
"bin": {
|
||||
|
@ -417,9 +417,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001700",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001700.tgz",
|
||||
"integrity": "sha512-2S6XIXwaE7K7erT8dY+kLQcpa5ms63XlRkMkReXjle+kf6c5g38vyMl+Z5y8dSxOFDhcFe+nxnn261PLxBSQsQ==",
|
||||
"version": "1.0.30001709",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001709.tgz",
|
||||
"integrity": "sha512-NgL3vUTnDrPCZ3zTahp4fsugQ4dc7EKTSzwQDPEel6DMoMnfH2jhry9n2Zm8onbSR+f/QtKHFOA+iAQu4kbtWA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
|
@ -703,9 +703,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/electron-to-chromium": {
|
||||
"version": "1.5.102",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.102.tgz",
|
||||
"integrity": "sha512-eHhqaja8tE/FNpIiBrvBjFV/SSKpyWHLvxuR9dPTdo+3V9ppdLmFB7ZZQ98qNovcngPLYIz0oOBF9P0FfZef5Q==",
|
||||
"version": "1.5.130",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.130.tgz",
|
||||
"integrity": "sha512-Ou2u7L9j2XLZbhqzyX0jWDj6gA8D3jIfVzt4rikLf3cGBa0VdReuFimBKS9tQJA4+XpeCxj1NoWlfBXzbMa9IA==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/entities": {
|
||||
|
@ -803,9 +803,9 @@
|
|||
"license": "CC0-1.0"
|
||||
},
|
||||
"node_modules/nanoid": {
|
||||
"version": "3.3.8",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
|
||||
"integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==",
|
||||
"version": "3.3.11",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
|
||||
"integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
|
@ -884,9 +884,9 @@
|
|||
"license": "ISC"
|
||||
},
|
||||
"node_modules/postcss": {
|
||||
"version": "8.5.2",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.2.tgz",
|
||||
"integrity": "sha512-MjOadfU3Ys9KYoX0AdkBlFEF1Vx37uCCeN4ZHnmwm9FfpbsGWMZeBLMmmpY+6Ocqod7mkdZ0DT31OlbsFrLlkA==",
|
||||
"version": "8.5.3",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz",
|
||||
"integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
|
@ -1524,9 +1524,9 @@
|
|||
"license": "0BSD"
|
||||
},
|
||||
"node_modules/update-browserslist-db": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz",
|
||||
"integrity": "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==",
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",
|
||||
"integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
|
|
|
@ -8,7 +8,7 @@ if(!isset($msz) || !($msz instanceof \Misuzu\MisuzuContext))
|
|||
die('Script must be called through the Misuzu route dispatcher.');
|
||||
|
||||
if($msz->authInfo->loggedIn) {
|
||||
Tools::redirect($msz->urls->format('index'));
|
||||
Tools::redirect($msz->routingCtx->urls->format('index'));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ if(!empty($_GET['resolve'])) {
|
|||
echo json_encode([
|
||||
'id' => 0,
|
||||
'name' => '',
|
||||
'avatar' => $msz->urls->format('user-avatar', ['res' => 200, 'user' => 0]),
|
||||
'avatar' => $msz->routingCtx->urls->format('user-avatar', ['res' => 200, 'user' => 0]),
|
||||
]);
|
||||
return;
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ if(!empty($_GET['resolve'])) {
|
|||
echo json_encode([
|
||||
'id' => (int)$userInfo->id,
|
||||
'name' => $userInfo->name,
|
||||
'avatar' => $msz->urls->format('user-avatar', ['user' => $userInfo->id, 'res' => 200]),
|
||||
'avatar' => $msz->routingCtx->urls->format('user-avatar', ['user' => $userInfo->id, 'res' => 200]),
|
||||
]);
|
||||
return;
|
||||
}
|
||||
|
@ -132,7 +132,7 @@ while($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||
|
||||
if($msz->usersCtx->totps->hasUserTotp($userInfo)) {
|
||||
$tfaToken = $msz->authCtx->tfaSessions->createToken($userInfo);
|
||||
Tools::redirect($msz->urls->format('auth-two-factor', ['token' => $tfaToken, 'redirect' => $loginRedirect]));
|
||||
Tools::redirect($msz->routingCtx->urls->format('auth-two-factor', ['token' => $tfaToken, 'redirect' => $loginRedirect]));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -154,7 +154,7 @@ while($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||
AuthTokenCookie::apply($msz->authCtx->createAuthTokenPacker()->pack($tokenInfo));
|
||||
|
||||
if(!Tools::isLocalURL($loginRedirect))
|
||||
$loginRedirect = $msz->urls->format('index');
|
||||
$loginRedirect = $msz->routingCtx->urls->format('index');
|
||||
|
||||
Tools::redirect($loginRedirect);
|
||||
return;
|
||||
|
@ -165,7 +165,7 @@ $oauth2Mode = !empty($_GET['oauth2']);
|
|||
$loginUsername = !empty($_POST['username']) && is_string($_POST['username']) ? $_POST['username'] : (
|
||||
!empty($_GET['username']) && is_string($_GET['username']) ? $_GET['username'] : ''
|
||||
);
|
||||
$loginRedirect = $welcomeMode ? $msz->urls->format('index') : (!empty($_GET['redirect']) && is_string($_GET['redirect']) ? $_GET['redirect'] : null) ?? $_SERVER['HTTP_REFERER'] ?? $msz->urls->format('index');
|
||||
$loginRedirect = $welcomeMode ? $msz->routingCtx->urls->format('index') : (!empty($_GET['redirect']) && is_string($_GET['redirect']) ? $_GET['redirect'] : null) ?? $_SERVER['HTTP_REFERER'] ?? $msz->routingCtx->urls->format('index');
|
||||
$canRegisterAccount = !$siteIsPrivate;
|
||||
|
||||
Template::render('auth.login', [
|
||||
|
|
|
@ -24,4 +24,4 @@ if($msz->authInfo->loggedIn) {
|
|||
AuthTokenCookie::apply($msz->authCtx->createAuthTokenPacker()->pack($tokenInfo));
|
||||
}
|
||||
|
||||
Tools::redirect($msz->urls->format('index'));;
|
||||
Tools::redirect($msz->routingCtx->urls->format('index'));;
|
||||
|
|
|
@ -8,7 +8,7 @@ if(!isset($msz) || !($msz instanceof \Misuzu\MisuzuContext))
|
|||
die('Script must be called through the Misuzu route dispatcher.');
|
||||
|
||||
if($msz->authInfo->loggedIn) {
|
||||
Tools::redirect($msz->urls->format('settings-account'));
|
||||
Tools::redirect($msz->routingCtx->urls->format('settings-account'));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ if($userId > 0)
|
|||
try {
|
||||
$userInfo = $msz->usersCtx->users->getUser((string)$userId, 'id');
|
||||
} catch(RuntimeException $ex) {
|
||||
Tools::redirect($msz->urls->format('auth-forgot'));
|
||||
Tools::redirect($msz->routingCtx->urls->format('auth-forgot'));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -75,7 +75,7 @@ while($canResetPassword) {
|
|||
|
||||
$msz->authCtx->recoveryTokens->invalidateToken($tokenInfo);
|
||||
|
||||
Tools::redirect($msz->urls->format('auth-login', ['redirect' => '/']));
|
||||
Tools::redirect($msz->routingCtx->urls->format('auth-login', ['redirect' => '/']));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -106,8 +106,6 @@ while($canResetPassword) {
|
|||
} catch(RuntimeException $ex) {
|
||||
$tokenInfo = $msz->authCtx->recoveryTokens->createToken($forgotUser, $ipAddress);
|
||||
|
||||
$msz->initMailer();
|
||||
|
||||
$recoveryMessage = Mailer::template('password-recovery', [
|
||||
'username' => $forgotUser->name,
|
||||
'token' => $tokenInfo->code,
|
||||
|
@ -125,7 +123,7 @@ while($canResetPassword) {
|
|||
}
|
||||
}
|
||||
|
||||
Tools::redirect($msz->urls->format('auth-reset', ['user' => $forgotUser->id]));
|
||||
Tools::redirect($msz->routingCtx->urls->format('auth-reset', ['user' => $forgotUser->id]));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ if(!isset($msz) || !($msz instanceof \Misuzu\MisuzuContext))
|
|||
die('Script must be called through the Misuzu route dispatcher.');
|
||||
|
||||
if($msz->authInfo->loggedIn) {
|
||||
Tools::redirect($msz->urls->format('index'));
|
||||
Tools::redirect($msz->routingCtx->urls->format('index'));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -86,13 +86,13 @@ while($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||
}
|
||||
|
||||
$msz->usersCtx->users->addRoles($userInfo, $defaultRoleInfo);
|
||||
$msz->config->setString('users.newest', $userInfo->id);
|
||||
$msz->usersCtx->newestUserId = $userInfo->id;
|
||||
$msz->perms->precalculatePermissions(
|
||||
$msz->forumCtx->categories,
|
||||
[$userInfo->id]
|
||||
);
|
||||
|
||||
Tools::redirect($msz->urls->format('auth-login-welcome', ['username' => $userInfo->name]));
|
||||
Tools::redirect($msz->routingCtx->urls->format('auth-login-welcome', ['username' => $userInfo->name]));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,9 +17,9 @@ if($msz->csrfCtx->verifyLegacy()) {
|
|||
|
||||
$tokenInfo = $tokenBuilder->toInfo();
|
||||
AuthTokenCookie::apply($msz->authCtx->createAuthTokenPacker()->pack($tokenInfo));
|
||||
Tools::redirect($msz->urls->format('manage-user', ['user' => $impUserId]));
|
||||
Tools::redirect($msz->routingCtx->urls->format('manage-user', ['user' => $impUserId]));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Tools::redirect($msz->urls->format('index'));
|
||||
Tools::redirect($msz->routingCtx->urls->format('index'));
|
||||
|
|
|
@ -9,7 +9,7 @@ if(!isset($msz) || !($msz instanceof \Misuzu\MisuzuContext))
|
|||
die('Script must be called through the Misuzu route dispatcher.');
|
||||
|
||||
if($msz->authInfo->loggedIn) {
|
||||
Tools::redirect($msz->urls->format('index'));
|
||||
Tools::redirect($msz->routingCtx->urls->format('index'));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -26,13 +26,13 @@ $tokenString = !empty($_GET['token']) && is_scalar($_GET['token']) ? (string)$_G
|
|||
|
||||
$tokenUserId = $msz->authCtx->tfaSessions->getTokenUserId($tokenString);
|
||||
if(empty($tokenUserId)) {
|
||||
Tools::redirect($msz->urls->format('auth-login'));
|
||||
Tools::redirect($msz->routingCtx->urls->format('auth-login'));
|
||||
return;
|
||||
}
|
||||
|
||||
$totpInfo = $msz->usersCtx->totps->getUserTotp($tokenUserId);
|
||||
if($totpInfo === null) {
|
||||
Tools::redirect($msz->urls->format('auth-login'));
|
||||
Tools::redirect($msz->routingCtx->urls->format('auth-login'));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -87,7 +87,7 @@ while($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||
AuthTokenCookie::apply($msz->authCtx->createAuthTokenPacker()->pack($tokenInfo));
|
||||
|
||||
if(!Tools::isLocalURL($redirect))
|
||||
$redirect = $msz->urls->format('index');
|
||||
$redirect = $msz->routingCtx->urls->format('index');
|
||||
|
||||
Tools::redirect($redirect);
|
||||
return;
|
||||
|
@ -95,7 +95,7 @@ while($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||
|
||||
Template::render('auth.twofactor', [
|
||||
'twofactor_notices' => $notices,
|
||||
'twofactor_redirect' => !empty($_GET['redirect']) && is_string($_GET['redirect']) ? $_GET['redirect'] : $msz->urls->format('index'),
|
||||
'twofactor_redirect' => !empty($_GET['redirect']) && is_string($_GET['redirect']) ? $_GET['redirect'] : $msz->routingCtx->urls->format('index'),
|
||||
'twofactor_attempts_remaining' => $remainingAttempts,
|
||||
'twofactor_token' => $tokenString,
|
||||
]);
|
||||
|
|
|
@ -93,9 +93,9 @@ MD;
|
|||
foreach($rankings as $ranking) {
|
||||
$totalPostsCount += $ranking->postsCount;
|
||||
$markdown .= sprintf("| %s | [%s](%s%s) | %s |\r\n", $ranking->position,
|
||||
$ranking->user?->name ?? 'Deleted User', // @phpstan-ignore-line: no, it can be null
|
||||
$ranking->user?->name ?? 'Deleted User', // @phpstan-ignore nullsafe.neverNull
|
||||
$msz->siteInfo->url,
|
||||
$msz->urls->format('user-profile', ['user' => $ranking->userId]),
|
||||
$msz->routingCtx->urls->format('user-profile', ['user' => $ranking->userId]),
|
||||
number_format($ranking->postsCount));
|
||||
}
|
||||
|
||||
|
|
|
@ -168,9 +168,9 @@ if(!empty($_POST)) {
|
|||
}
|
||||
|
||||
if($isEditingTopic) {
|
||||
$originalTopicTitle = $topicInfo?->title ?? null; // @phpstan-ignore-line: nope it can be null
|
||||
$originalTopicTitle = $topicInfo?->title ?? null; // @phpstan-ignore nullsafe.neverNull
|
||||
$topicTitleChanged = $topicTitle !== $originalTopicTitle;
|
||||
$originalTopicType = $topicInfo?->typeString ?? 'discussion'; // @phpstan-ignore-line: this also
|
||||
$originalTopicType = $topicInfo?->typeString ?? 'discussion'; // @phpstan-ignore nullsafe.neverNull
|
||||
$topicTypeChanged = $topicType !== null && $topicType !== $originalTopicType;
|
||||
|
||||
$topicTitleLengths = $msz->config->getValues([
|
||||
|
@ -255,9 +255,9 @@ if(!empty($_POST)) {
|
|||
break;
|
||||
}
|
||||
|
||||
if(empty($notices)) { // @phpstan-ignore-line: i'm guessing it gets the type confused at this point
|
||||
if(empty($notices)) { // @phpstan-ignore empty.variable
|
||||
// does this ternary ever return forum-topic?
|
||||
$redirect = $msz->urls->format(empty($topicInfo) ? 'forum-topic' : 'forum-post', [
|
||||
$redirect = $msz->routingCtx->urls->format(empty($topicInfo) ? 'forum-topic' : 'forum-post', [
|
||||
'topic' => $topicId,
|
||||
'post' => $postId,
|
||||
]);
|
||||
|
|
|
@ -39,7 +39,7 @@ if($_SERVER['REQUEST_METHOD'] === 'GET' && !empty($_GET['delete'])) {
|
|||
|
||||
$msz->changelog->deleteChange($changeInfo);
|
||||
$msz->logsCtx->createAuthedLog('CHANGELOG_ENTRY_DELETE', [$changeInfo->id]);
|
||||
Tools::redirect($msz->urls->format('manage-changelog-changes'));
|
||||
Tools::redirect($msz->routingCtx->urls->format('manage-changelog-changes'));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -105,7 +105,7 @@ while($_SERVER['REQUEST_METHOD'] === 'POST' && $msz->csrfCtx->verifyLegacy()) {
|
|||
[$changeInfo->id],
|
||||
);
|
||||
|
||||
Tools::redirect($msz->urls->format('manage-changelog-change', ['change' => $changeInfo->id]));
|
||||
Tools::redirect($msz->routingCtx->urls->format('manage-changelog-change', ['change' => $changeInfo->id]));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ if($_SERVER['REQUEST_METHOD'] === 'GET' && !empty($_GET['delete'])) {
|
|||
|
||||
$msz->changelog->deleteTag($tagInfo);
|
||||
$msz->logsCtx->createAuthedLog('CHANGELOG_TAG_DELETE', [$tagInfo->id]);
|
||||
Tools::redirect($msz->urls->format('manage-changelog-tags'));
|
||||
Tools::redirect($msz->routingCtx->urls->format('manage-changelog-tags'));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,7 @@ while($_SERVER['REQUEST_METHOD'] === 'POST' && $msz->csrfCtx->verifyLegacy()) {
|
|||
);
|
||||
|
||||
if($isNew) {
|
||||
Tools::redirect($msz->urls->format('manage-changelog-tag', ['tag' => $tagInfo->id]));
|
||||
Tools::redirect($msz->routingCtx->urls->format('manage-changelog-tag', ['tag' => $tagInfo->id]));
|
||||
return;
|
||||
} else $tagInfo = $loadTagInfo();
|
||||
break;
|
||||
|
|
|
@ -16,7 +16,7 @@ if($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||
|
||||
$msz->logsCtx->createAuthedLog('FORUM_TOPIC_REDIR_CREATE', [$rTopicId]);
|
||||
$msz->forumCtx->topicRedirects->createTopicRedirect($rTopicId, $msz->authInfo->userInfo, $rTopicURL);
|
||||
Tools::redirect($msz->urls->format('manage-forum-topic-redirs'));
|
||||
Tools::redirect($msz->routingCtx->urls->format('manage-forum-topic-redirs'));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ if(!empty($_GET['m']) && $_GET['m'] === 'explode') {
|
|||
$rTopicId = !empty($_GET['t']) && is_scalar($_GET['t']) ? (string)$_GET['t'] : '';
|
||||
$msz->logsCtx->createAuthedLog('FORUM_TOPIC_REDIR_REMOVE', [$rTopicId]);
|
||||
$msz->forumCtx->topicRedirects->deleteTopicRedirect($rTopicId);
|
||||
Tools::redirect($msz->urls->format('manage-forum-topic-redirs'));
|
||||
Tools::redirect($msz->routingCtx->urls->format('manage-forum-topic-redirs'));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ while($_SERVER['REQUEST_METHOD'] === 'POST' && $msz->csrfCtx->verifyLegacy()) {
|
|||
[$emoteInfo->id],
|
||||
);
|
||||
|
||||
Tools::redirect($msz->urls->format('manage-general-emoticon', ['emote' => $emoteInfo->id]));
|
||||
Tools::redirect($msz->routingCtx->urls->format('manage-general-emoticon', ['emote' => $emoteInfo->id]));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ if($msz->csrfCtx->verifyLegacy() && !empty($_GET['emote'])) {
|
|||
}
|
||||
}
|
||||
|
||||
Tools::redirect($msz->urls->format('manage-general-emoticons'));
|
||||
Tools::redirect($msz->routingCtx->urls->format('manage-general-emoticons'));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ if($valueInfo === null)
|
|||
if($_SERVER['REQUEST_METHOD'] === 'POST' && $msz->csrfCtx->verifyLegacy()) {
|
||||
$msz->logsCtx->createAuthedLog('CONFIG_DELETE', [$valueInfo->name]);
|
||||
$msz->config->removeValues($valueInfo->name);
|
||||
Tools::redirect($msz->urls->format('manage-general-settings'));
|
||||
Tools::redirect($msz->routingCtx->urls->format('manage-general-settings'));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ while($_SERVER['REQUEST_METHOD'] === 'POST' && $msz->csrfCtx->verifyLegacy()) {
|
|||
|
||||
$msz->logsCtx->createAuthedLog($isNew ? 'CONFIG_CREATE' : 'CONFIG_UPDATE', [$sName]);
|
||||
$applyFunc($sName, $sValue);
|
||||
Tools::redirect($msz->urls->format('manage-general-settings'));
|
||||
Tools::redirect($msz->routingCtx->urls->format('manage-general-settings'));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ if($_SERVER['REQUEST_METHOD'] === 'GET' && !empty($_GET['delete'])) {
|
|||
|
||||
$msz->news->deleteCategory($categoryInfo);
|
||||
$msz->logsCtx->createAuthedLog('NEWS_CATEGORY_DELETE', [$categoryInfo->id]);
|
||||
Tools::redirect($msz->urls->format('manage-news-categories'));
|
||||
Tools::redirect($msz->routingCtx->urls->format('manage-news-categories'));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,7 @@ while($_SERVER['REQUEST_METHOD'] === 'POST' && $msz->csrfCtx->verifyLegacy()) {
|
|||
);
|
||||
|
||||
if($isNew) {
|
||||
Tools::redirect($msz->urls->format('manage-news-category', ['category' => $categoryInfo->id]));
|
||||
Tools::redirect($msz->routingCtx->urls->format('manage-news-category', ['category' => $categoryInfo->id]));
|
||||
return;
|
||||
} else $categoryInfo = $loadCategoryInfo();
|
||||
break;
|
||||
|
|
|
@ -29,7 +29,7 @@ if($_SERVER['REQUEST_METHOD'] === 'GET' && !empty($_GET['delete'])) {
|
|||
|
||||
$msz->news->deletePost($postInfo);
|
||||
$msz->logsCtx->createAuthedLog('NEWS_POST_DELETE', [$postInfo->id]);
|
||||
Tools::redirect($msz->urls->format('manage-news-posts'));
|
||||
Tools::redirect($msz->routingCtx->urls->format('manage-news-posts'));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -75,7 +75,7 @@ while($_SERVER['REQUEST_METHOD'] === 'POST' && $msz->csrfCtx->verifyLegacy()) {
|
|||
|
||||
if(isset($session->accessJwt) && is_string($session->accessJwt)
|
||||
&& isset($session->did) && is_string($session->did)) {
|
||||
$url = $msz->siteInfo->url . $msz->urls->format('news-post', ['post' => $postInfo->id]);
|
||||
$url = $msz->siteInfo->url . $msz->routingCtx->urls->format('news-post', ['post' => $postInfo->id]);
|
||||
$body = sprintf("News :: %s\n", $postInfo->title);
|
||||
$urlStart = strlen($body);
|
||||
$body .= $url;
|
||||
|
@ -129,7 +129,7 @@ while($_SERVER['REQUEST_METHOD'] === 'POST' && $msz->csrfCtx->verifyLegacy()) {
|
|||
} catch(RuntimeException $ex) {}
|
||||
}
|
||||
|
||||
Tools::redirect($msz->urls->format('manage-news-post', ['post' => $postInfo->id]));
|
||||
Tools::redirect($msz->routingCtx->urls->format('manage-news-post', ['post' => $postInfo->id]));
|
||||
return;
|
||||
} else $postInfo = $loadPostInfo();
|
||||
break;
|
||||
|
|
|
@ -23,7 +23,7 @@ if($_SERVER['REQUEST_METHOD'] === 'GET' && !empty($_GET['delete'])) {
|
|||
|
||||
$msz->usersCtx->bans->deleteBans($banInfo);
|
||||
$msz->logsCtx->createAuthedLog('BAN_DELETE', [$banInfo->id, $banInfo->userId]);
|
||||
Tools::redirect($msz->urls->format('manage-users-bans', ['user' => $banInfo->userId]));
|
||||
Tools::redirect($msz->routingCtx->urls->format('manage-users-bans', ['user' => $banInfo->userId]));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -68,7 +68,7 @@ while($_SERVER['REQUEST_METHOD'] === 'POST' && $msz->csrfCtx->verifyLegacy()) {
|
|||
);
|
||||
|
||||
$msz->logsCtx->createAuthedLog('BAN_CREATE', [$banInfo->id, $userInfo->id]);
|
||||
Tools::redirect($msz->urls->format('manage-users-bans', ['user' => $userInfo->id]));
|
||||
Tools::redirect($msz->routingCtx->urls->format('manage-users-bans', ['user' => $userInfo->id]));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ if($hasUserId) {
|
|||
|
||||
$msz->usersCtx->modNotes->deleteNotes($noteInfo);
|
||||
$msz->logsCtx->createAuthedLog('MOD_NOTE_DELETE', [$noteInfo->id, $noteInfo->userId]);
|
||||
Tools::redirect($msz->urls->format('manage-users-notes', ['user' => $noteInfo->userId]));
|
||||
Tools::redirect($msz->routingCtx->urls->format('manage-users-notes', ['user' => $noteInfo->userId]));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,7 @@ while($_SERVER['REQUEST_METHOD'] === 'POST' && $msz->csrfCtx->verifyLegacy()) {
|
|||
);
|
||||
|
||||
// this is easier
|
||||
Tools::redirect($msz->urls->format('manage-users-note', ['note' => $noteInfo->id]));
|
||||
Tools::redirect($msz->routingCtx->urls->format('manage-users-note', ['note' => $noteInfo->id]));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -162,7 +162,7 @@ while($_SERVER['REQUEST_METHOD'] === 'POST' && $msz->csrfCtx->verifyLegacy()) {
|
|||
$msz->config->setBoolean('perms.needsRecalc', true);
|
||||
}
|
||||
|
||||
Tools::redirect($msz->urls->format('manage-role', ['role' => $roleInfo->id]));
|
||||
Tools::redirect($msz->routingCtx->urls->format('manage-role', ['role' => $roleInfo->id]));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -53,26 +53,17 @@ if($msz->csrfCtx->verifyLegacy() && $canEdit) {
|
|||
$notices[] = 'You must be a super user to do this.';
|
||||
} elseif(!is_string($_POST['impersonate_user']) || $_POST['impersonate_user'] !== 'meow') {
|
||||
$notices[] = "You didn't say the magic word!";
|
||||
} else {
|
||||
$allowToImpersonate = $currentUser->super;
|
||||
} elseif($msz->usersCtx->canImpersonateUser($currentUser, $userInfo)) {
|
||||
$msz->logsCtx->createAuthedLog('USER_IMPERSONATE', [$userInfo->id, $userInfo->name]);
|
||||
|
||||
if(!$allowToImpersonate) {
|
||||
$allowImpersonateUsers = $msz->config->getArray(sprintf('impersonate.allow.u%s', $currentUser->id));
|
||||
$allowToImpersonate = in_array($userInfo->id, $allowImpersonateUsers, true);
|
||||
}
|
||||
$tokenBuilder = $msz->authInfo->tokenInfo->toBuilder();
|
||||
$tokenBuilder->setImpersonatedUserId($userInfo->id);
|
||||
$tokenInfo = $tokenBuilder->toInfo();
|
||||
|
||||
if($allowToImpersonate) {
|
||||
$msz->logsCtx->createAuthedLog('USER_IMPERSONATE', [$userInfo->id, $userInfo->name]);
|
||||
|
||||
$tokenBuilder = $msz->authInfo->tokenInfo->toBuilder();
|
||||
$tokenBuilder->setImpersonatedUserId($userInfo->id);
|
||||
$tokenInfo = $tokenBuilder->toInfo();
|
||||
|
||||
AuthTokenCookie::apply($msz->authCtx->createAuthTokenPacker()->pack($tokenInfo));
|
||||
Tools::redirect($msz->urls->format('index'));
|
||||
return;
|
||||
} else $notices[] = "You aren't allowed to impersonate this user.";
|
||||
}
|
||||
AuthTokenCookie::apply($msz->authCtx->createAuthTokenPacker()->pack($tokenInfo));
|
||||
Tools::redirect($msz->routingCtx->urls->format('index'));
|
||||
return;
|
||||
} else $notices[] = "You aren't allowed to impersonate this user.";
|
||||
}
|
||||
|
||||
if(!empty($_POST['send_test_email'])) {
|
||||
|
@ -81,7 +72,6 @@ if($msz->csrfCtx->verifyLegacy() && $canEdit) {
|
|||
} elseif(!is_string($_POST['send_test_email']) || $_POST['send_test_email'] !== 'yes_send_it') {
|
||||
$notices[] = 'Invalid request thing shut the fuck up.';
|
||||
} else {
|
||||
$msz->initMailer();
|
||||
$testMail = Mailer::sendMessage(
|
||||
[$userInfo->emailAddress => $userInfo->name],
|
||||
'Flashii Test E-mail',
|
||||
|
@ -215,7 +205,7 @@ if($msz->csrfCtx->verifyLegacy() && $canEdit) {
|
|||
[$userInfo->id]
|
||||
);
|
||||
|
||||
Tools::redirect($msz->urls->format('manage-user', ['user' => $userInfo->id]));
|
||||
Tools::redirect($msz->routingCtx->urls->format('manage-user', ['user' => $userInfo->id]));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ if($_SERVER['REQUEST_METHOD'] === 'GET' && !empty($_GET['delete'])) {
|
|||
|
||||
$msz->usersCtx->warnings->deleteWarnings($warnInfo);
|
||||
$msz->logsCtx->createAuthedLog('WARN_DELETE', [$warnInfo->id, $warnInfo->userId]);
|
||||
Tools::redirect($msz->urls->format('manage-users-warnings', ['user' => $warnInfo->userId]));
|
||||
Tools::redirect($msz->routingCtx->urls->format('manage-users-warnings', ['user' => $warnInfo->userId]));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ while($_SERVER['REQUEST_METHOD'] === 'POST' && $msz->csrfCtx->verifyLegacy()) {
|
|||
);
|
||||
|
||||
$msz->logsCtx->createAuthedLog('WARN_CREATE', [$warnInfo->id, $userInfo->id]);
|
||||
Tools::redirect($msz->urls->format('manage-users-warnings', ['user' => $userInfo->id]));
|
||||
Tools::redirect($msz->routingCtx->urls->format('manage-users-warnings', ['user' => $userInfo->id]));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ try {
|
|||
} catch(RuntimeException $ex) {
|
||||
$userId = $msz->usersCtx->namesHistory->resolvePastUserName($userId);
|
||||
if($userId !== null) {
|
||||
header(sprintf('Location: %s', $msz->urls->format('user-profile', ['user' => $userId])));
|
||||
header(sprintf('Location: %s', $msz->routingCtx->urls->format('user-profile', ['user' => $userId])));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -58,11 +58,11 @@ switch($profileMode) {
|
|||
Template::throwError(404);
|
||||
|
||||
case 'forum-topics':
|
||||
Tools::redirect($msz->urls->format('search-query', ['query' => sprintf('type:forum:topic author:%s', $userInfo->name), 'section' => 'topics']));
|
||||
Tools::redirect($msz->routingCtx->urls->format('search-query', ['query' => sprintf('type:forum:topic author:%s', $userInfo->name), 'section' => 'topics']));
|
||||
return;
|
||||
|
||||
case 'forum-posts':
|
||||
Tools::redirect($msz->urls->format('search-query', ['query' => sprintf('type:forum:post author:%s', $userInfo->name), 'section' => 'posts']));
|
||||
Tools::redirect($msz->routingCtx->urls->format('search-query', ['query' => sprintf('type:forum:post author:%s', $userInfo->name), 'section' => 'posts']));
|
||||
return;
|
||||
|
||||
case '':
|
||||
|
|
|
@ -37,7 +37,7 @@ while($_SERVER['REQUEST_METHOD'] === 'POST' && $msz->csrfCtx->verifyLegacy()) {
|
|||
}
|
||||
|
||||
if($activeSessionKilled) {
|
||||
Tools::redirect($msz->urls->format('index'));
|
||||
Tools::redirect($msz->routingCtx->urls->format('index'));
|
||||
return;
|
||||
} else break;
|
||||
}
|
||||
|
|
|
@ -27,12 +27,9 @@ if(is_file($msz->dbCtx->getMigrateLockPath())) {
|
|||
}
|
||||
|
||||
$request = \Index\Http\HttpRequest::fromRequest();
|
||||
$msz->registerRequestRoutes($request);
|
||||
|
||||
// order for these two currently matters i think: it shouldn't.
|
||||
$router = $msz->createRouting($request);
|
||||
$msz->startTemplating();
|
||||
|
||||
if($msz->domainRoles->hasRole($request->getHeaderLine('Host'), 'main')) {
|
||||
if($msz->routingCtx->domainRoles->hasRole($request->getHeaderLine('Host'), 'main')) {
|
||||
$mszRequestPath = substr($request->requestTarget, 1);
|
||||
$mszLegacyPathPrefix = Misuzu::PATH_PUBLIC_LEGACY . '/';
|
||||
$mszLegacyPath = $mszLegacyPathPrefix . $mszRequestPath;
|
||||
|
@ -41,7 +38,7 @@ if($msz->domainRoles->hasRole($request->getHeaderLine('Host'), 'main')) {
|
|||
$mszLegacyPathReal = realpath($mszLegacyPath);
|
||||
if($mszLegacyPath === $mszLegacyPathReal || $mszLegacyPath === $mszLegacyPathReal . '/') {
|
||||
// this is here so filters can run...
|
||||
$router->router->route(RouteInfo::exact(
|
||||
$msz->routingCtx->router->route(RouteInfo::exact(
|
||||
$request->method,
|
||||
$request->requestTarget,
|
||||
#[Before('authz:cookie')]
|
||||
|
@ -50,7 +47,7 @@ if($msz->domainRoles->hasRole($request->getHeaderLine('Host'), 'main')) {
|
|||
return 403;
|
||||
},
|
||||
));
|
||||
$response = $router->router->handle($request);
|
||||
$response = $msz->routingCtx->router->handle($request);
|
||||
if($response->getBody()->getSize() > 0) {
|
||||
Router::output($response);
|
||||
exit;
|
||||
|
@ -112,4 +109,4 @@ if($msz->domainRoles->hasRole($request->getHeaderLine('Host'), 'main')) {
|
|||
}
|
||||
}
|
||||
|
||||
$router->dispatch($request);
|
||||
$msz->routingCtx->dispatch($request);
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
<?php
|
||||
namespace Misuzu;
|
||||
|
||||
class AssetInfo {
|
||||
use Index\Templating\Extension\TplExtensionCommon;
|
||||
use Twig\TwigFunction;
|
||||
use Twig\Extension\LastModifiedExtensionInterface;
|
||||
|
||||
class AssetInfo implements LastModifiedExtensionInterface {
|
||||
use TplExtensionCommon;
|
||||
|
||||
public const string CURRENT_PATH = Misuzu::PATH_ASSETS . DIRECTORY_SEPARATOR . 'current.json';
|
||||
|
||||
/** @var array<string, string> */
|
||||
|
@ -21,4 +27,10 @@ class AssetInfo {
|
|||
public function getAssetUrl(string $name): string {
|
||||
return array_key_exists($name, $this->assets) ? $this->assets[$name] : '';
|
||||
}
|
||||
|
||||
public function getFunctions() {
|
||||
return [
|
||||
new TwigFunction('asset', $this->getAssetUrl(...)),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,20 @@
|
|||
<?php
|
||||
namespace Misuzu\Auth;
|
||||
|
||||
use Misuzu\{Misuzu,Perm};
|
||||
use Misuzu\Apps\AppInfo;
|
||||
use Misuzu\Auth\SessionInfo;
|
||||
use Misuzu\Forum\ForumCategoryInfo;
|
||||
use Misuzu\OAuth2\OAuth2AccessInfo;
|
||||
use Misuzu\Perms\{IPermissionResult,PermissionsData,PermissionResult};
|
||||
use Misuzu\Users\UserInfo;
|
||||
use Misuzu\Users\{BanInfo,UsersContext,UserInfo};
|
||||
use Index\Templating\Extension\TplExtensionCommon;
|
||||
use Twig\TwigFunction;
|
||||
use Twig\Extension\LastModifiedExtensionInterface;
|
||||
|
||||
class AuthInfo implements LastModifiedExtensionInterface {
|
||||
use TplExtensionCommon;
|
||||
|
||||
class AuthInfo {
|
||||
public private(set) AuthTokenInfo $tokenInfo;
|
||||
public private(set) ?UserInfo $userInfo;
|
||||
public private(set) ?SessionInfo $sessionInfo;
|
||||
|
@ -20,7 +26,8 @@ class AuthInfo {
|
|||
public private(set) array $perms;
|
||||
|
||||
public function __construct(
|
||||
private PermissionsData $permissions
|
||||
private PermissionsData $permissions,
|
||||
private UsersContext $usersCtx,
|
||||
) {
|
||||
$this->removeInfo();
|
||||
}
|
||||
|
@ -131,4 +138,50 @@ class AuthInfo {
|
|||
|
||||
return $this->perms[$cacheKey] = $this->permissions->getPermissions($category, $this->userInfo, $forumCategoryInfo);
|
||||
}
|
||||
|
||||
private function getLoggedIn(): bool {
|
||||
return $this->loggedIn;
|
||||
}
|
||||
|
||||
private function getImpersonating(): bool {
|
||||
return $this->impersonating;
|
||||
}
|
||||
|
||||
private function getInfo(?object $object, ?string $name = null, string|int|null $default = null): object|string|int|null {
|
||||
if($name === null)
|
||||
return $object;
|
||||
|
||||
if($object === null || !property_exists($object, $name))
|
||||
return $default;
|
||||
|
||||
return $object->{$name} ?? $default;
|
||||
}
|
||||
|
||||
private function getUserInfo(?string $name = null, string|int|null $default = null): object|string|int|null {
|
||||
return $this->getInfo($this->userInfo, $name, $default);
|
||||
}
|
||||
|
||||
private function getRealUserInfo(?string $name = null, string|int|null $default = null): object|string|int|null {
|
||||
return $this->getInfo($this->realUserInfo ?? $this->userInfo, $name, $default);
|
||||
}
|
||||
|
||||
private function getBanInfo(): ?BanInfo {
|
||||
return $this->usersCtx->tryGetActiveBan($this->userInfo);
|
||||
}
|
||||
|
||||
public function getDisplayTimings(): bool {
|
||||
return Misuzu::debug() || $this->getPerms('global')->check(Perm::G_TIMINGS_VIEW);
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function getFunctions() {
|
||||
return [
|
||||
new TwigFunction('auth_logged_in', $this->getLoggedIn(...)),
|
||||
new TwigFunction('auth_get_user_info', $this->getUserInfo(...)),
|
||||
new TwigFunction('auth_impersonating', $this->getImpersonating(...)),
|
||||
new TwigFunction('auth_get_real_user_info', $this->getRealUserInfo(...)),
|
||||
new TwigFunction('auth_get_ban_info', $this->getBanInfo(...)),
|
||||
new TwigFunction('auth_display_timings', $this->getDisplayTimings(...)),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ namespace Misuzu\Auth;
|
|||
|
||||
use RuntimeException;
|
||||
use Carbon\Carbon;
|
||||
use Index\Config\Config;
|
||||
use Index\Http\{HttpRequest,HttpResponseBuilder};
|
||||
use Index\Http\Content\FormContent;
|
||||
use Index\Http\Routing\{HandlerContext,RouteHandler,RouteHandlerCommon};
|
||||
|
@ -16,7 +15,6 @@ final class AuthProcessors implements RouteHandler {
|
|||
use RouteHandlerCommon;
|
||||
|
||||
public function __construct(
|
||||
private Config $impersonateConfig,
|
||||
private UsersContext $usersCtx,
|
||||
private OAuth2Context $oauth2Ctx,
|
||||
private CsrfContext $csrfCtx,
|
||||
|
@ -24,14 +22,6 @@ final class AuthProcessors implements RouteHandler {
|
|||
private AuthInfo $authInfo,
|
||||
) {}
|
||||
|
||||
private function canImpersonateUserId(UserInfo $impersonator, string $targetId): bool {
|
||||
if($impersonator->super)
|
||||
return true;
|
||||
|
||||
$whitelist = $this->impersonateConfig->getArray(sprintf('allow.u%s', $impersonator->id));
|
||||
return in_array($targetId, $whitelist, true);
|
||||
}
|
||||
|
||||
/** @param array<string, string> $error */
|
||||
private static function applyErrorHeader(HttpResponseBuilder $response, string $method, array $error): void {
|
||||
$parts = [];
|
||||
|
@ -184,7 +174,7 @@ final class AuthProcessors implements RouteHandler {
|
|||
if($sessionInfo->shouldBumpExpires)
|
||||
$builder->setEdited();
|
||||
|
||||
if($tokenInfo->hasImpersonatedUserId && $this->canImpersonateUserId($userInfo, $tokenInfo->impersonatedUserId)) {
|
||||
if($tokenInfo->hasImpersonatedUserId && $this->usersCtx->canImpersonateUser($userInfo, $tokenInfo->impersonatedUserId)) {
|
||||
$userInfoReal = $userInfo;
|
||||
|
||||
try {
|
||||
|
@ -295,7 +285,7 @@ final class AuthProcessors implements RouteHandler {
|
|||
$this->authCtx->sessions->recordSessionActivity(sessionInfo: $sessionInfo, remoteAddr: $request->remoteAddress);
|
||||
|
||||
$userInfoReal = null;
|
||||
if($tokenInfo->hasImpersonatedUserId && $this->canImpersonateUserId($userInfo, $tokenInfo->impersonatedUserId)) {
|
||||
if($tokenInfo->hasImpersonatedUserId && $this->usersCtx->canImpersonateUser($userInfo, $tokenInfo->impersonatedUserId)) {
|
||||
$userInfoReal = $userInfo;
|
||||
|
||||
try {
|
||||
|
|
|
@ -4,15 +4,16 @@ namespace Misuzu\Changelog;
|
|||
use ErrorException;
|
||||
use RuntimeException;
|
||||
use Index\Http\{HttpRequest,HttpResponseBuilder};
|
||||
use Index\Http\Routing\{RouteHandler,RouteHandlerCommon};
|
||||
use Index\Http\Routing\Processors\Before;
|
||||
use Index\Http\Routing\Routes\{ExactRoute,PatternRoute};
|
||||
use Index\Syndication\FeedBuilder;
|
||||
use Index\Urls\{UrlFormat,UrlRegistry,UrlSource,UrlSourceCommon};
|
||||
use Misuzu\{Pagination,SiteInfo,Template};
|
||||
use Misuzu\Comments\CommentsContext;
|
||||
use Misuzu\Routing\{HandlerRoles,RouteHandler,RouteHandlerCommon};
|
||||
use Misuzu\Users\UsersContext;
|
||||
|
||||
#[HandlerRoles('main')]
|
||||
final class ChangelogRoutes implements RouteHandler, UrlSource {
|
||||
use RouteHandlerCommon, UrlSourceCommon;
|
||||
|
||||
|
|
|
@ -4,11 +4,12 @@ namespace Misuzu\Colours;
|
|||
use RuntimeException;
|
||||
use Index\XArray;
|
||||
use Index\Http\{HttpRequest,HttpResponseBuilder};
|
||||
use Index\Http\Routing\{RouteHandler,RouteHandlerCommon};
|
||||
use Index\Http\Routing\AccessControl\AccessControl;
|
||||
use Index\Http\Routing\Routes\{ExactRoute,PatternRoute};
|
||||
use Misuzu\FieldTransformer;
|
||||
use Misuzu\Routing\{HandlerRoles,RouteHandler,RouteHandlerCommon};
|
||||
|
||||
#[HandlerRoles('main')]
|
||||
final class ColoursApiRoutes implements RouteHandler {
|
||||
use RouteHandlerCommon;
|
||||
|
||||
|
|
|
@ -5,15 +5,16 @@ use RuntimeException;
|
|||
use Index\XArray;
|
||||
use Index\Http\{FormHttpContent,HttpRequest,HttpResponseBuilder};
|
||||
use Index\Http\Content\FormContent;
|
||||
use Index\Http\Routing\{RouteHandler,RouteHandlerCommon};
|
||||
use Index\Http\Routing\Processors\Before;
|
||||
use Index\Http\Routing\Routes\{ExactRoute,PatternRoute};
|
||||
use Index\Urls\{UrlFormat,UrlRegistry,UrlSource,UrlSourceCommon};
|
||||
use Misuzu\Perm;
|
||||
use Misuzu\Auth\AuthInfo;
|
||||
use Misuzu\Perms\{PermissionResult,IPermissionResult};
|
||||
use Misuzu\Routing\{HandlerRoles,RouteHandler,RouteHandlerCommon};
|
||||
use Misuzu\Users\{UserInfo,UsersContext,UsersData};
|
||||
|
||||
#[HandlerRoles('main')]
|
||||
class CommentsRoutes implements RouteHandler, UrlSource {
|
||||
use RouteHandlerCommon, UrlSourceCommon;
|
||||
|
||||
|
|
|
@ -6,11 +6,12 @@ use Index\Config\Config;
|
|||
use Index\Http\Content\FormContent;
|
||||
use Index\Http\Routing\{HandlerContext,RouteHandler,RouteHandlerCommon};
|
||||
use Index\Http\Routing\Processors\Preprocessor;
|
||||
use Index\Templating\Extension\TplExtensionCommon;
|
||||
use Twig\TwigFunction;
|
||||
use Twig\Extension\AbstractExtension;
|
||||
use Twig\Extension\LastModifiedExtensionInterface;
|
||||
|
||||
class CsrfContext extends AbstractExtension implements RouteHandler {
|
||||
use RouteHandlerCommon;
|
||||
class CsrfContext implements RouteHandler, LastModifiedExtensionInterface {
|
||||
use RouteHandlerCommon, TplExtensionCommon;
|
||||
|
||||
private ?CsrfToken $instance = null;
|
||||
|
||||
|
|
|
@ -6,9 +6,12 @@ use Index\Db\{DbBackends,DbConnection};
|
|||
use Index\Db\Migration\{DbMigrationManager,DbMigrationRepo,FsDbMigrationRepo};
|
||||
use Index\Http\Routing\{RouteHandler,RouteHandlerCommon};
|
||||
use Index\Http\Routing\Filters\PrefixFilter;
|
||||
use Index\Templating\Extension\TplExtensionCommon;
|
||||
use Twig\TwigFunction;
|
||||
use Twig\Extension\LastModifiedExtensionInterface;
|
||||
|
||||
class DatabaseContext implements RouteHandler {
|
||||
use RouteHandlerCommon;
|
||||
class DatabaseContext implements RouteHandler, LastModifiedExtensionInterface {
|
||||
use RouteHandlerCommon, TplExtensionCommon;
|
||||
|
||||
public private(set) DbConnection $conn;
|
||||
|
||||
|
@ -46,4 +49,11 @@ class DatabaseContext implements RouteHandler {
|
|||
if(is_file($this->getMigrateLockPath()))
|
||||
return 503;
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function getFunctions() {
|
||||
return [
|
||||
new TwigFunction('sql_query_count', $this->getQueryCount(...)),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,11 +4,12 @@ namespace Misuzu\Emoticons;
|
|||
use RuntimeException;
|
||||
use Index\XArray;
|
||||
use Index\Http\{HttpRequest,HttpResponseBuilder};
|
||||
use Index\Http\Routing\{RouteHandler,RouteHandlerCommon};
|
||||
use Index\Http\Routing\AccessControl\AccessControl;
|
||||
use Index\Http\Routing\Routes\{ExactRoute,PatternRoute};
|
||||
use Misuzu\FieldTransformer;
|
||||
use Misuzu\Routing\{HandlerRoles,RouteHandler,RouteHandlerCommon};
|
||||
|
||||
#[HandlerRoles('main')]
|
||||
final class EmotesApiRoutes implements RouteHandler {
|
||||
use RouteHandlerCommon;
|
||||
|
||||
|
|
|
@ -4,14 +4,15 @@ namespace Misuzu\Forum;
|
|||
use stdClass;
|
||||
use RuntimeException;
|
||||
use Index\Http\{HttpRequest,HttpResponseBuilder};
|
||||
use Index\Http\Routing\{RouteHandler,RouteHandlerCommon};
|
||||
use Index\Http\Routing\Processors\Before;
|
||||
use Index\Http\Routing\Routes\{ExactRoute,PatternRoute};
|
||||
use Index\Urls\{UrlFormat,UrlSource,UrlSourceCommon};
|
||||
use Misuzu\{Pagination,Perm,Template};
|
||||
use Misuzu\Auth\AuthInfo;
|
||||
use Misuzu\Routing\{HandlerRoles,RouteHandler,RouteHandlerCommon};
|
||||
use Misuzu\Users\UsersContext;
|
||||
|
||||
#[HandlerRoles('main')]
|
||||
class ForumCategoriesRoutes implements RouteHandler, UrlSource {
|
||||
use RouteHandlerCommon, UrlSourceCommon;
|
||||
|
||||
|
|
|
@ -5,9 +5,10 @@ use stdClass;
|
|||
use Index\Config\Config;
|
||||
use Index\Db\DbConnection;
|
||||
use Misuzu\Parsers\TextFormat;
|
||||
use Misuzu\Templating\TemplatingMetaVariableProvider;
|
||||
use Misuzu\Users\UserInfo;
|
||||
|
||||
class ForumContext {
|
||||
class ForumContext implements TemplatingMetaVariableProvider {
|
||||
public private(set) ForumCategoriesData $categories;
|
||||
public private(set) ForumTopicsData $topics;
|
||||
public private(set) ForumTopicRedirectsData $topicRedirects;
|
||||
|
@ -38,6 +39,10 @@ class ForumContext {
|
|||
$this->signatures = new ForumSignaturesData($dbConn);
|
||||
}
|
||||
|
||||
public function getTemplatingMetaVariables(): array {
|
||||
return ['forum-storage-pool' => $this->storagePoolName];
|
||||
}
|
||||
|
||||
// should be replaced by a static counter
|
||||
public function countTotalUserTopics(UserInfo|string|null $userInfo): int {
|
||||
if($userInfo === null)
|
||||
|
|
|
@ -3,14 +3,15 @@ namespace Misuzu\Forum;
|
|||
|
||||
use RuntimeException;
|
||||
use Index\Http\{HttpRequest,HttpResponseBuilder};
|
||||
use Index\Http\Routing\{RouteHandler,RouteHandlerCommon};
|
||||
use Index\Http\Routing\Processors\Before;
|
||||
use Index\Http\Routing\Routes\PatternRoute;
|
||||
use Index\Urls\{UrlFormat,UrlRegistry,UrlSource,UrlSourceCommon};
|
||||
use Misuzu\Perm;
|
||||
use Misuzu\Auth\AuthInfo;
|
||||
use Misuzu\Logs\LogsContext;
|
||||
use Misuzu\Routing\{HandlerRoles,RouteHandler,RouteHandlerCommon};
|
||||
|
||||
#[HandlerRoles('main')]
|
||||
class ForumPostsRoutes implements RouteHandler, UrlSource {
|
||||
use RouteHandlerCommon, UrlSourceCommon;
|
||||
|
||||
|
|
|
@ -5,15 +5,16 @@ use stdClass;
|
|||
use RuntimeException;
|
||||
use Index\Http\{HttpRequest,HttpResponseBuilder};
|
||||
use Index\Http\Content\FormContent;
|
||||
use Index\Http\Routing\{RouteHandler,RouteHandlerCommon};
|
||||
use Index\Http\Routing\Processors\Before;
|
||||
use Index\Http\Routing\Routes\PatternRoute;
|
||||
use Index\Urls\{UrlFormat,UrlRegistry,UrlSource,UrlSourceCommon};
|
||||
use Misuzu\{Pagination,Perm,Template};
|
||||
use Misuzu\Auth\AuthInfo;
|
||||
use Misuzu\Logs\LogsContext;
|
||||
use Misuzu\Routing\{HandlerRoles,RouteHandler,RouteHandlerCommon};
|
||||
use Misuzu\Users\UsersContext;
|
||||
|
||||
#[HandlerRoles('main')]
|
||||
class ForumTopicsRoutes implements RouteHandler, UrlSource {
|
||||
use RouteHandlerCommon, UrlSourceCommon;
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@ use Index\Config\Config;
|
|||
use Index\Colour\Colour;
|
||||
use Index\Db\{DbConnection,DbTools};
|
||||
use Index\Http\{HttpRequest,HttpResponseBuilder};
|
||||
use Index\Http\Routing\{RouteHandler,RouteHandlerCommon};
|
||||
use Index\Http\Routing\Processors\Before;
|
||||
use Index\Http\Routing\Routes\ExactRoute;
|
||||
use Index\Urls\{UrlFormat,UrlSource,UrlSourceCommon};
|
||||
|
@ -17,8 +16,10 @@ use Misuzu\Changelog\ChangelogData;
|
|||
use Misuzu\Comments\CommentsContext;
|
||||
use Misuzu\Counters\CountersData;
|
||||
use Misuzu\News\{NewsData,NewsCategoryInfo,NewsPostInfo};
|
||||
use Misuzu\Routing\{HandlerRoles,RouteHandler,RouteHandlerCommon};
|
||||
use Misuzu\Users\{UsersContext,UserInfo};
|
||||
|
||||
#[HandlerRoles('main')]
|
||||
class HomeRoutes implements RouteHandler, UrlSource {
|
||||
use RouteHandlerCommon, UrlSourceCommon;
|
||||
|
||||
|
@ -226,14 +227,14 @@ class HomeRoutes implements RouteHandler, UrlSource {
|
|||
|
||||
$newestMember = [];
|
||||
if(empty($birthdays)) {
|
||||
$newestMemberId = $this->config->getString('users.newest');
|
||||
$newestMemberId = $this->usersCtx->newestUserId;
|
||||
if(!empty($newestMemberId))
|
||||
try {
|
||||
$newestMember['info'] = $this->usersCtx->getUserInfo($newestMemberId);
|
||||
$newestMember['colour'] = $this->usersCtx->getUserColour($newestMemberId);
|
||||
} catch(RuntimeException $ex) {
|
||||
$newestMember = [];
|
||||
$this->config->removeValues('users.newest');
|
||||
$this->usersCtx->newestUserId = '';
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,13 +3,14 @@ namespace Misuzu\Info;
|
|||
|
||||
use Index\Index;
|
||||
use Index\Http\{HttpRequest,HttpResponseBuilder};
|
||||
use Index\Http\Routing\{RouteHandler,RouteHandlerCommon};
|
||||
use Index\Http\Routing\Processors\Before;
|
||||
use Index\Http\Routing\Routes\{ExactRoute,PatternRoute};
|
||||
use Index\Urls\{UrlFormat,UrlSource,UrlSourceCommon};
|
||||
use Misuzu\{Misuzu,Template};
|
||||
use Misuzu\Parsers\{Parsers,TextFormat};
|
||||
use Misuzu\Routing\{HandlerRoles,RouteHandler,RouteHandlerCommon};
|
||||
|
||||
#[HandlerRoles('main')]
|
||||
class InfoRoutes implements RouteHandler, UrlSource {
|
||||
use RouteHandlerCommon, UrlSourceCommon;
|
||||
|
||||
|
|
|
@ -2,10 +2,11 @@
|
|||
namespace Misuzu;
|
||||
|
||||
use Index\Http\{HttpRequest,HttpResponseBuilder};
|
||||
use Index\Http\Routing\{HttpGet,RouteHandler,RouteHandlerCommon};
|
||||
use Index\Http\Routing\Routes\{ExactRoute,PatternRoute};
|
||||
use Index\Urls\{UrlFormat,UrlRegistry,UrlSource};
|
||||
use Misuzu\Routing\{HandlerRoles,RouteHandler,RouteHandlerCommon};
|
||||
|
||||
#[HandlerRoles('main')]
|
||||
class LegacyRoutes implements RouteHandler, UrlSource {
|
||||
use RouteHandlerCommon;
|
||||
|
||||
|
|
|
@ -3,8 +3,9 @@ namespace Misuzu\Messages;
|
|||
|
||||
use Index\Config\Config;
|
||||
use Index\Db\DbConnection;
|
||||
use Misuzu\Templating\TemplatingMetaVariableProvider;
|
||||
|
||||
class MessagesContext {
|
||||
class MessagesContext implements TemplatingMetaVariableProvider {
|
||||
public private(set) MessagesData $database;
|
||||
|
||||
public string $storagePoolName {
|
||||
|
@ -17,4 +18,8 @@ class MessagesContext {
|
|||
) {
|
||||
$this->database = new MessagesData($dbConn);
|
||||
}
|
||||
|
||||
public function getTemplatingMetaVariables(): array {
|
||||
return ['messages-storage-pool' => $this->storagePoolName];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ use Index\Config\Config;
|
|||
use Index\Colour\Colour;
|
||||
use Index\Http\{FormHttpContent,HttpRequest,HttpResponseBuilder};
|
||||
use Index\Http\Content\FormContent;
|
||||
use Index\Http\Routing\{RouteHandler,RouteHandlerCommon};
|
||||
use Index\Http\Routing\Processors\{After,Before};
|
||||
use Index\Http\Routing\Routes\{ExactRoute,PatternRoute};
|
||||
use Index\Urls\{UrlFormat,UrlRegistry,UrlSource,UrlSourceCommon};
|
||||
|
@ -17,8 +16,10 @@ use Misuzu\{Misuzu,Pagination,Perm,Template};
|
|||
use Misuzu\Auth\AuthInfo;
|
||||
use Misuzu\Parsers\TextFormat;
|
||||
use Misuzu\Perms\PermissionsData;
|
||||
use Misuzu\Routing\{HandlerRoles,RouteHandler,RouteHandlerCommon};
|
||||
use Misuzu\Users\{UsersContext,UserInfo};
|
||||
|
||||
#[HandlerRoles('main')]
|
||||
class MessagesRoutes implements RouteHandler, UrlSource {
|
||||
use RouteHandlerCommon, UrlSourceCommon;
|
||||
|
||||
|
|
|
@ -4,28 +4,31 @@ namespace Misuzu;
|
|||
use Index\Dependencies;
|
||||
use Index\Config\Config;
|
||||
use Index\Config\Db\DbConfig;
|
||||
use Index\Db\DbConnection;
|
||||
use Index\Db\Migration\{DbMigrationManager,DbMigrationRepo,FsDbMigrationRepo};
|
||||
use Index\Http\HttpRequest;
|
||||
use Index\Http\Routing\RouteHandler;
|
||||
use Index\Http\{HttpRequest,HttpResponseBuilder};
|
||||
use Index\Http\Routing\{Router,RouteHandler,RouteHandlerCommon};
|
||||
use Index\Http\Routing\Filters\PrefixFilter;
|
||||
use Index\Snowflake\{BinarySnowflake,RandomSnowflake,SnowflakeGenerator};
|
||||
use Index\Templating\TplEnvironment;
|
||||
use Index\Urls\UrlRegistry;
|
||||
use Misuzu\Routing\RoutingContext;
|
||||
use Misuzu\Users\UserInfo;
|
||||
use Twig\Extension\ExtensionInterface;
|
||||
use Index\Urls\{ArrayUrlRegistry,UrlRegistry,UrlSource};
|
||||
|
||||
class MisuzuContext implements RouteHandler {
|
||||
use RouteHandlerCommon;
|
||||
|
||||
class MisuzuContext {
|
||||
public private(set) Dependencies $deps;
|
||||
|
||||
public private(set) Config $config;
|
||||
public private(set) DomainRoles $domainRoles;
|
||||
public private(set) TplEnvironment $templating;
|
||||
public private(set) Router $router;
|
||||
public private(set) UrlRegistry $urls;
|
||||
|
||||
public private(set) SnowflakeGenerator $snowflake;
|
||||
public private(set) BinarySnowflake $sfBinary;
|
||||
public private(set) RandomSnowflake $sfRandom;
|
||||
|
||||
public private(set) AssetInfo $assetInfo;
|
||||
public private(set) SiteInfo $siteInfo;
|
||||
public private(set) Auth\AuthInfo $authInfo;
|
||||
public private(set) Perms\PermissionsData $perms;
|
||||
public private(set) WebFinger\WebFingerRegistry $webfinger;
|
||||
|
||||
public private(set) Changelog\ChangelogData $changelog;
|
||||
public private(set) Counters\CountersData $counters;
|
||||
public private(set) News\NewsData $news;
|
||||
|
@ -42,23 +45,18 @@ class MisuzuContext {
|
|||
public private(set) Messages\MessagesContext $messagesCtx;
|
||||
public private(set) OAuth2\OAuth2Context $oauth2Ctx;
|
||||
public private(set) Profile\ProfileContext $profileCtx;
|
||||
public private(set) Storage\StorageContext $storageCtx;
|
||||
public private(set) Users\UsersContext $usersCtx;
|
||||
public private(set) Redirects\RedirectsContext $redirectsCtx;
|
||||
|
||||
public private(set) Perms\PermissionsData $perms;
|
||||
public private(set) Auth\AuthInfo $authInfo;
|
||||
public private(set) SiteInfo $siteInfo;
|
||||
public private(set) AssetInfo $assetInfo;
|
||||
|
||||
// this probably shouldn't be available
|
||||
public private(set) UrlRegistry $urls;
|
||||
public private(set) Routing\RoutingContext $routingCtx;
|
||||
public private(set) Storage\StorageContext $storageCtx;
|
||||
public private(set) Templating\TemplatingContext $tplCtx;
|
||||
public private(set) Users\UsersContext $usersCtx;
|
||||
|
||||
public function __construct(
|
||||
#[\SensitiveParameter] string $dsn,
|
||||
string $domainRoles,
|
||||
string $storageLocalPath,
|
||||
string $storageRemotePath,
|
||||
string $templateCachePath,
|
||||
) {
|
||||
$this->deps = new Dependencies;
|
||||
$this->deps->register($this);
|
||||
|
@ -71,10 +69,6 @@ class MisuzuContext {
|
|||
DbConfig::class,
|
||||
tableName: 'msz_config',
|
||||
));
|
||||
$this->deps->register($this->domainRoles = $this->deps->constructLazy(
|
||||
DomainRoles::class,
|
||||
domainRoles: $domainRoles,
|
||||
));
|
||||
|
||||
$this->deps->register($this->snowflake = $this->deps->constructLazy(SnowflakeGenerator::class));
|
||||
$this->deps->register($this->sfBinary = $this->deps->constructLazy(BinarySnowflake::class));
|
||||
|
@ -90,6 +84,7 @@ class MisuzuContext {
|
|||
AssetInfo::class,
|
||||
pathOrAssets: AssetInfo::CURRENT_PATH,
|
||||
));
|
||||
$this->deps->register($this->webfinger = $this->deps->constructLazy(WebFinger\WebFingerRegistry::class));
|
||||
|
||||
$this->deps->register($this->appsCtx = $this->deps->constructLazy(Apps\AppsContext::class));
|
||||
$this->deps->register($this->authCtx = $this->deps->constructLazy(
|
||||
|
@ -117,7 +112,14 @@ class MisuzuContext {
|
|||
config: $this->config->scopeTo('oauth2'),
|
||||
));
|
||||
$this->deps->register($this->profileCtx = $this->deps->constructLazy(Profile\ProfileContext::class));
|
||||
$this->deps->register($this->usersCtx = $this->deps->constructLazy(Users\UsersContext::class));
|
||||
$this->deps->register($this->tplCtx = $this->deps->constructLazy(
|
||||
Templating\TemplatingContext::class,
|
||||
cachePath: $templateCachePath,
|
||||
));
|
||||
$this->deps->register($this->usersCtx = $this->deps->constructLazy(
|
||||
Users\UsersContext::class,
|
||||
config: $this->config->scopeTo('users'),
|
||||
));
|
||||
$this->deps->register($this->redirectsCtx = $this->deps->constructLazy(
|
||||
Redirects\RedirectsContext::class,
|
||||
config: $this->config->scopeTo('redirects'),
|
||||
|
@ -127,15 +129,23 @@ class MisuzuContext {
|
|||
$this->deps->register($this->counters = $this->deps->constructLazy(Counters\CountersData::class));
|
||||
$this->deps->register($this->news = $this->deps->constructLazy(News\NewsData::class));
|
||||
|
||||
$this->deps->register($this->routingCtx = $this->deps->construct(
|
||||
Routing\RoutingContext::class,
|
||||
domainRoles: $domainRoles,
|
||||
));
|
||||
$this->deps->register($this->storageCtx = $this->deps->construct(
|
||||
Storage\StorageContext::class,
|
||||
localPath: $storageLocalPath,
|
||||
remotePath: $storageRemotePath,
|
||||
));
|
||||
|
||||
Mailer::init($this->config->scopeTo('mail'));
|
||||
Template::init($this);
|
||||
}
|
||||
|
||||
public function initMailer(): void {
|
||||
Mailer::init($this->config->scopeTo('mail'));
|
||||
#[PrefixFilter('/')]
|
||||
public function filterPoweredBy(HttpResponseBuilder $response): void {
|
||||
$response->setPoweredBy(__NAMESPACE__);
|
||||
}
|
||||
|
||||
private ?bool $hasManageAccess = null;
|
||||
|
@ -146,128 +156,75 @@ class MisuzuContext {
|
|||
return $this->hasManageAccess;
|
||||
}
|
||||
|
||||
private ?string $chatUrl = null;
|
||||
public function getChatURL(): string {
|
||||
$this->chatUrl ??= $this->config->getString('sockChat.chatPath.normal');
|
||||
return $this->chatUrl;
|
||||
}
|
||||
|
||||
public function startTemplating(bool $cache = true): void {
|
||||
$isDebug = Misuzu::debug();
|
||||
$globals = [
|
||||
'site_info' => $this->siteInfo,
|
||||
'auth_info' => $this->authInfo,
|
||||
'active_ban_info' => $this->usersCtx->tryGetActiveBan($this->authInfo->userInfo),
|
||||
'display_timings_info' => $isDebug || $this->authInfo->getPerms('global')->check(Perm::G_TIMINGS_VIEW),
|
||||
'meta' => [
|
||||
'forum-storage-pool' => $this->forumCtx->storagePoolName,
|
||||
'messages-storage-pool' => $this->messagesCtx->storagePoolName,
|
||||
],
|
||||
];
|
||||
|
||||
$this->templating = new TplEnvironment(
|
||||
Misuzu::PATH_TEMPLATES,
|
||||
cache: $isDebug || !$cache ? null : ['Misuzu', GitInfo::hash(true)],
|
||||
debug: $isDebug
|
||||
);
|
||||
|
||||
$exts = $this->deps->all(ExtensionInterface::class);
|
||||
foreach($exts as $ext)
|
||||
$this->templating->addExtension($ext);
|
||||
|
||||
$this->templating->addExtension($this->deps->construct(TemplatingExtension::class));
|
||||
$this->templating->addGlobal('globals', $globals);
|
||||
|
||||
Template::init($this->templating);
|
||||
}
|
||||
|
||||
public function createRouting(HttpRequest $request): RoutingContext {
|
||||
$host = $request->getHeaderLine('Host');
|
||||
$roles = $this->domainRoles->getRoles($host);
|
||||
|
||||
$routingCtx = $this->deps->construct(RoutingContext::class);
|
||||
$this->deps->register($this->urls = $routingCtx->urls);
|
||||
public function registerRequestRoutes(HttpRequest $request): void {
|
||||
$roles = $this->routingCtx->domainRoles->getRoles($request->getHeaderLine('Host'));
|
||||
|
||||
$handlers = $this->deps->all(RouteHandler::class);
|
||||
foreach($handlers as $handler)
|
||||
$routingCtx->register($handler);
|
||||
if($handler instanceof Routing\RouteHandler)
|
||||
$handler->registerRoleRoutes($this->routingCtx->router, $roles);
|
||||
else
|
||||
$handler->registerRoutes($this->routingCtx->router);
|
||||
|
||||
if(in_array('main', $roles))
|
||||
$this->registerMainRoutes($routingCtx);
|
||||
$sources = $this->deps->all(UrlSource::class);
|
||||
foreach($sources as $source)
|
||||
$source->registerUrls($this->routingCtx->urls);
|
||||
|
||||
if(in_array('redirect', $roles))
|
||||
$this->registerRedirectRoutes($routingCtx);
|
||||
|
||||
if(in_array('storage', $roles))
|
||||
$this->registerStorageRoutes($routingCtx);
|
||||
|
||||
return $routingCtx;
|
||||
}
|
||||
|
||||
public function registerMainRoutes(
|
||||
RoutingContext $routingCtx
|
||||
): void {
|
||||
$this->deps->register($wf = new WebFinger\WebFingerRegistry);
|
||||
$wf->register($this->deps->constructLazy(
|
||||
Users\UsersWebFingerResolver::class,
|
||||
config: $this->config->scopeTo('users')
|
||||
// needs better registration process
|
||||
// hijack registerRoutes for WebFingerRoutes to automate this
|
||||
$this->webfinger->register($this->deps->constructLazy(
|
||||
Users\UsersWebFingerResolver::class
|
||||
));
|
||||
$routingCtx->register($this->deps->constructLazy(WebFinger\WebFingerRoutes::class));
|
||||
|
||||
$routingCtx->register($this->deps->constructLazy(
|
||||
Auth\AuthProcessors::class,
|
||||
impersonateConfig: $this->config->scopeTo('impersonate')
|
||||
));
|
||||
$routingCtx->register($this->deps->constructLazy(Colours\ColoursApiRoutes::class));
|
||||
$routingCtx->register($this->deps->constructLazy(Emoticons\EmotesApiRoutes::class));
|
||||
$routingCtx->register($this->deps->constructLazy(Users\UsersApiRoutes::class));
|
||||
$this->routingCtx->register($this->deps->constructLazy(Auth\AuthProcessors::class), $roles);
|
||||
|
||||
$routingCtx->register($this->deps->constructLazy(Home\HomeRoutes::class));
|
||||
$routingCtx->register($this->deps->constructLazy(Users\Assets\AssetsRoutes::class));
|
||||
$routingCtx->register($this->deps->constructLazy(Info\InfoRoutes::class));
|
||||
$routingCtx->register($this->deps->constructLazy(News\NewsRoutes::class));
|
||||
$this->routingCtx->register($this->deps->constructLazy(WebFinger\WebFingerRoutes::class), $roles);
|
||||
|
||||
$routingCtx->register($this->deps->constructLazy(Comments\CommentsRoutes::class));
|
||||
$routingCtx->register($this->deps->constructLazy(
|
||||
$this->routingCtx->register($this->deps->constructLazy(Colours\ColoursApiRoutes::class), $roles);
|
||||
$this->routingCtx->register($this->deps->constructLazy(Emoticons\EmotesApiRoutes::class), $roles);
|
||||
$this->routingCtx->register($this->deps->constructLazy(Users\UsersApiRoutes::class), $roles);
|
||||
|
||||
$this->routingCtx->register($this->deps->constructLazy(Home\HomeRoutes::class), $roles);
|
||||
$this->routingCtx->register($this->deps->constructLazy(Users\Assets\AssetsRoutes::class), $roles);
|
||||
$this->routingCtx->register($this->deps->constructLazy(Info\InfoRoutes::class), $roles);
|
||||
$this->routingCtx->register($this->deps->constructLazy(News\NewsRoutes::class), $roles);
|
||||
|
||||
$this->routingCtx->register($this->deps->constructLazy(Comments\CommentsRoutes::class), $roles);
|
||||
$this->routingCtx->register($this->deps->constructLazy(
|
||||
Messages\MessagesRoutes::class,
|
||||
config: $this->config->scopeTo('messages')
|
||||
));
|
||||
), $roles);
|
||||
|
||||
$routingCtx->register($this->deps->constructLazy(Storage\Tasks\TasksRoutes::class));
|
||||
$routingCtx->register($this->deps->constructLazy(Storage\Uploads\UploadsLegacyRoutes::class));
|
||||
$this->routingCtx->register($this->deps->constructLazy(Storage\Tasks\TasksRoutes::class), $roles);
|
||||
$this->routingCtx->register($this->deps->constructLazy(Storage\Uploads\UploadsLegacyRoutes::class), $roles);
|
||||
|
||||
$routingCtx->register($this->deps->constructLazy(OAuth2\OAuth2ApiRoutes::class));
|
||||
$routingCtx->register($this->deps->constructLazy(OAuth2\OAuth2WebRoutes::class));
|
||||
$routingCtx->register($this->deps->constructLazy(WebFinger\WebFingerRoutes::class));
|
||||
$this->routingCtx->register($this->deps->constructLazy(OAuth2\OAuth2ApiRoutes::class), $roles);
|
||||
$this->routingCtx->register($this->deps->constructLazy(OAuth2\OAuth2WebRoutes::class), $roles);
|
||||
$this->routingCtx->register($this->deps->constructLazy(WebFinger\WebFingerRoutes::class), $roles);
|
||||
|
||||
$routingCtx->register($this->deps->constructLazy(Forum\ForumCategoriesRoutes::class));
|
||||
$routingCtx->register($this->deps->constructLazy(Forum\ForumTopicsRoutes::class));
|
||||
$routingCtx->register($this->deps->constructLazy(Forum\ForumPostsRoutes::class));
|
||||
$this->routingCtx->register($this->deps->constructLazy(Forum\ForumCategoriesRoutes::class), $roles);
|
||||
$this->routingCtx->register($this->deps->constructLazy(Forum\ForumTopicsRoutes::class), $roles);
|
||||
$this->routingCtx->register($this->deps->constructLazy(Forum\ForumPostsRoutes::class), $roles);
|
||||
|
||||
$routingCtx->register($this->deps->constructLazy(Changelog\ChangelogRoutes::class));
|
||||
$routingCtx->register($this->deps->constructLazy(
|
||||
$this->routingCtx->register($this->deps->constructLazy(Changelog\ChangelogRoutes::class), $roles);
|
||||
$this->routingCtx->register($this->deps->constructLazy(
|
||||
SharpChat\SharpChatRoutes::class,
|
||||
config: $this->config->scopeTo('sockChat'),
|
||||
impersonateConfig: $this->config->scopeTo('impersonate')
|
||||
));
|
||||
), $roles);
|
||||
|
||||
$routingCtx->register($this->deps->constructLazy(
|
||||
$this->routingCtx->register($this->deps->constructLazy(
|
||||
Satori\SatoriRoutes::class,
|
||||
config: $this->config->scopeTo('satori')
|
||||
));
|
||||
), $roles);
|
||||
|
||||
$routingCtx->register($this->deps->constructLazy(LegacyRoutes::class));
|
||||
}
|
||||
$this->routingCtx->register($this->deps->constructLazy(LegacyRoutes::class), $roles);
|
||||
|
||||
public function registerRedirectRoutes(RoutingContext $routingCtx): void {
|
||||
$routingCtx->register($this->deps->constructLazy(Redirects\LandingRedirectsRoutes::class));
|
||||
$routingCtx->register($this->deps->constructLazy(Redirects\AliasRedirectsRoutes::class));
|
||||
$routingCtx->register($this->deps->constructLazy(Redirects\IncrementalRedirectsRoutes::class));
|
||||
$routingCtx->register($this->deps->constructLazy(Redirects\SocialRedirectsRoutes::class));
|
||||
$routingCtx->register($this->deps->constructLazy(Redirects\NamedRedirectsRoutes::class));
|
||||
}
|
||||
$this->routingCtx->register($this->deps->constructLazy(Redirects\LandingRedirectsRoutes::class), $roles);
|
||||
$this->routingCtx->register($this->deps->constructLazy(Redirects\AliasRedirectsRoutes::class), $roles);
|
||||
$this->routingCtx->register($this->deps->constructLazy(Redirects\IncrementalRedirectsRoutes::class), $roles);
|
||||
$this->routingCtx->register($this->deps->constructLazy(Redirects\SocialRedirectsRoutes::class), $roles);
|
||||
$this->routingCtx->register($this->deps->constructLazy(Redirects\NamedRedirectsRoutes::class), $roles);
|
||||
|
||||
public function registerStorageRoutes(RoutingContext $routingCtx): void {
|
||||
$routingCtx->register($this->deps->constructLazy(Storage\Uploads\UploadsViewRoutes::class));
|
||||
$this->routingCtx->register($this->deps->constructLazy(Storage\Uploads\UploadsViewRoutes::class), $roles);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ namespace Misuzu\News;
|
|||
use RuntimeException;
|
||||
use Index\Colour\Colour;
|
||||
use Index\Http\{HttpRequest,HttpResponseBuilder};
|
||||
use Index\Http\Routing\{RouteHandler,RouteHandlerCommon};
|
||||
use Index\Http\Routing\Processors\Before;
|
||||
use Index\Http\Routing\Routes\{ExactRoute,PatternRoute};
|
||||
use Index\Syndication\FeedBuilder;
|
||||
|
@ -12,8 +11,10 @@ use Index\Urls\{UrlFormat,UrlRegistry,UrlSource,UrlSourceCommon};
|
|||
use Misuzu\{Pagination,SiteInfo,Template};
|
||||
use Misuzu\Comments\CommentsContext;
|
||||
use Misuzu\Parsers\{Parsers,TextFormat};
|
||||
use Misuzu\Routing\{HandlerRoles,RouteHandler,RouteHandlerCommon};
|
||||
use Misuzu\Users\{UsersContext,UserInfo};
|
||||
|
||||
#[HandlerRoles('main')]
|
||||
class NewsRoutes implements RouteHandler, UrlSource {
|
||||
use RouteHandlerCommon, UrlSourceCommon;
|
||||
|
||||
|
@ -120,6 +121,7 @@ class NewsRoutes implements RouteHandler, UrlSource {
|
|||
}
|
||||
|
||||
#[PatternRoute('GET', '/news/([0-9]+)(?:\.(xml|rss|atom))?')]
|
||||
#[Before('authz:cookie')]
|
||||
#[UrlFormat('news-category', '/news/<category>', ['p' => '<page>'])]
|
||||
public function getCategory(HttpResponseBuilder $response, HttpRequest $request, string $categoryId, string $type = ''): int|string {
|
||||
try {
|
||||
|
|
|
@ -6,7 +6,6 @@ use Index\XArray;
|
|||
use Index\Colour\{Colour,ColourRgb};
|
||||
use Index\Http\{HttpResponseBuilder,HttpRequest};
|
||||
use Index\Http\Content\FormContent;
|
||||
use Index\Http\Routing\{RouteHandler,RouteHandlerCommon};
|
||||
use Index\Http\Routing\AccessControl\AccessControl;
|
||||
use Index\Http\Routing\Processors\Before;
|
||||
use Index\Http\Routing\Routes\{ExactRoute,PatternRoute};
|
||||
|
@ -15,8 +14,10 @@ use Misuzu\SiteInfo;
|
|||
use Misuzu\Apps\AppsContext;
|
||||
use Misuzu\Auth\AuthInfo;
|
||||
use Misuzu\Profile\ProfileContext;
|
||||
use Misuzu\Routing\{HandlerRoles,RouteHandler,RouteHandlerCommon};
|
||||
use Misuzu\Users\UsersContext;
|
||||
|
||||
#[HandlerRoles('main')]
|
||||
final class OAuth2ApiRoutes implements RouteHandler, UrlSource {
|
||||
use RouteHandlerCommon, UrlSourceCommon;
|
||||
|
||||
|
|
|
@ -6,14 +6,15 @@ use RuntimeException;
|
|||
use Index\XArray;
|
||||
use Index\Http\{HttpResponseBuilder,HttpRequest};
|
||||
use Index\Http\Content\FormContent;
|
||||
use Index\Http\Routing\{RouteHandler,RouteHandlerCommon};
|
||||
use Index\Http\Routing\Processors\Before;
|
||||
use Index\Http\Routing\Routes\{ExactRoute,PatternRoute};
|
||||
use Index\Urls\{UrlFormat,UrlRegistry,UrlSource,UrlSourceCommon};
|
||||
use Misuzu\{CsrfContext,Template};
|
||||
use Misuzu\Auth\AuthInfo;
|
||||
use Misuzu\Routing\{HandlerRoles,RouteHandler,RouteHandlerCommon};
|
||||
use Misuzu\Users\UsersContext;
|
||||
|
||||
#[HandlerRoles('main')]
|
||||
final class OAuth2WebRoutes implements RouteHandler, UrlSource {
|
||||
use RouteHandlerCommon, UrlSourceCommon;
|
||||
|
||||
|
|
|
@ -3,9 +3,10 @@ namespace Misuzu\Redirects;
|
|||
|
||||
use Index\Config\Config;
|
||||
use Index\Http\{HttpRequest,HttpResponseBuilder};
|
||||
use Index\Http\Routing\{RouteHandler,RouteHandlerCommon};
|
||||
use Index\Http\Routing\Routes\PatternRoute;
|
||||
use Misuzu\Routing\{HandlerRoles,RouteHandler,RouteHandlerCommon};
|
||||
|
||||
#[HandlerRoles('redirect')]
|
||||
class AliasRedirectsRoutes implements RouteHandler {
|
||||
use RouteHandlerCommon;
|
||||
|
||||
|
|
|
@ -5,10 +5,11 @@ use RuntimeException;
|
|||
use Index\XNumber;
|
||||
use Index\Http\HttpResponseBuilder;
|
||||
use Index\Http\Content\FormContent;
|
||||
use Index\Http\Routing\{RouteHandler,RouteHandlerCommon};
|
||||
use Index\Http\Routing\Processors\Before;
|
||||
use Index\Http\Routing\Routes\{ExactRoute,PatternRoute};
|
||||
use Misuzu\Routing\{HandlerRoles,RouteHandler,RouteHandlerCommon};
|
||||
|
||||
#[HandlerRoles('redirect')]
|
||||
class IncrementalRedirectsRoutes implements RouteHandler {
|
||||
use RouteHandlerCommon;
|
||||
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
<?php
|
||||
namespace Misuzu\Redirects;
|
||||
|
||||
use Index\Http\Routing\{RouteHandler,RouteHandlerCommon};
|
||||
use Index\Http\Routing\Routes\ExactRoute;
|
||||
use Misuzu\Template;
|
||||
use Misuzu\Routing\{HandlerRoles,RouteHandler,RouteHandlerCommon};
|
||||
|
||||
#[HandlerRoles('redirect')]
|
||||
class LandingRedirectsRoutes implements RouteHandler {
|
||||
use RouteHandlerCommon;
|
||||
|
||||
|
|
|
@ -3,9 +3,10 @@ namespace Misuzu\Redirects;
|
|||
|
||||
use RuntimeException;
|
||||
use Index\Http\{HttpRequest,HttpResponseBuilder};
|
||||
use Index\Http\Routing\{RouteHandler,RouteHandlerCommon};
|
||||
use Index\Http\Routing\Routes\PatternRoute;
|
||||
use Misuzu\Routing\{HandlerRoles,RouteHandler,RouteHandlerCommon};
|
||||
|
||||
#[HandlerRoles('redirect')]
|
||||
class NamedRedirectsRoutes implements RouteHandler {
|
||||
use RouteHandlerCommon;
|
||||
|
||||
|
|
|
@ -2,10 +2,11 @@
|
|||
namespace Misuzu\Redirects;
|
||||
|
||||
use Index\Http\HttpResponseBuilder;
|
||||
use Index\Http\Routing\{RouteHandler,RouteHandlerCommon};
|
||||
use Index\Http\Routing\Routes\PatternRoute;
|
||||
use Misuzu\Template;
|
||||
use Misuzu\Routing\{HandlerRoles,RouteHandler,RouteHandlerCommon};
|
||||
|
||||
#[HandlerRoles('redirect')]
|
||||
class SocialRedirectsRoutes implements RouteHandler {
|
||||
use RouteHandlerCommon;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
namespace Misuzu;
|
||||
namespace Misuzu\Routing;
|
||||
|
||||
use Index\XArray;
|
||||
|
36
src/Routing/HandlerRoles.php
Normal file
36
src/Routing/HandlerRoles.php
Normal file
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
namespace Misuzu\Routing;
|
||||
|
||||
use Attribute;
|
||||
use ReflectionAttribute;
|
||||
use ReflectionObject;
|
||||
use Index\Http\Routing\{Router,RouteHandler as IndexRouteHandler};
|
||||
|
||||
#[Attribute(Attribute::TARGET_CLASS)]
|
||||
final class HandlerRoles {
|
||||
/** @var string[] $roles */
|
||||
public private(set) array $roles;
|
||||
|
||||
public function __construct(string ...$roles) {
|
||||
$this->roles = $roles;
|
||||
}
|
||||
|
||||
public function hasRole(string $role): bool {
|
||||
return in_array($role, $this->roles);
|
||||
}
|
||||
|
||||
/** @param string[] $roles */
|
||||
public static function register(Router $router, IndexRouteHandler $handler, array $roles): void {
|
||||
$object = new ReflectionObject($handler);
|
||||
$attrs = $object->getAttributes(self::class, ReflectionAttribute::IS_INSTANCEOF);
|
||||
if(empty($attrs))
|
||||
return;
|
||||
|
||||
$info = $attrs[0]->newInstance();
|
||||
foreach($roles as $role)
|
||||
if($info->hasRole($role)) {
|
||||
$handler->registerRoutes($router);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
9
src/Routing/RouteHandler.php
Normal file
9
src/Routing/RouteHandler.php
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
namespace Misuzu\Routing;
|
||||
|
||||
use Index\Http\Routing\{Router,RouteHandler as IndexRouteHandler};
|
||||
|
||||
interface RouteHandler extends IndexRouteHandler {
|
||||
/** @param string[] $roles */
|
||||
public function registerRoleRoutes(Router $router, array $roles): void;
|
||||
}
|
13
src/Routing/RouteHandlerCommon.php
Normal file
13
src/Routing/RouteHandlerCommon.php
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
namespace Misuzu\Routing;
|
||||
|
||||
use Index\Http\Routing\{Router,RouteHandlerCommon as IndexRouteHandlerCommon};
|
||||
|
||||
trait RouteHandlerCommon {
|
||||
use IndexRouteHandlerCommon;
|
||||
|
||||
/** @param string[] $roles */
|
||||
public function registerRoleRoutes(Router $router, array $roles): void {
|
||||
HandlerRoles::register($router, $this, $roles);
|
||||
}
|
||||
}
|
|
@ -1,33 +1,59 @@
|
|||
<?php
|
||||
namespace Misuzu\Routing;
|
||||
|
||||
use Index\Dependencies;
|
||||
use Index\Config\Config;
|
||||
use Index\Http\{HttpRequest,HttpResponseBuilder};
|
||||
use Index\Http\Routing\{Router,RouteHandler};
|
||||
use Index\Http\Routing\{Router,RouteHandler as IndexRouteHandler};
|
||||
use Index\Http\Routing\Filters\FilterInfo;
|
||||
use Index\Templating\Extension\TplExtensionCommon;
|
||||
use Index\Urls\{ArrayUrlRegistry,UrlRegistry,UrlSource};
|
||||
use Twig\TwigFunction;
|
||||
use Twig\Extension\LastModifiedExtensionInterface;
|
||||
|
||||
|
||||
class RoutingContext implements LastModifiedExtensionInterface {
|
||||
use TplExtensionCommon;
|
||||
|
||||
class RoutingContext {
|
||||
public private(set) Router $router;
|
||||
public private(set) UrlRegistry $urls;
|
||||
public private(set) DomainRoles $domainRoles;
|
||||
|
||||
public function __construct(Config $config) {
|
||||
$this->urls = new ArrayUrlRegistry;
|
||||
$this->router = new Router(
|
||||
new RoutingErrorHandler,
|
||||
new RoutingAccessControlHandler($config),
|
||||
);
|
||||
$this->router->filter(FilterInfo::prefix('/', fn(HttpResponseBuilder $response) => $response->setPoweredBy('Misuzu')));
|
||||
public function __construct(
|
||||
Dependencies $deps,
|
||||
string $domainRoles,
|
||||
) {
|
||||
$deps->register($this->urls = $deps->constructLazy(ArrayUrlRegistry::class));
|
||||
$deps->register($this->router = $deps->constructLazy(
|
||||
Router::class,
|
||||
errorHandler: $deps->constructLazy(RoutingErrorHandler::class),
|
||||
accessControlHandler: $deps->constructLazy(RoutingAccessControlHandler::class),
|
||||
));
|
||||
$deps->register($this->domainRoles = $deps->constructLazy(
|
||||
DomainRoles::class,
|
||||
domainRoles: $domainRoles,
|
||||
));
|
||||
}
|
||||
|
||||
public function register(RouteHandler|UrlSource $handler): void {
|
||||
/** @param string[] $roles */
|
||||
public function register(IndexRouteHandler|UrlSource $handler, array $roles): void {
|
||||
if($handler instanceof RouteHandler)
|
||||
$this->router->register($handler);
|
||||
$handler->registerRoleRoutes($this->router, $roles);
|
||||
elseif($handler instanceof IndexRouteHandler)
|
||||
$handler->registerRoutes($this->router);
|
||||
|
||||
if($handler instanceof UrlSource)
|
||||
$this->urls->register($handler);
|
||||
$handler->registerUrls($this->urls);
|
||||
}
|
||||
|
||||
public function dispatch(?HttpRequest $request = null): void {
|
||||
$this->router->dispatch($request);
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function getFunctions() {
|
||||
return [
|
||||
new TwigFunction('url', $this->urls->format(...)),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ use Index\Colour\Colour;
|
|||
use Index\Config\Config;
|
||||
use Index\Http\{HttpRequest,HttpResponseBuilder};
|
||||
use Index\Http\Content\FormContent;
|
||||
use Index\Http\Routing\{RouteHandler,RouteHandlerCommon};
|
||||
use Index\Http\Routing\AccessControl\AccessControl;
|
||||
use Index\Http\Routing\Filters\PrefixFilter;
|
||||
use Index\Http\Routing\Processors\Before;
|
||||
|
@ -14,8 +13,10 @@ use Index\Http\Routing\Routes\ExactRoute;
|
|||
use Misuzu\Pagination;
|
||||
use Misuzu\Forum\ForumContext;
|
||||
use Misuzu\Profile\ProfileContext;
|
||||
use Misuzu\Routing\{HandlerRoles,RouteHandler,RouteHandlerCommon};
|
||||
use Misuzu\Users\UsersContext;
|
||||
|
||||
#[HandlerRoles('main')]
|
||||
final class SatoriRoutes implements RouteHandler {
|
||||
use RouteHandlerCommon;
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@ use Index\Colour\Colour;
|
|||
use Index\Config\Config;
|
||||
use Index\Http\{HttpRequest,HttpResponseBuilder};
|
||||
use Index\Http\Content\{FormContent,UrlEncodedFormContent};
|
||||
use Index\Http\Routing\{RouteHandler,RouteHandlerCommon};
|
||||
use Index\Http\Routing\AccessControl\AccessControl;
|
||||
use Index\Http\Routing\Processors\Before;
|
||||
use Index\Http\Routing\Routes\ExactRoute;
|
||||
|
@ -16,8 +15,10 @@ use Misuzu\Counters\CountersData;
|
|||
use Misuzu\Emoticons\EmotesContext;
|
||||
use Misuzu\OAuth2\{OAuth2AccessInfoGetField,OAuth2Context};
|
||||
use Misuzu\Perms\PermissionsData;
|
||||
use Misuzu\Routing\{HandlerRoles,RouteHandler,RouteHandlerCommon};
|
||||
use Misuzu\Users\{BansData,UsersContext,UserInfo};
|
||||
|
||||
#[HandlerRoles('main')]
|
||||
final class SharpChatRoutes implements RouteHandler {
|
||||
use RouteHandlerCommon;
|
||||
|
||||
|
@ -25,7 +26,6 @@ final class SharpChatRoutes implements RouteHandler {
|
|||
|
||||
public function __construct(
|
||||
private Config $config,
|
||||
private Config $impersonateConfig, // this sucks lol
|
||||
private UrlRegistry $urls,
|
||||
private UsersContext $usersCtx,
|
||||
private AuthContext $authCtx,
|
||||
|
@ -77,14 +77,6 @@ final class SharpChatRoutes implements RouteHandler {
|
|||
));
|
||||
}
|
||||
|
||||
private function canImpersonateUserId(UserInfo $impersonator, string $targetId): bool {
|
||||
if($impersonator->super)
|
||||
return true;
|
||||
|
||||
$whitelist = $this->impersonateConfig->getArray(sprintf('allow.u%s', $impersonator->id));
|
||||
return in_array($targetId, $whitelist, true);
|
||||
}
|
||||
|
||||
/** @return array{ok: false, err: string}|array{ok: true, usr: int, tkn: string} */
|
||||
#[AccessControl(credentials: true)]
|
||||
#[ExactRoute('GET', '/_sockchat/token')]
|
||||
|
@ -106,7 +98,7 @@ final class SharpChatRoutes implements RouteHandler {
|
|||
return ['ok' => false, 'err' => 'user'];
|
||||
|
||||
$userInfo = $this->usersCtx->users->getUser($sessionInfo->userId, 'id');
|
||||
$userId = $tokenInfo->hasImpersonatedUserId && $this->canImpersonateUserId($userInfo, $tokenInfo->impersonatedUserId)
|
||||
$userId = $tokenInfo->hasImpersonatedUserId && $this->usersCtx->canImpersonateUser($userInfo, $tokenInfo->impersonatedUserId)
|
||||
? $tokenInfo->impersonatedUserId
|
||||
: $userInfo->id;
|
||||
|
||||
|
@ -227,7 +219,7 @@ final class SharpChatRoutes implements RouteHandler {
|
|||
$this->authCtx->sessions->recordSessionActivity(sessionInfo: $sessionInfo, remoteAddr: $ipAddress);
|
||||
|
||||
$userInfo = $this->usersCtx->users->getUser($sessionInfo->userId, 'id');
|
||||
if($tokenInfo->hasImpersonatedUserId && $this->canImpersonateUserId($userInfo, $tokenInfo->impersonatedUserId)) {
|
||||
if($tokenInfo->hasImpersonatedUserId && $this->usersCtx->canImpersonateUser($userInfo, $tokenInfo->impersonatedUserId)) {
|
||||
$userInfoReal = $userInfo;
|
||||
|
||||
try {
|
||||
|
|
|
@ -2,48 +2,58 @@
|
|||
namespace Misuzu;
|
||||
|
||||
use Index\Config\Config;
|
||||
use Index\Templating\Extension\TplExtensionCommon;
|
||||
use Twig\TwigFunction;
|
||||
use Twig\Extension\LastModifiedExtensionInterface;
|
||||
|
||||
class SiteInfo {
|
||||
/** @var array<string, string> */
|
||||
private array $props;
|
||||
class SiteInfo implements LastModifiedExtensionInterface {
|
||||
use TplExtensionCommon;
|
||||
|
||||
public function __construct(Config $config) {
|
||||
$this->props = $config->getValues([
|
||||
['name:s', 'Misuzu'],
|
||||
'desc:s',
|
||||
'domain:s',
|
||||
'url:s',
|
||||
'email:s',
|
||||
'bsky:s',
|
||||
'ext_logo:s',
|
||||
]);
|
||||
}
|
||||
public function __construct(
|
||||
private Config $config,
|
||||
) {}
|
||||
|
||||
public string $name {
|
||||
get => $this->props['name'];
|
||||
get => $this->config->getString('name', 'Misuzu');
|
||||
}
|
||||
|
||||
public string $description {
|
||||
get => $this->props['desc'];
|
||||
get => $this->config->getString('desc');
|
||||
}
|
||||
|
||||
public string $url {
|
||||
get => rtrim($this->props['url'], '/');
|
||||
get => $this->config->getString('url');
|
||||
}
|
||||
|
||||
public string $email {
|
||||
get => $this->props['email'];
|
||||
get => $this->config->getString('email');
|
||||
}
|
||||
|
||||
public string $bsky {
|
||||
get => $this->props['bsky'];
|
||||
get => $this->config->getString('bsky');
|
||||
}
|
||||
|
||||
public string $domain {
|
||||
get => $this->props['domain'];
|
||||
get => $this->config->getString('domain');
|
||||
}
|
||||
|
||||
public string $externalLogo {
|
||||
get => $this->props['ext_logo'];
|
||||
get => $this->config->getString('ext_logo');
|
||||
}
|
||||
|
||||
public function getProperty(string $name): string {
|
||||
return $this->config->getString($name);
|
||||
}
|
||||
|
||||
public function hasProperty(string $name): bool {
|
||||
return $this->config->hasValues($name);
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function getFunctions() {
|
||||
return [
|
||||
new TwigFunction('site_has_info', $this->getProperty(...)),
|
||||
new TwigFunction('site_get_info', $this->getProperty(...)),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,10 +4,11 @@ namespace Misuzu\Storage\Tasks;
|
|||
use RuntimeException;
|
||||
use Index\{ByteFormat,XNumber};
|
||||
use Index\Http\{HttpResponseBuilder,HttpRequest};
|
||||
use Index\Http\Routing\{HttpPut,RouteHandler,RouteHandlerCommon};
|
||||
use Index\Http\Routing\AccessControl\AccessControl;
|
||||
use Index\Http\Routing\Routes\PatternRoute;
|
||||
use Misuzu\Routing\{HandlerRoles,RouteHandler,RouteHandlerCommon};
|
||||
|
||||
#[HandlerRoles('main')]
|
||||
class TasksRoutes implements RouteHandler {
|
||||
use RouteHandlerCommon;
|
||||
|
||||
|
|
|
@ -6,19 +6,20 @@ use Index\{ByteFormat,XArray,XNumber};
|
|||
use Index\Http\{HttpResponseBuilder,HttpRequest};
|
||||
use Index\Http\Content\MultipartFormContent;
|
||||
use Index\Http\Content\Multipart\FileMultipartFormData;
|
||||
use Index\Http\Routing\{HttpDelete,HttpOptions,HttpPost,RouteHandler,RouteHandlerCommon};
|
||||
use Index\Http\Routing\AccessControl\AccessControl;
|
||||
use Index\Http\Routing\Processors\Before;
|
||||
use Index\Http\Routing\Routes\{ExactRoute,PatternRoute};
|
||||
use Index\Urls\{UrlFormat,UrlSource,UrlSourceCommon};
|
||||
use Misuzu\Perm;
|
||||
use Misuzu\Auth\AuthInfo;
|
||||
use Misuzu\Routing\{HandlerRoles,RouteHandler,RouteHandlerCommon};
|
||||
use Misuzu\Storage\Denylist\{DenylistContext,DenylistReason};
|
||||
use Misuzu\Storage\Pools\{PoolsContext,PoolInfoGetField};
|
||||
use Misuzu\Storage\Pools\Rules\{ConstrainSizeRule,EnsureVariantRule,EnsureVariantRuleThumb};
|
||||
use Misuzu\Storage\Files\{FilesContext,FileImportMode,FileInfoGetFileField};
|
||||
use Misuzu\Users\UsersContext;
|
||||
|
||||
#[HandlerRoles('main')]
|
||||
class UploadsLegacyRoutes implements RouteHandler, UrlSource {
|
||||
use RouteHandlerCommon, UrlSourceCommon;
|
||||
|
||||
|
|
|
@ -4,14 +4,16 @@ namespace Misuzu\Storage\Uploads;
|
|||
use RuntimeException;
|
||||
use Index\{XArray,XNumber};
|
||||
use Index\Http\{HttpResponseBuilder,HttpRequest};
|
||||
use Index\Http\Routing\{Router,RouteHandler,RouteHandlerCommon};
|
||||
use Index\Http\Routing\Router;
|
||||
use Index\Http\Routing\AccessControl\AccessControl;
|
||||
use Index\Http\Routing\Routes\PatternRoute;
|
||||
use Misuzu\Storage\Denylist\DenylistContext;
|
||||
use Misuzu\Storage\Pools\PoolsContext;
|
||||
use Misuzu\Storage\Pools\Rules\{EnsureVariantRule,EnsureVariantRuleThumb};
|
||||
use Misuzu\Storage\Files\FilesContext;
|
||||
use Misuzu\Routing\{HandlerRoles,RouteHandler,RouteHandlerCommon};
|
||||
|
||||
#[HandlerRoles('storage')]
|
||||
class UploadsViewRoutes implements RouteHandler {
|
||||
use RouteHandlerCommon;
|
||||
|
||||
|
|
|
@ -12,8 +12,8 @@ final class Template {
|
|||
/** @var array<string, mixed> */
|
||||
private static array $vars = [];
|
||||
|
||||
public static function init(TplEnvironment $env): void {
|
||||
self::$env = $env;
|
||||
public static function init(MisuzuContext $env): void {
|
||||
self::$env = $env->tplCtx->env;
|
||||
}
|
||||
|
||||
public static function addFunction(string $name, callable $body): void {
|
||||
|
|
34
src/Templating/TemplatingContext.php
Normal file
34
src/Templating/TemplatingContext.php
Normal file
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
namespace Misuzu\Templating;
|
||||
|
||||
use Index\Dependencies;
|
||||
use Index\Templating\{TplContext,TplEnvironment};
|
||||
use Misuzu\Misuzu;
|
||||
use Twig\Extension\ExtensionInterface;
|
||||
|
||||
class TemplatingContext {
|
||||
public private(set) TplEnvironment $env;
|
||||
|
||||
public function __construct(
|
||||
Dependencies $deps,
|
||||
string $cachePath,
|
||||
) {
|
||||
$this->env = new TplEnvironment(
|
||||
Misuzu::PATH_TEMPLATES,
|
||||
cache: Misuzu::cli() || empty($cachePath) ? null : $cachePath,
|
||||
debug: Misuzu::debug(),
|
||||
);
|
||||
|
||||
$deps->register($this->env);
|
||||
$this->env->addExtension($deps->construct(TemplatingExtension::class));
|
||||
|
||||
$exts = $deps->all(ExtensionInterface::class);
|
||||
foreach($exts as $ext)
|
||||
$this->env->addExtension($ext);
|
||||
}
|
||||
|
||||
/** @param array<string, mixed> $vars Context local variables to add right away. */
|
||||
public function loadTemplate(string $name, array $vars = []): TplContext {
|
||||
return $this->env->load($name, $vars);
|
||||
}
|
||||
}
|
|
@ -1,18 +1,33 @@
|
|||
<?php
|
||||
namespace Misuzu;
|
||||
namespace Misuzu\Templating;
|
||||
|
||||
use DateTimeInterface;
|
||||
use Carbon\CarbonImmutable;
|
||||
use Index\Dependencies;
|
||||
use Index\Config\Config;
|
||||
use Index\Templating\Extension\TplExtensionCommon;
|
||||
use Index\Urls\UrlRegistry;
|
||||
use Misuzu\{CsrfContext,GitInfo,Perm,SiteInfo,Tools};
|
||||
use Misuzu\Auth\AuthInfo;
|
||||
use Misuzu\Parsers\{Parsers,TextFormat};
|
||||
use Misuzu\Users\UsersContext;
|
||||
use Twig\{TwigFilter,TwigFunction};
|
||||
use Twig\Extension\AbstractExtension;
|
||||
use Twig\Extension\LastModifiedExtensionInterface;
|
||||
|
||||
final class TemplatingExtension implements LastModifiedExtensionInterface {
|
||||
use TplExtensionCommon;
|
||||
|
||||
final class TemplatingExtension extends AbstractExtension {
|
||||
public function __construct(
|
||||
private MisuzuContext $ctx,
|
||||
private AssetInfo $assetInfo
|
||||
private Config $config,
|
||||
private Dependencies $deps,
|
||||
private UrlRegistry $urls,
|
||||
private CsrfContext $csrfCtx,
|
||||
private UsersContext $usersCtx,
|
||||
private AuthInfo $authInfo,
|
||||
private SiteInfo $siteInfo,
|
||||
) {}
|
||||
|
||||
#[\Override]
|
||||
public function getFilters() {
|
||||
return [
|
||||
new TwigFilter('country_name', Tools::countryName(...)),
|
||||
|
@ -22,15 +37,14 @@ final class TemplatingExtension extends AbstractExtension {
|
|||
];
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function getFunctions() {
|
||||
return [
|
||||
new TwigFunction('asset', $this->assetInfo->getAssetUrl(...)),
|
||||
new TwigFunction('url', $this->ctx->urls->format(...)),
|
||||
new TwigFunction('get_meta_vars', $this->getMetaVariables(...)),
|
||||
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->dbCtx->getQueryCount(...)),
|
||||
new TwigFunction('msz_header_menu', $this->getHeaderMenu(...)),
|
||||
new TwigFunction('msz_user_menu', $this->getUserMenu(...)),
|
||||
new TwigFunction('msz_manage_menu', $this->getManageMenu(...)),
|
||||
|
@ -44,6 +58,14 @@ final class TemplatingExtension extends AbstractExtension {
|
|||
];
|
||||
}
|
||||
|
||||
/** @return array<string, string> */
|
||||
public function getMetaVariables(): array {
|
||||
return array_merge(...array_map(
|
||||
fn($provider) => $provider->getTemplatingMetaVariables(),
|
||||
$this->deps->all(TemplatingMetaVariableProvider::class),
|
||||
));
|
||||
}
|
||||
|
||||
public function timeFormat(DateTimeInterface|string|int|null $dateTime): string {
|
||||
if($dateTime === null)
|
||||
return 'never';
|
||||
|
@ -73,56 +95,56 @@ final class TemplatingExtension extends AbstractExtension {
|
|||
|
||||
$home = [
|
||||
'title' => 'Home',
|
||||
'url' => $this->ctx->urls->format('index'),
|
||||
'url' => $this->urls->format('index'),
|
||||
'menu' => [],
|
||||
];
|
||||
|
||||
if($this->ctx->authInfo->loggedIn)
|
||||
if($this->authInfo->loggedIn)
|
||||
$home['menu'][] = [
|
||||
'title' => 'Members',
|
||||
'url' => $this->ctx->urls->format('user-list'),
|
||||
'url' => $this->urls->format('user-list'),
|
||||
];
|
||||
|
||||
$home['menu'][] = [
|
||||
'title' => 'Changelog',
|
||||
'url' => $this->ctx->urls->format('changelog-index'),
|
||||
'url' => $this->urls->format('changelog-index'),
|
||||
];
|
||||
$home['menu'][] = [
|
||||
'title' => 'Contact',
|
||||
'url' => $this->ctx->urls->format('info', ['title' => 'contact']),
|
||||
'url' => $this->urls->format('info', ['title' => 'contact']),
|
||||
];
|
||||
$home['menu'][] = [
|
||||
'title' => 'Rules',
|
||||
'url' => $this->ctx->urls->format('info', ['title' => 'rules']),
|
||||
'url' => $this->urls->format('info', ['title' => 'rules']),
|
||||
];
|
||||
if(!empty($this->ctx->siteInfo->bsky))
|
||||
if(!empty($this->siteInfo->bsky))
|
||||
$home['menu'][] = [
|
||||
'title' => 'Bluesky',
|
||||
'url' => $this->ctx->siteInfo->bsky,
|
||||
'url' => $this->siteInfo->bsky,
|
||||
];
|
||||
|
||||
$menu[] = $home;
|
||||
|
||||
$menu[] = [
|
||||
'title' => 'News',
|
||||
'url' => $this->ctx->urls->format('news-index'),
|
||||
'url' => $this->urls->format('news-index'),
|
||||
];
|
||||
|
||||
$forum = [
|
||||
'title' => 'Forum',
|
||||
'url' => $this->ctx->urls->format('forum-index'),
|
||||
'url' => $this->urls->format('forum-index'),
|
||||
'menu' => [],
|
||||
];
|
||||
|
||||
if($this->ctx->authInfo->getPerms('global')->check(Perm::G_FORUM_LEADERBOARD_VIEW))
|
||||
if($this->authInfo->getPerms('global')->check(Perm::G_FORUM_LEADERBOARD_VIEW))
|
||||
$forum['menu'][] = [
|
||||
'title' => 'Leaderboard',
|
||||
'url' => $this->ctx->urls->format('forum-leaderboard'),
|
||||
'url' => $this->urls->format('forum-leaderboard'),
|
||||
];
|
||||
|
||||
$menu[] = $forum;
|
||||
|
||||
$chatPath = $this->ctx->getChatURL();
|
||||
$chatPath = $this->config->getString('sockChat.chatPath.normal');
|
||||
if(!empty($chatPath))
|
||||
$menu[] = [
|
||||
'title' => 'Chat',
|
||||
|
@ -142,64 +164,64 @@ final class TemplatingExtension extends AbstractExtension {
|
|||
public function getUserMenu(bool $inBroomCloset, string $manageUrl = ''): array {
|
||||
$menu = [];
|
||||
|
||||
if($this->ctx->authInfo->loggedIn) {
|
||||
$userInfo = $this->ctx->authInfo->userInfo;
|
||||
$globalPerms = $this->ctx->authInfo->getPerms('global');
|
||||
if($this->authInfo->loggedIn) {
|
||||
$userInfo = $this->authInfo->userInfo;
|
||||
$globalPerms = $this->authInfo->getPerms('global');
|
||||
|
||||
$menu[] = [
|
||||
'title' => 'Profile',
|
||||
'url' => $this->ctx->urls->format('user-profile', ['user' => $userInfo->id]),
|
||||
'url' => $this->urls->format('user-profile', ['user' => $userInfo->id]),
|
||||
'icon' => 'fas fa-user fa-fw',
|
||||
];
|
||||
if($globalPerms->check(Perm::G_MESSAGES_VIEW))
|
||||
$menu[] = [
|
||||
'title' => 'Messages',
|
||||
'url' => $this->ctx->urls->format('messages-index'),
|
||||
'url' => $this->urls->format('messages-index'),
|
||||
'icon' => 'fas fa-envelope fa-fw',
|
||||
'class' => 'js-header-pms-button',
|
||||
];
|
||||
$menu[] = [
|
||||
'title' => 'Settings',
|
||||
'url' => $this->ctx->urls->format('settings-index'),
|
||||
'url' => $this->urls->format('settings-index'),
|
||||
'icon' => 'fas fa-cog fa-fw',
|
||||
];
|
||||
$menu[] = [
|
||||
'title' => 'Search',
|
||||
'url' => $this->ctx->urls->format('search-index'),
|
||||
'url' => $this->urls->format('search-index'),
|
||||
'icon' => 'fas fa-search fa-fw',
|
||||
];
|
||||
|
||||
if(!$this->ctx->usersCtx->hasActiveBan($userInfo) && $globalPerms->check(Perm::G_IS_JANITOR)) {
|
||||
if(!$this->usersCtx->hasActiveBan($userInfo) && $globalPerms->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 === '' ? $this->ctx->urls->format('index') : $manageUrl,
|
||||
'url' => $manageUrl === '' ? $this->urls->format('index') : $manageUrl,
|
||||
'icon' => 'fas fa-door-open fa-fw',
|
||||
];
|
||||
else
|
||||
$menu[] = [
|
||||
'title' => 'Enter Broom Closet',
|
||||
'url' => $manageUrl === '' ? $this->ctx->urls->format('manage-index') : $manageUrl,
|
||||
'url' => $manageUrl === '' ? $this->urls->format('manage-index') : $manageUrl,
|
||||
'icon' => 'fas fa-door-closed fa-fw',
|
||||
];
|
||||
}
|
||||
|
||||
$menu[] = [
|
||||
'title' => 'Log out',
|
||||
'url' => $this->ctx->urls->format('auth-logout', ['csrf' => $this->ctx->csrfCtx->createToken()]),
|
||||
'url' => $this->urls->format('auth-logout', ['csrf' => $this->csrfCtx->createToken()]),
|
||||
'icon' => 'fas fa-sign-out-alt fa-fw',
|
||||
];
|
||||
} else {
|
||||
$menu[] = [
|
||||
'title' => 'Register',
|
||||
'url' => $this->ctx->urls->format('auth-register'),
|
||||
'url' => $this->urls->format('auth-register'),
|
||||
'icon' => 'fas fa-user-plus fa-fw',
|
||||
];
|
||||
$menu[] = [
|
||||
'title' => 'Log in',
|
||||
'url' => $this->ctx->urls->format('auth-login'),
|
||||
'url' => $this->urls->format('auth-login'),
|
||||
'icon' => 'fas fa-sign-in-alt fa-fw',
|
||||
];
|
||||
}
|
||||
|
@ -209,49 +231,49 @@ final class TemplatingExtension extends AbstractExtension {
|
|||
|
||||
/** @return array<string, array<string, string>> */
|
||||
public function getManageMenu(): array {
|
||||
$globalPerms = $this->ctx->authInfo->getPerms('global');
|
||||
if(!$this->ctx->authInfo->loggedIn || !$globalPerms->check(Perm::G_IS_JANITOR))
|
||||
$globalPerms = $this->authInfo->getPerms('global');
|
||||
if(!$this->authInfo->loggedIn || !$globalPerms->check(Perm::G_IS_JANITOR))
|
||||
return [];
|
||||
|
||||
$menu = [
|
||||
'General' => [
|
||||
'Overview' => $this->ctx->urls->format('manage-general-overview'),
|
||||
'Overview' => $this->urls->format('manage-general-overview'),
|
||||
],
|
||||
];
|
||||
|
||||
if($globalPerms->check(Perm::G_LOGS_VIEW))
|
||||
$menu['General']['Logs'] = $this->ctx->urls->format('manage-general-logs');
|
||||
$menu['General']['Logs'] = $this->urls->format('manage-general-logs');
|
||||
if($globalPerms->check(Perm::G_EMOTES_MANAGE))
|
||||
$menu['General']['Emoticons'] = $this->ctx->urls->format('manage-general-emoticons');
|
||||
$menu['General']['Emoticons'] = $this->urls->format('manage-general-emoticons');
|
||||
if($globalPerms->check(Perm::G_CONFIG_MANAGE))
|
||||
$menu['General']['Settings'] = $this->ctx->urls->format('manage-general-settings');
|
||||
$menu['General']['Settings'] = $this->urls->format('manage-general-settings');
|
||||
|
||||
$userPerms = $this->ctx->authInfo->getPerms('user');
|
||||
$userPerms = $this->authInfo->getPerms('user');
|
||||
if($userPerms->check(Perm::U_USERS_MANAGE))
|
||||
$menu['Users & Roles']['Users'] = $this->ctx->urls->format('manage-users');
|
||||
$menu['Users & Roles']['Users'] = $this->urls->format('manage-users');
|
||||
if($userPerms->check(Perm::U_ROLES_MANAGE))
|
||||
$menu['Users & Roles']['Roles'] = $this->ctx->urls->format('manage-roles');
|
||||
$menu['Users & Roles']['Roles'] = $this->urls->format('manage-roles');
|
||||
if($userPerms->check(Perm::U_NOTES_MANAGE))
|
||||
$menu['Users & Roles']['Notes'] = $this->ctx->urls->format('manage-users-notes');
|
||||
$menu['Users & Roles']['Notes'] = $this->urls->format('manage-users-notes');
|
||||
if($userPerms->check(Perm::U_WARNINGS_MANAGE))
|
||||
$menu['Users & Roles']['Warnings'] = $this->ctx->urls->format('manage-users-warnings');
|
||||
$menu['Users & Roles']['Warnings'] = $this->urls->format('manage-users-warnings');
|
||||
if($userPerms->check(Perm::U_BANS_MANAGE))
|
||||
$menu['Users & Roles']['Bans'] = $this->ctx->urls->format('manage-users-bans');
|
||||
$menu['Users & Roles']['Bans'] = $this->urls->format('manage-users-bans');
|
||||
|
||||
if($globalPerms->check(Perm::G_NEWS_POSTS_MANAGE))
|
||||
$menu['News']['Posts'] = $this->ctx->urls->format('manage-news-posts');
|
||||
$menu['News']['Posts'] = $this->urls->format('manage-news-posts');
|
||||
if($globalPerms->check(Perm::G_NEWS_CATEGORIES_MANAGE))
|
||||
$menu['News']['Categories'] = $this->ctx->urls->format('manage-news-categories');
|
||||
$menu['News']['Categories'] = $this->urls->format('manage-news-categories');
|
||||
|
||||
if($globalPerms->check(Perm::G_FORUM_CATEGORIES_MANAGE))
|
||||
$menu['Forum']['Permission Calculator'] = $this->ctx->urls->format('manage-forum-categories');
|
||||
$menu['Forum']['Permission Calculator'] = $this->urls->format('manage-forum-categories');
|
||||
if($globalPerms->check(Perm::G_FORUM_TOPIC_REDIRS_MANAGE))
|
||||
$menu['Forum']['Topic Redirects'] = $this->ctx->urls->format('manage-forum-topic-redirs');
|
||||
$menu['Forum']['Topic Redirects'] = $this->urls->format('manage-forum-topic-redirs');
|
||||
|
||||
if($globalPerms->check(Perm::G_CL_CHANGES_MANAGE))
|
||||
$menu['Changelog']['Changes'] = $this->ctx->urls->format('manage-changelog-changes');
|
||||
$menu['Changelog']['Changes'] = $this->urls->format('manage-changelog-changes');
|
||||
if($globalPerms->check(Perm::G_CL_TAGS_MANAGE))
|
||||
$menu['Changelog']['Tags'] = $this->ctx->urls->format('manage-changelog-tags');
|
||||
$menu['Changelog']['Tags'] = $this->urls->format('manage-changelog-tags');
|
||||
|
||||
return $menu;
|
||||
}
|
7
src/Templating/TemplatingMetaVariableProvider.php
Normal file
7
src/Templating/TemplatingMetaVariableProvider.php
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
namespace Misuzu\Templating;
|
||||
|
||||
interface TemplatingMetaVariableProvider {
|
||||
/** @return array<string, string> */
|
||||
public function getTemplatingMetaVariables(): array;
|
||||
}
|
|
@ -4,14 +4,15 @@ namespace Misuzu\Users\Assets;
|
|||
use InvalidArgumentException;
|
||||
use RuntimeException;
|
||||
use Index\Http\{HttpRequest,HttpResponseBuilder};
|
||||
use Index\Http\Routing\{HttpGet,RouteHandler,RouteHandlerCommon};
|
||||
use Index\Http\Routing\Processors\Before;
|
||||
use Index\Http\Routing\Routes\{ExactRoute,PatternRoute};
|
||||
use Index\Urls\{UrlFormat,UrlRegistry,UrlSource,UrlSourceCommon};
|
||||
use Misuzu\{Misuzu,Perm};
|
||||
use Misuzu\Auth\AuthInfo;
|
||||
use Misuzu\Routing\{HandlerRoles,RouteHandler,RouteHandlerCommon};
|
||||
use Misuzu\Users\{UsersContext,UserInfo};
|
||||
|
||||
#[HandlerRoles('main')]
|
||||
class AssetsRoutes implements RouteHandler, UrlSource {
|
||||
use RouteHandlerCommon, UrlSourceCommon;
|
||||
|
||||
|
|
|
@ -5,16 +5,17 @@ use RuntimeException;
|
|||
use Index\XArray;
|
||||
use Index\Colour\{Colour,ColourRgb};
|
||||
use Index\Http\{HttpRequest,HttpResponseBuilder};
|
||||
use Index\Http\Routing\{RouteHandler,RouteHandlerCommon};
|
||||
use Index\Http\Routing\AccessControl\AccessControl;
|
||||
use Index\Http\Routing\Processors\Before;
|
||||
use Index\Http\Routing\Routes\ExactRoute;
|
||||
use Index\Urls\UrlRegistry;
|
||||
use Misuzu\{FieldTransformer,SiteInfo};
|
||||
use Misuzu\Auth\AuthInfo;
|
||||
use Misuzu\Routing\{HandlerRoles,RouteHandler,RouteHandlerCommon};
|
||||
use Misuzu\Users\UserInfo;
|
||||
use Misuzu\Users\Assets\UserAvatarAsset;
|
||||
|
||||
#[HandlerRoles('main')]
|
||||
final class UsersApiRoutes implements RouteHandler {
|
||||
use RouteHandlerCommon;
|
||||
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
<?php
|
||||
namespace Misuzu\Users;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use RuntimeException;
|
||||
use Index\Colour\Colour;
|
||||
use Index\Config\Config;
|
||||
use Index\Db\DbConnection;
|
||||
|
||||
class UsersContext {
|
||||
|
@ -27,7 +30,24 @@ class UsersContext {
|
|||
/** @var array<string, ?BanInfo> */
|
||||
private array $activeBans = [];
|
||||
|
||||
public function __construct(DbConnection $dbConn) {
|
||||
public string $accountHost {
|
||||
get => $this->config->getString('accthost');
|
||||
}
|
||||
|
||||
public string $newestUserId {
|
||||
get => $this->config->getString('newest');
|
||||
set(string $value) {
|
||||
if($value === '')
|
||||
$this->config->removeValues('newest');
|
||||
else
|
||||
$this->config->setString('newest', $value);
|
||||
}
|
||||
}
|
||||
|
||||
public function __construct(
|
||||
DbConnection $dbConn,
|
||||
private Config $config,
|
||||
) {
|
||||
$this->users = new UsersData($dbConn);
|
||||
$this->roles = new RolesData($dbConn);
|
||||
$this->bans = new BansData($dbConn);
|
||||
|
@ -94,4 +114,42 @@ class UsersContext {
|
|||
): bool {
|
||||
return $this->tryGetActiveBan($userInfo, $minimumSeverity) !== null;
|
||||
}
|
||||
|
||||
/** @return string[] */
|
||||
public function getAllowedImpersonationIds(UserInfo|string $userInfo): array {
|
||||
return $this->config->getArray(
|
||||
sprintf('allow_impersonate.u%s', $userInfo instanceof UserInfo ? $userInfo->id : $userInfo)
|
||||
);
|
||||
}
|
||||
|
||||
/** @param array<UserInfo|string> $users */
|
||||
public function setAllowedImpersonationIds(UserInfo|string $userInfo, array $users): void {
|
||||
foreach($users as $key => $value)
|
||||
if($value instanceof UserInfo)
|
||||
$users[$key] = $value->id;
|
||||
elseif(!is_string($value))
|
||||
throw new InvalidArgumentException('$users must be an array of UserInfo instances or id strings');
|
||||
|
||||
$name = sprintf('allow_impersonate.u%s', $userInfo instanceof UserInfo ? $userInfo->id : $userInfo);
|
||||
|
||||
if(empty($users))
|
||||
$this->config->removeValues($name);
|
||||
else
|
||||
$this->config->setArray($name, $users);
|
||||
}
|
||||
|
||||
public function canImpersonateUser(UserInfo|string $actorInfo, UserInfo|string $targetInfo): bool {
|
||||
if(is_string($actorInfo))
|
||||
try {
|
||||
$actorInfo = $this->getUserInfo($actorInfo);
|
||||
} catch(RuntimeException $ex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $actorInfo->super || in_array(
|
||||
$targetInfo instanceof UserInfo ? $targetInfo->id : $targetInfo,
|
||||
$this->getAllowedImpersonationIds($actorInfo),
|
||||
true,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
namespace Misuzu\Users;
|
||||
|
||||
use Exception;
|
||||
use Index\Config\Config;
|
||||
use Index\Urls\UrlRegistry;
|
||||
use Misuzu\SiteInfo;
|
||||
use Misuzu\WebFinger\{
|
||||
|
@ -15,11 +14,10 @@ class UsersWebFingerResolver implements WebFingerResolver {
|
|||
private UsersContext $usersCtx,
|
||||
private SiteInfo $siteInfo,
|
||||
private UrlRegistry $urls,
|
||||
private Config $config
|
||||
) {}
|
||||
|
||||
public function resolve(string $uri, array $components): ?WebFingerResourceInfo {
|
||||
$acctHost = $this->config->getString('accthost');
|
||||
$acctHost = $this->usersCtx->accountHost;
|
||||
$getValue = null;
|
||||
|
||||
if(isset($components['scheme']) && isset($components['path'])) {
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
<?php
|
||||
namespace Misuzu\WebFinger;
|
||||
|
||||
use Index\XArray;
|
||||
use Index\{Dependencies,XArray};
|
||||
use Index\Http\{HttpResponseBuilder,HttpRequest};
|
||||
use Index\Http\Routing\{RouteHandler,RouteHandlerCommon};
|
||||
use Index\Http\Routing\AccessControl\AccessControl;
|
||||
use Index\Http\Routing\Routes\ExactRoute;
|
||||
use Misuzu\Routing\{HandlerRoles,RouteHandler,RouteHandlerCommon};
|
||||
|
||||
#[HandlerRoles('main')]
|
||||
class WebFingerRoutes implements RouteHandler {
|
||||
use RouteHandlerCommon;
|
||||
|
||||
public function __construct(
|
||||
private WebFingerRegistry $registry
|
||||
private WebFingerRegistry $registry,
|
||||
) {}
|
||||
|
||||
/**
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<a href="https://patchii.net/flashii/misuzu/src/tag/{{ git_tag }}" target="_blank" rel="noopener" class="footer__link">{{ git_tag }}</a>
|
||||
{% endif %}
|
||||
# <a href="https://patchii.net/flashii/misuzu/commit/{{ git_commit_hash(true) }}" target="_blank" rel="noopener" class="footer__link">{{ git_commit_hash() }}</a>
|
||||
{% if globals.display_timings_info %}
|
||||
{% if auth_display_timings() %}
|
||||
/ Index {{ ndx_version() }}
|
||||
/ {{ sql_query_count()|number_format }} queries
|
||||
/ {{ (startup_time() - startup_time(constant('MSZ_TPL_RENDER')))|number_format(5) }} load
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
{% from 'macros.twig' import avatar %}
|
||||
{% from '_layout/input.twig' import input_checkbox_raw %}
|
||||
|
||||
{% if globals.auth_info.impersonating %}
|
||||
{% set real_user_info = globals.auth_info.realUserInfo %}
|
||||
{% if auth_impersonating() %}
|
||||
{% set real_user_id = auth_get_real_user_info('id') %}
|
||||
{% set real_user_name = auth_get_real_user_info('name') %}
|
||||
<div class="impersonate">
|
||||
<div class="impersonate-content">
|
||||
<div class="impersonate-user">
|
||||
You are <a href="{{ url('user-profile', {'user': real_user_info.id}) }}" class="impersonate-user-link">
|
||||
<div class="avatar impersonate-user-avatar">{{ avatar(real_user_info.id, 20, real_user_info.name) }}</div>
|
||||
{{ real_user_info.name }}
|
||||
You are <a href="{{ url('user-profile', {'user': real_user_id}) }}" class="impersonate-user-link">
|
||||
<div class="avatar impersonate-user-avatar">{{ avatar(real_user_id, 20, real_user_name) }}</div>
|
||||
{{ real_user_name }}
|
||||
</a>
|
||||
</div>
|
||||
<div class="impersonate-options">
|
||||
|
@ -26,8 +27,8 @@
|
|||
<div class="header__background"></div>
|
||||
|
||||
<div class="header__desktop">
|
||||
<a class="header__desktop__logo" href="{{ url('index') }}" title="{{ globals.site_info.name }}">
|
||||
{{ globals.site_info.name }}
|
||||
<a class="header__desktop__logo" href="{{ url('index') }}" title="{{ site_get_info('name') }}">
|
||||
{{ site_get_info('name') }}
|
||||
</a>
|
||||
|
||||
<div class="header__desktop__menus">
|
||||
|
@ -56,10 +57,11 @@
|
|||
</a>
|
||||
{% endfor %}
|
||||
|
||||
{% if globals.auth_info.loggedIn %}
|
||||
{% set user_info = globals.auth_info.userInfo %}
|
||||
<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) }}
|
||||
{% if auth_logged_in() %}
|
||||
{% set header_user_id = auth_get_user_info('id') %}
|
||||
{% set header_user_name = auth_get_user_info('name') %}
|
||||
<a href="{{ url('user-profile', {'user': header_user_id}) }}" class="avatar header__desktop__user__avatar" title="{{ header_user_name }}">
|
||||
{{ avatar(header_user_id, 60, header_user_name) }}
|
||||
</a>
|
||||
{% else %}
|
||||
<a href="{{ url('auth-login') }}" class="avatar header__desktop__user__avatar">
|
||||
|
@ -76,13 +78,12 @@
|
|||
</label>
|
||||
|
||||
<a class="header__mobile__logo header__mobile__icon" href="{{ url('index') }}">
|
||||
{{ globals.site_info.name }}
|
||||
{{ site_get_info('name') }}
|
||||
</a>
|
||||
|
||||
<label class="header__mobile__icon header__mobile__avatar" for="toggle-mobile-header">
|
||||
{% if globals.auth_info.loggedIn %}
|
||||
{% set user_info = globals.auth_info.userInfo %}
|
||||
{{ avatar(user_info.id, 40, user_info.name) }}
|
||||
{% if auth_logged_in() %}
|
||||
{{ avatar(auth_get_user_info('id'), 40, auth_get_user_info('name')) }}
|
||||
{% else %}
|
||||
{{ avatar(0, 40, 'Log in') }}
|
||||
{% endif %}
|
||||
|
|
|
@ -1,27 +1,29 @@
|
|||
{% apply spaceless %}
|
||||
{% set description = description|default(globals.site_info.description) %}
|
||||
{% set site_name = site_get_info('name') %}
|
||||
{% set site_description = description|default(site_get_info('desc')) %}
|
||||
{% set site_url = site_get_info('url') %}
|
||||
|
||||
{% if title is defined %}
|
||||
{% set browser_title = title ~ ' :: ' ~ globals.site_info.name %}
|
||||
{% set browser_title = title ~ ' :: ' ~ site_name %}
|
||||
{% else %}
|
||||
{% set browser_title = globals.site_info.name %}
|
||||
{% set browser_title = site_name %}
|
||||
{% endif %}
|
||||
|
||||
<title>{{ browser_title }}</title>
|
||||
|
||||
<meta property="og:title" content="{{ title|default(globals.site_info.name) }}">
|
||||
<meta property="og:site_name" content="{{ globals.site_info.name }}">
|
||||
<meta property="og:title" content="{{ title|default(site_name) }}">
|
||||
<meta property="og:site_name" content="{{ site_name }}">
|
||||
|
||||
{% if description|length > 0 %}
|
||||
<meta name="description" content="{{ description }}">
|
||||
<meta property="og:description" content="{{ description }}">
|
||||
{% if site_description|length > 0 %}
|
||||
<meta name="description" content="{{ site_description }}">
|
||||
<meta property="og:description" content="{{ site_description }}">
|
||||
{% endif %}
|
||||
|
||||
<meta property="og:type" content="object">
|
||||
|
||||
{% if image is defined %}
|
||||
{% if image|slice(0, 1) == '/' %}
|
||||
{% set image = globals.site_info.url is not empty ? (globals.site_info.url ~ image) : '' %}
|
||||
{% set image = site_url ~ image %}
|
||||
{% endif %}
|
||||
|
||||
{% if image|length > 0 %}
|
||||
|
@ -31,7 +33,7 @@
|
|||
|
||||
{% if canonical_url is defined %}
|
||||
{% if canonical_url|slice(0, 1) == '/' %}
|
||||
{% set canonical_url = globals.site_info.url is not empty ? (globals.site_info.url ~ canonical_url) : '' %}
|
||||
{% set canonical_url = site_url ~ canonical_url %}
|
||||
{% endif %}
|
||||
|
||||
{% if canonical_url|length > 0 %}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
{% from 'macros.twig' import container_title %}
|
||||
|
||||
{% set error_string = '%03d %s'|format(error_code, error_text) %}
|
||||
{% set html_title = error_string ~ ' :: ' ~ globals.site_info.name %}
|
||||
{% set html_title = error_string ~ ' :: ' ~ site_get_info('name') %}
|
||||
|
||||
{% block html_head %}
|
||||
<meta name="description" content="{{ error_blerb }}">
|
||||
|
@ -20,15 +20,15 @@
|
|||
<div class="error-wrapper">
|
||||
<div class="error-container">
|
||||
<nav class="error-top">
|
||||
<div class="error-logo"><a href="{{ globals.site_info.url }}"><img src="/images/logos/imouto-default.png" alt=""></a></div>
|
||||
<div class="error-home"><a href="{{ globals.site_info.url }}">{{ globals.site_info.name }}</a></div>
|
||||
<div class="error-logo"><a href="{{ site_get_info('url') }}"><img src="/images/logos/imouto-default.png" alt=""></a></div>
|
||||
<div class="error-home"><a href="{{ site_get_info('url') }}">{{ site_get_info('name') }}</a></div>
|
||||
{% if error_code >= 500 %}
|
||||
<div class="error-nav">
|
||||
{% if globals.site_info.email is not empty %}
|
||||
<a href="mailto:{{ globals.site_info.email }}" rel="noopener" target="_blank">E-mail</a>
|
||||
{% if site_has_info('email') %}
|
||||
<a href="mailto:{{ site_get_info('email') }}" rel="noopener" target="_blank">E-mail</a>
|
||||
{% endif %}
|
||||
{% if globals.site_info.bsky is not empty %}
|
||||
<a href="{{ globals.site_info.bsky }}" rel="noopener" target="_blank">Bluesky</a>
|
||||
{% if site_has_info('bsky') %}
|
||||
<a href="{{ site_get_info('bsky') }}" rel="noopener" target="_blank">Bluesky</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
<div class="landingv2-header-content">
|
||||
<div class="landingv2-welcome">
|
||||
<a href="{{ url('index') }}">
|
||||
<img src="/images/landing-logo.png" alt="{{ globals.site_info.name }}">
|
||||
<img src="/images/landing-logo.png" alt="{{ site_get_info('name') }}">
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
@ -89,7 +89,7 @@
|
|||
{% endif %}
|
||||
# <a href="https://github.com/flashwave/misuzu/commit/{{ git_commit_hash(true) }}" target="_blank" rel="noreferrer noopener">{{ git_commit_hash() }}</a>
|
||||
</div>
|
||||
{% if globals.display_timings_info %}
|
||||
{% if auth_display_timings() %}
|
||||
<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
|
||||
</div>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<link href="/vendor/fontawesome/css/all.min.css" rel="stylesheet">
|
||||
<link href="{{ asset('common.css') }}" rel="stylesheet">
|
||||
<link href="{{ asset('misuzu.css') }}" rel="stylesheet">
|
||||
{% for name, value in globals.meta %}
|
||||
{% for name, value in get_meta_vars() %}
|
||||
{% if value is not empty %}<meta name="msz-{{ name }}" content="{{ value }}">{% endif %}
|
||||
{% endfor %}
|
||||
{% if main_css_vars is defined and main_css_vars is iterable and main_css_vars is not empty %}
|
||||
|
@ -36,12 +36,13 @@
|
|||
</div>
|
||||
</noscript>
|
||||
|
||||
{% if globals.active_ban_info is not null %}
|
||||
{% set active_ban_info = auth_get_ban_info() %}
|
||||
{% if active_ban_info is not null %}
|
||||
<div class="warning warning--red">
|
||||
<div class="warning__content">
|
||||
<p>You have been banned {% if globals.active_ban_info.permanent %}<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 globals.active_ban_info.publicReason is not empty %}
|
||||
<p>Reason: {{ globals.active_ban_info.publicReason }}</p>
|
||||
<p>You have been banned {% if active_ban_info.permanent %}<strong>permanently</strong>{% else %}for <strong title="{{ active_ban_info.expiresTime|date('r') }}">{{ active_ban_info.remainingString }}</strong>{% endif %} since <strong><time datetime="{{ active_ban_info.createdTime|date('c') }}" title="{{ active_ban_info.createdTime|date('r') }}">{{ active_ban_info.createdTime|time_format }}</time></strong>.</p>
|
||||
{% if active_ban_info.publicReason is not empty %}
|
||||
<p>Reason: {{ active_ban_info.publicReason }}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{% extends 'html.twig' %}
|
||||
|
||||
{% set html_title = (title is defined ? (title ~ ' :: ') : '') ~ globals.site_info.name %}
|
||||
{% set html_title = (title is defined ? (title ~ ' :: ') : '') ~ site_get_info('name') %}
|
||||
|
||||
{% block html_head %}
|
||||
<link href="{{ asset('common.css') }}" rel="stylesheet">
|
||||
|
@ -27,7 +27,7 @@
|
|||
<div class="oauth2-body">
|
||||
<div class="oauth2-banner">
|
||||
<div class="oauth2-banner-text">{{ body_title|default('') }}</div>
|
||||
<div class="oauth2-banner-logo">{{ globals.site_info.name }}</div>
|
||||
<div class="oauth2-banner-logo">{{ site_get_info('name') }}</div>
|
||||
</div>
|
||||
|
||||
{% block body_content %}{% endblock %}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{% extends 'redirects/master.twig' %}
|
||||
|
||||
{% set html_title = globals.site_info.name ~ ' Redirect Service' %}
|
||||
{% set html_title = site_get_info('name') ~ ' Redirect Service' %}
|
||||
|
||||
{% block content %}
|
||||
<div class="redir-landing">
|
||||
|
@ -8,7 +8,7 @@
|
|||
<article class="redir-landing-body">
|
||||
<p><div class="redir-landing-logo"></div></p>
|
||||
<h1>{{ html_title }}</h1>
|
||||
<p>Short URL Service for <a href="{{ globals.site_info.url }}" rel="noopener">{{ globals.site_info.name }}</a></p>
|
||||
<p>Short URL Service for <a href="{{ site_get_info('url') }}/" rel="noopener">{{ site_get_info('name') }}</a></p>
|
||||
</article>
|
||||
<footer class="redir-landing-footer">
|
||||
<p>
|
||||
|
|
|
@ -77,10 +77,11 @@ handleValue:
|
|||
$hostName ??= 'localhost';
|
||||
|
||||
// this should really not be necessary, mostly done to make sure the url registry is available
|
||||
$msz->createRouting(new HttpRequest('1.1', ['Host' => [$hostName]], NullStream::instance(), [], 'GET', HttpUri::createUri('/'), [], []));
|
||||
$msz->startTemplating(false);
|
||||
$msz->registerRequestRoutes(
|
||||
new HttpRequest('1.1', ['Host' => [$hostName]], NullStream::instance(), [], 'GET', HttpUri::createUri('/'), [], [])
|
||||
);
|
||||
|
||||
$ctx = $msz->templating->load(implode(' ', array_slice($argv, $pathIndex)));
|
||||
$ctx = $msz->tplCtx->loadTemplate(implode(' ', array_slice($argv, $pathIndex)));
|
||||
|
||||
foreach($tplArgs as $name => $value)
|
||||
$ctx->setVar($name, $value);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue