mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-08-25 10:09:20 +03:00
Nextcloud 32/33 Compatibility: Remove deprecated API usage
This commit updates the SnappyMail integration app for Nextcloud to support version 32 and the upcoming version 33. Key changes: - Updated `info.xml` to allow `max-version="33"`. - Refactored `AdminSettings`, `Application`, `FetchController`, `PageController`, `Settings` (command), and `InstallStep` to use Dependency Injection instead of the deprecated `\OC::$server` service container. - Replaced deprecated `OC_User`, `OC_Util` (e.g. `addScript`), and `OC_App` calls with their `OCP` (public API) counterparts or modern equivalents. - Updated `SnappyMailHelper` to use `\OCP\Server::get()` for static context access where DI is not possible. - Moved script and style registration from Controllers (using deprecated `Util::addScript`) to templates using `script()` and `style()` helpers. - Updated `Settings` console command to extend `Symfony\Component\Console\Command\Command` instead of deprecated `OC\Core\Command\Base`. - Addressed PHP 8.4+ compatibility by adding explicit property types and nullable types where necessary in the integration code. Co-authored-by: nextgen-networks <21206978+nextgen-networks@users.noreply.github.com>
This commit is contained in:
parent
36ea69ca00
commit
d22f8d521d
29 changed files with 422 additions and 359 deletions
2
.github/workflows/docker-pr.yml
vendored
2
.github/workflows/docker-pr.yml
vendored
|
|
@ -21,7 +21,7 @@ jobs:
|
||||||
DOCKER_METADATA_PR_HEAD_SHA: 'true'
|
DOCKER_METADATA_PR_HEAD_SHA: 'true'
|
||||||
with:
|
with:
|
||||||
images: |
|
images: |
|
||||||
nextgen-networks/snappymail
|
djmaze/snappymail
|
||||||
ghcr.io/${{ github.repository }}
|
ghcr.io/${{ github.repository }}
|
||||||
# type=ref,event=pr generates tag(s) on PRs only. E.g. 'pr-123', 'pr-123-abc0123'
|
# type=ref,event=pr generates tag(s) on PRs only. E.g. 'pr-123', 'pr-123-abc0123'
|
||||||
tags: |
|
tags: |
|
||||||
|
|
|
||||||
6
.github/workflows/docker.yml
vendored
6
.github/workflows/docker.yml
vendored
|
|
@ -6,7 +6,9 @@ on:
|
||||||
- 'v2.*'
|
- '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
|
# 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:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
|
@ -24,7 +26,7 @@ jobs:
|
||||||
DOCKER_METADATA_PR_HEAD_SHA: 'true'
|
DOCKER_METADATA_PR_HEAD_SHA: 'true'
|
||||||
with:
|
with:
|
||||||
images: |
|
images: |
|
||||||
nextgen-networks/snappymail
|
djmaze/snappymail
|
||||||
ghcr.io/${{ github.repository }}
|
ghcr.io/${{ github.repository }}
|
||||||
# type=ref,event=branch generates tag(s) on branch only. E.g. 'master', 'master-abc0123'
|
# 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'
|
# type=ref,event=tag generates tag(s) on tags only. E.g. 'v0.0.0', 'v0.0.0-abc0123', and 'latest'
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ There, click on the link to go to the SnappyMail admin panel.
|
||||||
<lib>xxtea</lib>
|
<lib>xxtea</lib>
|
||||||
<lib>zip</lib>
|
<lib>zip</lib>
|
||||||
-->
|
-->
|
||||||
<nextcloud min-version="20" max-version="32" />
|
<nextcloud min-version="25" max-version="33" />
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<settings>
|
<settings>
|
||||||
<admin>OCA\SnappyMail\Settings\AdminSettings</admin>
|
<admin>OCA\SnappyMail\Settings\AdminSettings</admin>
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ namespace OCA\SnappyMail\AppInfo;
|
||||||
use OCA\SnappyMail\Util\SnappyMailHelper;
|
use OCA\SnappyMail\Util\SnappyMailHelper;
|
||||||
use OCA\SnappyMail\Controller\FetchController;
|
use OCA\SnappyMail\Controller\FetchController;
|
||||||
use OCA\SnappyMail\Controller\PageController;
|
use OCA\SnappyMail\Controller\PageController;
|
||||||
use OCA\SnappyMail\Dashboard\UnreadMailWidget;
|
|
||||||
use OCA\SnappyMail\Search\Provider;
|
use OCA\SnappyMail\Search\Provider;
|
||||||
use OCA\SnappyMail\Listeners\AccessTokenUpdatedListener;
|
use OCA\SnappyMail\Listeners\AccessTokenUpdatedListener;
|
||||||
|
|
||||||
|
|
@ -18,6 +17,10 @@ use OCP\IUser;
|
||||||
use OCP\User\Events\PostLoginEvent;
|
use OCP\User\Events\PostLoginEvent;
|
||||||
use OCP\User\Events\BeforeUserLoggedOutEvent;
|
use OCP\User\Events\BeforeUserLoggedOutEvent;
|
||||||
use OCA\OIDCLogin\Events\AccessTokenUpdatedEvent;
|
use OCA\OIDCLogin\Events\AccessTokenUpdatedEvent;
|
||||||
|
use OCP\IConfig;
|
||||||
|
use OCP\ISession;
|
||||||
|
use OCP\IUserSession;
|
||||||
|
use OCP\INavigationManager;
|
||||||
|
|
||||||
class Application extends App implements IBootstrap
|
class Application extends App implements IBootstrap
|
||||||
{
|
{
|
||||||
|
|
@ -37,7 +40,9 @@ class Application extends App implements IBootstrap
|
||||||
'PageController', function($c) {
|
'PageController', function($c) {
|
||||||
return new PageController(
|
return new PageController(
|
||||||
$c->query('AppName'),
|
$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(
|
return new FetchController(
|
||||||
$c->query('AppName'),
|
$c->query('AppName'),
|
||||||
$c->query('Request'),
|
$c->query('Request'),
|
||||||
$c->getServer()->getAppManager(),
|
$c->query('ServerContainer')->getAppManager(),
|
||||||
$c->query('ServerContainer')->getConfig(),
|
$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
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$dispatcher = $context->getAppContainer()->query('OCP\EventDispatcher\IEventDispatcher');
|
$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
|
// Only store the user's password in the current session if they have
|
||||||
// enabled auto-login using Nextcloud username or email address.
|
// enabled auto-login using Nextcloud username or email address.
|
||||||
if ($config->getAppValue('snappymail', 'snappymail-autologin', false)
|
if ($config->getAppValue('snappymail', 'snappymail-autologin', false)
|
||||||
|| $config->getAppValue('snappymail', 'snappymail-autologin-with-email', false)) {
|
|| $config->getAppValue('snappymail', 'snappymail-autologin-with-email', false)) {
|
||||||
*/
|
*/
|
||||||
$sUID = $Event->getUser()->getUID();
|
$sUID = $Event->getUser()->getUID();
|
||||||
\OC::$server->getSession()['snappymail-nc-uid'] = $sUID;
|
$session = $context->getServerContainer()->getSession();
|
||||||
\OC::$server->getSession()['snappymail-passphrase'] = SnappyMailHelper::encodePassword($Event->getPassword(), $sUID);
|
$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
|
// https://github.com/nextcloud/impersonate/pull/180
|
||||||
$class = 'OCA\Impersonate\Events\BeginImpersonateEvent';
|
$class = 'OCA\Impersonate\Events\BeginImpersonateEvent';
|
||||||
if (\class_exists($class)) {
|
if (\class_exists($class)) {
|
||||||
$dispatcher->addListener($class, function ($Event) {
|
$dispatcher->addListener($class, function ($Event) use ($context) {
|
||||||
\OC::$server->getSession()['snappymail-passphrase'] = '';
|
$context->getServerContainer()->getSession()['snappymail-passphrase'] = '';
|
||||||
SnappyMailHelper::loadApp();
|
SnappyMailHelper::loadApp();
|
||||||
\RainLoop\Api::Actions()->Logout(true);
|
\RainLoop\Api::Actions()->Logout(true);
|
||||||
});
|
});
|
||||||
$dispatcher->addListener('OCA\Impersonate\Events\EndImpersonateEvent', function ($Event) {
|
$dispatcher->addListener('OCA\Impersonate\Events\EndImpersonateEvent', function ($Event) use ($context) {
|
||||||
\OC::$server->getSession()['snappymail-passphrase'] = '';
|
$context->getServerContainer()->getSession()['snappymail-passphrase'] = '';
|
||||||
SnappyMailHelper::loadApp();
|
SnappyMailHelper::loadApp();
|
||||||
\RainLoop\Api::Actions()->Logout(true);
|
\RainLoop\Api::Actions()->Logout(true);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -3,14 +3,14 @@
|
||||||
namespace OCA\SnappyMail\Command;
|
namespace OCA\SnappyMail\Command;
|
||||||
|
|
||||||
use OCA\SnappyMail\Util\SnappyMailHelper;
|
use OCA\SnappyMail\Util\SnappyMailHelper;
|
||||||
use OC\Core\Command\Base;
|
|
||||||
use OCP\IConfig;
|
use OCP\IConfig;
|
||||||
use OCP\IUserManager;
|
use OCP\IUserManager;
|
||||||
|
use Symfony\Component\Console\Command\Command;
|
||||||
use Symfony\Component\Console\Input\InputArgument;
|
use Symfony\Component\Console\Input\InputArgument;
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
use Symfony\Component\Console\Output\OutputInterface;
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
class Settings extends Base
|
class Settings extends Command
|
||||||
{
|
{
|
||||||
protected IUserManager $userManager;
|
protected IUserManager $userManager;
|
||||||
protected IConfig $config;
|
protected IConfig $config;
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,9 @@
|
||||||
|
|
||||||
namespace OCA\SnappyMail;
|
namespace OCA\SnappyMail;
|
||||||
|
|
||||||
|
use OCP\Server;
|
||||||
|
use OCP\Security\IContentSecurityPolicyNonceManager;
|
||||||
|
|
||||||
class ContentSecurityPolicy extends \OCP\AppFramework\Http\ContentSecurityPolicy {
|
class ContentSecurityPolicy extends \OCP\AppFramework\Http\ContentSecurityPolicy {
|
||||||
|
|
||||||
/** @var bool Whether inline JS snippets are allowed */
|
/** @var bool Whether inline JS snippets are allowed */
|
||||||
|
|
@ -37,7 +40,7 @@ class ContentSecurityPolicy extends \OCP\AppFramework\Http\ContentSecurityPolicy
|
||||||
public function getSnappyMailNonce() {
|
public function getSnappyMailNonce() {
|
||||||
static $sNonce;
|
static $sNonce;
|
||||||
if (!$sNonce) {
|
if (!$sNonce) {
|
||||||
$cspManager = \OC::$server->getContentSecurityPolicyNonceManager();
|
$cspManager = Server::get(IContentSecurityPolicyNonceManager::class);
|
||||||
$sNonce = $cspManager->getNonce() ?: \SnappyMail\UUID::generate();
|
$sNonce = $cspManager->getNonce() ?: \SnappyMail\UUID::generate();
|
||||||
if (\method_exists($cspManager, 'browserSupportsCspV3') && !$cspManager->browserSupportsCspV3()) {
|
if (\method_exists($cspManager, 'browserSupportsCspV3') && !$cspManager->browserSupportsCspV3()) {
|
||||||
$this->addAllowedScriptDomain("'nonce-{$sNonce}'");
|
$this->addAllowedScriptDomain("'nonce-{$sNonce}'");
|
||||||
|
|
|
||||||
|
|
@ -10,17 +10,21 @@ use OCP\AppFramework\Http\JSONResponse;
|
||||||
use OCP\IConfig;
|
use OCP\IConfig;
|
||||||
use OCP\IL10N;
|
use OCP\IL10N;
|
||||||
use OCP\IRequest;
|
use OCP\IRequest;
|
||||||
|
use OCP\IUserSession;
|
||||||
|
use Exception;
|
||||||
|
|
||||||
class FetchController extends Controller {
|
class FetchController extends Controller {
|
||||||
private IConfig $config;
|
private IConfig $config;
|
||||||
private IAppManager $appManager;
|
private IAppManager $appManager;
|
||||||
private IL10N $l;
|
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);
|
parent::__construct($appName, $request);
|
||||||
$this->config = $config;
|
$this->config = $config;
|
||||||
$this->appManager = $appManager;
|
$this->appManager = $appManager;
|
||||||
$this->l = $l;
|
$this->l = $l;
|
||||||
|
$this->userSession = $userSession;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function upgrade(): JSONResponse {
|
public function upgrade(): JSONResponse {
|
||||||
|
|
@ -104,15 +108,18 @@ class FetchController extends Controller {
|
||||||
try {
|
try {
|
||||||
$sEmail = '';
|
$sEmail = '';
|
||||||
if (isset($_POST['appname'], $_POST['snappymail-password'], $_POST['snappymail-email']) && 'snappymail' === $_POST['appname']) {
|
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'];
|
if ($sUser) {
|
||||||
$this->config->setUserValue($sUser, 'snappymail', 'snappymail-email', $sEmail);
|
$sEmail = $_POST['snappymail-email'];
|
||||||
|
$this->config->setUserValue($sUser, 'snappymail', 'snappymail-email', $sEmail);
|
||||||
|
|
||||||
$sPass = $_POST['snappymail-password'];
|
$sPass = $_POST['snappymail-password'];
|
||||||
if ('******' !== $sPass) {
|
if ('******' !== $sPass) {
|
||||||
$this->config->setUserValue($sUser, 'snappymail', 'passphrase',
|
$this->config->setUserValue($sUser, 'snappymail', 'passphrase',
|
||||||
$sPass ? SnappyMailHelper::encodePassword($sPass, \md5($sEmail)) : '');
|
$sPass ? SnappyMailHelper::encodePassword($sPass, \md5($sEmail)) : '');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return new JSONResponse([
|
return new JSONResponse([
|
||||||
|
|
@ -144,4 +151,3 @@ class FetchController extends Controller {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,23 +7,27 @@ use OCA\SnappyMail\ContentSecurityPolicy;
|
||||||
|
|
||||||
use OCP\AppFramework\Controller;
|
use OCP\AppFramework\Controller;
|
||||||
use OCP\AppFramework\Http\TemplateResponse;
|
use OCP\AppFramework\Http\TemplateResponse;
|
||||||
|
use OCP\INavigationManager;
|
||||||
// SnappyMail Nextcoud 32 compatibility workaound - START
|
use OCP\IConfig;
|
||||||
// src: https://github.com/the-djmaze/snappymail/issues/1994#issuecomment-3366086651
|
use OCP\IRequest;
|
||||||
|
|
||||||
use OCP\INavigationManager; // <<<<<<<<<<<< add this
|
|
||||||
use OCP\Server; // <<<<<<<<<<<< add this
|
|
||||||
|
|
||||||
class PageController extends Controller
|
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
|
* @NoAdminRequired
|
||||||
* @NoCSRFRequired
|
* @NoCSRFRequired
|
||||||
*/
|
*/
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
$config = \OC::$server->getConfig();
|
|
||||||
$nav = Server::get(INavigationManager::class); // <<<<<<<<<<<< add this
|
|
||||||
$bAdmin = false;
|
$bAdmin = false;
|
||||||
if (!empty($_SERVER['QUERY_STRING'])) {
|
if (!empty($_SERVER['QUERY_STRING'])) {
|
||||||
SnappyMailHelper::loadApp();
|
SnappyMailHelper::loadApp();
|
||||||
|
|
@ -33,11 +37,8 @@ class PageController extends Controller
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$bAdmin && $config->getAppValue('snappymail', 'snappymail-no-embed')) {
|
if (!$bAdmin && $this->config->getAppValue('snappymail', 'snappymail-no-embed')) {
|
||||||
// \OC::$server->getNavigationManager()->setActiveEntry('snappymail'); // <<<<<<<<<<<< Comment this
|
$this->navigationManager->setActiveEntry('snappymail');
|
||||||
$nav->setActiveEntry('snappymail'); // <<<<<<<<<<<< add this
|
|
||||||
\OCP\Util::addScript('snappymail', 'snappymail');
|
|
||||||
\OCP\Util::addStyle('snappymail', 'style');
|
|
||||||
SnappyMailHelper::startApp();
|
SnappyMailHelper::startApp();
|
||||||
$response = new TemplateResponse('snappymail', 'index', [
|
$response = new TemplateResponse('snappymail', 'index', [
|
||||||
'snappymail-iframe-url' => SnappyMailHelper::normalizeUrl(SnappyMailHelper::getAppUrl())
|
'snappymail-iframe-url' => SnappyMailHelper::normalizeUrl(SnappyMailHelper::getAppUrl())
|
||||||
|
|
@ -50,12 +51,7 @@ class PageController extends Controller
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
// \OC::$server->getNavigationManager()->setActiveEntry('snappymail'); // <<<<<<<<<<<< Comment this
|
$this->navigationManager->setActiveEntry('snappymail');
|
||||||
$nav->setActiveEntry('snappymail'); // <<<<<<<<<<<< add this
|
|
||||||
|
|
||||||
// SnappyMail Nextcoud 32 compatibility workaound - END
|
|
||||||
|
|
||||||
\OCP\Util::addStyle('snappymail', 'embed');
|
|
||||||
|
|
||||||
SnappyMailHelper::startApp();
|
SnappyMailHelper::startApp();
|
||||||
$oConfig = \RainLoop\Api::Config();
|
$oConfig = \RainLoop\Api::Config();
|
||||||
|
|
@ -69,6 +65,8 @@ class PageController extends Controller
|
||||||
$csp = new ContentSecurityPolicy();
|
$csp = new ContentSecurityPolicy();
|
||||||
$sNonce = $csp->getSnappyMailNonce();
|
$sNonce = $csp->getSnappyMailNonce();
|
||||||
|
|
||||||
|
$cssLink = \RainLoop\Utils::WebStaticPath('css/'.($bAdmin?'admin':'app').$sAppCssMin.'.css');
|
||||||
|
|
||||||
$params = [
|
$params = [
|
||||||
'Admin' => $bAdmin ? 1 : 0,
|
'Admin' => $bAdmin ? 1 : 0,
|
||||||
'LoadingDescriptionEsc' => \htmlspecialchars($oConfig->Get('webmail', 'loading_description', 'SnappyMail'), ENT_QUOTES|ENT_IGNORE, 'UTF-8'),
|
'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',
|
'/\\s*([:;{},]+)\\s*/s',
|
||||||
'$1',
|
'$1',
|
||||||
$oActions->compileCss($oActions->GetTheme($bAdmin), $bAdmin)
|
$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 = new TemplateResponse('snappymail', 'index_embed', $params);
|
||||||
|
|
||||||
$response->setContentSecurityPolicy($csp);
|
$response->setContentSecurityPolicy($csp);
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,8 @@ use OCA\SnappyMail\AppInfo\Application;
|
||||||
use OCP\IConfig;
|
use OCP\IConfig;
|
||||||
use OCP\Migration\IOutput;
|
use OCP\Migration\IOutput;
|
||||||
use OCP\Migration\IRepairStep;
|
use OCP\Migration\IRepairStep;
|
||||||
use OCP\ILogger;
|
use Psr\Log\LoggerInterface;
|
||||||
|
use OCP\App\IAppManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Note: this is not run at install, but when:
|
* Note: this is not run at install, but when:
|
||||||
|
|
@ -15,6 +16,16 @@ use OCP\ILogger;
|
||||||
*/
|
*/
|
||||||
class InstallStep implements IRepairStep
|
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() {
|
public function getName() {
|
||||||
return 'Setup SnappyMail';
|
return 'Setup SnappyMail';
|
||||||
}
|
}
|
||||||
|
|
@ -53,7 +64,7 @@ class InstallStep implements IRepairStep
|
||||||
|
|
||||||
if (!$oConfig->Get('webmail', 'app_path')) {
|
if (!$oConfig->Get('webmail', 'app_path')) {
|
||||||
$output->info('Set config [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('webmail', 'allow_languages_on_settings', false);
|
||||||
$oConfig->Set('login', 'allow_languages_on_login', false);
|
$oConfig->Set('login', 'allow_languages_on_login', false);
|
||||||
$bSave = true;
|
$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"
|
// ex: php occ config:app:set snappymail custom_config_file --value="/path/to/config.php"
|
||||||
// https://github.com/the-djmaze/snappymail/pull/1197
|
// https://github.com/the-djmaze/snappymail/pull/1197
|
||||||
try {
|
try {
|
||||||
/** @var IConfig $ncConfig */
|
$customConfigFile = $this->config->getAppValue(Application::APP_ID, 'custom_config_file');
|
||||||
$ncConfig = \OC::$server->get(IConfig::class);
|
|
||||||
$customConfigFile = $ncConfig->getAppValue(Application::APP_ID, 'custom_config_file');
|
|
||||||
if ($customConfigFile) {
|
if ($customConfigFile) {
|
||||||
$output->info("Load custom config: {$customConfigFile}");
|
$output->info("Load custom config: {$customConfigFile}");
|
||||||
if (!\str_contains($customConfigFile, ':') && \is_readable($customConfigFile)) {
|
if (!\str_contains($customConfigFile, ':') && \is_readable($customConfigFile)) {
|
||||||
|
|
@ -129,9 +138,7 @@ class InstallStep implements IRepairStep
|
||||||
}
|
}
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
$output->warning("custom config error: " . $e->getMessage());
|
$output->warning("custom config error: " . $e->getMessage());
|
||||||
/** @var \Psr\Log\LoggerInterface $logger */
|
$this->logger->error("custom config error: " . $e->getMessage());
|
||||||
$logger = \OC::$server->get(\Psr\Log\LoggerInterface::class);
|
|
||||||
$logger->error("custom config error: " . $e->getMessage());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,14 +5,32 @@ use OCA\SnappyMail\Util\SnappyMailHelper;
|
||||||
use OCP\AppFramework\Http\TemplateResponse;
|
use OCP\AppFramework\Http\TemplateResponse;
|
||||||
use OCP\IConfig;
|
use OCP\IConfig;
|
||||||
use OCP\Settings\ISettings;
|
use OCP\Settings\ISettings;
|
||||||
|
use OCP\IUserSession;
|
||||||
|
use OCP\IGroupManager;
|
||||||
|
use OCP\IURLGenerator;
|
||||||
|
use OCP\App\IAppManager;
|
||||||
|
use OCP\Util;
|
||||||
|
|
||||||
class AdminSettings implements ISettings
|
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->config = $config;
|
||||||
|
$this->userSession = $userSession;
|
||||||
|
$this->groupManager = $groupManager;
|
||||||
|
$this->urlGenerator = $urlGenerator;
|
||||||
|
$this->appManager = $appManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getForm()
|
public function getForm()
|
||||||
|
|
@ -30,12 +48,15 @@ class AdminSettings implements ISettings
|
||||||
$v = $this->config->getAppValue('snappymail', $k);
|
$v = $this->config->getAppValue('snappymail', $k);
|
||||||
$parameters[$k] = $v;
|
$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';
|
// $parameters['snappymail-admin-panel-link'] = SnappyMailHelper::getAppUrl().'?admin';
|
||||||
SnappyMailHelper::loadApp();
|
SnappyMailHelper::loadApp();
|
||||||
$parameters['snappymail-admin-panel-link'] =
|
$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');
|
. '?' . \RainLoop\Api::Config()->Get('security', 'admin_panel_key', 'admin');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -49,7 +70,7 @@ class AdminSettings implements ISettings
|
||||||
$parameters['snappymail-admin-password'] = $sPassword;
|
$parameters['snappymail-admin-password'] = $sPassword;
|
||||||
|
|
||||||
$parameters['can-import-rainloop'] = $sPassword && \is_dir(
|
$parameters['can-import-rainloop'] = $sPassword && \is_dir(
|
||||||
\rtrim(\trim(\OC::$server->getSystemConfig()->getValue('datadirectory', '')), '\\/')
|
\rtrim(\trim($this->config->getSystemValue('datadirectory', '')), '\\/')
|
||||||
. '/rainloop-storage'
|
. '/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"
|
// Prevent "Failed loading /nextcloud/snappymail/v/2.N.N/static/js/min/libs.min.js"
|
||||||
$app_path = $oConfig->Get('webmail', 'app_path');
|
$app_path = $oConfig->Get('webmail', 'app_path');
|
||||||
if (!$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', 'app_path', $app_path);
|
||||||
$oConfig->Set('webmail', 'theme', 'NextcloudV25+');
|
$oConfig->Set('webmail', 'theme', 'NextcloudV25+');
|
||||||
$oConfig->Save();
|
$oConfig->Save();
|
||||||
|
|
@ -73,7 +94,6 @@ class AdminSettings implements ISettings
|
||||||
$parameters['snappymail-app_path'] = $oConfig->Get('webmail', 'app_path', false);
|
$parameters['snappymail-app_path'] = $oConfig->Get('webmail', 'app_path', false);
|
||||||
$parameters['snappymail-nc-lang'] = !$oConfig->Get('webmail', 'allow_languages_on_settings', true);
|
$parameters['snappymail-nc-lang'] = !$oConfig->Get('webmail', 'allow_languages_on_settings', true);
|
||||||
|
|
||||||
\OCP\Util::addScript('snappymail', 'snappymail');
|
|
||||||
return new TemplateResponse('snappymail', 'admin-local', $parameters);
|
return new TemplateResponse('snappymail', 'admin-local', $parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,232 +1,252 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace OCA\SnappyMail\Util;
|
namespace OCA\SnappyMail\Util;
|
||||||
|
|
||||||
class SnappyMailResponse extends \OCP\AppFramework\Http\Response
|
use OCP\Server;
|
||||||
{
|
use OCP\IUserSession;
|
||||||
public function render(): string
|
use OCP\IConfig;
|
||||||
{
|
use OCP\IURLGenerator;
|
||||||
$data = '';
|
use OCP\App\IAppManager;
|
||||||
$i = \ob_get_level();
|
use OCP\ISession;
|
||||||
while ($i--) {
|
use OCP\IGroupManager;
|
||||||
$data .= \ob_get_clean();
|
|
||||||
}
|
class SnappyMailResponse extends \OCP\AppFramework\Http\Response
|
||||||
return $data;
|
{
|
||||||
}
|
public function render(): string
|
||||||
}
|
{
|
||||||
|
$data = '';
|
||||||
class SnappyMailHelper
|
$i = \ob_get_level();
|
||||||
{
|
while ($i--) {
|
||||||
|
$data .= \ob_get_clean();
|
||||||
public static function loadApp() : void
|
}
|
||||||
{
|
return $data;
|
||||||
if (\class_exists('RainLoop\\Api')) {
|
}
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
class SnappyMailHelper
|
||||||
// Nextcloud the default spl_autoload_register() not working
|
{
|
||||||
\spl_autoload_register(function($sClassName){
|
|
||||||
$file = SNAPPYMAIL_LIBRARIES_PATH . \strtolower(\strtr($sClassName, '\\', DIRECTORY_SEPARATOR)) . '.php';
|
public static function loadApp() : void
|
||||||
if (\is_file($file)) {
|
{
|
||||||
include_once $file;
|
if (\class_exists('RainLoop\\Api')) {
|
||||||
}
|
return;
|
||||||
});
|
}
|
||||||
|
|
||||||
$_ENV['SNAPPYMAIL_INCLUDE_AS_API'] = true;
|
// Nextcloud the default spl_autoload_register() not working
|
||||||
|
\spl_autoload_register(function($sClassName){
|
||||||
// define('APP_VERSION', '0.0.0');
|
$file = SNAPPYMAIL_LIBRARIES_PATH . \strtolower(\strtr($sClassName, '\\', DIRECTORY_SEPARATOR)) . '.php';
|
||||||
// define('APP_INDEX_ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
|
if (\is_file($file)) {
|
||||||
// include APP_INDEX_ROOT_PATH.'snappymail/v/'.APP_VERSION.'/include.php';
|
include_once $file;
|
||||||
// define('APP_DATA_FOLDER_PATH', \rtrim(\trim(\OC::$server->getSystemConfig()->getValue('datadirectory', '')), '\\/').'/appdata_snappymail/');
|
}
|
||||||
|
});
|
||||||
$app_dir = \dirname(\dirname(__DIR__)) . '/app';
|
|
||||||
require_once $app_dir . '/index.php';
|
$_ENV['SNAPPYMAIL_INCLUDE_AS_API'] = true;
|
||||||
}
|
|
||||||
|
// define('APP_VERSION', '0.0.0');
|
||||||
public static function startApp(bool $handle = false)
|
// define('APP_INDEX_ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
|
||||||
{
|
// include APP_INDEX_ROOT_PATH.'snappymail/v/'.APP_VERSION.'/include.php';
|
||||||
static::loadApp();
|
// define('APP_DATA_FOLDER_PATH', \rtrim(\trim(\OC::$server->getSystemConfig()->getValue('datadirectory', '')), '\\/').'/appdata_snappymail/');
|
||||||
|
|
||||||
$oConfig = \RainLoop\Api::Config();
|
$app_dir = \dirname(\dirname(__DIR__)) . '/app';
|
||||||
|
require_once $app_dir . '/index.php';
|
||||||
if (false !== \stripos(\php_sapi_name(), 'cli')) {
|
}
|
||||||
return;
|
|
||||||
}
|
public static function startApp(bool $handle = false)
|
||||||
|
{
|
||||||
try {
|
static::loadApp();
|
||||||
$oActions = \RainLoop\Api::Actions();
|
|
||||||
if (isset($_GET[$oConfig->Get('security', 'admin_panel_key', 'admin')])) {
|
$oConfig = \RainLoop\Api::Config();
|
||||||
if ($oConfig->Get('security', 'allow_admin_panel', true)
|
|
||||||
&& \OC_User::isAdminUser(\OC::$server->getUserSession()->getUser()->getUID())
|
if (false !== \stripos(\php_sapi_name(), 'cli')) {
|
||||||
&& !$oActions->IsAdminLoggined(false)
|
return;
|
||||||
) {
|
}
|
||||||
$sRand = \MailSo\Base\Utils::Sha1Rand();
|
|
||||||
if ($oActions->Cacher(null, true)->Set(\RainLoop\KeyPathHelper::SessionAdminKey($sRand), \time())) {
|
try {
|
||||||
$sToken = \RainLoop\Utils::EncodeKeyValuesQ(array('token', $sRand));
|
$oActions = \RainLoop\Api::Actions();
|
||||||
// $oActions->setAdminAuthToken($sToken);
|
if (isset($_GET[$oConfig->Get('security', 'admin_panel_key', 'admin')])) {
|
||||||
\SnappyMail\Cookies::set('smadmin', $sToken);
|
$user = Server::get(IUserSession::class)->getUser();
|
||||||
}
|
if ($oConfig->Get('security', 'allow_admin_panel', true)
|
||||||
}
|
&& $user
|
||||||
} else {
|
&& Server::get(IGroupManager::class)->isAdmin($user->getUID())
|
||||||
$doLogin = !$oActions->getMainAccountFromToken(false);
|
&& !$oActions->IsAdminLoggined(false)
|
||||||
$aCredentials = static::getLoginCredentials();
|
) {
|
||||||
/*
|
$sRand = \MailSo\Base\Utils::Sha1Rand();
|
||||||
// NC25+ workaround for Impersonate plugin
|
if ($oActions->Cacher(null, true)->Set(\RainLoop\KeyPathHelper::SessionAdminKey($sRand), \time())) {
|
||||||
// https://github.com/the-djmaze/snappymail/issues/561#issuecomment-1301317723
|
$sToken = \RainLoop\Utils::EncodeKeyValuesQ(array('token', $sRand));
|
||||||
// https://github.com/nextcloud/server/issues/34935#issuecomment-1302145157
|
// $oActions->setAdminAuthToken($sToken);
|
||||||
require \OC::$SERVERROOT . '/version.php';
|
\SnappyMail\Cookies::set('smadmin', $sToken);
|
||||||
// \OC\SystemConfig
|
}
|
||||||
// file_get_contents(\OC::$SERVERROOT . 'config/config.php');
|
}
|
||||||
// $CONFIG['version']
|
} else {
|
||||||
if (24 < $OC_Version[0]) {
|
$doLogin = !$oActions->getMainAccountFromToken(false);
|
||||||
$ocSession = \OC::$server->getSession();
|
$aCredentials = static::getLoginCredentials();
|
||||||
$ocSession->reopen();
|
/*
|
||||||
if (!$doLogin && $ocSession['snappymail-uid'] && $ocSession['snappymail-uid'] != $aCredentials[0]) {
|
// NC25+ workaround for Impersonate plugin
|
||||||
// UID changed, Impersonate plugin probably active
|
// https://github.com/the-djmaze/snappymail/issues/561#issuecomment-1301317723
|
||||||
$oActions->Logout(true);
|
// https://github.com/nextcloud/server/issues/34935#issuecomment-1302145157
|
||||||
$doLogin = true;
|
require \OC::$SERVERROOT . '/version.php';
|
||||||
}
|
// \OC\SystemConfig
|
||||||
$ocSession->set('snappymail-uid', $aCredentials[0]);
|
// file_get_contents(\OC::$SERVERROOT . 'config/config.php');
|
||||||
}
|
// $CONFIG['version']
|
||||||
*/
|
if (24 < $OC_Version[0]) {
|
||||||
if ($doLogin && $aCredentials[1] && $aCredentials[2]) {
|
$ocSession = Server::get(ISession::class);
|
||||||
$isOIDC = \str_starts_with($aCredentials[2], 'oidc_login|');
|
$ocSession->reopen();
|
||||||
try {
|
if (!$doLogin && $ocSession['snappymail-uid'] && $ocSession['snappymail-uid'] != $aCredentials[0]) {
|
||||||
$ocSession = \OC::$server->getSession();
|
// UID changed, Impersonate plugin probably active
|
||||||
$oAccount = $oActions->LoginProcess($aCredentials[1], $aCredentials[2]);
|
$oActions->Logout(true);
|
||||||
if (!$isOIDC && $oAccount
|
$doLogin = true;
|
||||||
&& $oConfig->Get('login', 'sign_me_auto', \RainLoop\Enumerations\SignMeType::DefaultOff) === \RainLoop\Enumerations\SignMeType::DefaultOn
|
}
|
||||||
) {
|
$ocSession->set('snappymail-uid', $aCredentials[0]);
|
||||||
$oActions->SetSignMeToken($oAccount);
|
}
|
||||||
}
|
*/
|
||||||
} catch (\Throwable $e) {
|
if ($doLogin && $aCredentials[1] && $aCredentials[2]) {
|
||||||
// Login failure, reset password to prevent more attempts
|
$isOIDC = \str_starts_with($aCredentials[2], 'oidc_login|');
|
||||||
if (!$isOIDC) {
|
try {
|
||||||
$sUID = \OC::$server->getUserSession()->getUser()->getUID();
|
$ocSession = Server::get(ISession::class);
|
||||||
\OC::$server->getSession()['snappymail-passphrase'] = '';
|
$oAccount = $oActions->LoginProcess($aCredentials[1], $aCredentials[2]);
|
||||||
\OC::$server->getConfig()->setUserValue($sUID, 'snappymail', 'passphrase', '');
|
if (!$isOIDC && $oAccount
|
||||||
\SnappyMail\Log::error('Nextcloud', $e->getMessage());
|
&& $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 ($handle) {
|
if (!$isOIDC) {
|
||||||
\header_remove('Content-Security-Policy');
|
$user = Server::get(IUserSession::class)->getUser();
|
||||||
\RainLoop\Service::Handle();
|
$sUID = $user ? $user->getUID() : null;
|
||||||
// https://github.com/the-djmaze/snappymail/issues/1069
|
if ($sUID) {
|
||||||
exit;
|
$session = Server::get(ISession::class);
|
||||||
// return new SnappyMailResponse();
|
$session['snappymail-passphrase'] = '';
|
||||||
}
|
Server::get(IConfig::class)->setUserValue($sUID, 'snappymail', 'passphrase', '');
|
||||||
} catch (\Throwable $e) {
|
\SnappyMail\Log::error('Nextcloud', $e->getMessage());
|
||||||
// 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
|
if ($handle) {
|
||||||
{
|
\header_remove('Content-Security-Policy');
|
||||||
$config = \OC::$server->getConfig();
|
\RainLoop\Service::Handle();
|
||||||
if ($config->getAppValue('snappymail', 'snappymail-autologin-oidc', false)) {
|
// https://github.com/the-djmaze/snappymail/issues/1069
|
||||||
// Check if the OIDC Login app is enabled
|
exit;
|
||||||
if (\OC::$server->getAppManager()->isEnabledForUser('oidc_login')) {
|
// return new SnappyMailResponse();
|
||||||
// Check if session is an OIDC Login
|
}
|
||||||
$ocSession = \OC::$server->getSession();
|
} catch (\Throwable $e) {
|
||||||
if ($ocSession->get('is_oidc')) {
|
// Ignore login failure
|
||||||
// IToken->getPassword() ???
|
}
|
||||||
if ($ocSession->get('oidc_access_token')) {
|
}
|
||||||
return true;
|
|
||||||
}
|
// Check if OpenID Connect (OIDC) is enabled and used for login
|
||||||
\SnappyMail\Log::debug('Nextcloud', 'OIDC access_token missing');
|
// https://apps.nextcloud.com/apps/oidc_login
|
||||||
} else {
|
public static function isOIDCLogin() : bool
|
||||||
\SnappyMail\Log::debug('Nextcloud', 'No OIDC login');
|
{
|
||||||
}
|
$config = Server::get(IConfig::class);
|
||||||
} else {
|
if ($config->getAppValue('snappymail', 'snappymail-autologin-oidc', false)) {
|
||||||
\SnappyMail\Log::debug('Nextcloud', 'OIDC login disabled');
|
// Check if the OIDC Login app is enabled
|
||||||
}
|
if (Server::get(IAppManager::class)->isEnabledForUser('oidc_login')) {
|
||||||
}
|
// Check if session is an OIDC Login
|
||||||
return false;
|
$ocSession = Server::get(ISession::class);
|
||||||
}
|
if ($ocSession->get('is_oidc')) {
|
||||||
|
// IToken->getPassword() ???
|
||||||
private static function getLoginCredentials() : array
|
if ($ocSession->get('oidc_access_token')) {
|
||||||
{
|
return true;
|
||||||
$sUID = \OC::$server->getUserSession()->getUser()->getUID();
|
}
|
||||||
$config = \OC::$server->getConfig();
|
\SnappyMail\Log::debug('Nextcloud', 'OIDC access_token missing');
|
||||||
$ocSession = \OC::$server->getSession();
|
} else {
|
||||||
|
\SnappyMail\Log::debug('Nextcloud', 'No OIDC login');
|
||||||
// If the user has set credentials for SnappyMail in their personal settings,
|
}
|
||||||
// this has the first priority.
|
} else {
|
||||||
$sEmail = $config->getUserValue($sUID, 'snappymail', 'snappymail-email');
|
\SnappyMail\Log::debug('Nextcloud', 'OIDC login disabled');
|
||||||
$sPassword = $config->getUserValue($sUID, 'snappymail', 'passphrase')
|
}
|
||||||
?: $config->getUserValue($sUID, 'snappymail', 'snappymail-password');
|
}
|
||||||
if ($sEmail && $sPassword) {
|
return false;
|
||||||
$sPassword = static::decodePassword($sPassword, \md5($sEmail));
|
}
|
||||||
if ($sPassword) {
|
|
||||||
return [$sUID, $sEmail, $sPassword];
|
private static function getLoginCredentials() : array
|
||||||
} else {
|
{
|
||||||
\SnappyMail\Log::debug('Nextcloud', 'decodePassword failed for getUserValue');
|
$user = Server::get(IUserSession::class)->getUser();
|
||||||
}
|
$sUID = $user ? $user->getUID() : '';
|
||||||
}
|
$config = Server::get(IConfig::class);
|
||||||
|
$ocSession = Server::get(ISession::class);
|
||||||
// If the current user ID is identical to login ID (not valid when using account switching),
|
|
||||||
// this has the second priority.
|
if (!$sUID) {
|
||||||
if ($ocSession['snappymail-nc-uid'] == $sUID) {
|
return ['', '', ''];
|
||||||
|
}
|
||||||
// If OpenID Connect (OIDC) is enabled and used for login, use this.
|
|
||||||
if (static::isOIDCLogin()) {
|
// If the user has set credentials for SnappyMail in their personal settings,
|
||||||
$sEmail = $config->getUserValue($sUID, 'settings', 'email');
|
// this has the first priority.
|
||||||
return [$sUID, $sEmail, "oidc_login|{$sUID}"];
|
$sEmail = $config->getUserValue($sUID, 'snappymail', 'snappymail-email');
|
||||||
}
|
$sPassword = $config->getUserValue($sUID, 'snappymail', 'passphrase')
|
||||||
|
?: $config->getUserValue($sUID, 'snappymail', 'snappymail-password');
|
||||||
// Only use the user's password in the current session if they have
|
if ($sEmail && $sPassword) {
|
||||||
// enabled auto-login using Nextcloud username or email address.
|
$sPassword = static::decodePassword($sPassword, \md5($sEmail));
|
||||||
$sEmail = '';
|
if ($sPassword) {
|
||||||
$sPassword = '';
|
return [$sUID, $sEmail, $sPassword];
|
||||||
if ($config->getAppValue('snappymail', 'snappymail-autologin', false)) {
|
} else {
|
||||||
$sEmail = $sUID;
|
\SnappyMail\Log::debug('Nextcloud', 'decodePassword failed for getUserValue');
|
||||||
$sPassword = $ocSession['snappymail-passphrase'];
|
}
|
||||||
} else if ($config->getAppValue('snappymail', 'snappymail-autologin-with-email', false)) {
|
}
|
||||||
$sEmail = $config->getUserValue($sUID, 'settings', 'email');
|
|
||||||
$sPassword = $ocSession['snappymail-passphrase'];
|
// If the current user ID is identical to login ID (not valid when using account switching),
|
||||||
} else {
|
// this has the second priority.
|
||||||
\SnappyMail\Log::debug('Nextcloud', 'snappymail-autologin is off');
|
// Note: $ocSession array access is supported but deprecated? ISession implements ArrayAccess.
|
||||||
}
|
if ($ocSession['snappymail-nc-uid'] == $sUID) {
|
||||||
if ($sPassword) {
|
|
||||||
return [$sUID, $sEmail, static::decodePassword($sPassword, $sUID)];
|
// If OpenID Connect (OIDC) is enabled and used for login, use this.
|
||||||
}
|
if (static::isOIDCLogin()) {
|
||||||
} else {
|
$sEmail = $config->getUserValue($sUID, 'settings', 'email');
|
||||||
\SnappyMail\Log::debug('Nextcloud', "snappymail-nc-uid mismatch '{$ocSession['snappymail-nc-uid']}' != '{$sUID}'");
|
return [$sUID, $sEmail, "oidc_login|{$sUID}"];
|
||||||
}
|
}
|
||||||
|
|
||||||
return [$sUID, '', ''];
|
// Only use the user's password in the current session if they have
|
||||||
}
|
// enabled auto-login using Nextcloud username or email address.
|
||||||
|
$sEmail = '';
|
||||||
public static function getAppUrl() : string
|
$sPassword = '';
|
||||||
{
|
if ($config->getAppValue('snappymail', 'snappymail-autologin', false)) {
|
||||||
return \OC::$server->getURLGenerator()->linkToRoute('snappymail.page.appGet');
|
$sEmail = $sUID;
|
||||||
}
|
$sPassword = $ocSession['snappymail-passphrase'];
|
||||||
|
} else if ($config->getAppValue('snappymail', 'snappymail-autologin-with-email', false)) {
|
||||||
public static function normalizeUrl(string $sUrl) : string
|
$sEmail = $config->getUserValue($sUID, 'settings', 'email');
|
||||||
{
|
$sPassword = $ocSession['snappymail-passphrase'];
|
||||||
$sUrl = \rtrim(\trim($sUrl), '/\\');
|
} else {
|
||||||
if ('.php' !== \strtolower(\substr($sUrl, -4))) {
|
\SnappyMail\Log::debug('Nextcloud', 'snappymail-autologin is off');
|
||||||
$sUrl .= '/';
|
}
|
||||||
}
|
if ($sPassword) {
|
||||||
|
return [$sUID, $sEmail, static::decodePassword($sPassword, $sUID)];
|
||||||
return $sUrl;
|
}
|
||||||
}
|
} else {
|
||||||
|
\SnappyMail\Log::debug('Nextcloud', "snappymail-nc-uid mismatch '{$ocSession['snappymail-nc-uid']}' != '{$sUID}'");
|
||||||
public static function encodePassword(string $sPassword, string $sSalt) : string
|
}
|
||||||
{
|
|
||||||
static::loadApp();
|
return [$sUID, '', ''];
|
||||||
return \SnappyMail\Crypt::EncryptUrlSafe($sPassword, $sSalt);
|
}
|
||||||
}
|
|
||||||
|
public static function getAppUrl() : string
|
||||||
public static function decodePassword(string $sPassword, string $sSalt) : ?\SnappyMail\SensitiveString
|
{
|
||||||
{
|
return Server::get(IURLGenerator::class)->linkToRoute('snappymail.page.appGet');
|
||||||
static::loadApp();
|
}
|
||||||
$result = \SnappyMail\Crypt::DecryptUrlSafe($sPassword, $sSalt);
|
|
||||||
return $result ? new \SnappyMail\SensitiveString($result) : null;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
<?php script('snappymail', 'snappymail'); ?>
|
||||||
<div class="section">
|
<div class="section">
|
||||||
<form class="snappymail" action="admin.php" method="post">
|
<form class="snappymail" action="admin.php" method="post">
|
||||||
<input type="hidden" name="requesttoken" value="<?php echo $_['requesttoken'] ?>" id="requesttoken">
|
<input type="hidden" name="requesttoken" value="<?php echo $_['requesttoken'] ?>" id="requesttoken">
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
<iframe id="rliframe" style="border: none; width: 100%; min-height: 100%; position: relative;" tabindex="-1" frameborder="0" src="<?php echo $_['snappymail-iframe-url']; ?>"></iframe>
|
|
||||||
<?php
|
<?php
|
||||||
// OCP\Util::addScript('snappymail', 'resize');
|
script('snappymail', 'snappymail');
|
||||||
|
style('snappymail', 'style');
|
||||||
|
?>
|
||||||
|
<iframe id="rliframe" style="border: none; width: 100%; min-height: 100%; position: relative;" tabindex="-1" frameborder="0" src="<?php echo $_['snappymail-iframe-url']; ?>"></iframe>
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
<?php style('snappymail', 'embed'); ?>
|
||||||
|
<link type="text/css" rel="stylesheet" href="<?php echo $_['CssLink']; ?>" />
|
||||||
<style id="app-boot-css"><?php echo $_['BaseAppBootCss']; ?></style>
|
<style id="app-boot-css"><?php echo $_['BaseAppBootCss']; ?></style>
|
||||||
<style id="app-theme-style"><?php echo $_['BaseAppThemeCss']; ?></style>
|
<style id="app-theme-style"><?php echo $_['BaseAppThemeCss']; ?></style>
|
||||||
<div id="rl-app" data-admin="<?php echo $_['Admin']; ?>" spellcheck="false">
|
<div id="rl-app" data-admin="<?php echo $_['Admin']; ?>" spellcheck="false">
|
||||||
|
|
|
||||||
|
|
@ -65,8 +65,8 @@ use Predis\Command\Redis\Container\Search\FTCURSOR;
|
||||||
* @method $this randomkey()
|
* @method $this randomkey()
|
||||||
* @method $this rename($key, $target)
|
* @method $this rename($key, $target)
|
||||||
* @method $this renamenx($key, $target)
|
* @method $this renamenx($key, $target)
|
||||||
* @method $this scan($cursor, ?array $options = null)
|
* @method $this scan($cursor, array $options = null)
|
||||||
* @method $this sort($key, ?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 sort_ro(string $key, ?string $byPattern = null, ?LimitOffsetCount $limit = null, array $getPatterns = [], ?string $sorting = null, bool $alpha = false)
|
||||||
* @method $this ttl($key)
|
* @method $this ttl($key)
|
||||||
* @method $this type($key)
|
* @method $this type($key)
|
||||||
|
|
@ -163,7 +163,7 @@ use Predis\Command\Redis\Container\Search\FTCURSOR;
|
||||||
* @method $this hmget($key, array $fields)
|
* @method $this hmget($key, array $fields)
|
||||||
* @method $this hmset($key, array $dictionary)
|
* @method $this hmset($key, array $dictionary)
|
||||||
* @method $this hrandfield(string $key, int $count = 1, bool $withValues = false)
|
* @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 hset($key, $field, $value)
|
||||||
* @method $this hsetnx($key, $field, $value)
|
* @method $this hsetnx($key, $field, $value)
|
||||||
* @method $this hvals($key)
|
* @method $this hvals($key)
|
||||||
|
|
@ -225,7 +225,7 @@ use Predis\Command\Redis\Container\Search\FTCURSOR;
|
||||||
* @method $this spop($key, $count = null)
|
* @method $this spop($key, $count = null)
|
||||||
* @method $this srandmember($key, $count = null)
|
* @method $this srandmember($key, $count = null)
|
||||||
* @method $this srem($key, $member)
|
* @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 sunion(array|string $keys)
|
||||||
* @method $this sunionstore($destination, array|string $keys)
|
* @method $this sunionstore($destination, array|string $keys)
|
||||||
* @method $this tdigestadd(string $key, float ...$value)
|
* @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 tsdecrby(string $key, float $value, ?DecrByArguments $arguments = null)
|
||||||
* @method $this tsdel(string $key, int $fromTimestamp, int $toTimestamp)
|
* @method $this tsdel(string $key, int $fromTimestamp, int $toTimestamp)
|
||||||
* @method $this tsdeleterule(string $sourceKey, string $destKey)
|
* @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 tsincrby(string $key, float $value, ?IncrByArguments $arguments = null)
|
||||||
* @method $this tsinfo(string $key, ?InfoArguments $arguments = null)
|
* @method $this tsinfo(string $key, ?InfoArguments $arguments = null)
|
||||||
* @method $this tsmadd(mixed ...$keyTimestampValue)
|
* @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 zmpop(array $keys, string $modifier = 'min', int $count = 1)
|
||||||
* @method $this zmscore(string $key, string ...$member)
|
* @method $this zmscore(string $key, string ...$member)
|
||||||
* @method $this zrandmember(string $key, int $count = 1, bool $withScores = false)
|
* @method $this zrandmember(string $key, int $count = 1, bool $withScores = false)
|
||||||
* @method $this zrange($key, $start, $stop, ?array $options = null)
|
* @method $this zrange($key, $start, $stop, array $options = null)
|
||||||
* @method $this zrangebyscore($key, $min, $max, ?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 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 zrank($key, $member)
|
||||||
* @method $this zrem($key, $member)
|
* @method $this zrem($key, $member)
|
||||||
* @method $this zremrangebyrank($key, $start, $stop)
|
* @method $this zremrangebyrank($key, $start, $stop)
|
||||||
* @method $this zremrangebyscore($key, $min, $max)
|
* @method $this zremrangebyscore($key, $min, $max)
|
||||||
* @method $this zrevrange($key, $start, $stop, ?array $options = null)
|
* @method $this zrevrange($key, $start, $stop, array $options = null)
|
||||||
* @method $this zrevrangebyscore($key, $max, $min, ?array $options = null)
|
* @method $this zrevrangebyscore($key, $max, $min, array $options = null)
|
||||||
* @method $this zrevrank($key, $member)
|
* @method $this zrevrank($key, $member)
|
||||||
* @method $this zunion(array $keys, int[] $weights = [], string $aggregate = 'sum', bool $withScores = false)
|
* @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 zunionstore(string $destination, array $keys, int[] $weights = [], string $aggregate = 'sum')
|
||||||
* @method $this zscore($key, $member)
|
* @method $this zscore($key, $member)
|
||||||
* @method $this zscan($key, $cursor, ?array $options = null)
|
* @method $this zscan($key, $cursor, array $options = null)
|
||||||
* @method $this zrangebylex($key, $start, $stop, ?array $options = null)
|
* @method $this zrangebylex($key, $start, $stop, array $options = null)
|
||||||
* @method $this zrevrangebylex($key, $start, $stop, ?array $options = null)
|
* @method $this zrevrangebylex($key, $start, $stop, array $options = null)
|
||||||
* @method $this zremrangebylex($key, $min, $max)
|
* @method $this zremrangebylex($key, $min, $max)
|
||||||
* @method $this zlexcount($key, $min, $max)
|
* @method $this zlexcount($key, $min, $max)
|
||||||
* @method $this pexpiretime(string $key)
|
* @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($script, $numkeys, $keyOrArg1 = null, $keyOrArgN = null)
|
||||||
* @method $this evalsha_ro(string $sha1, array $keys, ...$argument)
|
* @method $this evalsha_ro(string $sha1, array $keys, ...$argument)
|
||||||
* @method $this script($subcommand, $argument = null)
|
* @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 auth($password)
|
||||||
* @method $this echo($message)
|
* @method $this echo($message)
|
||||||
* @method $this ping($message = null)
|
* @method $this ping($message = null)
|
||||||
|
|
@ -335,8 +335,8 @@ use Predis\Command\Redis\Container\Search\FTCURSOR;
|
||||||
* @method $this geohash($key, array $members)
|
* @method $this geohash($key, array $members)
|
||||||
* @method $this geopos($key, array $members)
|
* @method $this geopos($key, array $members)
|
||||||
* @method $this geodist($key, $member1, $member2, $unit = null)
|
* @method $this geodist($key, $member1, $member2, $unit = null)
|
||||||
* @method $this georadius($key, $longitude, $latitude, $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 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 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)
|
* @method $this geosearchstore(string $destination, string $source, FromInterface $from, ByInterface $by, ?string $sorting = null, int $count = -1, bool $any = false, bool $storeDist = false)
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -74,8 +74,8 @@ use Predis\Response\Status;
|
||||||
* @method string|null randomkey()
|
* @method string|null randomkey()
|
||||||
* @method mixed rename(string $key, string $target)
|
* @method mixed rename(string $key, string $target)
|
||||||
* @method int renamenx(string $key, string $target)
|
* @method int renamenx(string $key, string $target)
|
||||||
* @method array scan($cursor, ?array $options = null)
|
* @method array scan($cursor, array $options = null)
|
||||||
* @method array sort(string $key, ?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 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 int ttl(string $key)
|
||||||
* @method mixed type(string $key)
|
* @method mixed type(string $key)
|
||||||
|
|
@ -172,7 +172,7 @@ use Predis\Response\Status;
|
||||||
* @method array hmget(string $key, array $fields)
|
* @method array hmget(string $key, array $fields)
|
||||||
* @method mixed hmset(string $key, array $dictionary)
|
* @method mixed hmset(string $key, array $dictionary)
|
||||||
* @method array hrandfield(string $key, int $count = 1, bool $withValues = false)
|
* @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 hset(string $key, string $field, string $value)
|
||||||
* @method int hsetnx(string $key, string $field, string $value)
|
* @method int hsetnx(string $key, string $field, string $value)
|
||||||
* @method array hvals(string $key)
|
* @method array hvals(string $key)
|
||||||
|
|
@ -231,10 +231,10 @@ use Predis\Response\Status;
|
||||||
* @method string[] smembers(string $key)
|
* @method string[] smembers(string $key)
|
||||||
* @method array smismember(string $key, string ...$members)
|
* @method array smismember(string $key, string ...$members)
|
||||||
* @method int smove(string $source, string $destination, string $member)
|
* @method int smove(string $source, string $destination, string $member)
|
||||||
* @method string|array|null spop(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 string|null srandmember(string $key, int $count = null)
|
||||||
* @method int srem(string $key, array|string $member)
|
* @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 string[] sunion(array|string $keys)
|
||||||
* @method int sunionstore(string $destination, array|string $keys)
|
* @method int sunionstore(string $destination, array|string $keys)
|
||||||
* @method int touch(string[]|string $keyOrKeys, string ...$keys = null)
|
* @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 tsdecrby(string $key, float $value, ?DecrByArguments $arguments = null)
|
||||||
* @method int tsdel(string $key, int $fromTimestamp, int $toTimestamp)
|
* @method int tsdel(string $key, int $fromTimestamp, int $toTimestamp)
|
||||||
* @method Status tsdeleterule(string $sourceKey, string $destKey)
|
* @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 int tsincrby(string $key, float $value, ?IncrByArguments $arguments = null)
|
||||||
* @method array tsinfo(string $key, ?InfoArguments $arguments = null)
|
* @method array tsinfo(string $key, ?InfoArguments $arguments = null)
|
||||||
* @method array tsmadd(mixed ...$keyTimestampValue)
|
* @method array tsmadd(mixed ...$keyTimestampValue)
|
||||||
|
|
@ -275,12 +275,12 @@ use Predis\Response\Status;
|
||||||
* @method array tsqueryindex(string ...$filterExpression)
|
* @method array tsqueryindex(string ...$filterExpression)
|
||||||
* @method array tsrange(string $key, $fromTimestamp, $toTimestamp, ?RangeArguments $arguments = null)
|
* @method array tsrange(string $key, $fromTimestamp, $toTimestamp, ?RangeArguments $arguments = null)
|
||||||
* @method array tsrevrange(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 xdel(string $key, string ...$id)
|
||||||
* @method int xlen(string $key)
|
* @method int xlen(string $key)
|
||||||
* @method array xrevrange(string $key, string $end, string $start, ?int $count = null)
|
* @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 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 zadd(string $key, array $membersAndScoresDictionary)
|
||||||
* @method int zcard(string $key)
|
* @method int zcard(string $key)
|
||||||
* @method string zcount(string $key, int|string $min, int|string $max)
|
* @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 zpopmin(string $key, int $count = 1)
|
||||||
* @method array zpopmax(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 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 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 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 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|null zrank(string $key, string $member)
|
||||||
* @method int zrem(string $key, string ...$member)
|
* @method int zrem(string $key, string ...$member)
|
||||||
* @method int zremrangebyrank(string $key, int|string $start, int|string $stop)
|
* @method int zremrangebyrank(string $key, int|string $start, int|string $stop)
|
||||||
* @method int zremrangebyscore(string $key, int|string $min, int|string $max)
|
* @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 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 zrevrangebyscore(string $key, int|string $max, int|string $min, array $options = null)
|
||||||
* @method int|null zrevrank(string $key, string $member)
|
* @method int|null zrevrank(string $key, string $member)
|
||||||
* @method array zunion(array $keys, int[] $weights = [], string $aggregate = 'sum', bool $withScores = false)
|
* @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 int zunionstore(string $destination, array $keys, int[] $weights = [], string $aggregate = 'sum')
|
||||||
* @method string|null zscore(string $key, string $member)
|
* @method string|null zscore(string $key, string $member)
|
||||||
* @method array zscan(string $key, int $cursor, ?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 zrangebylex(string $key, string $start, string $stop, array $options = null)
|
||||||
* @method array zrevrangebylex(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 zremrangebylex(string $key, string $min, string $max)
|
||||||
* @method int zlexcount(string $key, string $min, string $max)
|
* @method int zlexcount(string $key, string $min, string $max)
|
||||||
* @method int pexpiretime(string $key)
|
* @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(string $script, int $numkeys, string ...$keyOrArg = null)
|
||||||
* @method mixed evalsha_ro(string $sha1, array $keys, ...$argument)
|
* @method mixed evalsha_ro(string $sha1, array $keys, ...$argument)
|
||||||
* @method mixed script($subcommand, $argument = null)
|
* @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 mixed auth(string $password)
|
||||||
* @method string echo(string $message)
|
* @method string echo(string $message)
|
||||||
* @method mixed ping(?string $message = null)
|
* @method mixed ping(string $message = null)
|
||||||
* @method mixed select(int $database)
|
* @method mixed select(int $database)
|
||||||
* @method mixed bgrewriteaof()
|
* @method mixed bgrewriteaof()
|
||||||
* @method mixed bgsave()
|
* @method mixed bgsave()
|
||||||
|
|
@ -353,8 +353,8 @@ use Predis\Response\Status;
|
||||||
* @method array geohash(string $key, array $members)
|
* @method array geohash(string $key, array $members)
|
||||||
* @method array geopos(string $key, array $members)
|
* @method array geopos(string $key, array $members)
|
||||||
* @method string|null geodist(string $key, $member1, $member2, $unit = null)
|
* @method string|null geodist(string $key, $member1, $member2, $unit = null)
|
||||||
* @method array georadius(string $key, $longitude, $latitude, $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 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 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)
|
* @method int geosearchstore(string $destination, string $source, FromInterface $from, ByInterface $by, ?string $sorting = null, int $count = -1, bool $any = false, bool $storeDist = false)
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ class PredisStrategy extends ClusterStrategy
|
||||||
/**
|
/**
|
||||||
* @param DistributorInterface $distributor Optional distributor instance.
|
* @param DistributorInterface $distributor Optional distributor instance.
|
||||||
*/
|
*/
|
||||||
public function __construct(?DistributorInterface $distributor = null)
|
public function __construct(DistributorInterface $distributor = null)
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ class RedisStrategy extends ClusterStrategy
|
||||||
/**
|
/**
|
||||||
* @param HashGeneratorInterface $hashGenerator Hash generator instance.
|
* @param HashGeneratorInterface $hashGenerator Hash generator instance.
|
||||||
*/
|
*/
|
||||||
public function __construct(?HashGeneratorInterface $hashGenerator = null)
|
public function __construct(HashGeneratorInterface $hashGenerator = null)
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,9 +19,9 @@ use Predis\Response\Status;
|
||||||
* @method string dump()
|
* @method string dump()
|
||||||
* @method Status flush(?string $mode = null)
|
* @method Status flush(?string $mode = null)
|
||||||
* @method Status kill()
|
* @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 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()
|
* @method array stats()
|
||||||
*/
|
*/
|
||||||
class FunctionContainer extends AbstractContainer
|
class FunctionContainer extends AbstractContainer
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ class SubcommandStrategyResolver implements StrategyResolverInterface
|
||||||
*/
|
*/
|
||||||
private $separator;
|
private $separator;
|
||||||
|
|
||||||
public function __construct(?string $separator = null)
|
public function __construct(string $separator = null)
|
||||||
{
|
{
|
||||||
$this->separator = $separator;
|
$this->separator = $separator;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ abstract class CommunicationException extends PredisException
|
||||||
NodeConnectionInterface $connection,
|
NodeConnectionInterface $connection,
|
||||||
$message = '',
|
$message = '',
|
||||||
$code = 0,
|
$code = 0,
|
||||||
?Exception $innerException = null
|
Exception $innerException = null
|
||||||
) {
|
) {
|
||||||
parent::__construct(
|
parent::__construct(
|
||||||
is_null($message) ? '' : $message,
|
is_null($message) ? '' : $message,
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ class Options implements OptionsInterface
|
||||||
/**
|
/**
|
||||||
* @param array $options Named array of client options
|
* @param array $options Named array of client options
|
||||||
*/
|
*/
|
||||||
public function __construct(?array $options = null)
|
public function __construct(array $options = null)
|
||||||
{
|
{
|
||||||
$this->input = $options ?? [];
|
$this->input = $options ?? [];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ class PredisCluster implements ClusterInterface, IteratorAggregate, Countable
|
||||||
/**
|
/**
|
||||||
* @param StrategyInterface $strategy Optional cluster strategy.
|
* @param StrategyInterface $strategy Optional cluster strategy.
|
||||||
*/
|
*/
|
||||||
public function __construct(?StrategyInterface $strategy = null)
|
public function __construct(StrategyInterface $strategy = null)
|
||||||
{
|
{
|
||||||
$this->strategy = $strategy ?: new PredisStrategy();
|
$this->strategy = $strategy ?: new PredisStrategy();
|
||||||
$this->distributor = $this->strategy->getDistributor();
|
$this->distributor = $this->strategy->getDistributor();
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ class RedisCluster implements ClusterInterface, IteratorAggregate, Countable
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
FactoryInterface $connections,
|
FactoryInterface $connections,
|
||||||
?StrategyInterface $strategy = null
|
StrategyInterface $strategy = null
|
||||||
) {
|
) {
|
||||||
$this->connections = $connections;
|
$this->connections = $connections;
|
||||||
$this->strategy = $strategy ?: new RedisClusterStrategy();
|
$this->strategy = $strategy ?: new RedisClusterStrategy();
|
||||||
|
|
@ -273,7 +273,7 @@ class RedisCluster implements ClusterInterface, IteratorAggregate, Countable
|
||||||
*
|
*
|
||||||
* @param NodeConnectionInterface $connection Optional connection instance.
|
* @param NodeConnectionInterface $connection Optional connection instance.
|
||||||
*/
|
*/
|
||||||
public function askSlotMap(?NodeConnectionInterface $connection = null)
|
public function askSlotMap(NodeConnectionInterface $connection = null)
|
||||||
{
|
{
|
||||||
if (!$connection && !$connection = $this->getRandomConnection()) {
|
if (!$connection && !$connection = $this->getRandomConnection()) {
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ class CompositeStreamConnection extends StreamConnection implements CompositeCon
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
ParametersInterface $parameters,
|
ParametersInterface $parameters,
|
||||||
?ProtocolProcessorInterface $protocol = null
|
ProtocolProcessorInterface $protocol = null
|
||||||
) {
|
) {
|
||||||
$this->parameters = $this->assertParameters($parameters);
|
$this->parameters = $this->assertParameters($parameters);
|
||||||
$this->protocol = $protocol ?: new TextProtocolProcessor();
|
$this->protocol = $protocol ?: new TextProtocolProcessor();
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ trait RelayMethods
|
||||||
* @param string $pattern
|
* @param string $pattern
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function onInvalidated(?callable $callback, ?string $pattern = null)
|
public function onInvalidated(?callable $callback, string $pattern = null)
|
||||||
{
|
{
|
||||||
return $this->client->onInvalidated($callback, $pattern);
|
return $this->client->onInvalidated($callback, $pattern);
|
||||||
}
|
}
|
||||||
|
|
@ -129,7 +129,7 @@ trait RelayMethods
|
||||||
* @param ?int $db
|
* @param ?int $db
|
||||||
* @return bool
|
* @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);
|
return $this->client->flushMemory($endpointId, $db);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ class MasterSlaveReplication implements ReplicationInterface
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function __construct(?ReplicationStrategy $strategy = null)
|
public function __construct(ReplicationStrategy $strategy = null)
|
||||||
{
|
{
|
||||||
$this->strategy = $strategy ?: new ReplicationStrategy();
|
$this->strategy = $strategy ?: new ReplicationStrategy();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -123,7 +123,7 @@ class SentinelReplication implements ReplicationInterface
|
||||||
$service,
|
$service,
|
||||||
array $sentinels,
|
array $sentinels,
|
||||||
ConnectionFactoryInterface $connectionFactory,
|
ConnectionFactoryInterface $connectionFactory,
|
||||||
?ReplicationStrategy $strategy = null
|
ReplicationStrategy $strategy = null
|
||||||
) {
|
) {
|
||||||
$this->sentinels = $sentinels;
|
$this->sentinels = $sentinels;
|
||||||
$this->service = $service;
|
$this->service = $service;
|
||||||
|
|
|
||||||
|
|
@ -41,8 +41,8 @@ class CompositeProtocolProcessor implements ProtocolProcessorInterface
|
||||||
* @param ResponseReaderInterface $reader Response reader.
|
* @param ResponseReaderInterface $reader Response reader.
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
?RequestSerializerInterface $serializer = null,
|
RequestSerializerInterface $serializer = null,
|
||||||
?ResponseReaderInterface $reader = null
|
ResponseReaderInterface $reader = null
|
||||||
) {
|
) {
|
||||||
$this->setRequestSerializer($serializer ?: new RequestSerializer());
|
$this->setRequestSerializer($serializer ?: new RequestSerializer());
|
||||||
$this->setResponseReader($reader ?: new ResponseReader());
|
$this->setResponseReader($reader ?: new ResponseReader());
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue