diff --git a/integrations/nextcloud/snappymail/lib/ContentSecurityPolicy.php b/integrations/nextcloud/snappymail/lib/ContentSecurityPolicy.php index 55df22c7b..3aa4db906 100644 --- a/integrations/nextcloud/snappymail/lib/ContentSecurityPolicy.php +++ b/integrations/nextcloud/snappymail/lib/ContentSecurityPolicy.php @@ -2,52 +2,54 @@ namespace OCA\SnappyMail; -class ContentSecurityPolicy extends \OCP\AppFramework\Http\ContentSecurityPolicy { +class ContentSecurityPolicy extends \OCP\AppFramework\Http\ContentSecurityPolicy +{ + private string $nonce; - /** @var bool Whether inline JS snippets are allowed */ - protected $inlineScriptAllowed = false; - /** @var bool Whether eval in JS scripts is allowed */ - protected $evalScriptAllowed = true; - /** @var bool Whether strict-dynamic should be set */ -// protected $strictDynamicAllowed = true; // NC24+ - /** @var bool Whether inline CSS is allowed */ - protected $inlineStyleAllowed = true; - - function __construct() { + function __construct() + { $CSP = \RainLoop\Api::getCSP(); - $this->allowedScriptDomains = \array_unique(\array_merge($this->allowedScriptDomains, $CSP->get('script-src'))); - $this->allowedScriptDomains = \array_diff($this->allowedScriptDomains, ["'unsafe-inline'", "'unsafe-eval'"]); - - // Nextcloud only sets 'strict-dynamic' when browserSupportsCspV3() ? - \method_exists($this, 'useStrictDynamic') - ? $this->useStrictDynamic(true) // NC24+ - : $this->addAllowedScriptDomain("'strict-dynamic'"); - - $this->allowedImageDomains = \array_unique(\array_merge($this->allowedImageDomains, $CSP->get('img-src'))); - - $this->allowedStyleDomains = \array_unique(\array_merge($this->allowedStyleDomains, $CSP->get('style-src'))); - $this->allowedStyleDomains = \array_diff($this->allowedStyleDomains, ["'unsafe-inline'"]); - - $this->allowedFrameDomains = \array_unique(\array_merge($this->allowedFrameDomains, $CSP->get('frame-src'))); - - $this->reportTo = \array_unique(\array_merge($this->reportTo, $CSP->report_to)); - } - - public function getSnappyMailNonce() { - static $sNonce; - if (!$sNonce) { - $cspManager = (\method_exists(\OC::$server, 'getContentSecurityPolicyNonceManager') - ? \OC::$server->getContentSecurityPolicyNonceManager() - // Nextcloud 34+ - : \OCP\Server::get(\OC\Security\CSP\ContentSecurityPolicyNonceManager::class) - ); - $sNonce = $cspManager->getNonce() ?: \SnappyMail\UUID::generate(); - if (\method_exists($cspManager, 'browserSupportsCspV3') && !$cspManager->browserSupportsCspV3()) { - $this->addAllowedScriptDomain("'nonce-{$sNonce}'"); + foreach ($CSP->get('script-src') as $domain) { + // Knockout's legacy binding parser still evaluates binding strings. + // Keep unsafe-eval until those bindings have been migrated. + if ("'unsafe-inline'" !== $domain) { + $this->addAllowedScriptDomain($domain); } } - return $sNonce; + + if (\method_exists($this, 'useStrictDynamic')) { + $this->useStrictDynamic(true); + } else { + $this->addAllowedScriptDomain("'strict-dynamic'"); + } + + foreach ($CSP->get('img-src') as $domain) { + $this->addAllowedImageDomain($domain); + } + + foreach ($CSP->get('style-src') as $domain) { + if ("'unsafe-inline'" !== $domain) { + $this->addAllowedStyleDomain($domain); + } + } + + foreach ($CSP->get('frame-src') as $domain) { + $this->addAllowedFrameDomain($domain); + } + + if (\method_exists($this, 'addReportTo')) { + foreach ($CSP->report_to as $reportTo) { + $this->addReportTo($reportTo); + } + } + + $this->nonce = \SnappyMail\UUID::generate(); + $this->addAllowedScriptDomain("'nonce-{$this->nonce}'"); } + public function getSnappyMailNonce() + { + return $this->nonce; + } } diff --git a/integrations/nextcloud/snappymail/lib/Controller/PageController.php b/integrations/nextcloud/snappymail/lib/Controller/PageController.php index 058cb45ee..1e1137064 100644 --- a/integrations/nextcloud/snappymail/lib/Controller/PageController.php +++ b/integrations/nextcloud/snappymail/lib/Controller/PageController.php @@ -56,7 +56,7 @@ class PageController extends Controller $csp = new ContentSecurityPolicy(); $csp->addAllowedFrameDomain("'self'"); // $csp->addAllowedFrameAncestorDomain("'self'"); - $response->setContentSecurityPolicy($csp->getPolicy()); + $response->setContentSecurityPolicy($csp); return $response; } @@ -209,7 +209,7 @@ class PageController extends Controller $response = new TemplateResponse('snappymail', 'index_embed', $params, $blank ? 'blank' : 'user'); - $response->setContentSecurityPolicy($csp->getPolicy()); + $response->setContentSecurityPolicy($csp); return $response; } diff --git a/integrations/nextcloud/snappymail/lib/Util/SnappyMailHelper.php b/integrations/nextcloud/snappymail/lib/Util/SnappyMailHelper.php index d7e3e8848..c80d77400 100644 --- a/integrations/nextcloud/snappymail/lib/Util/SnappyMailHelper.php +++ b/integrations/nextcloud/snappymail/lib/Util/SnappyMailHelper.php @@ -52,13 +52,13 @@ class SnappyMailHelper : \OCP\Server::get(\OCP\IConfig::class); } - public static function getAppConfigValue(string $key, mixed $default = null): object + public static function getAppConfigValue(string $key, mixed $default = null): mixed { return (\method_exists(\OC::$server, 'getConfig') - ? \OC::$server->getConfig() + ? \OC::$server->getConfig()->getAppValue('snappymail', $key, $default) // Nextcloud 34+ - : \OCP\Server::get(\OCP\IAppConfig::class) - )->getAppValue('snappymail', $key, $default); + : \OCP\Server::get(\OCP\IAppConfig::class)->getValue('snappymail', $key, $default) + ); } public static function getNavigationManager(): object @@ -120,13 +120,18 @@ class SnappyMailHelper } } - public static function linkToRoute(string $value): string + public static function getURLGenerator(): object { return (\method_exists(\OC::$server, 'getURLGenerator') ? \OC::$server->getURLGenerator() // Nextcloud 34+ : \OCP\Server::get(\OCP\IURLGenerator::class) - )->linkToRoute($value); + ); + } + + public static function linkToRoute(string $value): string + { + return static::getURLGenerator()->linkToRoute($value); } public static function loadApp(): void diff --git a/plugins/nextcloud/index.php b/plugins/nextcloud/index.php index 9999577cd..0b977aa07 100644 --- a/plugins/nextcloud/index.php +++ b/plugins/nextcloud/index.php @@ -6,11 +6,11 @@ class NextcloudPlugin extends \RainLoop\Plugins\AbstractPlugin { const NAME = 'Nextcloud', - VERSION = '2.38.1', - RELEASE = '2024-10-08', + VERSION = '3.0.0', + RELEASE = '2026-11-03', CATEGORY = 'Integrations', - DESCRIPTION = 'Integrate with Nextcloud v20+', - REQUIRED = '2.38.0'; + DESCRIPTION = 'Integrate with Nextcloud v25+', + REQUIRED = '3.0.0'; public function Init() : void { @@ -217,7 +217,7 @@ class NextcloudPlugin extends \RainLoop\Plugins\AbstractPlugin if (!$bAdmin && \is_array($aResult)) { $ocUser = SnappyMailHelper::getUser(); $sUID = $ocUser->getUID(); - $oUrlGen = \OC::$server->getURLGenerator(); + $oUrlGen = SnappyMailHelper::getURLGenerator(); $sWebDAV = $oUrlGen->getAbsoluteURL($oUrlGen->linkTo('', 'remote.php') . '/dav'); // $sWebDAV = \OCP\Util::linkToRemote('dav'); $aResult['Nextcloud'] = [