From 5adb29d7002b9cea86c4b1d9f2bb7ebb21612c58 Mon Sep 17 00:00:00 2001 From: Sergio Brighenti Date: Fri, 15 Nov 2019 00:56:25 +0100 Subject: [PATCH] Added ability to set custom html improved session samesite implementation for older php versions Fixes #82 --- CHANGELOG.md | 3 + app/Controllers/AdminController.php | 22 +++- app/Database/Migrator.php | 2 +- app/Middleware/AuthMiddleware.php | 2 +- app/Middleware/InjectMiddleware.php | 26 +++++ app/Middleware/Middleware.php | 4 +- app/Web/Session.php | 24 ++-- app/Web/View.php | 8 ++ app/routes.php | 2 + bootstrap/app.php | 7 +- resources/lang/en.lang.php | 5 + resources/schemas/mysql/mysql.3.sql | 5 + resources/schemas/sqlite/sqlite.3.sql | 4 + resources/templates/base.twig | 1 + resources/templates/dashboard/system.twig | 129 +++++++++++++--------- src/css/app.css | 4 + src/js/app.js | 10 ++ 17 files changed, 187 insertions(+), 71 deletions(-) create mode 100644 app/Middleware/InjectMiddleware.php create mode 100644 resources/schemas/mysql/mysql.3.sql create mode 100644 resources/schemas/sqlite/sqlite.3.sql diff --git a/CHANGELOG.md b/CHANGELOG.md index d06421e..6112113 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,10 @@ + Added web upload. + Raw URL now accept file extensions. + Improved installer. ++ Improved thumbnail generation. + Replaced videojs player with Plyr. ++ Implemented SameSite XSS protection. ++ Added ability to add custom HTML in tag. + Small fixes and improvements. ## v.2.6.6 diff --git a/app/Controllers/AdminController.php b/app/Controllers/AdminController.php index f3e2e17..7ada958 100644 --- a/app/Controllers/AdminController.php +++ b/app/Controllers/AdminController.php @@ -80,8 +80,8 @@ class AdminController extends Controller { $config = require BASE_DIR.'config.php'; - if (param($request,'lang') !== 'auto') { - $config['lang'] = param($request,'lang'); + if (param($request, 'lang') !== 'auto') { + $config['lang'] = param($request, 'lang'); } else { unset($config['lang']); } @@ -92,4 +92,22 @@ class AdminController extends Controller return redirect($response, route('system')); } + + /** + * @param Request $request + * @param Response $response + * @return Response + */ + public function applyCustomHead(Request $request, Response $response): Response + { + if ($request->getAttribute('custom_head_key_present')) { + $this->database->query('UPDATE `settings` SET `value`=? WHERE `key` = \'custom_head\'', param($request, 'custom_head')); + } else { + $this->database->query('INSERT INTO `settings`(`key`, `value`) VALUES (\'custom_head\', ?)', param($request, 'custom_head')); + } + + $this->session->alert(lang('custom_head_set')); + + return redirect($response, route('system')); + } } \ No newline at end of file diff --git a/app/Database/Migrator.php b/app/Database/Migrator.php index fc94363..736cf98 100644 --- a/app/Database/Migrator.php +++ b/app/Database/Migrator.php @@ -47,7 +47,7 @@ class Migrator $this->db->getPdo()->exec(file_get_contents($this->schemaPath.DIRECTORY_SEPARATOR.'migrations.sql')); } - $files = glob($this->schemaPath.DIRECTORY_SEPARATOR.$this->db->getCurrentDriver().'/*.sql'); + $files = glob($this->schemaPath.'/'.$this->db->getCurrentDriver().'/*.sql'); $names = array_map(function ($path) { return basename($path); diff --git a/app/Middleware/AuthMiddleware.php b/app/Middleware/AuthMiddleware.php index 39730ab..a9ed1e9 100644 --- a/app/Middleware/AuthMiddleware.php +++ b/app/Middleware/AuthMiddleware.php @@ -24,7 +24,7 @@ class AuthMiddleware extends Middleware } if (!$this->database->query('SELECT `id`, `active` FROM `users` WHERE `id` = ? LIMIT 1', [$this->session->get('user_id')])->fetch()->active) { - $this->session->alert('Your account is not active anymore.', 'danger'); + $this->session->alert(lang('account_disabled'), 'danger'); $this->session->set('logged', false); return redirect(new Response(), route('login.show')); } diff --git a/app/Middleware/InjectMiddleware.php b/app/Middleware/InjectMiddleware.php new file mode 100644 index 0000000..7024f3b --- /dev/null +++ b/app/Middleware/InjectMiddleware.php @@ -0,0 +1,26 @@ +database->query('SELECT `value` FROM `settings` WHERE `key` = \'custom_head\'')->fetch(); + $this->view->getTwig()->addGlobal('customHead', $head->value ?? null); + + return $handler->handle($request->withAttribute('custom_head_key_present', isset($head->value))); + } +} \ No newline at end of file diff --git a/app/Middleware/Middleware.php b/app/Middleware/Middleware.php index 4c90d98..7a36a3a 100644 --- a/app/Middleware/Middleware.php +++ b/app/Middleware/Middleware.php @@ -6,17 +6,17 @@ namespace App\Middleware; use App\Database\DB; use App\Web\Lang; use App\Web\Session; +use App\Web\View; use DI\Container; use League\Flysystem\Filesystem; use Monolog\Logger; use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as Request; use Psr\Http\Server\RequestHandlerInterface as RequestHandler; -use Twig\Environment; /** * @property Session|null session - * @property Environment view + * @property View view * @property DB|null database * @property Logger|null logger * @property Filesystem|null storage diff --git a/app/Web/Session.php b/app/Web/Session.php index f832715..3b56e44 100644 --- a/app/Web/Session.php +++ b/app/Web/Session.php @@ -21,6 +21,18 @@ class Session throw new Exception("The given path '{$path}' is not writable."); } + // Workaround for php <= 7.3 + if (PHP_VERSION_ID < 70300) { + $params = session_get_cookie_params(); + session_set_cookie_params( + $params['lifetime'], + $params['path'].'; SameSite=Lax', + $params['domain'], + $params['secure'], + $params['httponly'] + ); + } + $started = @session_start([ 'name' => $name, 'save_path' => $path, @@ -29,18 +41,6 @@ class Session 'cookie_samesite' => 'Lax' // works only for php >= 7.3 ]); - // Workaround for php <= 7.3 - if (PHP_VERSION_ID < 70300) { - $sessionParams = session_get_cookie_params(); - setcookie( - $name, - $this->getId(), - $sessionParams['filetime'], - $sessionParams['path'], - $sessionParams['domain'].'; SameSite=Lax' - ); - } - if (!$started) { throw new Exception("Cannot start the HTTP session. That the session path '{$path}' is writable and your PHP settings."); } diff --git a/app/Web/View.php b/app/Web/View.php index a57ad45..f7f7ce1 100644 --- a/app/Web/View.php +++ b/app/Web/View.php @@ -60,4 +60,12 @@ class View return $this->twig->render($view, $parameters); } + /** + * @return Environment + */ + public function getTwig(): Environment + { + return $this->twig; + } + } \ No newline at end of file diff --git a/app/routes.php b/app/routes.php index b084391..03ed8e6 100644 --- a/app/routes.php +++ b/app/routes.php @@ -27,6 +27,8 @@ $app->group('', function (RouteCollectorProxy $group) { $group->post('/system/lang/apply', [AdminController::class, 'applyLang'])->setName('lang.apply'); + $group->post('/system/customHead', [AdminController::class, 'applyCustomHead'])->setName('customHead.apply'); + $group->post('/system/upgrade', [UpgradeController::class, 'upgrade'])->setName('system.upgrade'); $group->get('/system/checkForUpdates', [UpgradeController::class, 'checkForUpdates'])->setName('system.checkForUpdates'); diff --git a/bootstrap/app.php b/bootstrap/app.php index 144bcc3..808ce4a 100644 --- a/bootstrap/app.php +++ b/bootstrap/app.php @@ -4,6 +4,7 @@ use App\Database\DB; use App\Exception\Handlers\AppErrorHandler; use App\Exception\Handlers\Renderers\HtmlErrorRenderer; use App\Factories\ViewFactory; +use App\Middleware\InjectMiddleware; use App\Web\Lang; use App\Web\Session; use Aws\S3\S3Client; @@ -172,8 +173,7 @@ $app->add(function (Request $request, RequestHandler $handler) { return $handler->handle($request); }); -// Load the application routes -require BASE_DIR.'app/routes.php'; +$app->add(InjectMiddleware::class); // Configure the error handler $errorHandler = new AppErrorHandler($app->getCallableResolver(), $app->getResponseFactory()); @@ -183,4 +183,7 @@ $errorHandler->registerErrorRenderer('text/html', HtmlErrorRenderer::class); $errorMiddleware = $app->addErrorMiddleware($config['debug'], true, true); $errorMiddleware->setDefaultErrorHandler($errorHandler); +// Load the application routes +require BASE_DIR.'app/routes.php'; + return $app; \ No newline at end of file diff --git a/resources/lang/en.lang.php b/resources/lang/en.lang.php index d9d8e48..4ba4ab2 100644 --- a/resources/lang/en.lang.php +++ b/resources/lang/en.lang.php @@ -102,4 +102,9 @@ return [ 'prerelease_channel' => 'Prerelease Channel', 'no_upload_token' => 'You don\'t have a personal upload token. (Generate one and try again)', 'drop_to_upload' => 'Click or drop your files here to upload.', + 'donation' => 'Donation', + 'donate_text' => 'If you like XBackBone, consider a donation to support development!', + 'custom_head_html' => 'Custom HTML Head content', + 'custom_head_html_hint' => 'This content will be added at the tag on every page.', + 'custom_head_set' => 'Custom Head HTML applied successfully.', ]; diff --git a/resources/schemas/mysql/mysql.3.sql b/resources/schemas/mysql/mysql.3.sql new file mode 100644 index 0000000..c83a16b --- /dev/null +++ b/resources/schemas/mysql/mysql.3.sql @@ -0,0 +1,5 @@ + +CREATE TABLE IF NOT EXISTS `settings` ( + `key` VARCHAR(32) PRIMARY KEY, + `value` TEXT +); \ No newline at end of file diff --git a/resources/schemas/sqlite/sqlite.3.sql b/resources/schemas/sqlite/sqlite.3.sql new file mode 100644 index 0000000..6adc875 --- /dev/null +++ b/resources/schemas/sqlite/sqlite.3.sql @@ -0,0 +1,4 @@ +CREATE TABLE IF NOT EXISTS `settings` ( + `key` VARCHAR(32) PRIMARY KEY, + `value` TEXT +); \ No newline at end of file diff --git a/resources/templates/base.twig b/resources/templates/base.twig index a673e98..a303083 100644 --- a/resources/templates/base.twig +++ b/resources/templates/base.twig @@ -27,6 +27,7 @@ } {% block head %}{% endblock %} + {{ customHead|raw }} {% block content %}{% endblock %} diff --git a/resources/templates/dashboard/system.twig b/resources/templates/dashboard/system.twig index 5a984de..6ec1427 100644 --- a/resources/templates/dashboard/system.twig +++ b/resources/templates/dashboard/system.twig @@ -14,7 +14,7 @@
{{ lang('users') }}
-

{{ usersCount }}

+

{{ usersCount }}

@@ -25,7 +25,7 @@
{{ lang('size') }}
-

{{ totalSize }}

+

{{ totalSize }}

@@ -36,7 +36,7 @@
{{ lang('files') }}
-

{{ mediasCount }}

+

{{ mediasCount }}

@@ -47,60 +47,66 @@
{{ lang('orphaned_files') }}
-

{{ orphanFilesCount }}

+

{{ orphanFilesCount }}

-
-
-
{{ lang('theme') }}
-
-
-
-
- -
+
+
+
+
+
{{ lang('theme') }}
+
+ +
+
+ +
+
+
+
+ +
+
+
-
-
- -
+
+
+
+
+
{{ lang('enforce_language') }}
+
+
+
+
+ + {{ lang('default_lang_behavior') }} +
+
+
+
+ +
+
+
- +
-
-
{{ lang('enforce_language') }}
-
-
-
-
- - {{ lang('default_lang_behavior') }} -
-
-
-
- -
-
-
-
-
-
+
{{ lang('updates') }} v{{ PLATFORM_VERSION }}
@@ -125,9 +131,21 @@
+
+
{{ lang('custom_head_html') }}
+
+
+ + {{ lang('custom_head_html_hint') }} + +
+
+
-
-
+
+
{{ lang('system_info') }}
Max upload size: @@ -137,12 +155,21 @@
-
+
{{ lang('maintenance') }}
+
+
{{ lang('donation') }}
+
+

{{ lang('donate_text') }}

+
+ +
+
+
diff --git a/src/css/app.css b/src/css/app.css index 9d3d592..6914ed7 100644 --- a/src/css/app.css +++ b/src/css/app.css @@ -111,4 +111,8 @@ body { .dropzone .dz-image { border-radius: .25rem !important; +} + +.system-tile { + font-size: 2.5rem; } \ No newline at end of file diff --git a/src/js/app.js b/src/js/app.js index 695ca27..f9d0b2b 100644 --- a/src/js/app.js +++ b/src/js/app.js @@ -29,6 +29,16 @@ var app = { $('.footer').fadeIn(600); + $('.same-height-container').each(function () { + var highestBox = 0; + $('.same-height', this).each(function () { + if ($(this).height() > highestBox) { + highestBox = $(this).height(); + } + }); + $('.same-height', this).height(highestBox); + }); + console.log('Application is ready.'); }, modalDelete: function () {