Merge pull request #39867 from nextcloud/login-less

Add a separate event for login page rendering
This commit is contained in:
Joas Schilling 2023-08-18 13:54:15 +02:00 committed by GitHub
commit be41dc4fa7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 120 additions and 52 deletions

View file

@ -116,11 +116,6 @@ class Application extends App implements IBootstrap {
Share::registerBackend('file', File::class);
Share::registerBackend('folder', Folder::class, 'file');
/**
* Always add main sharing script
*/
Util::addScript(self::APP_ID, 'main');
}
@ -139,6 +134,12 @@ class Application extends App implements IBootstrap {
$dispatcher->addListener(ResourcesLoadAdditionalScriptsEvent::class, function () {
\OCP\Util::addScript('files_sharing', 'collaboration');
});
$dispatcher->addListener(\OCP\AppFramework\Http\Events\BeforeTemplateRenderedEvent::class, function () {
/**
* Always add main sharing script
*/
Util::addScript(self::APP_ID, 'main');
});
// notifications api to accept incoming user shares
$dispatcher->addListener(ShareCreatedEvent::class, function (ShareCreatedEvent $event) {

View file

@ -31,6 +31,7 @@ use OCP\AppFramework\App;
use OCP\AppFramework\Bootstrap\IBootContext;
use OCP\AppFramework\Bootstrap\IBootstrap;
use OCP\AppFramework\Bootstrap\IRegistrationContext;
use OCP\AppFramework\Http\Events\BeforeLoginTemplateRenderedEvent;
use OCP\AppFramework\Http\Events\BeforeTemplateRenderedEvent;
use OCP\Config\BeforePreferenceDeletedEvent;
use OCP\Config\BeforePreferenceSetEvent;
@ -45,6 +46,7 @@ class Application extends App implements IBootstrap {
public function register(IRegistrationContext $context): void {
$context->registerCapability(Capabilities::class);
$context->registerEventListener(BeforeTemplateRenderedEvent::class, BeforeTemplateRenderedListener::class);
$context->registerEventListener(BeforeLoginTemplateRenderedEvent::class, BeforeTemplateRenderedListener::class);
$context->registerEventListener(BeforePreferenceSetEvent::class, BeforePreferenceListener::class);
$context->registerEventListener(BeforePreferenceDeletedEvent::class, BeforePreferenceListener::class);
}

View file

@ -47,6 +47,7 @@ use OC\Core\Notification\CoreNotifier;
use OC\Metadata\FileEventListener;
use OC\TagManager;
use OCP\AppFramework\App;
use OCP\AppFramework\Http\Events\BeforeLoginTemplateRenderedEvent;
use OCP\AppFramework\Http\Events\BeforeTemplateRenderedEvent;
use OCP\DB\Events\AddMissingColumnsEvent;
use OCP\DB\Events\AddMissingIndicesEvent;
@ -317,6 +318,7 @@ class Application extends App {
});
$eventDispatcher->addServiceListener(BeforeTemplateRenderedEvent::class, BeforeTemplateRenderedListener::class);
$eventDispatcher->addServiceListener(BeforeLoginTemplateRenderedEvent::class, BeforeTemplateRenderedListener::class);
$eventDispatcher->addServiceListener(RemoteWipeStarted::class, RemoteWipeActivityListener::class);
$eventDispatcher->addServiceListener(RemoteWipeStarted::class, RemoteWipeNotificationsListener::class);
$eventDispatcher->addServiceListener(RemoteWipeStarted::class, RemoteWipeEmailListener::class);

View file

@ -25,20 +25,53 @@ declare(strict_types=1);
*/
namespace OC\Core\Listener;
use OCP\AppFramework\Http\Events\BeforeLoginTemplateRenderedEvent;
use OCP\AppFramework\Http\Events\BeforeTemplateRenderedEvent;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventListener;
use OCP\IConfig;
use OCP\Util;
class BeforeTemplateRenderedListener implements IEventListener {
public function __construct(private IConfig $config) {
}
public function handle(Event $event): void {
if (!($event instanceof BeforeTemplateRenderedEvent)) {
if (!($event instanceof BeforeTemplateRenderedEvent || $event instanceof BeforeLoginTemplateRenderedEvent)) {
return;
}
if ($event->getResponse()->getRenderAs() === TemplateResponse::RENDER_AS_USER) {
// Making sure to inject just after core
\OCP\Util::addScript('core', 'unsupported-browser-redirect');
Util::addScript('core', 'unsupported-browser-redirect');
}
\OC_Util::addStyle('server', null, true);
if ($event instanceof BeforeLoginTemplateRenderedEvent) {
// todo: make login work without these
Util::addScript('core', 'common');
Util::addScript('core', 'main');
}
if ($event instanceof BeforeTemplateRenderedEvent) {
// include common nextcloud webpack bundle
Util::addScript('core', 'common');
Util::addScript('core', 'main');
Util::addTranslations('core');
if ($event->getResponse()->getRenderAs() !== TemplateResponse::RENDER_AS_ERROR) {
Util::addScript('core', 'merged-template-prepend', 'core', true);
Util::addScript('core', 'files_client', 'core', true);
Util::addScript('core', 'files_fileinfo', 'core', true);
// If installed and background job is set to ajax, add dedicated script
if ($this->config->getAppValue('core', 'backgroundjobs_mode', 'ajax') == 'ajax') {
Util::addScript('core', 'backgroundjobs');
}
}
}
}
}

View file

@ -57,6 +57,7 @@ return array(
'OCP\\AppFramework\\Http\\DownloadResponse' => $baseDir . '/lib/public/AppFramework/Http/DownloadResponse.php',
'OCP\\AppFramework\\Http\\EmptyContentSecurityPolicy' => $baseDir . '/lib/public/AppFramework/Http/EmptyContentSecurityPolicy.php',
'OCP\\AppFramework\\Http\\EmptyFeaturePolicy' => $baseDir . '/lib/public/AppFramework/Http/EmptyFeaturePolicy.php',
'OCP\\AppFramework\\Http\\Events\\BeforeLoginTemplateRenderedEvent' => $baseDir . '/lib/public/AppFramework/Http/Events/BeforeLoginTemplateRenderedEvent.php',
'OCP\\AppFramework\\Http\\Events\\BeforeTemplateRenderedEvent' => $baseDir . '/lib/public/AppFramework/Http/Events/BeforeTemplateRenderedEvent.php',
'OCP\\AppFramework\\Http\\FeaturePolicy' => $baseDir . '/lib/public/AppFramework/Http/FeaturePolicy.php',
'OCP\\AppFramework\\Http\\FileDisplayResponse' => $baseDir . '/lib/public/AppFramework/Http/FileDisplayResponse.php',

View file

@ -90,6 +90,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OCP\\AppFramework\\Http\\DownloadResponse' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/DownloadResponse.php',
'OCP\\AppFramework\\Http\\EmptyContentSecurityPolicy' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/EmptyContentSecurityPolicy.php',
'OCP\\AppFramework\\Http\\EmptyFeaturePolicy' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/EmptyFeaturePolicy.php',
'OCP\\AppFramework\\Http\\Events\\BeforeLoginTemplateRenderedEvent' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/Events/BeforeLoginTemplateRenderedEvent.php',
'OCP\\AppFramework\\Http\\Events\\BeforeTemplateRenderedEvent' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/Events/BeforeTemplateRenderedEvent.php',
'OCP\\AppFramework\\Http\\FeaturePolicy' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/FeaturePolicy.php',
'OCP\\AppFramework\\Http\\FileDisplayResponse' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/FileDisplayResponse.php',

View file

@ -27,6 +27,8 @@ declare(strict_types=1);
*/
namespace OC\AppFramework\Middleware;
use OC\Core\Controller\LoginController;
use OCP\AppFramework\Http\Events\BeforeLoginTemplateRenderedEvent;
use OCP\AppFramework\Http\Events\BeforeTemplateRenderedEvent;
use OCP\AppFramework\Http\Response;
use OCP\AppFramework\Http\StandaloneTemplateResponse;
@ -44,8 +46,12 @@ class AdditionalScriptsMiddleware extends Middleware {
public function afterController($controller, $methodName, Response $response): Response {
if ($response instanceof TemplateResponse) {
$isLoggedIn = !($response instanceof StandaloneTemplateResponse) && $this->userSession->isLoggedIn();
$this->dispatcher->dispatchTyped(new BeforeTemplateRenderedEvent($isLoggedIn, $response));
if ($controller instanceof LoginController) {
$this->dispatcher->dispatchTyped(new BeforeLoginTemplateRenderedEvent($response));
} else {
$isLoggedIn = !($response instanceof StandaloneTemplateResponse) && $this->userSession->isLoggedIn();
$this->dispatcher->dispatchTyped(new BeforeTemplateRenderedEvent($isLoggedIn, $response));
}
}
return $response;

View file

@ -39,7 +39,6 @@
*/
use OC\TemplateLayout;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\Util;
require_once __DIR__.'/template/functions.php';
@ -59,8 +58,6 @@ class OC_Template extends \OC\Template\Base {
/** @var string */
protected $app; // app id
protected static $initTemplateEngineFirstRun = true;
/**
* Constructor
*
@ -73,9 +70,6 @@ class OC_Template extends \OC\Template\Base {
* @param bool $registerCall = true
*/
public function __construct($app, $name, $renderAs = TemplateResponse::RENDER_AS_BLANK, $registerCall = true) {
// Read the selected theme from the config file
self::initTemplateEngine($renderAs);
$theme = OC_Util::getTheme();
$requestToken = (OC::$server->getSession() && $registerCall) ? \OCP\Util::callRegister() : '';
@ -95,40 +89,6 @@ class OC_Template extends \OC\Template\Base {
parent::__construct($template, $requestToken, $l10n, $themeDefaults);
}
/**
* @param string $renderAs
*/
public static function initTemplateEngine($renderAs) {
if (self::$initTemplateEngineFirstRun) {
// apps that started before the template initialization can load their own scripts/styles
// so to make sure this scripts/styles here are loaded first we put all core scripts first
// check lib/public/Util.php
OC_Util::addStyle('server', null, true);
// include common nextcloud webpack bundle
Util::addScript('core', 'common');
Util::addScript('core', 'main');
Util::addTranslations('core');
if (\OC::$server->getSystemConfig()->getValue('installed', false) && !\OCP\Util::needUpgrade()) {
Util::addScript('core', 'files_fileinfo');
Util::addScript('core', 'files_client');
Util::addScript('core', 'merged-template-prepend');
}
// If installed and background job is set to ajax, add dedicated script
if (\OC::$server->getSystemConfig()->getValue('installed', false)
&& $renderAs !== TemplateResponse::RENDER_AS_ERROR
&& !\OCP\Util::needUpgrade()) {
if (\OC::$server->getConfig()->getAppValue('core', 'backgroundjobs_mode', 'ajax') == 'ajax') {
Util::addScript('core', 'backgroundjobs');
}
}
self::$initTemplateEngineFirstRun = false;
}
}
/**
* find the template with the given name

View file

@ -0,0 +1,52 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2020, Roeland Jago Douma <roeland@famdouma.nl>
*
* @author Julius Härtl <jus@bitgrid.net>
* @author Morris Jobke <hey@morrisjobke.de>
* @author Roeland Jago Douma <roeland@famdouma.nl>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCP\AppFramework\Http\Events;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\EventDispatcher\Event;
/**
* Emitted before the rendering step of the login TemplateResponse.
*
* @since 28.0.0
*/
class BeforeLoginTemplateRenderedEvent extends Event {
/**
* @since 28.0.0
*/
public function __construct(private TemplateResponse $response) {
parent::__construct();
}
/**
* @since 28.0.0
*/
public function getResponse(): TemplateResponse {
return $this->response;
}
}

View file

@ -169,9 +169,10 @@ class Util {
* @param string $application
* @param string|null $file
* @param string $afterAppId
* @param bool $prepend
* @since 4.0.0
*/
public static function addScript(string $application, string $file = null, string $afterAppId = 'core'): void {
public static function addScript(string $application, string $file = null, string $afterAppId = 'core', bool $prepend = false): void {
if (!empty($application)) {
$path = "$application/js/$file";
} else {
@ -194,7 +195,11 @@ class Util {
self::$scriptDeps[$application]->addDep($afterAppId);
}
self::$scripts[$application][] = $path;
if ($prepend) {
array_unshift(self::$scripts[$application], $path);
} else {
self::$scripts[$application][] = $path;
}
}
/**
@ -212,7 +217,12 @@ class Util {
$sortedScripts = $sortedScripts ? array_merge(...array_values(($sortedScripts))) : [];
// Override core-common and core-main order
array_unshift($sortedScripts, 'core/js/common', 'core/js/main');
if (in_array('core/js/main', $sortedScripts)) {
array_unshift($sortedScripts, 'core/js/main');
}
if (in_array('core/js/common', $sortedScripts)) {
array_unshift($sortedScripts, 'core/js/common');
}
return array_unique($sortedScripts);
}