mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-07-13 03:27:39 +03:00
Redesign Nextcloud integration with better security and SSO #96
This commit is contained in:
parent
a6d5f6ad91
commit
32059330dd
7 changed files with 162 additions and 662 deletions
|
|
@ -1,107 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
class OwnCloudSuggestions implements \RainLoop\Providers\Suggestions\ISuggestions
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @var \MailSo\Log\Logger
|
|
||||||
*/
|
|
||||||
protected $oLogger;
|
|
||||||
|
|
||||||
public function Process(\RainLoop\Model\Account $oAccount, string $sQuery, int $iLimit = 20): array
|
|
||||||
{
|
|
||||||
$iInputLimit = $iLimit;
|
|
||||||
$aResult = array();
|
|
||||||
$sQuery = \trim($sQuery);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if ('' === $sQuery || !$oAccount || !OwnCloudPlugin::IsOwnCloudLoggedIn())
|
|
||||||
{
|
|
||||||
return $aResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
$aParams = array('FN', 'NICKNAME', 'TITLE', 'EMAIL');
|
|
||||||
if (\class_exists('OC') && isset(\OC::$server) && \method_exists(\OC::$server, 'getContactsManager'))
|
|
||||||
{
|
|
||||||
$cm = \OC::$server->getContactsManager();
|
|
||||||
if (!$cm && !$cm->isEnabled())
|
|
||||||
{
|
|
||||||
return $aResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
$aSearchResult = $cm->search($sQuery, $aParams);
|
|
||||||
}
|
|
||||||
else if (\class_exists('OCP\Contacts') && \OCP\Contacts::isEnabled())
|
|
||||||
{
|
|
||||||
$aSearchResult = \OCP\Contacts::search($sQuery, $aParams);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return $aResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
//$this->oLogger->WriteDump($aSearchResult);
|
|
||||||
|
|
||||||
$aHashes = array();
|
|
||||||
if (\is_array($aSearchResult) && 0 < \count($aSearchResult))
|
|
||||||
{
|
|
||||||
foreach ($aSearchResult as $aContact)
|
|
||||||
{
|
|
||||||
if (0 >= $iLimit)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$sUid = empty($aContact['UID']) ? '' : $aContact['UID'];
|
|
||||||
if (!empty($sUid))
|
|
||||||
{
|
|
||||||
$mEmails = isset($aContact['EMAIL']) ? $aContact['EMAIL'] : '';
|
|
||||||
|
|
||||||
$sFullName = isset($aContact['FN']) ? \trim($aContact['FN']) : '';
|
|
||||||
if (empty($sFullName))
|
|
||||||
{
|
|
||||||
$sFullName = isset($aContact['NICKNAME']) ? \trim($aContact['NICKNAME']) : '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!\is_array($mEmails))
|
|
||||||
{
|
|
||||||
$mEmails = array($mEmails);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($mEmails as $sEmail)
|
|
||||||
{
|
|
||||||
$sHash = '"'.$sFullName.'" <'.$sEmail.'>';
|
|
||||||
if (!isset($aHashes[$sHash]))
|
|
||||||
{
|
|
||||||
$aHashes[$sHash] = true;
|
|
||||||
$aResult[] = array($sEmail, $sFullName);
|
|
||||||
$iLimit--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$aResult = \array_slice($aResult, 0, $iInputLimit);
|
|
||||||
}
|
|
||||||
|
|
||||||
unset($aSearchResult, $aHashes);
|
|
||||||
}
|
|
||||||
catch (\Throwable $oException)
|
|
||||||
{
|
|
||||||
if ($this->oLogger)
|
|
||||||
{
|
|
||||||
$this->oLogger->WriteException($oException);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $aResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param \MailSo\Log\Logger $oLogger
|
|
||||||
*/
|
|
||||||
public function SetLogger($oLogger)
|
|
||||||
{
|
|
||||||
$this->oLogger = $oLogger instanceof \MailSo\Log\Logger ? $oLogger : null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,180 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
class NextCloudPlugin extends \RainLoop\Plugins\AbstractPlugin
|
|
||||||
{
|
|
||||||
const
|
|
||||||
NAME = 'NextCloud',
|
|
||||||
VERSION = '2.0',
|
|
||||||
CATEGORY = 'Integrations',
|
|
||||||
DESCRIPTION = 'Plugin that adds functionality to integrate with NextCloud.';
|
|
||||||
|
|
||||||
private static function IsNextCloud() : bool
|
|
||||||
{
|
|
||||||
return !empty($_ENV['SNAPPYMAIL_NEXTCLOUD']) && \class_exists('OC');
|
|
||||||
}
|
|
||||||
|
|
||||||
private static function IsNextCloudLoggedIn() : bool
|
|
||||||
{
|
|
||||||
return static::IsNextCloud() && \class_exists('OCP\User') && \OCP\User::isLoggedIn();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function Init() : void
|
|
||||||
{
|
|
||||||
if (static::IsNextCloud()) {
|
|
||||||
$this->addHook('main.fabrica', 'MainFabrica');
|
|
||||||
$this->addHook('filter.app-data', 'FilterAppData');
|
|
||||||
$this->addHook('json.attachments', 'DoAttachmentsActions');
|
|
||||||
|
|
||||||
$sAppPath = '';
|
|
||||||
if (\class_exists('OC_App')) {
|
|
||||||
$sAppPath = \rtrim(\trim(\OC_App::getAppWebPath('snappymail')), '\\/').'/app/';
|
|
||||||
}
|
|
||||||
if (!$sAppPath) {
|
|
||||||
$sUrl = \MailSo\Base\Http::SingletonInstance()->GetUrl();
|
|
||||||
if ($sUrl && \preg_match('/\/index\.php\/apps\/snappymail/', $sUrl)) {
|
|
||||||
$sAppPath = \preg_replace('/\/index\.php\/apps\/snappymail.+$/',
|
|
||||||
'/apps/snappymail/app/', $sUrl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$_SERVER['SCRIPT_NAME'] = $sAppPath;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function Supported() : string
|
|
||||||
{
|
|
||||||
if (!static::IsNextCloud()) {
|
|
||||||
return 'NextCloud not found to use this plugin';
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
// DoAttachmentsActions
|
|
||||||
public function DoAttachmentsActions(\SnappyMail\AttachmentsAction $data)
|
|
||||||
{
|
|
||||||
if ('nextcloud' === $data->action) {
|
|
||||||
if (static::IsNextCloudLoggedIn() && \class_exists('OCP\Files')) {
|
|
||||||
$oFiles = \OCP\Files::getStorage('files');
|
|
||||||
if ($oFiles && $data->filesProvider->IsActive() && \method_exists($oFiles, 'file_put_contents')) {
|
|
||||||
$sSaveFolder = $this->Config()->Get('plugin', 'save_folder', '') ?: 'Attachments';
|
|
||||||
$oFiles->is_dir($sSaveFolder) || $oFiles->mkdir($sSaveFolder);
|
|
||||||
$data->result = true;
|
|
||||||
foreach ($data->items as $aItem) {
|
|
||||||
$sSavedFileName = isset($aItem['FileName']) ? $aItem['FileName'] : 'file.dat';
|
|
||||||
$sSavedFileHash = !empty($aItem['FileHash']) ? $aItem['FileHash'] : '';
|
|
||||||
if (!empty($sSavedFileHash)) {
|
|
||||||
$fFile = $data->filesProvider->GetFile($data->account, $sSavedFileHash, 'rb');
|
|
||||||
if (\is_resource($fFile)) {
|
|
||||||
$sSavedFileNameFull = \MailSo\Base\Utils::SmartFileExists($sSaveFolder.'/'.$sSavedFileName, function ($sPath) use ($oFiles) {
|
|
||||||
return $oFiles->file_exists($sPath);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!$oFiles->file_put_contents($sSavedFileNameFull, $fFile)) {
|
|
||||||
$data->result = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (\is_resource($fFile)) {
|
|
||||||
\fclose($fFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($data->items as $aItem) {
|
|
||||||
$sFileHash = (string) (isset($aItem['FileHash']) ? $aItem['FileHash'] : '');
|
|
||||||
if (!empty($sFileHash)) {
|
|
||||||
$data->filesProvider->Clear($data->account, $sFileHash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO: create pre-login auth hook
|
|
||||||
*/
|
|
||||||
public function ServiceNextCloudAuth()
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
$this->oHttp->ServerNoCache();
|
|
||||||
|
|
||||||
if (!static::IsNextCloud() ||
|
|
||||||
!isset($_ENV['___snappymail_nextcloud_email']) ||
|
|
||||||
!isset($_ENV['___snappymail_nextcloud_password']) ||
|
|
||||||
empty($_ENV['___snappymail_nextcloud_email'])
|
|
||||||
)
|
|
||||||
{
|
|
||||||
$this->oActions->SetAuthLogoutToken();
|
|
||||||
$this->oActions->Location('./');
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
$bLogout = true;
|
|
||||||
|
|
||||||
$sEmail = $_ENV['___snappymail_nextcloud_email'];
|
|
||||||
$sPassword = $_ENV['___snappymail_nextcloud_password'];
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
$oAccount = $this->oActions->LoginProcess($sEmail, $sPassword);
|
|
||||||
$this->oActions->AuthToken($oAccount);
|
|
||||||
|
|
||||||
$bLogout = !($oAccount instanceof \snappymail\Model\Account);
|
|
||||||
}
|
|
||||||
catch (\Exception $oException)
|
|
||||||
{
|
|
||||||
$this->oActions->Logger()->WriteException($oException);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($bLogout)
|
|
||||||
{
|
|
||||||
$this->oActions->SetAuthLogoutToken();
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->oActions->Location('./');
|
|
||||||
return '';
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function FilterAppData($bAdmin, &$aResult)
|
|
||||||
{
|
|
||||||
if (!$bAdmin && \is_array($aResult) && static::IsNextCloud()) {
|
|
||||||
$key = \array_search(\RainLoop\Enumerations\Capa::AUTOLOGOUT, $aResult['Capa']);
|
|
||||||
if (false !== $key) {
|
|
||||||
unset($aResult['Capa'][$key]);
|
|
||||||
}
|
|
||||||
if (static::IsNextCloudLoggedIn() && \class_exists('OCP\Files')) {
|
|
||||||
$aResult['System']['attachmentsActions'][] = 'nextcloud';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $sName
|
|
||||||
* @param mixed $mResult
|
|
||||||
*/
|
|
||||||
public function MainFabrica($sName, &$mResult)
|
|
||||||
{
|
|
||||||
if ('suggestions' === $sName && static::IsNextCloud() && $this->Config()->Get('plugin', 'suggestions', true)) {
|
|
||||||
include_once __DIR__.'/NextCloudSuggestions.php';
|
|
||||||
if (!\is_array($mResult)) {
|
|
||||||
$mResult = array();
|
|
||||||
}
|
|
||||||
$mResult[] = new NextCloudSuggestions();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function configMapping() : array
|
|
||||||
{
|
|
||||||
return array(
|
|
||||||
\RainLoop\Plugins\Property::NewInstance('save_folder')->SetLabel('Save Folder')
|
|
||||||
->SetDefaultValue('Attachments'),
|
|
||||||
\RainLoop\Plugins\Property::NewInstance('suggestions')->SetLabel('Suggestions')
|
|
||||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::BOOL)
|
|
||||||
->SetDefaultValue(true)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -16,8 +16,8 @@ class Application extends App {
|
||||||
parent::__construct('snappymail', $urlParams);
|
parent::__construct('snappymail', $urlParams);
|
||||||
|
|
||||||
$container = $this->getContainer();
|
$container = $this->getContainer();
|
||||||
$server = $container->getServer();
|
// $server = $container->getServer();
|
||||||
$config = $server->getConfig();
|
// $config = $server->getConfig();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controllers
|
* Controllers
|
||||||
|
|
@ -26,10 +26,7 @@ class Application extends App {
|
||||||
'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->getServer()->getAppManager(),
|
|
||||||
$c->query('ServerContainer')->getConfig(),
|
|
||||||
$c->getServer()->getSession()
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
@ -51,12 +48,7 @@ class Application extends App {
|
||||||
*/
|
*/
|
||||||
$container->registerService(
|
$container->registerService(
|
||||||
'SnappyMailHelper', function($c) {
|
'SnappyMailHelper', function($c) {
|
||||||
return new SnappyMailHelper(
|
return new SnappyMailHelper();
|
||||||
$c->getServer()->getConfig(),
|
|
||||||
$c->getServer()->getUserSession(),
|
|
||||||
$c->getServer()->getAppManager(),
|
|
||||||
$c->getServer()->getSession()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -67,10 +67,10 @@ class AjaxController extends Controller {
|
||||||
|
|
||||||
$sPass = $_POST['snappymail-password'];
|
$sPass = $_POST['snappymail-password'];
|
||||||
if ('******' !== $sPass && '' !== $sPass) {
|
if ('******' !== $sPass && '' !== $sPass) {
|
||||||
include_once $this->appManager->getAppPath('snappymail').'/lib/Util/SnappyMailHelper.php';
|
require_once $this->appManager->getAppPath('snappymail').'/lib/Util/SnappyMailHelper.php';
|
||||||
|
|
||||||
$this->config->setUserValue($sUser, 'snappymail', 'snappymail-password',
|
$this->config->setUserValue($sUser, 'snappymail', 'snappymail-password',
|
||||||
SnappyMailHelper::encodePassword($sPass, md5($sPostEmail)));
|
SnappyMailHelper::encodePassword($sPass, \md5($sPostEmail)));
|
||||||
}
|
}
|
||||||
|
|
||||||
$sEmail = $this->config->getUserValue($sUser, 'snappymail', 'snappymail-email', '');
|
$sEmail = $this->config->getUserValue($sUser, 'snappymail', 'snappymail-email', '');
|
||||||
|
|
|
||||||
|
|
@ -4,42 +4,26 @@ namespace OCA\SnappyMail\Controller;
|
||||||
|
|
||||||
use OCA\SnappyMail\Util\SnappyMailHelper;
|
use OCA\SnappyMail\Util\SnappyMailHelper;
|
||||||
|
|
||||||
use OCP\App\IAppManager;
|
|
||||||
use OCP\AppFramework\Controller;
|
use OCP\AppFramework\Controller;
|
||||||
use OCP\AppFramework\Http\ContentSecurityPolicy;
|
use OCP\AppFramework\Http\ContentSecurityPolicy;
|
||||||
use OCP\AppFramework\Http\TemplateResponse;
|
use OCP\AppFramework\Http\TemplateResponse;
|
||||||
use OCP\IConfig;
|
|
||||||
use OCP\IRequest;
|
|
||||||
use OCP\ISession;
|
|
||||||
|
|
||||||
class PageController extends Controller {
|
|
||||||
private $userId;
|
|
||||||
private $config;
|
|
||||||
private $appManager;
|
|
||||||
private $appPath;
|
|
||||||
private $session;
|
|
||||||
|
|
||||||
public function __construct($AppName, IRequest $request, IAppManager $appManager, IConfig $config, ISession $session) {
|
|
||||||
parent::__construct($AppName, $request);
|
|
||||||
$this->appPath = $appManager->getAppPath('snappymail');
|
|
||||||
$this->config = $config;
|
|
||||||
$this->appManager = $appManager;
|
|
||||||
$this->session = $session;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
class PageController extends Controller
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* @NoAdminRequired
|
* @NoAdminRequired
|
||||||
* @NoCSRFRequired
|
* @NoCSRFRequired
|
||||||
*/
|
*/
|
||||||
public function index() {
|
public function index()
|
||||||
|
{
|
||||||
\OC::$server->getNavigationManager()->setActiveEntry('snappymail');
|
\OC::$server->getNavigationManager()->setActiveEntry('snappymail');
|
||||||
|
|
||||||
\OCP\Util::addStyle('snappymail', 'style');
|
\OCP\Util::addStyle('snappymail', 'style');
|
||||||
|
|
||||||
$sUrl = SnappyMailHelper::normalizeUrl(SnappyMailHelper::getAppUrl());
|
$session = \OC::$server->getSession();
|
||||||
|
|
||||||
$params = [
|
$params = [
|
||||||
'snappymail-iframe-url' => SnappyMailHelper::normalizeUrl($sUrl).'?OwnCloudAuth'
|
'snappymail-iframe-url' => SnappyMailHelper::normalizeUrl(SnappyMailHelper::getAppUrl())
|
||||||
|
. (empty($session['snappymail-sso-hash']) ? '' : '?sso&hash=' . $session['snappymail-sso-hash'])
|
||||||
];
|
];
|
||||||
|
|
||||||
$response = new TemplateResponse('snappymail', 'index', $params);
|
$response = new TemplateResponse('snappymail', 'index', $params);
|
||||||
|
|
@ -55,56 +39,18 @@ class PageController extends Controller {
|
||||||
* @NoAdminRequired
|
* @NoAdminRequired
|
||||||
* @NoCSRFRequired
|
* @NoCSRFRequired
|
||||||
*/
|
*/
|
||||||
public function appGet() {
|
public function appGet()
|
||||||
$this->app();
|
{
|
||||||
|
SnappyMailHelper::startApp();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @NoAdminRequired
|
* @NoAdminRequired
|
||||||
* @NoCSRFRequired
|
* @NoCSRFRequired
|
||||||
*/
|
*/
|
||||||
public function appPost() {
|
public function appPost()
|
||||||
$this->app();
|
{
|
||||||
|
SnappyMailHelper::startApp();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function app() {
|
|
||||||
|
|
||||||
SnappyMailHelper::regSnappyMailDataFunction();
|
|
||||||
|
|
||||||
if (isset($_GET['OwnCloudAuth'])) {
|
|
||||||
$sEmail = '';
|
|
||||||
$sEncodedPassword = '';
|
|
||||||
|
|
||||||
$sUser = \OC::$server->getUserSession()->getUser()->getUID();
|
|
||||||
|
|
||||||
if ($this->config->getAppValue('snappymail', 'snappymail-autologin', false)) {
|
|
||||||
$sEmail = $sUser;
|
|
||||||
$sPasswordSalt = $sUser;
|
|
||||||
$sEncodedPassword = $this->session['snappymail-autologin-password'];
|
|
||||||
} else if ($this->config->getAppValue('snappymail', 'snappymail-autologin-with-email', false)) {
|
|
||||||
$sEmail = $this->config->getUserValue($sUser, 'settings', 'email', '');
|
|
||||||
$sPasswordSalt = $sUser;
|
|
||||||
$sEncodedPassword = $this->session['snappymail-autologin-password'];
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the user has set credentials for SnappyMail in their personal
|
|
||||||
// settings, override everything before and use those instead.
|
|
||||||
$sIndividualEmail = $this->config->getUserValue($sUser, 'snappymail', 'snappymail-email', '');
|
|
||||||
if ($sIndividualEmail) {
|
|
||||||
$sEmail = $sIndividualEmail;
|
|
||||||
$sPasswordSalt = $sEmail;
|
|
||||||
$sEncodedPassword = $this->config->getUserValue($sUser, 'snappymail', 'snappymail-password', '');
|
|
||||||
}
|
|
||||||
|
|
||||||
$sDecodedPassword = SnappyMailHelper::decodePassword($sEncodedPassword, md5($sPasswordSalt));
|
|
||||||
|
|
||||||
$_ENV['___snappymail_owncloud_email'] = $sEmail;
|
|
||||||
$_ENV['___snappymail_owncloud_password'] = $sDecodedPassword;
|
|
||||||
}
|
|
||||||
|
|
||||||
include $this->appPath . '/app/index.php';
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,33 +2,59 @@
|
||||||
|
|
||||||
namespace OCA\SnappyMail\Util;
|
namespace OCA\SnappyMail\Util;
|
||||||
|
|
||||||
use OCP\App\IAppManager;
|
class SnappyMailHelper
|
||||||
use OCP\IConfig;
|
{
|
||||||
use OCP\ISession;
|
|
||||||
use OCP\IUserSession;
|
|
||||||
|
|
||||||
class SnappyMailHelper {
|
public function registerHooks()
|
||||||
|
{
|
||||||
|
$config = \OC::$server->getConfig();
|
||||||
|
$session = \OC::$server->getSession();
|
||||||
|
$userSession = \OC::$server->getUserSession();
|
||||||
|
$userSession->listen('\OC\User', 'postLogin', function($user, $loginName, $password, $isTokenLogin) {
|
||||||
|
$sEmail = '';
|
||||||
|
// If the user has set credentials for SnappyMail in their personal
|
||||||
|
// settings, override everything before and use those instead.
|
||||||
|
$sIndividualEmail = $config->getUserValue($user->getUID(), 'snappymail', 'snappymail-email', '');
|
||||||
|
if ($sIndividualEmail) {
|
||||||
|
$sEmail = $sIndividualEmail;
|
||||||
|
$password = SnappyMailHelper::decodePassword(
|
||||||
|
$this->config->getUserValue($sUser, 'snappymail', 'snappymail-password', ''),
|
||||||
|
\md5($sEmail)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// Only store the user's password in the current session if they have
|
||||||
|
// enabled auto-login using Nextcloud username or email address.
|
||||||
|
else if ($config->getAppValue('snappymail', 'snappymail-autologin', false)) {
|
||||||
|
$sEmail = $user->getUID();
|
||||||
|
} else if ($config->getAppValue('snappymail', 'snappymail-autologin-with-email', false)) {
|
||||||
|
$sEmail = $config->getUserValue($user->getUID(), 'settings', 'email', '');
|
||||||
|
}
|
||||||
|
if ($sEmail) {
|
||||||
|
static::startApp(true);
|
||||||
|
$session['snappymail-sso-hash'] = \RainLoop\Api::CreateUserSsoHash($sEmail, $password/*, array $aAdditionalOptions = array(), bool $bUseTimeout = true*/);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
private $appManager;
|
$userSession->listen('\OC\User', 'logout', function($user) {
|
||||||
private $config;
|
$session['snappymail-sso-hash'] = '';
|
||||||
private $session;
|
static::startApp(true);
|
||||||
private $userSession;
|
\RainLoop\Api::LogoutCurrentLogginedUser();
|
||||||
|
});
|
||||||
public function __construct(IConfig $config, IUserSession $userSession, IAppManager $appManager, ISession $session) {
|
|
||||||
$this->appManager = $appManager;
|
|
||||||
$this->config = $config;
|
|
||||||
$this->userSession = $userSession;
|
|
||||||
$this->session = $session;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function registerHooks() {
|
public static function startApp(bool $api = false)
|
||||||
$this->userSession->listen('\OC\User', 'postLogin', function($user, $loginName, $password, $isTokenLogin) {
|
{
|
||||||
$this->login($user, $loginName, $password, $isTokenLogin, $this->config, $this->session);
|
if (!\class_exists('RainLoop\\Api')) {
|
||||||
});
|
if ($api) {
|
||||||
|
$_ENV['SNAPPYMAIL_INCLUDE_AS_API'] = true;
|
||||||
$this->userSession->listen('\OC\User', 'logout', function() {
|
}
|
||||||
$this->logout($this->appManager, $this->config, $this->session);
|
$_ENV['SNAPPYMAIL_NEXTCLOUD'] = true;
|
||||||
});
|
$sData = \rtrim(\trim(\OC::$server->getSystemConfig()->getValue('datadirectory', '')), '\\/').'/';
|
||||||
|
if (\is_dir($sData)) {
|
||||||
|
\define('APP_DATA_FOLDER_PATH', $sData);
|
||||||
|
}
|
||||||
|
require_once \OC::$server->getAppManager()->getAppPath('snappymail') . '/app/index.php';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -37,44 +63,13 @@ class SnappyMailHelper {
|
||||||
public static function getAppUrl()
|
public static function getAppUrl()
|
||||||
{
|
{
|
||||||
$sRequestUri = \OC::$server->getURLGenerator()->linkToRoute('snappymail.page.appGet');
|
$sRequestUri = \OC::$server->getURLGenerator()->linkToRoute('snappymail.page.appGet');
|
||||||
if ($sRequestUri)
|
if ($sRequestUri) {
|
||||||
{
|
|
||||||
return $sRequestUri;
|
return $sRequestUri;
|
||||||
}
|
}
|
||||||
|
$sRequestUri = empty($_SERVER['REQUEST_URI']) ? '': \trim($_SERVER['REQUEST_URI']);
|
||||||
$sRequestUri = empty($_SERVER['REQUEST_URI']) ? '': trim($_SERVER['REQUEST_URI']);
|
$sRequestUri = \preg_replace('/index.php\/.+$/', 'index.php/', $sRequestUri);
|
||||||
$sRequestUri = preg_replace('/index.php\/.+$/', 'index.php/', $sRequestUri);
|
|
||||||
$sRequestUri = $sRequestUri.'apps/snappymail/app/';
|
$sRequestUri = $sRequestUri.'apps/snappymail/app/';
|
||||||
|
return '/'.\ltrim($sRequestUri, '/\\');
|
||||||
return '/'.ltrim($sRequestUri, '/\\');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $sPath
|
|
||||||
* @param string $sEmail
|
|
||||||
* @param string $sPassword
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static function getSsoHash($sPath, $sEmail, $sPassword)
|
|
||||||
{
|
|
||||||
$SsoHash = '';
|
|
||||||
|
|
||||||
$sPath = rtrim(trim($sPath), '\\/').'/index.php';
|
|
||||||
if (file_exists($sPath))
|
|
||||||
{
|
|
||||||
self::regSnappyMailDataFunction();
|
|
||||||
|
|
||||||
$_ENV['SNAPPYMAIL_INCLUDE_AS_API'] = true;
|
|
||||||
include $sPath;
|
|
||||||
|
|
||||||
if (class_exists('\\RainLoop\\Api'))
|
|
||||||
{
|
|
||||||
$SsoHash = \RainLoop\Api::GetUserSsoHash($sEmail, $sPassword);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $SsoHash;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -84,83 +79,14 @@ class SnappyMailHelper {
|
||||||
*/
|
*/
|
||||||
public static function normalizeUrl($sUrl)
|
public static function normalizeUrl($sUrl)
|
||||||
{
|
{
|
||||||
$sUrl = rtrim(trim($sUrl), '/\\');
|
$sUrl = \rtrim(\trim($sUrl), '/\\');
|
||||||
if ('.php' !== strtolower(substr($sUrl, -4)))
|
if ('.php' !== \strtolower(\substr($sUrl, -4))) {
|
||||||
{
|
|
||||||
$sUrl .= '/';
|
$sUrl .= '/';
|
||||||
}
|
}
|
||||||
|
|
||||||
return $sUrl;
|
return $sUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public static function mcryptSupported()
|
|
||||||
{
|
|
||||||
return function_exists('mcrypt_encrypt') &&
|
|
||||||
function_exists('mcrypt_decrypt') &&
|
|
||||||
defined('MCRYPT_RIJNDAEL_256') &&
|
|
||||||
defined('MCRYPT_MODE_ECB');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static function openSslSupportedMethod()
|
|
||||||
{
|
|
||||||
$method = 'AES-256-CBC';
|
|
||||||
return function_exists('openssl_encrypt') &&
|
|
||||||
function_exists('openssl_decrypt') &&
|
|
||||||
function_exists('openssl_random_pseudo_bytes') &&
|
|
||||||
function_exists('openssl_cipher_iv_length') &&
|
|
||||||
function_exists('openssl_get_cipher_methods') &&
|
|
||||||
defined('OPENSSL_RAW_DATA') && defined('OPENSSL_ZERO_PADDING') &&
|
|
||||||
in_array($method, openssl_get_cipher_methods()) ? $method : '';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $sMethod
|
|
||||||
* @param string $sPassword
|
|
||||||
* @param string $sSalt
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static function encodePasswordSsl($sMethod, $sPassword, $sSalt)
|
|
||||||
{
|
|
||||||
$sData = base64_encode($sPassword);
|
|
||||||
|
|
||||||
$iv = @openssl_random_pseudo_bytes(openssl_cipher_iv_length($sMethod));
|
|
||||||
$r = @openssl_encrypt($sData, $sMethod, md5($sSalt), OPENSSL_RAW_DATA, $iv);
|
|
||||||
|
|
||||||
return @base64_encode(base64_encode($r).'|'.base64_encode($iv));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $sMethod
|
|
||||||
* @param string $sPassword
|
|
||||||
* @param string $sSalt
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static function decodePasswordSsl($sMethod, $sPassword, $sSalt)
|
|
||||||
{
|
|
||||||
$sLine = base64_decode(trim($sPassword));
|
|
||||||
$aParts = explode('|', $sLine, 2);
|
|
||||||
|
|
||||||
if (is_array($aParts) && !empty($aParts[0]) && !empty($aParts[1])) {
|
|
||||||
|
|
||||||
$sData = @base64_decode($aParts[0]);
|
|
||||||
$iv = @base64_decode($aParts[1]);
|
|
||||||
|
|
||||||
return @base64_decode(trim(
|
|
||||||
@openssl_decrypt($sData, $sMethod, md5($sSalt), OPENSSL_RAW_DATA, $iv)
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $sPassword
|
* @param string $sPassword
|
||||||
* @param string $sSalt
|
* @param string $sSalt
|
||||||
|
|
@ -169,19 +95,8 @@ class SnappyMailHelper {
|
||||||
*/
|
*/
|
||||||
public static function encodePassword($sPassword, $sSalt)
|
public static function encodePassword($sPassword, $sSalt)
|
||||||
{
|
{
|
||||||
$method = self::openSslSupportedMethod();
|
static::startApp(true);
|
||||||
if ($method)
|
return \SnappyMail\Crypt::EncryptUrlSafe($sPassword, $sSalt);
|
||||||
{
|
|
||||||
return self::encodePasswordSsl($method, $sPassword, $sSalt);
|
|
||||||
}
|
|
||||||
else if (self::mcryptSupported())
|
|
||||||
{
|
|
||||||
return @trim(base64_encode(
|
|
||||||
@mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($sSalt), base64_encode($sPassword), MCRYPT_MODE_ECB)
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
return @trim(base64_encode($sPassword));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -192,150 +107,7 @@ class SnappyMailHelper {
|
||||||
*/
|
*/
|
||||||
public static function decodePassword($sPassword, $sSalt)
|
public static function decodePassword($sPassword, $sSalt)
|
||||||
{
|
{
|
||||||
$method = self::openSslSupportedMethod();
|
static::startApp(true);
|
||||||
if ($method)
|
return \SnappyMail\Crypt::DecryptUrlSafe($sPassword, $sSalt);
|
||||||
{
|
|
||||||
return self::decodePasswordSsl($method, $sPassword, $sSalt);
|
|
||||||
}
|
|
||||||
else if (self::mcryptSupported())
|
|
||||||
{
|
|
||||||
return @base64_decode(trim(
|
|
||||||
@mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($sSalt), base64_decode(trim($sPassword)), MCRYPT_MODE_ECB)
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
return @base64_decode(trim($sPassword));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param array $aParams
|
|
||||||
* @return boolean
|
|
||||||
* @UseSession
|
|
||||||
*/
|
|
||||||
public static function login($user, $loginName, $password, $isTokenLogin, $config, &$session)
|
|
||||||
{
|
|
||||||
$sUser = $user->getUID();
|
|
||||||
|
|
||||||
$sEmail = $sUser;
|
|
||||||
$sPassword = $password;
|
|
||||||
$sEncodedPassword = self::encodePassword($sPassword, md5($sEmail));
|
|
||||||
|
|
||||||
// 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') || $config->getAppValue('snappymail', 'snappymail-autologin-with-email')) {
|
|
||||||
$session['snappymail-autologin-password'] = $sEncodedPassword;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @UseSession
|
|
||||||
*/
|
|
||||||
public static function logout($appManager, $config, &$session)
|
|
||||||
{
|
|
||||||
$session['snappymail-autologin-password'] = '';
|
|
||||||
|
|
||||||
$sApiPath = $appManager->getAppPath('snappymail') . '/app/index.php';
|
|
||||||
|
|
||||||
self::regSnappyMailDataFunction();
|
|
||||||
|
|
||||||
$_ENV['SNAPPYMAIL_INCLUDE_AS_API'] = true;
|
|
||||||
include $sApiPath;
|
|
||||||
|
|
||||||
\RainLoop\Api::LogoutCurrentLogginedUser();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function regSnappyMailDataFunction()
|
|
||||||
{
|
|
||||||
if (!@function_exists('__get_custom_data_full_path'))
|
|
||||||
{
|
|
||||||
$_ENV['SNAPPYMAIL_NEXTCLOUD'] = true;
|
|
||||||
|
|
||||||
function __get_custom_data_full_path()
|
|
||||||
{
|
|
||||||
$sData = rtrim(trim(OC::$server->getSystemConfig()->getValue('datadirectory', '')), '\\/').'/';
|
|
||||||
return @is_dir($sData) ? $sData.'snappymail-storage' : '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function mimeContentType($filename) {
|
|
||||||
|
|
||||||
$mime_types = array(
|
|
||||||
|
|
||||||
'woff' => 'application/font-woff',
|
|
||||||
|
|
||||||
'txt' => 'text/plain',
|
|
||||||
'htm' => 'text/html',
|
|
||||||
'html' => 'text/html',
|
|
||||||
'php' => 'text/html',
|
|
||||||
'css' => 'text/css',
|
|
||||||
'js' => 'application/javascript',
|
|
||||||
'json' => 'application/json',
|
|
||||||
'xml' => 'application/xml',
|
|
||||||
'swf' => 'application/x-shockwave-flash',
|
|
||||||
'flv' => 'video/x-flv',
|
|
||||||
|
|
||||||
// images
|
|
||||||
'png' => 'image/png',
|
|
||||||
'jpe' => 'image/jpeg',
|
|
||||||
'jpeg' => 'image/jpeg',
|
|
||||||
'jpg' => 'image/jpeg',
|
|
||||||
'gif' => 'image/gif',
|
|
||||||
'bmp' => 'image/bmp',
|
|
||||||
'ico' => 'image/vnd.microsoft.icon',
|
|
||||||
'tiff' => 'image/tiff',
|
|
||||||
'tif' => 'image/tiff',
|
|
||||||
'svg' => 'image/svg+xml',
|
|
||||||
'svgz' => 'image/svg+xml',
|
|
||||||
|
|
||||||
// archives
|
|
||||||
'zip' => 'application/zip',
|
|
||||||
'rar' => 'application/x-rar-compressed',
|
|
||||||
'exe' => 'application/x-msdownload',
|
|
||||||
'msi' => 'application/x-msdownload',
|
|
||||||
'cab' => 'application/vnd.ms-cab-compressed',
|
|
||||||
|
|
||||||
// audio/video
|
|
||||||
'mp3' => 'audio/mpeg',
|
|
||||||
'qt' => 'video/quicktime',
|
|
||||||
'mov' => 'video/quicktime',
|
|
||||||
|
|
||||||
// adobe
|
|
||||||
'pdf' => 'application/pdf',
|
|
||||||
'psd' => 'image/vnd.adobe.photoshop',
|
|
||||||
'ai' => 'application/postscript',
|
|
||||||
'eps' => 'application/postscript',
|
|
||||||
'ps' => 'application/postscript',
|
|
||||||
|
|
||||||
// ms office
|
|
||||||
'doc' => 'application/msword',
|
|
||||||
'rtf' => 'application/rtf',
|
|
||||||
'xls' => 'application/vnd.ms-excel',
|
|
||||||
'ppt' => 'application/vnd.ms-powerpoint',
|
|
||||||
|
|
||||||
// open office
|
|
||||||
'odt' => 'application/vnd.oasis.opendocument.text',
|
|
||||||
'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
|
|
||||||
);
|
|
||||||
|
|
||||||
if (0 < strpos($filename, '.'))
|
|
||||||
{
|
|
||||||
$ext = strtolower(array_pop(explode('.',$filename)));
|
|
||||||
if (array_key_exists($ext, $mime_types))
|
|
||||||
{
|
|
||||||
return $mime_types[$ext];
|
|
||||||
}
|
|
||||||
else if (function_exists('finfo_open'))
|
|
||||||
{
|
|
||||||
$finfo = finfo_open(FILEINFO_MIME);
|
|
||||||
$mimetype = finfo_file($finfo, $filename);
|
|
||||||
finfo_close($finfo);
|
|
||||||
return $mimetype;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 'application/octet-stream';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,26 +4,39 @@ class NextcloudPlugin extends \RainLoop\Plugins\AbstractPlugin
|
||||||
{
|
{
|
||||||
const
|
const
|
||||||
NAME = 'Nextcloud',
|
NAME = 'Nextcloud',
|
||||||
VERSION = '1.0',
|
VERSION = '2.1',
|
||||||
RELEASE = '2022-10-10',
|
RELEASE = '2022-10-10',
|
||||||
CATEGORY = 'Integrations',
|
CATEGORY = 'Integrations',
|
||||||
DESCRIPTION = 'Integrate with Nextcloud',
|
DESCRIPTION = 'Integrate with Nextcloud v18+',
|
||||||
REQUIRED = '2.15.2';
|
REQUIRED = '2.15.2';
|
||||||
|
|
||||||
public function Init() : void
|
public function Init() : void
|
||||||
{
|
{
|
||||||
|
if (static::IsIntegrated()) {
|
||||||
$this->addHook('main.fabrica', 'MainFabrica');
|
$this->addHook('main.fabrica', 'MainFabrica');
|
||||||
|
$this->addHook('filter.app-data', 'FilterAppData');
|
||||||
|
$this->addHook('json.attachments', 'SaveAttachments');
|
||||||
|
|
||||||
|
$sAppPath = \rtrim(\trim(\OC::$server->getAppManager()->getAppWebPath()), '\\/').'/app/';
|
||||||
|
if (!$sAppPath) {
|
||||||
|
$sUrl = \MailSo\Base\Http::SingletonInstance()->GetUrl();
|
||||||
|
if (\str_contains($sUrl, '/index.php/apps/snappymail/')) {
|
||||||
|
$sAppPath = \preg_replace('/\/index\.php\/apps\/snappymail.+$/',
|
||||||
|
'/apps/snappymail/app/', $sUrl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$_SERVER['SCRIPT_NAME'] = $sAppPath;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function Supported() : string
|
public function Supported() : string
|
||||||
{
|
{
|
||||||
return static::IsIntegrated() ? '' : 'Not running inside Nextcloud';
|
return static::IsIntegrated() ? '' : 'Nextcloud not found to use this plugin';
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function IsIntegrated()
|
public static function IsIntegrated()
|
||||||
{
|
{
|
||||||
// return !empty($_ENV['RAINLOOP_OWNCLOUD']) &&
|
return !empty($_ENV['SNAPPYMAIL_NEXTCLOUD']) && \class_exists('OC') && isset(\OC::$server);
|
||||||
return \class_exists('OC') && isset(\OC::$server);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function IsLoggedIn()
|
public static function IsLoggedIn()
|
||||||
|
|
@ -31,13 +44,66 @@ class NextcloudPlugin extends \RainLoop\Plugins\AbstractPlugin
|
||||||
return static::IsIntegrated() && \OC::$server->getUserSession()->isLoggedIn();
|
return static::IsIntegrated() && \OC::$server->getUserSession()->isLoggedIn();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DoAttachmentsActions
|
||||||
|
public function SaveAttachments(\SnappyMail\AttachmentsAction $data)
|
||||||
|
{
|
||||||
|
if ('nextcloud' === $data->action) {
|
||||||
|
$oFiles = \OCP\Files::getStorage('files');
|
||||||
|
if ($oFiles && $data->filesProvider->IsActive() && \method_exists($oFiles, 'file_put_contents')) {
|
||||||
|
$sSaveFolder = $this->Config()->Get('plugin', 'save_folder', '') ?: 'Attachments';
|
||||||
|
$oFiles->is_dir($sSaveFolder) || $oFiles->mkdir($sSaveFolder);
|
||||||
|
$data->result = true;
|
||||||
|
foreach ($data->items as $aItem) {
|
||||||
|
$sSavedFileName = isset($aItem['FileName']) ? $aItem['FileName'] : 'file.dat';
|
||||||
|
$sSavedFileHash = !empty($aItem['FileHash']) ? $aItem['FileHash'] : '';
|
||||||
|
if (!empty($sSavedFileHash)) {
|
||||||
|
$fFile = $data->filesProvider->GetFile($data->account, $sSavedFileHash, 'rb');
|
||||||
|
if (\is_resource($fFile)) {
|
||||||
|
$sSavedFileNameFull = \MailSo\Base\Utils::SmartFileExists($sSaveFolder.'/'.$sSavedFileName, function ($sPath) use ($oFiles) {
|
||||||
|
return $oFiles->file_exists($sPath);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!$oFiles->file_put_contents($sSavedFileNameFull, $fFile)) {
|
||||||
|
$data->result = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (\is_resource($fFile)) {
|
||||||
|
\fclose($fFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($data->items as $aItem) {
|
||||||
|
$sFileHash = (string) (isset($aItem['FileHash']) ? $aItem['FileHash'] : '');
|
||||||
|
if (!empty($sFileHash)) {
|
||||||
|
$data->filesProvider->Clear($data->account, $sFileHash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function FilterAppData($bAdmin, &$aResult) : void
|
||||||
|
{
|
||||||
|
if (!$bAdmin && \is_array($aResult) && static::IsIntegrated()) {
|
||||||
|
$key = \array_search(\RainLoop\Enumerations\Capa::AUTOLOGOUT, $aResult['Capa']);
|
||||||
|
if (false !== $key) {
|
||||||
|
unset($aResult['Capa'][$key]);
|
||||||
|
}
|
||||||
|
if (static::IsLoggedIn() && \class_exists('OCP\Files')) {
|
||||||
|
$aResult['System']['attachmentsActions'][] = 'nextcloud';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed $mResult
|
* @param mixed $mResult
|
||||||
*/
|
*/
|
||||||
public function MainFabrica(string $sName, &$mResult)
|
public function MainFabrica(string $sName, &$mResult)
|
||||||
{
|
{
|
||||||
if (static::isLoggedIn()) {
|
if (static::isLoggedIn()) {
|
||||||
if ('suggestions' === $sName) {
|
if ('suggestions' === $sName && $this->Config()->Get('plugin', 'suggestions', true)) {
|
||||||
if (!\is_array($mResult)) {
|
if (!\is_array($mResult)) {
|
||||||
$mResult = array();
|
$mResult = array();
|
||||||
}
|
}
|
||||||
|
|
@ -46,4 +112,15 @@ class NextcloudPlugin extends \RainLoop\Plugins\AbstractPlugin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function configMapping() : array
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
\RainLoop\Plugins\Property::NewInstance('save_folder')->SetLabel('Save Folder')
|
||||||
|
->SetDefaultValue('Attachments'),
|
||||||
|
\RainLoop\Plugins\Property::NewInstance('suggestions')->SetLabel('Suggestions')
|
||||||
|
->SetType(\RainLoop\Enumerations\PluginPropertyType::BOOL)
|
||||||
|
->SetDefaultValue(true)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue