diff --git a/.github/workflows/docker-pr.yml b/.github/workflows/docker-pr.yml index 0ba375b5c..af069cdf6 100644 --- a/.github/workflows/docker-pr.yml +++ b/.github/workflows/docker-pr.yml @@ -21,7 +21,7 @@ jobs: DOCKER_METADATA_PR_HEAD_SHA: 'true' with: images: | - nextgen-networks/snappymail + djmaze/snappymail ghcr.io/${{ github.repository }} # type=ref,event=pr generates tag(s) on PRs only. E.g. 'pr-123', 'pr-123-abc0123' tags: | diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index a233327e1..b957e2fc8 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -6,7 +6,9 @@ on: - 'v2.*' # This is needed to push to GitHub Container Registry. See https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry -permissions: write-all +permissions: + contents: read + packages: write jobs: build: @@ -24,7 +26,7 @@ jobs: DOCKER_METADATA_PR_HEAD_SHA: 'true' with: images: | - nextgen-networks/snappymail + djmaze/snappymail ghcr.io/${{ github.repository }} # type=ref,event=branch generates tag(s) on branch only. E.g. 'master', 'master-abc0123' # type=ref,event=tag generates tag(s) on tags only. E.g. 'v0.0.0', 'v0.0.0-abc0123', and 'latest' diff --git a/integrations/nextcloud/snappymail/appinfo/info.xml b/integrations/nextcloud/snappymail/appinfo/info.xml index d73ef28a0..b1a67e0b1 100644 --- a/integrations/nextcloud/snappymail/appinfo/info.xml +++ b/integrations/nextcloud/snappymail/appinfo/info.xml @@ -64,7 +64,7 @@ There, click on the link to go to the SnappyMail admin panel. xxtea zip --> - + OCA\SnappyMail\Settings\AdminSettings diff --git a/integrations/nextcloud/snappymail/lib/AppInfo/Application.php b/integrations/nextcloud/snappymail/lib/AppInfo/Application.php index d764520ca..d8e6b294b 100644 --- a/integrations/nextcloud/snappymail/lib/AppInfo/Application.php +++ b/integrations/nextcloud/snappymail/lib/AppInfo/Application.php @@ -5,7 +5,6 @@ namespace OCA\SnappyMail\AppInfo; use OCA\SnappyMail\Util\SnappyMailHelper; use OCA\SnappyMail\Controller\FetchController; use OCA\SnappyMail\Controller\PageController; -use OCA\SnappyMail\Dashboard\UnreadMailWidget; use OCA\SnappyMail\Search\Provider; use OCA\SnappyMail\Listeners\AccessTokenUpdatedListener; @@ -18,6 +17,10 @@ use OCP\IUser; use OCP\User\Events\PostLoginEvent; use OCP\User\Events\BeforeUserLoggedOutEvent; use OCA\OIDCLogin\Events\AccessTokenUpdatedEvent; +use OCP\IConfig; +use OCP\ISession; +use OCP\IUserSession; +use OCP\INavigationManager; class Application extends App implements IBootstrap { @@ -37,7 +40,9 @@ class Application extends App implements IBootstrap 'PageController', function($c) { return new PageController( $c->query('AppName'), - $c->query('Request') + $c->query('Request'), + $c->query(IConfig::class), + $c->query(INavigationManager::class) ); } ); @@ -47,9 +52,10 @@ class Application extends App implements IBootstrap return new FetchController( $c->query('AppName'), $c->query('Request'), - $c->getServer()->getAppManager(), + $c->query('ServerContainer')->getAppManager(), $c->query('ServerContainer')->getConfig(), - $c->query(IL10N::class) + $c->query(IL10N::class), + $c->query(IUserSession::class) ); } ); @@ -72,22 +78,24 @@ class Application extends App implements IBootstrap public function boot(IBootContext $context): void { - if (!\is_dir(\rtrim(\trim(\OC::$server->getSystemConfig()->getValue('datadirectory', '')), '\\/') . '/appdata_snappymail')) { + $config = $context->getServerContainer()->getConfig(); + if (!\is_dir(\rtrim(\trim($config->getSystemValue('datadirectory', '')), '\\/') . '/appdata_snappymail')) { return; } $dispatcher = $context->getAppContainer()->query('OCP\EventDispatcher\IEventDispatcher'); - $dispatcher->addListener(PostLoginEvent::class, function (PostLoginEvent $Event) { + $dispatcher->addListener(PostLoginEvent::class, function (PostLoginEvent $Event) use ($context) { /* - $config = \OC::$server->getConfig(); + $config = $context->getServerContainer()->getConfig(); // Only store the user's password in the current session if they have // enabled auto-login using Nextcloud username or email address. if ($config->getAppValue('snappymail', 'snappymail-autologin', false) || $config->getAppValue('snappymail', 'snappymail-autologin-with-email', false)) { */ $sUID = $Event->getUser()->getUID(); - \OC::$server->getSession()['snappymail-nc-uid'] = $sUID; - \OC::$server->getSession()['snappymail-passphrase'] = SnappyMailHelper::encodePassword($Event->getPassword(), $sUID); + $session = $context->getServerContainer()->getSession(); + $session['snappymail-nc-uid'] = $sUID; + $session['snappymail-passphrase'] = SnappyMailHelper::encodePassword($Event->getPassword(), $sUID); /* } */ @@ -105,13 +113,13 @@ class Application extends App implements IBootstrap // https://github.com/nextcloud/impersonate/pull/180 $class = 'OCA\Impersonate\Events\BeginImpersonateEvent'; if (\class_exists($class)) { - $dispatcher->addListener($class, function ($Event) { - \OC::$server->getSession()['snappymail-passphrase'] = ''; + $dispatcher->addListener($class, function ($Event) use ($context) { + $context->getServerContainer()->getSession()['snappymail-passphrase'] = ''; SnappyMailHelper::loadApp(); \RainLoop\Api::Actions()->Logout(true); }); - $dispatcher->addListener('OCA\Impersonate\Events\EndImpersonateEvent', function ($Event) { - \OC::$server->getSession()['snappymail-passphrase'] = ''; + $dispatcher->addListener('OCA\Impersonate\Events\EndImpersonateEvent', function ($Event) use ($context) { + $context->getServerContainer()->getSession()['snappymail-passphrase'] = ''; SnappyMailHelper::loadApp(); \RainLoop\Api::Actions()->Logout(true); }); diff --git a/integrations/nextcloud/snappymail/lib/Command/Settings.php b/integrations/nextcloud/snappymail/lib/Command/Settings.php index 1e6cae25d..2843d9f3b 100644 --- a/integrations/nextcloud/snappymail/lib/Command/Settings.php +++ b/integrations/nextcloud/snappymail/lib/Command/Settings.php @@ -3,14 +3,14 @@ namespace OCA\SnappyMail\Command; use OCA\SnappyMail\Util\SnappyMailHelper; -use OC\Core\Command\Base; use OCP\IConfig; use OCP\IUserManager; +use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; -class Settings extends Base +class Settings extends Command { protected IUserManager $userManager; protected IConfig $config; diff --git a/integrations/nextcloud/snappymail/lib/ContentSecurityPolicy.php b/integrations/nextcloud/snappymail/lib/ContentSecurityPolicy.php index 27a9c44d1..fb8bea501 100644 --- a/integrations/nextcloud/snappymail/lib/ContentSecurityPolicy.php +++ b/integrations/nextcloud/snappymail/lib/ContentSecurityPolicy.php @@ -2,6 +2,9 @@ namespace OCA\SnappyMail; +use OCP\Server; +use OCP\Security\IContentSecurityPolicyNonceManager; + class ContentSecurityPolicy extends \OCP\AppFramework\Http\ContentSecurityPolicy { /** @var bool Whether inline JS snippets are allowed */ @@ -37,7 +40,7 @@ class ContentSecurityPolicy extends \OCP\AppFramework\Http\ContentSecurityPolicy public function getSnappyMailNonce() { static $sNonce; if (!$sNonce) { - $cspManager = \OC::$server->getContentSecurityPolicyNonceManager(); + $cspManager = Server::get(IContentSecurityPolicyNonceManager::class); $sNonce = $cspManager->getNonce() ?: \SnappyMail\UUID::generate(); if (\method_exists($cspManager, 'browserSupportsCspV3') && !$cspManager->browserSupportsCspV3()) { $this->addAllowedScriptDomain("'nonce-{$sNonce}'"); diff --git a/integrations/nextcloud/snappymail/lib/Controller/FetchController.php b/integrations/nextcloud/snappymail/lib/Controller/FetchController.php index 6ba8a7761..2091e6122 100644 --- a/integrations/nextcloud/snappymail/lib/Controller/FetchController.php +++ b/integrations/nextcloud/snappymail/lib/Controller/FetchController.php @@ -10,17 +10,21 @@ use OCP\AppFramework\Http\JSONResponse; use OCP\IConfig; use OCP\IL10N; use OCP\IRequest; +use OCP\IUserSession; +use Exception; class FetchController extends Controller { private IConfig $config; private IAppManager $appManager; private IL10N $l; + private IUserSession $userSession; - public function __construct(string $appName, IRequest $request, IAppManager $appManager, IConfig $config, IL10N $l) { + public function __construct(string $appName, IRequest $request, IAppManager $appManager, IConfig $config, IL10N $l, IUserSession $userSession) { parent::__construct($appName, $request); $this->config = $config; $this->appManager = $appManager; $this->l = $l; + $this->userSession = $userSession; } public function upgrade(): JSONResponse { @@ -104,15 +108,18 @@ class FetchController extends Controller { try { $sEmail = ''; if (isset($_POST['appname'], $_POST['snappymail-password'], $_POST['snappymail-email']) && 'snappymail' === $_POST['appname']) { - $sUser = \OC::$server->getUserSession()->getUser()->getUID(); + $user = $this->userSession->getUser(); + $sUser = $user ? $user->getUID() : ''; - $sEmail = $_POST['snappymail-email']; - $this->config->setUserValue($sUser, 'snappymail', 'snappymail-email', $sEmail); + if ($sUser) { + $sEmail = $_POST['snappymail-email']; + $this->config->setUserValue($sUser, 'snappymail', 'snappymail-email', $sEmail); - $sPass = $_POST['snappymail-password']; - if ('******' !== $sPass) { - $this->config->setUserValue($sUser, 'snappymail', 'passphrase', - $sPass ? SnappyMailHelper::encodePassword($sPass, \md5($sEmail)) : ''); + $sPass = $_POST['snappymail-password']; + if ('******' !== $sPass) { + $this->config->setUserValue($sUser, 'snappymail', 'passphrase', + $sPass ? SnappyMailHelper::encodePassword($sPass, \md5($sEmail)) : ''); + } } } else { return new JSONResponse([ @@ -144,4 +151,3 @@ class FetchController extends Controller { } } } - diff --git a/integrations/nextcloud/snappymail/lib/Controller/PageController.php b/integrations/nextcloud/snappymail/lib/Controller/PageController.php index 469d6fb26..ee11d74e7 100644 --- a/integrations/nextcloud/snappymail/lib/Controller/PageController.php +++ b/integrations/nextcloud/snappymail/lib/Controller/PageController.php @@ -7,23 +7,27 @@ use OCA\SnappyMail\ContentSecurityPolicy; use OCP\AppFramework\Controller; use OCP\AppFramework\Http\TemplateResponse; - -// SnappyMail Nextcoud 32 compatibility workaound - START -// src: https://github.com/the-djmaze/snappymail/issues/1994#issuecomment-3366086651 - -use OCP\INavigationManager; // <<<<<<<<<<<< add this -use OCP\Server; // <<<<<<<<<<<< add this +use OCP\INavigationManager; +use OCP\IConfig; +use OCP\IRequest; class PageController extends Controller { + private IConfig $config; + private INavigationManager $navigationManager; + + public function __construct($appName, IRequest $request, IConfig $config, INavigationManager $navigationManager) { + parent::__construct($appName, $request); + $this->config = $config; + $this->navigationManager = $navigationManager; + } + /** * @NoAdminRequired * @NoCSRFRequired */ public function index() { - $config = \OC::$server->getConfig(); - $nav = Server::get(INavigationManager::class); // <<<<<<<<<<<< add this $bAdmin = false; if (!empty($_SERVER['QUERY_STRING'])) { SnappyMailHelper::loadApp(); @@ -33,11 +37,8 @@ class PageController extends Controller } } - if (!$bAdmin && $config->getAppValue('snappymail', 'snappymail-no-embed')) { - // \OC::$server->getNavigationManager()->setActiveEntry('snappymail'); // <<<<<<<<<<<< Comment this - $nav->setActiveEntry('snappymail'); // <<<<<<<<<<<< add this - \OCP\Util::addScript('snappymail', 'snappymail'); - \OCP\Util::addStyle('snappymail', 'style'); + if (!$bAdmin && $this->config->getAppValue('snappymail', 'snappymail-no-embed')) { + $this->navigationManager->setActiveEntry('snappymail'); SnappyMailHelper::startApp(); $response = new TemplateResponse('snappymail', 'index', [ 'snappymail-iframe-url' => SnappyMailHelper::normalizeUrl(SnappyMailHelper::getAppUrl()) @@ -50,12 +51,7 @@ class PageController extends Controller return $response; } - // \OC::$server->getNavigationManager()->setActiveEntry('snappymail'); // <<<<<<<<<<<< Comment this - $nav->setActiveEntry('snappymail'); // <<<<<<<<<<<< add this - -// SnappyMail Nextcoud 32 compatibility workaound - END - - \OCP\Util::addStyle('snappymail', 'embed'); + $this->navigationManager->setActiveEntry('snappymail'); SnappyMailHelper::startApp(); $oConfig = \RainLoop\Api::Config(); @@ -69,6 +65,8 @@ class PageController extends Controller $csp = new ContentSecurityPolicy(); $sNonce = $csp->getSnappyMailNonce(); + $cssLink = \RainLoop\Utils::WebStaticPath('css/'.($bAdmin?'admin':'app').$sAppCssMin.'.css'); + $params = [ 'Admin' => $bAdmin ? 1 : 0, 'LoadingDescriptionEsc' => \htmlspecialchars($oConfig->Get('webmail', 'loading_description', 'SnappyMail'), ENT_QUOTES|ENT_IGNORE, 'UTF-8'), @@ -81,16 +79,10 @@ class PageController extends Controller '/\\s*([:;{},]+)\\s*/s', '$1', $oActions->compileCss($oActions->GetTheme($bAdmin), $bAdmin) - ) + ), + 'CssLink' => $cssLink ]; -// \OCP\Util::addScript('snappymail', '../app/snappymail/v/'.APP_VERSION.'/static/js'.($sAppJsMin ? '/min' : '').'/boot'.$sAppJsMin); - - // Nextcloud html encodes, so addHeader('style') is not possible -// \OCP\Util::addHeader('style', ['id'=>'app-boot-css'], \file_get_contents(APP_VERSION_ROOT_PATH.'static/css/boot'.$sAppCssMin.'.css')); - \OCP\Util::addHeader('link', ['type'=>'text/css','rel'=>'stylesheet','href'=>\RainLoop\Utils::WebStaticPath('css/'.($bAdmin?'admin':'app').$sAppCssMin.'.css')], ''); -// \OCP\Util::addHeader('style', ['id'=>'app-theme-style','data-href'=>$params['BaseAppThemeCssLink']], $params['BaseAppThemeCss']); - $response = new TemplateResponse('snappymail', 'index_embed', $params); $response->setContentSecurityPolicy($csp); diff --git a/integrations/nextcloud/snappymail/lib/Migration/InstallStep.php b/integrations/nextcloud/snappymail/lib/Migration/InstallStep.php index 966ef2352..6f00cedfe 100644 --- a/integrations/nextcloud/snappymail/lib/Migration/InstallStep.php +++ b/integrations/nextcloud/snappymail/lib/Migration/InstallStep.php @@ -6,7 +6,8 @@ use OCA\SnappyMail\AppInfo\Application; use OCP\IConfig; use OCP\Migration\IOutput; use OCP\Migration\IRepairStep; -use OCP\ILogger; +use Psr\Log\LoggerInterface; +use OCP\App\IAppManager; /** * Note: this is not run at install, but when: @@ -15,6 +16,16 @@ use OCP\ILogger; */ class InstallStep implements IRepairStep { + private IAppManager $appManager; + private IConfig $config; + private LoggerInterface $logger; + + public function __construct(IAppManager $appManager, IConfig $config, LoggerInterface $logger) { + $this->appManager = $appManager; + $this->config = $config; + $this->logger = $logger; + } + public function getName() { return 'Setup SnappyMail'; } @@ -53,7 +64,7 @@ class InstallStep implements IRepairStep if (!$oConfig->Get('webmail', 'app_path')) { $output->info('Set config [webmail]app_path'); - $oConfig->Set('webmail', 'app_path', \OC::$server->getAppManager()->getAppWebPath('snappymail') . '/app/'); + $oConfig->Set('webmail', 'app_path', $this->appManager->getAppWebPath('snappymail') . '/app/'); $oConfig->Set('webmail', 'allow_languages_on_settings', false); $oConfig->Set('login', 'allow_languages_on_login', false); $bSave = true; @@ -116,9 +127,7 @@ class InstallStep implements IRepairStep // ex: php occ config:app:set snappymail custom_config_file --value="/path/to/config.php" // https://github.com/the-djmaze/snappymail/pull/1197 try { - /** @var IConfig $ncConfig */ - $ncConfig = \OC::$server->get(IConfig::class); - $customConfigFile = $ncConfig->getAppValue(Application::APP_ID, 'custom_config_file'); + $customConfigFile = $this->config->getAppValue(Application::APP_ID, 'custom_config_file'); if ($customConfigFile) { $output->info("Load custom config: {$customConfigFile}"); if (!\str_contains($customConfigFile, ':') && \is_readable($customConfigFile)) { @@ -129,9 +138,7 @@ class InstallStep implements IRepairStep } } catch (\Throwable $e) { $output->warning("custom config error: " . $e->getMessage()); - /** @var \Psr\Log\LoggerInterface $logger */ - $logger = \OC::$server->get(\Psr\Log\LoggerInterface::class); - $logger->error("custom config error: " . $e->getMessage()); + $this->logger->error("custom config error: " . $e->getMessage()); } } } diff --git a/integrations/nextcloud/snappymail/lib/Settings/AdminSettings.php b/integrations/nextcloud/snappymail/lib/Settings/AdminSettings.php index 7a69cb96f..4bf372eae 100644 --- a/integrations/nextcloud/snappymail/lib/Settings/AdminSettings.php +++ b/integrations/nextcloud/snappymail/lib/Settings/AdminSettings.php @@ -5,14 +5,32 @@ use OCA\SnappyMail\Util\SnappyMailHelper; use OCP\AppFramework\Http\TemplateResponse; use OCP\IConfig; use OCP\Settings\ISettings; +use OCP\IUserSession; +use OCP\IGroupManager; +use OCP\IURLGenerator; +use OCP\App\IAppManager; +use OCP\Util; class AdminSettings implements ISettings { - private $config; + private IConfig $config; + private IUserSession $userSession; + private IGroupManager $groupManager; + private IURLGenerator $urlGenerator; + private IAppManager $appManager; - public function __construct(IConfig $config) - { + public function __construct( + IConfig $config, + IUserSession $userSession, + IGroupManager $groupManager, + IURLGenerator $urlGenerator, + IAppManager $appManager + ) { $this->config = $config; + $this->userSession = $userSession; + $this->groupManager = $groupManager; + $this->urlGenerator = $urlGenerator; + $this->appManager = $appManager; } public function getForm() @@ -30,12 +48,15 @@ class AdminSettings implements ISettings $v = $this->config->getAppValue('snappymail', $k); $parameters[$k] = $v; } - $uid = \OC::$server->getUserSession()->getUser()->getUID(); - if (\OC_User::isAdminUser($uid)) { + + $user = $this->userSession->getUser(); + $uid = $user ? $user->getUID() : null; + + if ($uid && $this->groupManager->isAdmin($uid)) { // $parameters['snappymail-admin-panel-link'] = SnappyMailHelper::getAppUrl().'?admin'; SnappyMailHelper::loadApp(); $parameters['snappymail-admin-panel-link'] = - \OC::$server->getURLGenerator()->linkToRoute('snappymail.page.index') + $this->urlGenerator->linkToRoute('snappymail.page.index') . '?' . \RainLoop\Api::Config()->Get('security', 'admin_panel_key', 'admin'); } @@ -49,7 +70,7 @@ class AdminSettings implements ISettings $parameters['snappymail-admin-password'] = $sPassword; $parameters['can-import-rainloop'] = $sPassword && \is_dir( - \rtrim(\trim(\OC::$server->getSystemConfig()->getValue('datadirectory', '')), '\\/') + \rtrim(\trim($this->config->getSystemValue('datadirectory', '')), '\\/') . '/rainloop-storage' ); @@ -65,7 +86,7 @@ class AdminSettings implements ISettings // Prevent "Failed loading /nextcloud/snappymail/v/2.N.N/static/js/min/libs.min.js" $app_path = $oConfig->Get('webmail', 'app_path'); if (!$app_path) { - $app_path = \OC::$server->getAppManager()->getAppWebPath('snappymail') . '/app/'; + $app_path = $this->appManager->getAppWebPath('snappymail') . '/app/'; $oConfig->Set('webmail', 'app_path', $app_path); $oConfig->Set('webmail', 'theme', 'NextcloudV25+'); $oConfig->Save(); @@ -73,7 +94,6 @@ class AdminSettings implements ISettings $parameters['snappymail-app_path'] = $oConfig->Get('webmail', 'app_path', false); $parameters['snappymail-nc-lang'] = !$oConfig->Get('webmail', 'allow_languages_on_settings', true); - \OCP\Util::addScript('snappymail', 'snappymail'); return new TemplateResponse('snappymail', 'admin-local', $parameters); } diff --git a/integrations/nextcloud/snappymail/lib/Util/SnappyMailHelper.php b/integrations/nextcloud/snappymail/lib/Util/SnappyMailHelper.php index 80a93d061..528f5917d 100644 --- a/integrations/nextcloud/snappymail/lib/Util/SnappyMailHelper.php +++ b/integrations/nextcloud/snappymail/lib/Util/SnappyMailHelper.php @@ -1,232 +1,252 @@ -getSystemConfig()->getValue('datadirectory', '')), '\\/').'/appdata_snappymail/'); - - $app_dir = \dirname(\dirname(__DIR__)) . '/app'; - require_once $app_dir . '/index.php'; - } - - public static function startApp(bool $handle = false) - { - static::loadApp(); - - $oConfig = \RainLoop\Api::Config(); - - if (false !== \stripos(\php_sapi_name(), 'cli')) { - return; - } - - try { - $oActions = \RainLoop\Api::Actions(); - if (isset($_GET[$oConfig->Get('security', 'admin_panel_key', 'admin')])) { - if ($oConfig->Get('security', 'allow_admin_panel', true) - && \OC_User::isAdminUser(\OC::$server->getUserSession()->getUser()->getUID()) - && !$oActions->IsAdminLoggined(false) - ) { - $sRand = \MailSo\Base\Utils::Sha1Rand(); - if ($oActions->Cacher(null, true)->Set(\RainLoop\KeyPathHelper::SessionAdminKey($sRand), \time())) { - $sToken = \RainLoop\Utils::EncodeKeyValuesQ(array('token', $sRand)); -// $oActions->setAdminAuthToken($sToken); - \SnappyMail\Cookies::set('smadmin', $sToken); - } - } - } else { - $doLogin = !$oActions->getMainAccountFromToken(false); - $aCredentials = static::getLoginCredentials(); -/* - // NC25+ workaround for Impersonate plugin - // https://github.com/the-djmaze/snappymail/issues/561#issuecomment-1301317723 - // https://github.com/nextcloud/server/issues/34935#issuecomment-1302145157 - require \OC::$SERVERROOT . '/version.php'; -// \OC\SystemConfig -// file_get_contents(\OC::$SERVERROOT . 'config/config.php'); -// $CONFIG['version'] - if (24 < $OC_Version[0]) { - $ocSession = \OC::$server->getSession(); - $ocSession->reopen(); - if (!$doLogin && $ocSession['snappymail-uid'] && $ocSession['snappymail-uid'] != $aCredentials[0]) { - // UID changed, Impersonate plugin probably active - $oActions->Logout(true); - $doLogin = true; - } - $ocSession->set('snappymail-uid', $aCredentials[0]); - } -*/ - if ($doLogin && $aCredentials[1] && $aCredentials[2]) { - $isOIDC = \str_starts_with($aCredentials[2], 'oidc_login|'); - try { - $ocSession = \OC::$server->getSession(); - $oAccount = $oActions->LoginProcess($aCredentials[1], $aCredentials[2]); - if (!$isOIDC && $oAccount - && $oConfig->Get('login', 'sign_me_auto', \RainLoop\Enumerations\SignMeType::DefaultOff) === \RainLoop\Enumerations\SignMeType::DefaultOn - ) { - $oActions->SetSignMeToken($oAccount); - } - } catch (\Throwable $e) { - // Login failure, reset password to prevent more attempts - if (!$isOIDC) { - $sUID = \OC::$server->getUserSession()->getUser()->getUID(); - \OC::$server->getSession()['snappymail-passphrase'] = ''; - \OC::$server->getConfig()->setUserValue($sUID, 'snappymail', 'passphrase', ''); - \SnappyMail\Log::error('Nextcloud', $e->getMessage()); - } - } - } - } - - if ($handle) { - \header_remove('Content-Security-Policy'); - \RainLoop\Service::Handle(); - // https://github.com/the-djmaze/snappymail/issues/1069 - exit; -// return new SnappyMailResponse(); - } - } catch (\Throwable $e) { - // Ignore login failure - } - } - - // Check if OpenID Connect (OIDC) is enabled and used for login - // https://apps.nextcloud.com/apps/oidc_login - public static function isOIDCLogin() : bool - { - $config = \OC::$server->getConfig(); - if ($config->getAppValue('snappymail', 'snappymail-autologin-oidc', false)) { - // Check if the OIDC Login app is enabled - if (\OC::$server->getAppManager()->isEnabledForUser('oidc_login')) { - // Check if session is an OIDC Login - $ocSession = \OC::$server->getSession(); - if ($ocSession->get('is_oidc')) { - // IToken->getPassword() ??? - if ($ocSession->get('oidc_access_token')) { - return true; - } - \SnappyMail\Log::debug('Nextcloud', 'OIDC access_token missing'); - } else { - \SnappyMail\Log::debug('Nextcloud', 'No OIDC login'); - } - } else { - \SnappyMail\Log::debug('Nextcloud', 'OIDC login disabled'); - } - } - return false; - } - - private static function getLoginCredentials() : array - { - $sUID = \OC::$server->getUserSession()->getUser()->getUID(); - $config = \OC::$server->getConfig(); - $ocSession = \OC::$server->getSession(); - - // If the user has set credentials for SnappyMail in their personal settings, - // this has the first priority. - $sEmail = $config->getUserValue($sUID, 'snappymail', 'snappymail-email'); - $sPassword = $config->getUserValue($sUID, 'snappymail', 'passphrase') - ?: $config->getUserValue($sUID, 'snappymail', 'snappymail-password'); - if ($sEmail && $sPassword) { - $sPassword = static::decodePassword($sPassword, \md5($sEmail)); - if ($sPassword) { - return [$sUID, $sEmail, $sPassword]; - } else { - \SnappyMail\Log::debug('Nextcloud', 'decodePassword failed for getUserValue'); - } - } - - // If the current user ID is identical to login ID (not valid when using account switching), - // this has the second priority. - if ($ocSession['snappymail-nc-uid'] == $sUID) { - - // If OpenID Connect (OIDC) is enabled and used for login, use this. - if (static::isOIDCLogin()) { - $sEmail = $config->getUserValue($sUID, 'settings', 'email'); - return [$sUID, $sEmail, "oidc_login|{$sUID}"]; - } - - // Only use the user's password in the current session if they have - // enabled auto-login using Nextcloud username or email address. - $sEmail = ''; - $sPassword = ''; - if ($config->getAppValue('snappymail', 'snappymail-autologin', false)) { - $sEmail = $sUID; - $sPassword = $ocSession['snappymail-passphrase']; - } else if ($config->getAppValue('snappymail', 'snappymail-autologin-with-email', false)) { - $sEmail = $config->getUserValue($sUID, 'settings', 'email'); - $sPassword = $ocSession['snappymail-passphrase']; - } else { - \SnappyMail\Log::debug('Nextcloud', 'snappymail-autologin is off'); - } - if ($sPassword) { - return [$sUID, $sEmail, static::decodePassword($sPassword, $sUID)]; - } - } else { - \SnappyMail\Log::debug('Nextcloud', "snappymail-nc-uid mismatch '{$ocSession['snappymail-nc-uid']}' != '{$sUID}'"); - } - - return [$sUID, '', '']; - } - - public static function getAppUrl() : string - { - return \OC::$server->getURLGenerator()->linkToRoute('snappymail.page.appGet'); - } - - public static function normalizeUrl(string $sUrl) : string - { - $sUrl = \rtrim(\trim($sUrl), '/\\'); - if ('.php' !== \strtolower(\substr($sUrl, -4))) { - $sUrl .= '/'; - } - - return $sUrl; - } - - public static function encodePassword(string $sPassword, string $sSalt) : string - { - static::loadApp(); - return \SnappyMail\Crypt::EncryptUrlSafe($sPassword, $sSalt); - } - - public static function decodePassword(string $sPassword, string $sSalt) : ?\SnappyMail\SensitiveString - { - static::loadApp(); - $result = \SnappyMail\Crypt::DecryptUrlSafe($sPassword, $sSalt); - return $result ? new \SnappyMail\SensitiveString($result) : null; - } -} +getSystemConfig()->getValue('datadirectory', '')), '\\/').'/appdata_snappymail/'); + + $app_dir = \dirname(\dirname(__DIR__)) . '/app'; + require_once $app_dir . '/index.php'; + } + + public static function startApp(bool $handle = false) + { + static::loadApp(); + + $oConfig = \RainLoop\Api::Config(); + + if (false !== \stripos(\php_sapi_name(), 'cli')) { + return; + } + + try { + $oActions = \RainLoop\Api::Actions(); + if (isset($_GET[$oConfig->Get('security', 'admin_panel_key', 'admin')])) { + $user = Server::get(IUserSession::class)->getUser(); + if ($oConfig->Get('security', 'allow_admin_panel', true) + && $user + && Server::get(IGroupManager::class)->isAdmin($user->getUID()) + && !$oActions->IsAdminLoggined(false) + ) { + $sRand = \MailSo\Base\Utils::Sha1Rand(); + if ($oActions->Cacher(null, true)->Set(\RainLoop\KeyPathHelper::SessionAdminKey($sRand), \time())) { + $sToken = \RainLoop\Utils::EncodeKeyValuesQ(array('token', $sRand)); +// $oActions->setAdminAuthToken($sToken); + \SnappyMail\Cookies::set('smadmin', $sToken); + } + } + } else { + $doLogin = !$oActions->getMainAccountFromToken(false); + $aCredentials = static::getLoginCredentials(); +/* + // NC25+ workaround for Impersonate plugin + // https://github.com/the-djmaze/snappymail/issues/561#issuecomment-1301317723 + // https://github.com/nextcloud/server/issues/34935#issuecomment-1302145157 + require \OC::$SERVERROOT . '/version.php'; +// \OC\SystemConfig +// file_get_contents(\OC::$SERVERROOT . 'config/config.php'); +// $CONFIG['version'] + if (24 < $OC_Version[0]) { + $ocSession = Server::get(ISession::class); + $ocSession->reopen(); + if (!$doLogin && $ocSession['snappymail-uid'] && $ocSession['snappymail-uid'] != $aCredentials[0]) { + // UID changed, Impersonate plugin probably active + $oActions->Logout(true); + $doLogin = true; + } + $ocSession->set('snappymail-uid', $aCredentials[0]); + } +*/ + if ($doLogin && $aCredentials[1] && $aCredentials[2]) { + $isOIDC = \str_starts_with($aCredentials[2], 'oidc_login|'); + try { + $ocSession = Server::get(ISession::class); + $oAccount = $oActions->LoginProcess($aCredentials[1], $aCredentials[2]); + if (!$isOIDC && $oAccount + && $oConfig->Get('login', 'sign_me_auto', \RainLoop\Enumerations\SignMeType::DefaultOff) === \RainLoop\Enumerations\SignMeType::DefaultOn + ) { + $oActions->SetSignMeToken($oAccount); + } + } catch (\Throwable $e) { + // Login failure, reset password to prevent more attempts + if (!$isOIDC) { + $user = Server::get(IUserSession::class)->getUser(); + $sUID = $user ? $user->getUID() : null; + if ($sUID) { + $session = Server::get(ISession::class); + $session['snappymail-passphrase'] = ''; + Server::get(IConfig::class)->setUserValue($sUID, 'snappymail', 'passphrase', ''); + \SnappyMail\Log::error('Nextcloud', $e->getMessage()); + } + } + } + } + } + + if ($handle) { + \header_remove('Content-Security-Policy'); + \RainLoop\Service::Handle(); + // https://github.com/the-djmaze/snappymail/issues/1069 + exit; +// return new SnappyMailResponse(); + } + } catch (\Throwable $e) { + // Ignore login failure + } + } + + // Check if OpenID Connect (OIDC) is enabled and used for login + // https://apps.nextcloud.com/apps/oidc_login + public static function isOIDCLogin() : bool + { + $config = Server::get(IConfig::class); + if ($config->getAppValue('snappymail', 'snappymail-autologin-oidc', false)) { + // Check if the OIDC Login app is enabled + if (Server::get(IAppManager::class)->isEnabledForUser('oidc_login')) { + // Check if session is an OIDC Login + $ocSession = Server::get(ISession::class); + if ($ocSession->get('is_oidc')) { + // IToken->getPassword() ??? + if ($ocSession->get('oidc_access_token')) { + return true; + } + \SnappyMail\Log::debug('Nextcloud', 'OIDC access_token missing'); + } else { + \SnappyMail\Log::debug('Nextcloud', 'No OIDC login'); + } + } else { + \SnappyMail\Log::debug('Nextcloud', 'OIDC login disabled'); + } + } + return false; + } + + private static function getLoginCredentials() : array + { + $user = Server::get(IUserSession::class)->getUser(); + $sUID = $user ? $user->getUID() : ''; + $config = Server::get(IConfig::class); + $ocSession = Server::get(ISession::class); + + if (!$sUID) { + return ['', '', '']; + } + + // If the user has set credentials for SnappyMail in their personal settings, + // this has the first priority. + $sEmail = $config->getUserValue($sUID, 'snappymail', 'snappymail-email'); + $sPassword = $config->getUserValue($sUID, 'snappymail', 'passphrase') + ?: $config->getUserValue($sUID, 'snappymail', 'snappymail-password'); + if ($sEmail && $sPassword) { + $sPassword = static::decodePassword($sPassword, \md5($sEmail)); + if ($sPassword) { + return [$sUID, $sEmail, $sPassword]; + } else { + \SnappyMail\Log::debug('Nextcloud', 'decodePassword failed for getUserValue'); + } + } + + // If the current user ID is identical to login ID (not valid when using account switching), + // this has the second priority. + // Note: $ocSession array access is supported but deprecated? ISession implements ArrayAccess. + if ($ocSession['snappymail-nc-uid'] == $sUID) { + + // If OpenID Connect (OIDC) is enabled and used for login, use this. + if (static::isOIDCLogin()) { + $sEmail = $config->getUserValue($sUID, 'settings', 'email'); + return [$sUID, $sEmail, "oidc_login|{$sUID}"]; + } + + // Only use the user's password in the current session if they have + // enabled auto-login using Nextcloud username or email address. + $sEmail = ''; + $sPassword = ''; + if ($config->getAppValue('snappymail', 'snappymail-autologin', false)) { + $sEmail = $sUID; + $sPassword = $ocSession['snappymail-passphrase']; + } else if ($config->getAppValue('snappymail', 'snappymail-autologin-with-email', false)) { + $sEmail = $config->getUserValue($sUID, 'settings', 'email'); + $sPassword = $ocSession['snappymail-passphrase']; + } else { + \SnappyMail\Log::debug('Nextcloud', 'snappymail-autologin is off'); + } + if ($sPassword) { + return [$sUID, $sEmail, static::decodePassword($sPassword, $sUID)]; + } + } else { + \SnappyMail\Log::debug('Nextcloud', "snappymail-nc-uid mismatch '{$ocSession['snappymail-nc-uid']}' != '{$sUID}'"); + } + + return [$sUID, '', '']; + } + + public static function getAppUrl() : string + { + return Server::get(IURLGenerator::class)->linkToRoute('snappymail.page.appGet'); + } + + public static function normalizeUrl(string $sUrl) : string + { + $sUrl = \rtrim(\trim($sUrl), '/\\'); + if ('.php' !== \strtolower(\substr($sUrl, -4))) { + $sUrl .= '/'; + } + + return $sUrl; + } + + public static function encodePassword(string $sPassword, string $sSalt) : string + { + static::loadApp(); + return \SnappyMail\Crypt::EncryptUrlSafe($sPassword, $sSalt); + } + + public static function decodePassword(string $sPassword, string $sSalt) : ?\SnappyMail\SensitiveString + { + static::loadApp(); + $result = \SnappyMail\Crypt::DecryptUrlSafe($sPassword, $sSalt); + return $result ? new \SnappyMail\SensitiveString($result) : null; + } +} diff --git a/integrations/nextcloud/snappymail/templates/admin-local.php b/integrations/nextcloud/snappymail/templates/admin-local.php index 5270f3e50..dd5ddd6ee 100644 --- a/integrations/nextcloud/snappymail/templates/admin-local.php +++ b/integrations/nextcloud/snappymail/templates/admin-local.php @@ -1,3 +1,4 @@ + diff --git a/integrations/nextcloud/snappymail/templates/index.php b/integrations/nextcloud/snappymail/templates/index.php index f304654fb..ba1b7eee0 100644 --- a/integrations/nextcloud/snappymail/templates/index.php +++ b/integrations/nextcloud/snappymail/templates/index.php @@ -1,3 +1,5 @@ - + diff --git a/integrations/nextcloud/snappymail/templates/index_embed.php b/integrations/nextcloud/snappymail/templates/index_embed.php index 4384bef5d..f853e9320 100644 --- a/integrations/nextcloud/snappymail/templates/index_embed.php +++ b/integrations/nextcloud/snappymail/templates/index_embed.php @@ -1,3 +1,5 @@ + + diff --git a/plugins/cache-redis/Predis/ClientContextInterface.php b/plugins/cache-redis/Predis/ClientContextInterface.php index d6cb74512..e443ee5d1 100644 --- a/plugins/cache-redis/Predis/ClientContextInterface.php +++ b/plugins/cache-redis/Predis/ClientContextInterface.php @@ -65,8 +65,8 @@ use Predis\Command\Redis\Container\Search\FTCURSOR; * @method $this randomkey() * @method $this rename($key, $target) * @method $this renamenx($key, $target) - * @method $this scan($cursor, ?array $options = null) - * @method $this sort($key, ?array $options = null) + * @method $this scan($cursor, array $options = null) + * @method $this sort($key, array $options = null) * @method $this sort_ro(string $key, ?string $byPattern = null, ?LimitOffsetCount $limit = null, array $getPatterns = [], ?string $sorting = null, bool $alpha = false) * @method $this ttl($key) * @method $this type($key) @@ -163,7 +163,7 @@ use Predis\Command\Redis\Container\Search\FTCURSOR; * @method $this hmget($key, array $fields) * @method $this hmset($key, array $dictionary) * @method $this hrandfield(string $key, int $count = 1, bool $withValues = false) - * @method $this hscan($key, $cursor, ?array $options = null) + * @method $this hscan($key, $cursor, array $options = null) * @method $this hset($key, $field, $value) * @method $this hsetnx($key, $field, $value) * @method $this hvals($key) @@ -225,7 +225,7 @@ use Predis\Command\Redis\Container\Search\FTCURSOR; * @method $this spop($key, $count = null) * @method $this srandmember($key, $count = null) * @method $this srem($key, $member) - * @method $this sscan($key, $cursor, ?array $options = null) + * @method $this sscan($key, $cursor, array $options = null) * @method $this sunion(array|string $keys) * @method $this sunionstore($destination, array|string $keys) * @method $this tdigestadd(string $key, float ...$value) @@ -255,7 +255,7 @@ use Predis\Command\Redis\Container\Search\FTCURSOR; * @method $this tsdecrby(string $key, float $value, ?DecrByArguments $arguments = null) * @method $this tsdel(string $key, int $fromTimestamp, int $toTimestamp) * @method $this tsdeleterule(string $sourceKey, string $destKey) - * @method $this tsget(string $key, ?GetArguments $arguments = null) + * @method $this tsget(string $key, GetArguments $arguments = null) * @method $this tsincrby(string $key, float $value, ?IncrByArguments $arguments = null) * @method $this tsinfo(string $key, ?InfoArguments $arguments = null) * @method $this tsmadd(mixed ...$keyTimestampValue) @@ -277,22 +277,22 @@ use Predis\Command\Redis\Container\Search\FTCURSOR; * @method $this zmpop(array $keys, string $modifier = 'min', int $count = 1) * @method $this zmscore(string $key, string ...$member) * @method $this zrandmember(string $key, int $count = 1, bool $withScores = false) - * @method $this zrange($key, $start, $stop, ?array $options = null) - * @method $this zrangebyscore($key, $min, $max, ?array $options = null) + * @method $this zrange($key, $start, $stop, array $options = null) + * @method $this zrangebyscore($key, $min, $max, array $options = null) * @method $this zrangestore(string $destination, string $source, int|string $min, string|int $max, string|bool $by = false, bool $reversed = false, bool $limit = false, int $offset = 0, int $count = 0) * @method $this zrank($key, $member) * @method $this zrem($key, $member) * @method $this zremrangebyrank($key, $start, $stop) * @method $this zremrangebyscore($key, $min, $max) - * @method $this zrevrange($key, $start, $stop, ?array $options = null) - * @method $this zrevrangebyscore($key, $max, $min, ?array $options = null) + * @method $this zrevrange($key, $start, $stop, array $options = null) + * @method $this zrevrangebyscore($key, $max, $min, array $options = null) * @method $this zrevrank($key, $member) * @method $this zunion(array $keys, int[] $weights = [], string $aggregate = 'sum', bool $withScores = false) * @method $this zunionstore(string $destination, array $keys, int[] $weights = [], string $aggregate = 'sum') * @method $this zscore($key, $member) - * @method $this zscan($key, $cursor, ?array $options = null) - * @method $this zrangebylex($key, $start, $stop, ?array $options = null) - * @method $this zrevrangebylex($key, $start, $stop, ?array $options = null) + * @method $this zscan($key, $cursor, array $options = null) + * @method $this zrangebylex($key, $start, $stop, array $options = null) + * @method $this zrevrangebylex($key, $start, $stop, array $options = null) * @method $this zremrangebylex($key, $min, $max) * @method $this zlexcount($key, $min, $max) * @method $this pexpiretime(string $key) @@ -312,7 +312,7 @@ use Predis\Command\Redis\Container\Search\FTCURSOR; * @method $this evalsha($script, $numkeys, $keyOrArg1 = null, $keyOrArgN = null) * @method $this evalsha_ro(string $sha1, array $keys, ...$argument) * @method $this script($subcommand, $argument = null) - * @method $this shutdown(?bool $noSave = null, bool $now = false, bool $force = false, bool $abort = false) + * @method $this shutdown(bool $noSave = null, bool $now = false, bool $force = false, bool $abort = false) * @method $this auth($password) * @method $this echo($message) * @method $this ping($message = null) @@ -335,8 +335,8 @@ use Predis\Command\Redis\Container\Search\FTCURSOR; * @method $this geohash($key, array $members) * @method $this geopos($key, array $members) * @method $this geodist($key, $member1, $member2, $unit = null) - * @method $this georadius($key, $longitude, $latitude, $radius, $unit, ?array $options = null) - * @method $this georadiusbymember($key, $member, $radius, $unit, ?array $options = null) + * @method $this georadius($key, $longitude, $latitude, $radius, $unit, array $options = null) + * @method $this georadiusbymember($key, $member, $radius, $unit, array $options = null) * @method $this geosearch(string $key, FromInterface $from, ByInterface $by, ?string $sorting = null, int $count = -1, bool $any = false, bool $withCoord = false, bool $withDist = false, bool $withHash = false) * @method $this geosearchstore(string $destination, string $source, FromInterface $from, ByInterface $by, ?string $sorting = null, int $count = -1, bool $any = false, bool $storeDist = false) * diff --git a/plugins/cache-redis/Predis/ClientInterface.php b/plugins/cache-redis/Predis/ClientInterface.php index e7edb9750..2937c5804 100644 --- a/plugins/cache-redis/Predis/ClientInterface.php +++ b/plugins/cache-redis/Predis/ClientInterface.php @@ -74,8 +74,8 @@ use Predis\Response\Status; * @method string|null randomkey() * @method mixed rename(string $key, string $target) * @method int renamenx(string $key, string $target) - * @method array scan($cursor, ?array $options = null) - * @method array sort(string $key, ?array $options = null) + * @method array scan($cursor, array $options = null) + * @method array sort(string $key, array $options = null) * @method array sort_ro(string $key, ?string $byPattern = null, ?LimitOffsetCount $limit = null, array $getPatterns = [], ?string $sorting = null, bool $alpha = false) * @method int ttl(string $key) * @method mixed type(string $key) @@ -172,7 +172,7 @@ use Predis\Response\Status; * @method array hmget(string $key, array $fields) * @method mixed hmset(string $key, array $dictionary) * @method array hrandfield(string $key, int $count = 1, bool $withValues = false) - * @method array hscan(string $key, $cursor, ?array $options = null) + * @method array hscan(string $key, $cursor, array $options = null) * @method int hset(string $key, string $field, string $value) * @method int hsetnx(string $key, string $field, string $value) * @method array hvals(string $key) @@ -231,10 +231,10 @@ use Predis\Response\Status; * @method string[] smembers(string $key) * @method array smismember(string $key, string ...$members) * @method int smove(string $source, string $destination, string $member) - * @method string|array|null spop(string $key, ?int $count = null) - * @method string|null srandmember(string $key, ?int $count = null) + * @method string|array|null spop(string $key, int $count = null) + * @method string|null srandmember(string $key, int $count = null) * @method int srem(string $key, array|string $member) - * @method array sscan(string $key, int $cursor, ?array $options = null) + * @method array sscan(string $key, int $cursor, array $options = null) * @method string[] sunion(array|string $keys) * @method int sunionstore(string $destination, array|string $keys) * @method int touch(string[]|string $keyOrKeys, string ...$keys = null) @@ -265,7 +265,7 @@ use Predis\Response\Status; * @method int tsdecrby(string $key, float $value, ?DecrByArguments $arguments = null) * @method int tsdel(string $key, int $fromTimestamp, int $toTimestamp) * @method Status tsdeleterule(string $sourceKey, string $destKey) - * @method array tsget(string $key, ?GetArguments $arguments = null) + * @method array tsget(string $key, GetArguments $arguments = null) * @method int tsincrby(string $key, float $value, ?IncrByArguments $arguments = null) * @method array tsinfo(string $key, ?InfoArguments $arguments = null) * @method array tsmadd(mixed ...$keyTimestampValue) @@ -275,12 +275,12 @@ use Predis\Response\Status; * @method array tsqueryindex(string ...$filterExpression) * @method array tsrange(string $key, $fromTimestamp, $toTimestamp, ?RangeArguments $arguments = null) * @method array tsrevrange(string $key, $fromTimestamp, $toTimestamp, ?RangeArguments $arguments = null) - * @method string xadd(string $key, array $dictionary, string $id = '*', ?array $options = null) + * @method string xadd(string $key, array $dictionary, string $id = '*', array $options = null) * @method int xdel(string $key, string ...$id) * @method int xlen(string $key) * @method array xrevrange(string $key, string $end, string $start, ?int $count = null) * @method array xrange(string $key, string $start, string $end, ?int $count = null) - * @method string xtrim(string $key, array|string $strategy, string $threshold, ?array $options = null) + * @method string xtrim(string $key, array|string $strategy, string $threshold, array $options = null) * @method int zadd(string $key, array $membersAndScoresDictionary) * @method int zcard(string $key) * @method string zcount(string $key, int|string $min, int|string $max) @@ -295,22 +295,22 @@ use Predis\Response\Status; * @method array zpopmin(string $key, int $count = 1) * @method array zpopmax(string $key, int $count = 1) * @method mixed zrandmember(string $key, int $count = 1, bool $withScores = false) - * @method array zrange(string $key, int|string $start, int|string $stop, ?array $options = null) - * @method array zrangebyscore(string $key, int|string $min, int|string $max, ?array $options = null) + * @method array zrange(string $key, int|string $start, int|string $stop, array $options = null) + * @method array zrangebyscore(string $key, int|string $min, int|string $max, array $options = null) * @method int zrangestore(string $destination, string $source, int|string $min, int|string $max, string|bool $by = false, bool $reversed = false, bool $limit = false, int $offset = 0, int $count = 0) * @method int|null zrank(string $key, string $member) * @method int zrem(string $key, string ...$member) * @method int zremrangebyrank(string $key, int|string $start, int|string $stop) * @method int zremrangebyscore(string $key, int|string $min, int|string $max) - * @method array zrevrange(string $key, int|string $start, int|string $stop, ?array $options = null) - * @method array zrevrangebyscore(string $key, int|string $max, int|string $min, ?array $options = null) + * @method array zrevrange(string $key, int|string $start, int|string $stop, array $options = null) + * @method array zrevrangebyscore(string $key, int|string $max, int|string $min, array $options = null) * @method int|null zrevrank(string $key, string $member) * @method array zunion(array $keys, int[] $weights = [], string $aggregate = 'sum', bool $withScores = false) * @method int zunionstore(string $destination, array $keys, int[] $weights = [], string $aggregate = 'sum') * @method string|null zscore(string $key, string $member) - * @method array zscan(string $key, int $cursor, ?array $options = null) - * @method array zrangebylex(string $key, string $start, string $stop, ?array $options = null) - * @method array zrevrangebylex(string $key, string $start, string $stop, ?array $options = null) + * @method array zscan(string $key, int $cursor, array $options = null) + * @method array zrangebylex(string $key, string $start, string $stop, array $options = null) + * @method array zrevrangebylex(string $key, string $start, string $stop, array $options = null) * @method int zremrangebylex(string $key, string $min, string $max) * @method int zlexcount(string $key, string $min, string $max) * @method int pexpiretime(string $key) @@ -330,10 +330,10 @@ use Predis\Response\Status; * @method mixed evalsha(string $script, int $numkeys, string ...$keyOrArg = null) * @method mixed evalsha_ro(string $sha1, array $keys, ...$argument) * @method mixed script($subcommand, $argument = null) - * @method Status shutdown(?bool $noSave = null, bool $now = false, bool $force = false, bool $abort = false) + * @method Status shutdown(bool $noSave = null, bool $now = false, bool $force = false, bool $abort = false) * @method mixed auth(string $password) * @method string echo(string $message) - * @method mixed ping(?string $message = null) + * @method mixed ping(string $message = null) * @method mixed select(int $database) * @method mixed bgrewriteaof() * @method mixed bgsave() @@ -353,8 +353,8 @@ use Predis\Response\Status; * @method array geohash(string $key, array $members) * @method array geopos(string $key, array $members) * @method string|null geodist(string $key, $member1, $member2, $unit = null) - * @method array georadius(string $key, $longitude, $latitude, $radius, $unit, ?array $options = null) - * @method array georadiusbymember(string $key, $member, $radius, $unit, ?array $options = null) + * @method array georadius(string $key, $longitude, $latitude, $radius, $unit, array $options = null) + * @method array georadiusbymember(string $key, $member, $radius, $unit, array $options = null) * @method array geosearch(string $key, FromInterface $from, ByInterface $by, ?string $sorting = null, int $count = -1, bool $any = false, bool $withCoord = false, bool $withDist = false, bool $withHash = false) * @method int geosearchstore(string $destination, string $source, FromInterface $from, ByInterface $by, ?string $sorting = null, int $count = -1, bool $any = false, bool $storeDist = false) * diff --git a/plugins/cache-redis/Predis/Cluster/PredisStrategy.php b/plugins/cache-redis/Predis/Cluster/PredisStrategy.php index 04f31b117..574b86f9e 100644 --- a/plugins/cache-redis/Predis/Cluster/PredisStrategy.php +++ b/plugins/cache-redis/Predis/Cluster/PredisStrategy.php @@ -25,7 +25,7 @@ class PredisStrategy extends ClusterStrategy /** * @param DistributorInterface $distributor Optional distributor instance. */ - public function __construct(?DistributorInterface $distributor = null) + public function __construct(DistributorInterface $distributor = null) { parent::__construct(); diff --git a/plugins/cache-redis/Predis/Cluster/RedisStrategy.php b/plugins/cache-redis/Predis/Cluster/RedisStrategy.php index dadf782ed..8ae5c0f5e 100644 --- a/plugins/cache-redis/Predis/Cluster/RedisStrategy.php +++ b/plugins/cache-redis/Predis/Cluster/RedisStrategy.php @@ -27,7 +27,7 @@ class RedisStrategy extends ClusterStrategy /** * @param HashGeneratorInterface $hashGenerator Hash generator instance. */ - public function __construct(?HashGeneratorInterface $hashGenerator = null) + public function __construct(HashGeneratorInterface $hashGenerator = null) { parent::__construct(); diff --git a/plugins/cache-redis/Predis/Command/Redis/Container/FunctionContainer.php b/plugins/cache-redis/Predis/Command/Redis/Container/FunctionContainer.php index dfa309eea..8f2a673d1 100644 --- a/plugins/cache-redis/Predis/Command/Redis/Container/FunctionContainer.php +++ b/plugins/cache-redis/Predis/Command/Redis/Container/FunctionContainer.php @@ -19,9 +19,9 @@ use Predis\Response\Status; * @method string dump() * @method Status flush(?string $mode = null) * @method Status kill() - * @method array list(?string $libraryNamePattern = null, bool $withCode = false) + * @method array list(string $libraryNamePattern = null, bool $withCode = false) * @method string load(string $functionCode, bool $replace = 'false') - * @method Status restore(string $value, ?string $policy = null) + * @method Status restore(string $value, string $policy = null) * @method array stats() */ class FunctionContainer extends AbstractContainer diff --git a/plugins/cache-redis/Predis/Command/Strategy/SubcommandStrategyResolver.php b/plugins/cache-redis/Predis/Command/Strategy/SubcommandStrategyResolver.php index b714d5276..cda84268e 100644 --- a/plugins/cache-redis/Predis/Command/Strategy/SubcommandStrategyResolver.php +++ b/plugins/cache-redis/Predis/Command/Strategy/SubcommandStrategyResolver.php @@ -23,7 +23,7 @@ class SubcommandStrategyResolver implements StrategyResolverInterface */ private $separator; - public function __construct(?string $separator = null) + public function __construct(string $separator = null) { $this->separator = $separator; } diff --git a/plugins/cache-redis/Predis/CommunicationException.php b/plugins/cache-redis/Predis/CommunicationException.php index 9fd69a021..0fc7c07a6 100644 --- a/plugins/cache-redis/Predis/CommunicationException.php +++ b/plugins/cache-redis/Predis/CommunicationException.php @@ -32,7 +32,7 @@ abstract class CommunicationException extends PredisException NodeConnectionInterface $connection, $message = '', $code = 0, - ?Exception $innerException = null + Exception $innerException = null ) { parent::__construct( is_null($message) ? '' : $message, diff --git a/plugins/cache-redis/Predis/Configuration/Options.php b/plugins/cache-redis/Predis/Configuration/Options.php index 3cad8e951..3fff04129 100644 --- a/plugins/cache-redis/Predis/Configuration/Options.php +++ b/plugins/cache-redis/Predis/Configuration/Options.php @@ -43,7 +43,7 @@ class Options implements OptionsInterface /** * @param array $options Named array of client options */ - public function __construct(?array $options = null) + public function __construct(array $options = null) { $this->input = $options ?? []; } diff --git a/plugins/cache-redis/Predis/Connection/Cluster/PredisCluster.php b/plugins/cache-redis/Predis/Connection/Cluster/PredisCluster.php index a65e665f5..c30fd09d3 100644 --- a/plugins/cache-redis/Predis/Connection/Cluster/PredisCluster.php +++ b/plugins/cache-redis/Predis/Connection/Cluster/PredisCluster.php @@ -52,7 +52,7 @@ class PredisCluster implements ClusterInterface, IteratorAggregate, Countable /** * @param StrategyInterface $strategy Optional cluster strategy. */ - public function __construct(?StrategyInterface $strategy = null) + public function __construct(StrategyInterface $strategy = null) { $this->strategy = $strategy ?: new PredisStrategy(); $this->distributor = $this->strategy->getDistributor(); diff --git a/plugins/cache-redis/Predis/Connection/Cluster/RedisCluster.php b/plugins/cache-redis/Predis/Connection/Cluster/RedisCluster.php index 6e7a90239..7f3013c17 100644 --- a/plugins/cache-redis/Predis/Connection/Cluster/RedisCluster.php +++ b/plugins/cache-redis/Predis/Connection/Cluster/RedisCluster.php @@ -70,7 +70,7 @@ class RedisCluster implements ClusterInterface, IteratorAggregate, Countable */ public function __construct( FactoryInterface $connections, - ?StrategyInterface $strategy = null + StrategyInterface $strategy = null ) { $this->connections = $connections; $this->strategy = $strategy ?: new RedisClusterStrategy(); @@ -273,7 +273,7 @@ class RedisCluster implements ClusterInterface, IteratorAggregate, Countable * * @param NodeConnectionInterface $connection Optional connection instance. */ - public function askSlotMap(?NodeConnectionInterface $connection = null) + public function askSlotMap(NodeConnectionInterface $connection = null) { if (!$connection && !$connection = $this->getRandomConnection()) { return; diff --git a/plugins/cache-redis/Predis/Connection/CompositeStreamConnection.php b/plugins/cache-redis/Predis/Connection/CompositeStreamConnection.php index 431663cae..ad69cbc12 100644 --- a/plugins/cache-redis/Predis/Connection/CompositeStreamConnection.php +++ b/plugins/cache-redis/Predis/Connection/CompositeStreamConnection.php @@ -31,7 +31,7 @@ class CompositeStreamConnection extends StreamConnection implements CompositeCon */ public function __construct( ParametersInterface $parameters, - ?ProtocolProcessorInterface $protocol = null + ProtocolProcessorInterface $protocol = null ) { $this->parameters = $this->assertParameters($parameters); $this->protocol = $protocol ?: new TextProtocolProcessor(); diff --git a/plugins/cache-redis/Predis/Connection/RelayMethods.php b/plugins/cache-redis/Predis/Connection/RelayMethods.php index d59dd41f2..a52c4a035 100644 --- a/plugins/cache-redis/Predis/Connection/RelayMethods.php +++ b/plugins/cache-redis/Predis/Connection/RelayMethods.php @@ -32,7 +32,7 @@ trait RelayMethods * @param string $pattern * @return bool */ - public function onInvalidated(?callable $callback, ?string $pattern = null) + public function onInvalidated(?callable $callback, string $pattern = null) { return $this->client->onInvalidated($callback, $pattern); } @@ -129,7 +129,7 @@ trait RelayMethods * @param ?int $db * @return bool */ - public function flushMemory(?string $endpointId = null, ?int $db = null) + public function flushMemory(string $endpointId = null, int $db = null) { return $this->client->flushMemory($endpointId, $db); } diff --git a/plugins/cache-redis/Predis/Connection/Replication/MasterSlaveReplication.php b/plugins/cache-redis/Predis/Connection/Replication/MasterSlaveReplication.php index 31897ed3e..9d57a5ac3 100644 --- a/plugins/cache-redis/Predis/Connection/Replication/MasterSlaveReplication.php +++ b/plugins/cache-redis/Predis/Connection/Replication/MasterSlaveReplication.php @@ -72,7 +72,7 @@ class MasterSlaveReplication implements ReplicationInterface /** * {@inheritdoc} */ - public function __construct(?ReplicationStrategy $strategy = null) + public function __construct(ReplicationStrategy $strategy = null) { $this->strategy = $strategy ?: new ReplicationStrategy(); } diff --git a/plugins/cache-redis/Predis/Connection/Replication/SentinelReplication.php b/plugins/cache-redis/Predis/Connection/Replication/SentinelReplication.php index 146254e88..14dbe2758 100644 --- a/plugins/cache-redis/Predis/Connection/Replication/SentinelReplication.php +++ b/plugins/cache-redis/Predis/Connection/Replication/SentinelReplication.php @@ -123,7 +123,7 @@ class SentinelReplication implements ReplicationInterface $service, array $sentinels, ConnectionFactoryInterface $connectionFactory, - ?ReplicationStrategy $strategy = null + ReplicationStrategy $strategy = null ) { $this->sentinels = $sentinels; $this->service = $service; diff --git a/plugins/cache-redis/Predis/Protocol/Text/CompositeProtocolProcessor.php b/plugins/cache-redis/Predis/Protocol/Text/CompositeProtocolProcessor.php index 19494c05d..3f7df02e5 100644 --- a/plugins/cache-redis/Predis/Protocol/Text/CompositeProtocolProcessor.php +++ b/plugins/cache-redis/Predis/Protocol/Text/CompositeProtocolProcessor.php @@ -41,8 +41,8 @@ class CompositeProtocolProcessor implements ProtocolProcessorInterface * @param ResponseReaderInterface $reader Response reader. */ public function __construct( - ?RequestSerializerInterface $serializer = null, - ?ResponseReaderInterface $reader = null + RequestSerializerInterface $serializer = null, + ResponseReaderInterface $reader = null ) { $this->setRequestSerializer($serializer ?: new RequestSerializer()); $this->setResponseReader($reader ?: new ResponseReader());