From 6484118cca4cbcf9b9aac5c825b4590eff3550d1 Mon Sep 17 00:00:00 2001 From: flashwave Date: Sat, 14 Oct 2023 23:05:49 +0000 Subject: [PATCH] Prerender error pages. --- .gitignore | 6 ++ build.js | 48 +++++++++ package-lock.json | 213 ++++++++++++++++++++++++++++++++++++++ package.json | 1 + public/index.php | 6 +- src/CSRFPContainer.php | 41 ++++++++ src/MakaiContext.php | 16 ++- src/RoutingContext.php | 16 +-- src/Whois/WhoisRoutes.php | 8 +- templates/master.twig | 2 +- tools/render-tpl | 9 ++ 11 files changed, 338 insertions(+), 28 deletions(-) create mode 100644 src/CSRFPContainer.php create mode 100755 tools/render-tpl diff --git a/.gitignore b/.gitignore index 1c93aca..0b45d20 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,14 @@ .DS_Store [Dd]esktop.ini /.debug +/.migrating /config/*.ini /vendor /node_modules /public/assets /assets/current.json +/public/error-401.html +/public/error-403.html +/public/error-404.html +/public/error-500.html +/public/error-503.html diff --git a/build.js b/build.js index 8f68a03..5a4d8a1 100644 --- a/build.js +++ b/build.js @@ -2,7 +2,9 @@ const fs = require('fs'); const swc = require('@swc/core'); const path = require('path'); const util = require('util'); +const exec = util.promisify(require('child_process').exec); const postcss = require('postcss'); +const htmlminify = require('html-minifier-terser').minify; const utils = require('./assets/utils.js'); const assproc = require('./assets/assproc.js'); @@ -19,6 +21,14 @@ const pubAssetJSFormat = '%s-%s.js'; const isDebugBuild = fs.existsSync(path.join(rootDir, '.debug')); +const renderTemplates = [ + { in: 'errors/401', out: '/error-401.html' }, + { in: 'errors/403', out: '/error-403.html' }, + { in: 'errors/404', out: '/error-404.html' }, + { in: 'errors/500', out: '/error-500.html' }, + { in: 'errors/503', out: '/error-503.html' }, +]; + const swcJscOptions = { target: 'es2016', loose: false, @@ -47,6 +57,22 @@ const swcJscOptions = { }, }; +const htmlMinifyOptions = { + collapseBooleanAttributes: true, + collapseWhitespace: true, + conservativeCollapse: false, + decodeEntities: false, + quoteCharacter: '"', + removeAttributeQuotes: true, + removeComments: true, + removeEmptyAttributes: true, + removeOptionalTags: true, + removeScriptTypeAttributes: true, + removeStyleLinkTypeAttributes: true, + sortAttributes: true, + sortClassName: true, +}; + const postcssPlugins = []; if(!isDebugBuild) postcssPlugins.push(require('cssnano')); postcssPlugins.push(require('autoprefixer')({ @@ -103,5 +129,27 @@ fs.mkdirSync(pubAssetsFull, { recursive: true }); console.log('Writing assets info...'); fs.writeFileSync(assetsInfo, JSON.stringify(assets)); + console.log('Housekeeping...'); assproc.housekeep(pubAssetsFull); + + console.log('Prerendering templates...'); + + const renderCommand = path.join(rootDir, 'tools/render-tpl'); + console.log(renderCommand); + + for(const info of renderTemplates) { + console.log(); + console.log(info.in); + + const { stdout, stderr } = await exec(`${renderCommand} ${info.in}`); + + if(stdout.trim() === '') { + console.error(stderr); + continue; + } + + let body = await htmlminify(stdout, htmlMinifyOptions); + + fs.writeFileSync(path.join(pubDir, info.out), body); + } })(); diff --git a/package-lock.json b/package-lock.json index b568fa4..af96664 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,9 +8,62 @@ "@swc/core": "^1.3.69", "autoprefixer": "^10.4.14", "cssnano": "^6.0.1", + "html-minifier-terser": "^7.2.0", "postcss": "^8.4.26" } }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", + "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.19", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", + "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, "node_modules/@swc/core": { "version": "1.3.93", "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.3.93.tgz", @@ -216,6 +269,17 @@ "node": ">=10.13.0" } }, + "node_modules/acorn": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/autoprefixer": { "version": "10.4.16", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.16.tgz", @@ -288,6 +352,20 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "node_modules/camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "dependencies": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, "node_modules/caniuse-api": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", @@ -318,6 +396,17 @@ } ] }, + "node_modules/clean-css": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.2.tgz", + "integrity": "sha512-JVJbM+f3d3Q704rF4bqQ5UUyTtuJ0JRKNbTKVEeujCCBoMdkEi+V+e8oktO9qGQNSvHrFTM6JZRXrUvGR1czww==", + "dependencies": { + "source-map": "~0.6.0" + }, + "engines": { + "node": ">= 10.0" + } + }, "node_modules/colord": { "version": "2.9.3", "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", @@ -544,6 +633,15 @@ "url": "https://github.com/fb55/domutils?sponsor=1" } }, + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, "node_modules/electron-to-chromium": { "version": "1.4.554", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.554.tgz", @@ -580,6 +678,34 @@ "url": "https://github.com/sponsors/rawify" } }, + "node_modules/html-minifier-terser": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-7.2.0.tgz", + "integrity": "sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==", + "dependencies": { + "camel-case": "^4.1.2", + "clean-css": "~5.3.2", + "commander": "^10.0.0", + "entities": "^4.4.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.15.1" + }, + "bin": { + "html-minifier-terser": "cli.js" + }, + "engines": { + "node": "^14.13.1 || >=16.0.0" + } + }, + "node_modules/html-minifier-terser/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "engines": { + "node": ">=14" + } + }, "node_modules/lilconfig": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", @@ -598,6 +724,14 @@ "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dependencies": { + "tslib": "^2.0.3" + } + }, "node_modules/mdn-data": { "version": "2.0.30", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", @@ -620,6 +754,15 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, "node_modules/node-releases": { "version": "2.0.13", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", @@ -644,6 +787,24 @@ "url": "https://github.com/fb55/nth-check?sponsor=1" } }, + "node_modules/param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -1073,6 +1234,22 @@ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" }, + "node_modules/relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-js": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", @@ -1081,6 +1258,15 @@ "node": ">=0.10.0" } }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, "node_modules/stylehacks": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-6.0.0.tgz", @@ -1119,6 +1305,33 @@ "url": "https://opencollective.com/svgo" } }, + "node_modules/terser": { + "version": "5.21.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.21.0.tgz", + "integrity": "sha512-WtnFKrxu9kaoXuiZFSGrcAvvBqAdmKx0SFNmVNYdJamMu9yyN3I/QF0FbH4QcqJQ+y1CJnzxGIKH0cSj+FGYRw==", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + }, "node_modules/update-browserslist-db": { "version": "1.0.13", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", diff --git a/package.json b/package.json index 391b867..dcacf4f 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "@swc/core": "^1.3.69", "autoprefixer": "^10.4.14", "cssnano": "^6.0.1", + "html-minifier-terser": "^7.2.0", "postcss": "^8.4.26" } } diff --git a/public/index.php b/public/index.php index 8ff716a..b02f4d5 100644 --- a/public/index.php +++ b/public/index.php @@ -14,17 +14,17 @@ set_exception_handler(function(\Throwable $ex) { } header('Content-Type: text/html; charset=utf-8'); - echo file_get_contents(MKI_DIR_TEMPLATES . '/errors/500.html'); + echo file_get_contents(MKI_DIR_PUBLIC . '/error-500.html'); exit; }); if(file_exists(MKI_ROOT . '/.migrating')) { http_response_code(503); - echo file_get_contents(MKI_DIR_TEMPLATES . '/errors/503.html'); + echo file_get_contents(MKI_DIR_PUBLIC . '/error-503.html'); exit; } -$makai->startCSRFP( +$makai->getCSRFP()->setInfo( $cfg['csrfp'] ?? 'meow', (string)filter_input(INPUT_SERVER, 'REMOTE_ADDR') ); diff --git a/src/CSRFPContainer.php b/src/CSRFPContainer.php new file mode 100644 index 0000000..a623329 --- /dev/null +++ b/src/CSRFPContainer.php @@ -0,0 +1,41 @@ +secretKey = $secretKey; + if($identity !== null) + $this->identity = $identity; + + $this->instance = null; + } + + public function isAvailable(): bool { + return $this->instance !== null + || ($this->secretKey !== '' && $this->identity !== ''); + } + + public function getInstance(): ?CSRFP { + if($this->instance === null) + $this->instance = new CSRFP($this->secretKey, $this->identity); + return $this->instance; + } + + public function createToken(...$args): string { + return $this->getInstance()?->createToken(...$args) ?? ''; + } + + public function verifyToken(...$args): bool { + return $this->getInstance()?->verifyToken(...$args) ?? false; + } +} diff --git a/src/MakaiContext.php b/src/MakaiContext.php index ee83969..7606e86 100644 --- a/src/MakaiContext.php +++ b/src/MakaiContext.php @@ -6,13 +6,12 @@ use Index\Data\IDbConnection; use Index\Data\Migration\IDbMigrationRepo; use Index\Data\Migration\DbMigrationManager; use Index\Data\Migration\FsDbMigrationRepo; -use Index\Security\CSRFP; use Sasae\SasaeEnvironment; final class MakaiContext { private IDbConnection $dbConn; private SasaeEnvironment $templating; - private CSRFP $csrfp; + private CSRFPContainer $csrfp; private SiteInfo $siteInfo; @@ -24,6 +23,7 @@ final class MakaiContext { $this->dbConn = $dbConn; $this->siteInfo = new SiteInfo; + $this->csrfp = new CSRFPContainer; $this->startTemplating(); $this->contacts = new Contacts\Contacts($dbConn); @@ -76,28 +76,26 @@ final class MakaiContext { cache: $isDebug ? null : ['Makai', GitInfo::hash(true)], debug: $isDebug, ); - $this->templating->addFunction('csrfp_token', fn() => $this->getCSRFP()->createToken()); + $this->templating->addFunction('csrfp_token', $this->csrfp->createToken(...)); + $this->templating->addFunction('csrfp_available', $this->csrfp->isAvailable(...)); $this->templating->addGlobal('globals', [ 'siteInfo' => $this->siteInfo, 'assetsInfo' => AssetsInfo::fromCurrent(), ]); } - public function getCSRFP(): CSRFP { + public function getCSRFP(): CSRFPContainer { return $this->csrfp; } - public function startCSRFP(string $secretKey, string $identity): void { - $this->csrfp = new CSRFP($secretKey, $identity); - } - public function createRouting(): RoutingContext { $routingCtx = new RoutingContext($this->templating); $routingCtx->registerDefaultErrorPages(); $routingCtx->register(new DeveloperRoutes($this->templating, $this->contacts, $this->projects)); $routingCtx->register(new AssetsRoutes($this->siteInfo)); - $routingCtx->register(new Whois\WhoisRoutes($this->templating, fn() => $this->csrfp)); + $routingCtx->register(new Blog\BlogRoutes($this->templating, $this->contacts, $this->projects)); + $routingCtx->register(new Whois\WhoisRoutes($this->templating, $this->csrfp)); $routingCtx->register(new SSHKeys\SSHKeysRoutes($this->sshKeys)); $routingCtx->register(new Tools\AsciiRoutes($this->templating)); $routingCtx->register(new Tools\RandomStringRoutes); diff --git a/src/RoutingContext.php b/src/RoutingContext.php index 5054060..29ae9f8 100644 --- a/src/RoutingContext.php +++ b/src/RoutingContext.php @@ -22,17 +22,11 @@ class RoutingContext { } public function registerDefaultErrorPages(): void { - $this->router->get('/error-401.html', fn() => $this->templating->render('errors/401')); - $this->router->get('/error-403.html', fn() => $this->templating->render('errors/403')); - $this->router->get('/error-404.html', fn() => $this->templating->render('errors/404')); - $this->router->get('/error-500.html', fn() => $this->templating->render('errors/500')); - $this->router->get('/error-503.html', fn() => $this->templating->render('errors/503')); - - $this->router->addErrorHandler(401, fn($resp) => $resp->setContent($this->templating->render('errors/401'))); - $this->router->addErrorHandler(403, fn($resp) => $resp->setContent($this->templating->render('errors/403'))); - $this->router->addErrorHandler(404, fn($resp) => $resp->setContent($this->templating->render('errors/404'))); - $this->router->addErrorHandler(500, fn($resp) => $resp->setContent(file_get_contents(MKI_DIR_TEMPLATES . '/errors/500.html'))); - $this->router->addErrorHandler(503, fn($resp) => $resp->setContent(file_get_contents(MKI_DIR_TEMPLATES . '/errors/503.html'))); + $this->router->addErrorHandler(401, fn($resp) => $resp->setContent(file_get_contents(MKI_DIR_PUBLIC . '/error-401.html'))); + $this->router->addErrorHandler(403, fn($resp) => $resp->setContent(file_get_contents(MKI_DIR_PUBLIC . '/error-403.html'))); + $this->router->addErrorHandler(404, fn($resp) => $resp->setContent(file_get_contents(MKI_DIR_PUBLIC . '/error-404.html'))); + $this->router->addErrorHandler(500, fn($resp) => $resp->setContent(file_get_contents(MKI_DIR_PUBLIC . '/error-500.html'))); + $this->router->addErrorHandler(503, fn($resp) => $resp->setContent(file_get_contents(MKI_DIR_PUBLIC . '/error-503.html'))); } public function register(IRouteHandler $handler): void { diff --git a/src/Whois/WhoisRoutes.php b/src/Whois/WhoisRoutes.php index 8ffd228..56319ce 100644 --- a/src/Whois/WhoisRoutes.php +++ b/src/Whois/WhoisRoutes.php @@ -4,11 +4,12 @@ namespace Makai\Whois; use Index\Routing\Route; use Index\Routing\RouteHandler; use Sasae\SasaeEnvironment; +use Makai\CSRFPContainer; class WhoisRoutes extends RouteHandler { public function __construct( private SasaeEnvironment $templating, - private \Closure $csrfp, + private CSRFPContainer $csrfp, ) {} #[Route('GET', '/whois')] @@ -22,15 +23,14 @@ class WhoisRoutes extends RouteHandler { return 400; $content = $request->getContent(); - $csrfp = ($this->csrfp)(); - if(!$csrfp->verifyToken((string)$content->getParam('_csrfp'))) + if(!$this->csrfp->verifyToken((string)$content->getParam('_csrfp'))) return [ 'error' => true, 'text' => 'Could not validate request, please refresh the page.', ]; - $response->setHeader('X-CSRFP', $csrfp->createToken()); + $response->setHeader('X-CSRFP', $this->csrfp->createToken()); $target = trim((string)$content->getParam('target')); if(empty($target)) diff --git a/templates/master.twig b/templates/master.twig index 28e6bb8..924af05 100644 --- a/templates/master.twig +++ b/templates/master.twig @@ -4,7 +4,7 @@ {% if master_title is defined and master_title is not empty %}{{ master_title }}{% endif %} {% block master_head %}{% endblock %} - + {% if csrfp_available() %}{% endif %} {% if styles is defined and styles is iterable and styles is not empty %} {% for style in styles|reverse %} diff --git a/tools/render-tpl b/tools/render-tpl new file mode 100755 index 0000000..2dd2b2a --- /dev/null +++ b/tools/render-tpl @@ -0,0 +1,9 @@ +#!/usr/bin/env php +startTemplating(); +$templating = $makai->getTemplating(); +$path = implode(' ', array_slice($argv, 1)); + +echo $templating->render($path);