mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-07-13 03:27:39 +03:00
Many fixes
New ownCloud package with a built-in webmail
This commit is contained in:
parent
323dd34c8b
commit
6116597f6f
56 changed files with 1137 additions and 232 deletions
|
|
@ -263,7 +263,6 @@ class Http
|
|||
*/
|
||||
public function GetHeader($sHeader)
|
||||
{
|
||||
$sResultHeader = '';
|
||||
$sServerKey = 'HTTP_'.\strtoupper(\str_replace('-', '_', $sHeader));
|
||||
$sResultHeader = $this->GetServer($sServerKey, '');
|
||||
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ class SubStreams
|
|||
\stream_wrapper_register(self::STREAM_NAME, '\MailSo\Base\StreamWrappers\SubStreams');
|
||||
}
|
||||
|
||||
$sHashName = \md5(\microtime(true).\rand(1000, 9999));
|
||||
$sHashName = \MailSo\Base\Utils::Md5Rand();
|
||||
|
||||
self::$aStreams[$sHashName] = $aSubStreams;
|
||||
|
||||
|
|
@ -84,7 +84,7 @@ class SubStreams
|
|||
{
|
||||
return $this->aSubStreams[$this->iIndex];
|
||||
}
|
||||
|
||||
|
||||
return $nNull;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2147,6 +2147,28 @@ class Utils
|
|||
return \is_string($mResult) && 0 < \strlen($mResult) ? $mResult : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sAdditionalSalt = ''
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function Md5Rand($sAdditionalSalt = '')
|
||||
{
|
||||
return \md5(\microtime(true).\rand(10000, 99999).
|
||||
\md5($sAdditionalSalt).\rand(10000, 99999).\microtime(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sAdditionalSalt = ''
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function Sha1Rand($sAdditionalSalt = '')
|
||||
{
|
||||
return \sha1(\microtime(true).\rand(10000, 99999).
|
||||
\sha1($sAdditionalSalt).\rand(10000, 99999).\microtime(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sData
|
||||
* @param string $sKey
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ class Logger extends \MailSo\Base\Collection
|
|||
static $sCache = null;
|
||||
if (null === $sCache)
|
||||
{
|
||||
$sCache = \substr(\md5(\microtime(true).\rand(10000, 99999)), -8);
|
||||
$sCache = \substr(\MailSo\Base\Utils::Md5Rand(), -8);
|
||||
}
|
||||
|
||||
return $sCache;
|
||||
|
|
|
|||
|
|
@ -990,7 +990,7 @@ class MailClient
|
|||
{
|
||||
do
|
||||
{
|
||||
$sKey = \md5(\rand(10000, 90000).\microtime(true));
|
||||
$sKey = \MailSo\Base\Utils::Md5Rand();
|
||||
}
|
||||
while (isset($aCache[$sKey]));
|
||||
|
||||
|
|
@ -1006,7 +1006,7 @@ class MailClient
|
|||
{
|
||||
do
|
||||
{
|
||||
$sKey = \md5(\rand(10000, 90000).\microtime(true));
|
||||
$sKey = \MailSo\Base\Utils::Md5Rand();
|
||||
}
|
||||
while (isset($aCache[$sKey]));
|
||||
|
||||
|
|
|
|||
|
|
@ -535,8 +535,9 @@ class Message
|
|||
$sHostName = 'localhost';
|
||||
}
|
||||
|
||||
return '<'.\md5(\rand(100000, 999999).\time().$sHostName.
|
||||
(\MailSo\Base\Utils::FunctionExistsAndEnabled('getmypid') ? @\getmypid() : '')).'@'.$sHostName.'>';
|
||||
return '<'.
|
||||
\MailSo\Base\Utils::Md5Rand($sHostName.
|
||||
(\MailSo\Base\Utils::FunctionExistsAndEnabled('getmypid') ? @\getmypid() : '')).'@'.$sHostName.'>';
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1511,7 +1511,7 @@ class Actions
|
|||
$aResult['UseLocalProxyForExternalImages'] = (bool) $oConfig->Get('labs', 'use_local_proxy_for_external_images', false);
|
||||
|
||||
// user
|
||||
$aResult['ShowImages'] = (bool) $oConfig->Get('webmail', 'show_images', false);
|
||||
$aResult['ShowImages'] = (bool) $oConfig->Get('defaults', 'show_images', false);
|
||||
$aResult['MPP'] = (int) $oConfig->Get('webmail', 'messages_per_page', 25);
|
||||
$aResult['SoundNotification'] = false;
|
||||
$aResult['DesktopNotifications'] = false;
|
||||
|
|
@ -1982,7 +1982,7 @@ class Actions
|
|||
*/
|
||||
private function generateSignMeToken($sEmail)
|
||||
{
|
||||
return \md5(\microtime(true).APP_SALT.\rand(10000, 99999).$sEmail);
|
||||
return \MailSo\Base\Utils::Md5Rand(APP_SALT.$sEmail);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2122,6 +2122,85 @@ class Actions
|
|||
return $aAccounts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account $oAccount
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetTemplates($oAccount)
|
||||
{
|
||||
$aTemplates = array();
|
||||
if ($oAccount)
|
||||
{
|
||||
$aData = array();
|
||||
|
||||
$sData = $this->StorageProvider(true)->Get($oAccount,
|
||||
\RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG,
|
||||
'templates'
|
||||
);
|
||||
|
||||
if ('' !== $sData && '[' === \substr($sData, 0, 1))
|
||||
{
|
||||
$aData = @\json_decode($sData, true);
|
||||
}
|
||||
|
||||
if (\is_array($aData) && 0 < \count($aData))
|
||||
{
|
||||
foreach ($aData as $aItem)
|
||||
{
|
||||
$oItem = \RainLoop\Model\Template::NewInstance();
|
||||
$oItem->FromJSON($aItem);
|
||||
|
||||
if ($oItem && $oItem->Validate())
|
||||
{
|
||||
\array_push($aTemplates, $oItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (1 < \count($aTemplates))
|
||||
{
|
||||
$sOrder = $this->StorageProvider()->Get($oAccount,
|
||||
\RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG,
|
||||
'templates_order'
|
||||
);
|
||||
|
||||
$aOrder = empty($sOrder) ? array() : @\json_decode($sOrder, true);
|
||||
if (\is_array($aOrder) && 1 < \count($aOrder))
|
||||
{
|
||||
\usort($aTemplates, function ($a, $b) use ($aOrder) {
|
||||
return \array_search($a->Id(), $aOrder) < \array_search($b->Id(), $aOrder) ? -1 : 1;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $aTemplates;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account $oAccount
|
||||
* @param string $sID
|
||||
*
|
||||
* @return \RainLoop\Model\Identity
|
||||
*/
|
||||
public function GetTemplateByID($oAccount, $sID)
|
||||
{
|
||||
$aTemplates = $this->GetTemplates($oAccount);
|
||||
if (\is_array($aTemplates))
|
||||
{
|
||||
foreach ($aTemplates as $oIdentity)
|
||||
{
|
||||
if ($oIdentity && $sID === $oIdentity->Id())
|
||||
{
|
||||
return $oIdentity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return isset($aTemplates[0]) ? $aTemplates[0] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account $oAccount
|
||||
*
|
||||
|
|
@ -2279,6 +2358,27 @@ class Actions
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account $oAccount
|
||||
* @param array $aTemplates = array()
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function SetTemplates($oAccount, $aTemplates = array())
|
||||
{
|
||||
$aResult = array();
|
||||
foreach ($aTemplates as $oItem)
|
||||
{
|
||||
$aResult[] = $oItem->ToSimpleJSON(false);
|
||||
}
|
||||
|
||||
return $this->StorageProvider(true)->Put($oAccount,
|
||||
\RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG,
|
||||
'templates',
|
||||
@\json_encode($aResult)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*
|
||||
|
|
@ -2497,6 +2597,117 @@ class Actions
|
|||
return $this->DefaultResponse(__FUNCTION__, $this->SetIdentities($oAccount, $aNew));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*
|
||||
* @throws \MailSo\Base\Exceptions\Exception
|
||||
*/
|
||||
public function DoTemplateSetup()
|
||||
{
|
||||
$oAccount = $this->getAccountFromToken();
|
||||
|
||||
if (!$this->GetCapa(false, \RainLoop\Enumerations\Capa::TEMPLATES, $oAccount))
|
||||
{
|
||||
return $this->FalseResponse(__FUNCTION__);
|
||||
}
|
||||
|
||||
$oTemplate = \RainLoop\Model\Template::NewInstance();
|
||||
if (!$oTemplate->FromJSON($this->GetActionParams(), true))
|
||||
{
|
||||
throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::InvalidInputArgument);
|
||||
}
|
||||
|
||||
if ('' === $oTemplate->Id())
|
||||
{
|
||||
$oTemplate->GenerateID();
|
||||
}
|
||||
|
||||
$aTemplatesForSave = array();
|
||||
$aTemplates = $this->GetTemplates($oAccount);
|
||||
|
||||
|
||||
foreach ($aTemplates as $oItem)
|
||||
{
|
||||
if ($oItem && $oItem->Id() !== $oTemplate->Id())
|
||||
{
|
||||
$aTemplatesForSave[] = $oItem;
|
||||
}
|
||||
}
|
||||
|
||||
$aTemplatesForSave[] = $oTemplate;
|
||||
|
||||
return $this->DefaultResponse(__FUNCTION__, $this->SetTemplates($oAccount, $aTemplatesForSave));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*
|
||||
* @throws \MailSo\Base\Exceptions\Exception
|
||||
*/
|
||||
public function DoTemplateDelete()
|
||||
{
|
||||
$oAccount = $this->getAccountFromToken();
|
||||
|
||||
if (!$this->GetCapa(false, \RainLoop\Enumerations\Capa::TEMPLATES, $oAccount))
|
||||
{
|
||||
return $this->FalseResponse(__FUNCTION__);
|
||||
}
|
||||
|
||||
$sId = \trim($this->GetActionParam('IdToDelete', ''));
|
||||
if (empty($sId))
|
||||
{
|
||||
throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::UnknownError);
|
||||
}
|
||||
|
||||
$aNew = array();
|
||||
$aTemplates = $this->GetTemplates($oAccount);
|
||||
foreach ($aTemplates as $oItem)
|
||||
{
|
||||
if ($oItem && $sId !== $oItem->Id())
|
||||
{
|
||||
$aNew[] = $oItem;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->DefaultResponse(__FUNCTION__, $this->SetTemplates($oAccount, $aNew));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*
|
||||
* @throws \MailSo\Base\Exceptions\Exception
|
||||
*/
|
||||
public function DoTemplateGetByID()
|
||||
{
|
||||
$oAccount = $this->getAccountFromToken();
|
||||
|
||||
if (!$this->GetCapa(false, \RainLoop\Enumerations\Capa::TEMPLATES, $oAccount))
|
||||
{
|
||||
return $this->FalseResponse(__FUNCTION__);
|
||||
}
|
||||
|
||||
$sId = \trim($this->GetActionParam('ID', ''));
|
||||
if (empty($sId))
|
||||
{
|
||||
throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::UnknownError);
|
||||
}
|
||||
|
||||
$oTemplate = false;
|
||||
$aTemplates = $this->GetTemplates($oAccount);
|
||||
|
||||
foreach ($aTemplates as $oItem)
|
||||
{
|
||||
if ($oItem && $sId === $oItem->Id())
|
||||
{
|
||||
$oTemplate = $oItem;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$oTemplate->SetPopulateAlways(true);
|
||||
return $this->DefaultResponse(__FUNCTION__, $oTemplate);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*
|
||||
|
|
@ -2550,6 +2761,25 @@ class Actions
|
|||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*
|
||||
* @throws \MailSo\Base\Exceptions\Exception
|
||||
*/
|
||||
public function DoTemplates()
|
||||
{
|
||||
$oAccount = $this->getAccountFromToken();
|
||||
|
||||
if (!$this->GetCapa(false, \RainLoop\Enumerations\Capa::TEMPLATES, $oAccount))
|
||||
{
|
||||
return $this->FalseResponse(__FUNCTION__);
|
||||
}
|
||||
|
||||
return $this->DefaultResponse(__FUNCTION__, array(
|
||||
'Templates' => $this->GetTemplates($oAccount)
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sHash
|
||||
*
|
||||
|
|
@ -2821,6 +3051,9 @@ class Actions
|
|||
case \RainLoop\Enumerations\Capa::ADDITIONAL_ACCOUNTS:
|
||||
$this->setConfigFromParams($oConfig, $sParamName, 'webmail', 'allow_additional_accounts', 'bool');
|
||||
break;
|
||||
case \RainLoop\Enumerations\Capa::TEMPLATES:
|
||||
$this->setConfigFromParams($oConfig, $sParamName, 'capa', 'templates', 'bool');
|
||||
break;
|
||||
case \RainLoop\Enumerations\Capa::TWO_FACTOR:
|
||||
$this->setConfigFromParams($oConfig, $sParamName, 'security', 'allow_two_factor_auth', 'bool');
|
||||
break;
|
||||
|
|
@ -2923,6 +3156,7 @@ class Actions
|
|||
});
|
||||
|
||||
$this->setCapaFromParams($oConfig, 'CapaAdditionalAccounts', \RainLoop\Enumerations\Capa::ADDITIONAL_ACCOUNTS);
|
||||
$this->setCapaFromParams($oConfig, 'CapaTemplates', \RainLoop\Enumerations\Capa::TEMPLATES);
|
||||
$this->setCapaFromParams($oConfig, 'CapaTwoFactorAuth', \RainLoop\Enumerations\Capa::TWO_FACTOR);
|
||||
$this->setCapaFromParams($oConfig, 'CapaOpenPGP', \RainLoop\Enumerations\Capa::OPEN_PGP);
|
||||
$this->setCapaFromParams($oConfig, 'CapaGravatar', \RainLoop\Enumerations\Capa::GRAVATAR);
|
||||
|
|
@ -5303,6 +5537,27 @@ class Actions
|
|||
return $oMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account $oAccount
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function deleteMessageAttachmnets($oAccount)
|
||||
{
|
||||
$aAttachments = $this->GetActionParam('Attachments', null);
|
||||
|
||||
if (\is_array($aAttachments))
|
||||
{
|
||||
foreach (\array_keys($aAttachments) as $sTempName)
|
||||
{
|
||||
if ($this->FilesProvider()->FileExists($oAccount, $sTempName))
|
||||
{
|
||||
$this->FilesProvider()->Clear($oAccount, $sTempName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account $oAccount
|
||||
*
|
||||
|
|
@ -5600,6 +5855,8 @@ class Actions
|
|||
{
|
||||
$this->smtpSendMessage($oAccount, $oMessage, $rMessageStream, $iMessageStreamSize);
|
||||
|
||||
$this->deleteMessageAttachmnets($oAccount);
|
||||
|
||||
if (is_array($aDraftInfo) && 3 === count($aDraftInfo))
|
||||
{
|
||||
$sDraftInfoType = $aDraftInfo[0];
|
||||
|
|
@ -6967,7 +7224,7 @@ class Actions
|
|||
$oSettings = $this->SettingsProvider()->Load($oAccount);
|
||||
if ($oSettings)
|
||||
{
|
||||
$sHash = \md5($sName.APP_VERSION.APP_SALT.\rand(1000, 9999).\microtime(true));
|
||||
$sHash = \MailSo\Base\Utils::Md5Rand($sName.APP_VERSION.APP_SALT);
|
||||
|
||||
$oSettings->SetConf('UserBackgroundName', $sName);
|
||||
$oSettings->SetConf('UserBackgroundHash', $sHash);
|
||||
|
|
@ -7225,7 +7482,7 @@ class Actions
|
|||
$sLast = \array_pop($aParams);
|
||||
|
||||
$sUrl = $this->Http()->GetFullUrl().'?/Raw/&s=/'.implode('/', $aParams).'/&ss=/'.$sLast;
|
||||
$sFullUrl = 'http://docs.google.com/viewer?embedded=true&url='.urlencode($sUrl);
|
||||
$sFullUrl = 'https://docs.google.com/viewer?embedded=true&url='.urlencode($sUrl);
|
||||
|
||||
@\header('Content-Type: text/html; charset=utf-8');
|
||||
echo '<html style="height: 100%; width: 100%; margin: 0; padding: 0"><head></head>'.
|
||||
|
|
@ -7272,6 +7529,8 @@ class Actions
|
|||
$rMessageStream = $this->FilesProvider()->GetFile($oAccount, $sSavedName);
|
||||
|
||||
$this->MailClient()->MessageAppendStream($rMessageStream, $iMessageStreamSize, $sFolderFullNameRaw);
|
||||
|
||||
$this->FilesProvider()->Clear($oAccount, $sSavedName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7301,6 +7560,11 @@ class Actions
|
|||
}
|
||||
}
|
||||
|
||||
// if ($oConfig->Get('capa', 'templates', true))
|
||||
// {
|
||||
// $aResult[] = \RainLoop\Enumerations\Capa::TEMPLATES;
|
||||
// }
|
||||
|
||||
if ($oConfig->Get('webmail', 'allow_additional_accounts', false))
|
||||
{
|
||||
$aResult[] = \RainLoop\Enumerations\Capa::ADDITIONAL_ACCOUNTS;
|
||||
|
|
@ -7455,7 +7719,7 @@ class Actions
|
|||
{
|
||||
\MailSo\Base\StreamWrappers\TempFile::Reg();
|
||||
|
||||
$sFileName = 'mailsotempfile://'.\md5($sFileNameOut.\rand(1000, 9999));
|
||||
$sFileName = 'mailsotempfile://'.\MailSo\Base\Utils::Md5Rand($sFileNameOut);
|
||||
|
||||
$rTempResource = \fopen($sFileName, 'r+b');
|
||||
if (@\is_resource($rTempResource))
|
||||
|
|
@ -8256,25 +8520,6 @@ class Actions
|
|||
@\header('Location: '.$sUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sTitle
|
||||
* @param string $sDesc
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function ErrorTemplates($sTitle, $sDesc, $bShowBackLink = true)
|
||||
{
|
||||
return strtr(file_get_contents(APP_VERSION_ROOT_PATH.'app/templates/Error.html'), array(
|
||||
'{{BaseWebStaticPath}}' => APP_WEB_STATIC_PATH,
|
||||
'{{ErrorTitle}}' => $sTitle,
|
||||
'{{ErrorHeader}}' => $sTitle,
|
||||
'{{ErrorDesc}}' => $sDesc,
|
||||
'{{BackLinkVisibilityStyle}}' => $bShowBackLink ? 'display:inline-block' : 'display:none',
|
||||
'{{BackLink}}' => $this->StaticI18N('STATIC/BACK_LINK'),
|
||||
'{{BackHref}}' => './'
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param object $oData
|
||||
* @param string $sParent
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ class Api
|
|||
*/
|
||||
public static function GetUserSsoHash($sEmail, $sPassword, $bUseTimeout = true)
|
||||
{
|
||||
$sSsoHash = \sha1(\rand(10000, 99999).$sEmail.$sPassword.\microtime(true));
|
||||
$sSsoHash = \MailSo\Base\Utils::Sha1Rand($sEmail.$sPassword);
|
||||
|
||||
return \RainLoop\Api::Actions()->Cacher()->Set(\RainLoop\KeyPathHelper::SsoCacherKey($sSsoHash), \RainLoop\Utils::EncodeKeyValues(array(
|
||||
'Email' => $sEmail,
|
||||
|
|
|
|||
|
|
@ -129,7 +129,8 @@ class Application extends \RainLoop\Config\AbstractConfig
|
|||
),
|
||||
|
||||
'capa' => array(
|
||||
'filters' => array(true)
|
||||
'filters' => array(true),
|
||||
'templates' => array(true)
|
||||
),
|
||||
|
||||
'login' => array(
|
||||
|
|
@ -164,6 +165,7 @@ Values:
|
|||
'view_editor_type' => array('Html', 'Editor mode used by default (Plain, Html, HtmlForced or PlainForced)'),
|
||||
'view_layout' => array(1, 'layout: 0 - no preview, 1 - side preview, 3 - bottom preview'),
|
||||
'view_use_checkboxes' => array(true),
|
||||
'show_images' => array(false),
|
||||
'contacts_autosave' => array(true),
|
||||
'mail_use_threads' => array(false),
|
||||
'mail_reply_same_folder' => array(false)
|
||||
|
|
|
|||
|
|
@ -15,4 +15,5 @@ class Capa
|
|||
const FILTERS = 'FILTERS';
|
||||
const ATTACHMENT_THUMBNAILS = 'ATTACHMENT_THUMBNAILS';
|
||||
const ADDITIONAL_ACCOUNTS = 'ADDITIONAL_ACCOUNTS';
|
||||
const TEMPLATES = 'TEMPLATES';
|
||||
}
|
||||
|
|
|
|||
149
rainloop/v/0.0.0/app/libraries/RainLoop/Model/Template.php
Normal file
149
rainloop/v/0.0.0/app/libraries/RainLoop/Model/Template.php
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Model;
|
||||
|
||||
class Template
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sId;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sName;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sBody;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $bPopulateAlways;
|
||||
|
||||
/**
|
||||
* @param string $sId = ''
|
||||
* @param string $sName = ''
|
||||
* @param string $sBody = ''
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function __construct($sId = '', $sName = '', $sBody = '')
|
||||
{
|
||||
$this->sId = $sId;
|
||||
$this->sName = $sName;
|
||||
$this->sBody = $sBody;
|
||||
$this->bPopulateAlways = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sId = ''
|
||||
* @param string $sName = ''
|
||||
* @param string $sBody = ''
|
||||
*
|
||||
* @return \RainLoop\Model\Template
|
||||
*/
|
||||
public static function NewInstance($sId = '', $sName = '', $sBody = '')
|
||||
{
|
||||
return new self($sId, $sBody);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Id()
|
||||
{
|
||||
return $this->sId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Name()
|
||||
{
|
||||
return $this->sName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Body()
|
||||
{
|
||||
return $this->sBody;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bPopulateAlways
|
||||
*/
|
||||
public function SetPopulateAlways($bPopulateAlways)
|
||||
{
|
||||
$this->bPopulateAlways = !!$bPopulateAlways;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aData
|
||||
* @param bool $bAjax = false
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function FromJSON($aData, $bAjax = false)
|
||||
{
|
||||
if (isset($aData['ID'], $aData['Name'], $aData['Body']))
|
||||
{
|
||||
$this->sId = $aData['ID'];
|
||||
$this->sName = $aData['Name'];
|
||||
$this->sBody = $aData['Body'];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bAjax = false
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function ToSimpleJSON($bAjax = false)
|
||||
{
|
||||
$sBody = $this->Body();
|
||||
$bPopulated = true;
|
||||
|
||||
if ($bAjax && $bPopulated && !$this->bPopulateAlways)
|
||||
{
|
||||
if (1024 * 5 < \strlen($sBody) || true)
|
||||
{
|
||||
$bPopulated = false;
|
||||
$sBody = '';
|
||||
}
|
||||
}
|
||||
|
||||
return array(
|
||||
'ID' => $this->Id(),
|
||||
'Name' => $this->Name(),
|
||||
'Populated' => $bPopulated,
|
||||
'Body' => $sBody
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function GenerateID()
|
||||
{
|
||||
return $this->sId = \MailSo\Base\Utils::Md5Rand();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function Validate()
|
||||
{
|
||||
return 0 < \strlen($this->sBody);
|
||||
}
|
||||
}
|
||||
|
|
@ -151,7 +151,7 @@ class Contact
|
|||
public function RegenerateContactStr()
|
||||
{
|
||||
$this->IdContactStr = \class_exists('Sabre\DAV\Client') ?
|
||||
\Sabre\DAV\UUIDUtil::getUUID() : \md5(\microtime(true).'-'.\rand(10000, 99999));
|
||||
\Sabre\DAV\UUIDUtil::getUUID() : \MailSo\Base\Utils::Md5Rand();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -107,6 +107,15 @@ class Files extends \RainLoop\Providers\AbstractProvider
|
|||
return $this->oDriver ? $this->oDriver->GC($iTimeToClearInHours) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function CloseAllOpenedFiles()
|
||||
{
|
||||
return $this->oDriver && \method_exists($this->oDriver, 'CloseAllOpenedFiles') ?
|
||||
$this->oDriver->CloseAllOpenedFiles() : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -4,6 +4,11 @@ namespace RainLoop\Providers\Files;
|
|||
|
||||
class DefaultStorage implements \RainLoop\Providers\Files\FilesInterface
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aResources;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
|
|
@ -16,6 +21,7 @@ class DefaultStorage implements \RainLoop\Providers\Files\FilesInterface
|
|||
*/
|
||||
public function __construct($sStoragePath)
|
||||
{
|
||||
$this->aResources = array();
|
||||
$this->sDataPath = \rtrim(\trim($sStoragePath), '\\/');
|
||||
}
|
||||
|
||||
|
|
@ -70,6 +76,11 @@ class DefaultStorage implements \RainLoop\Providers\Files\FilesInterface
|
|||
if ($bCreate || \file_exists($sFileName))
|
||||
{
|
||||
$mResult = @\fopen($sFileName, $sOpenMode);
|
||||
|
||||
if (\is_resource($mResult))
|
||||
{
|
||||
$this->aResources[$sFileName] = $mResult;
|
||||
}
|
||||
}
|
||||
|
||||
return $mResult;
|
||||
|
|
@ -105,6 +116,11 @@ class DefaultStorage implements \RainLoop\Providers\Files\FilesInterface
|
|||
$sFileName = $this->generateFileName($oAccount, $sKey);
|
||||
if (\file_exists($sFileName))
|
||||
{
|
||||
if (isset($this->aResources[$sFileName]) && \is_resource($this->aResources[$sFileName]))
|
||||
{
|
||||
@\fclose($this->aResources[$sFileName]);
|
||||
}
|
||||
|
||||
$mResult = @\unlink($sFileName);
|
||||
}
|
||||
|
||||
|
|
@ -156,6 +172,25 @@ class DefaultStorage implements \RainLoop\Providers\Files\FilesInterface
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function CloseAllOpenedFiles()
|
||||
{
|
||||
if (\is_array($this->aResources) && 0 < \count($this->aResources))
|
||||
{
|
||||
foreach ($this->aResources as $sFileName => $rFile)
|
||||
{
|
||||
if (!empty($sFileName) && \is_resource($rFile))
|
||||
{
|
||||
@\fclose($rFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Model\Account $oAccount
|
||||
* @param string $sKey
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ class Service
|
|||
|
||||
if ($bAdmin && !$this->oActions->Config()->Get('security', 'allow_admin_panel', true))
|
||||
{
|
||||
echo $this->oActions->ErrorTemplates('Access Denied.',
|
||||
echo $this->oServiceActions->ErrorTemplates('Access Denied.',
|
||||
'Access to the RainLoop Webmail Admin Panel is not allowed!', true);
|
||||
|
||||
return $this;
|
||||
|
|
@ -150,6 +150,9 @@ class Service
|
|||
|
||||
if ($bIndex)
|
||||
{
|
||||
@\header('Content-Security-Policy:');
|
||||
@\header_remove('Content-Security-Policy');
|
||||
|
||||
@header('Content-Type: text/html; charset=utf-8');
|
||||
$this->oHttp->ServerNoCache();
|
||||
|
||||
|
|
@ -216,7 +219,7 @@ class Service
|
|||
$bAppJsDebug = !!$this->oActions->Config()->Get('labs', 'use_app_debug_js', false);
|
||||
$bAppCssDebug = !!$this->oActions->Config()->Get('labs', 'use_app_debug_css', false);
|
||||
|
||||
$sStaticPrefix = APP_WEB_STATIC_PATH;
|
||||
$sStaticPrefix = $this->oServiceActions->WebStaticPath();
|
||||
|
||||
$aData = array(
|
||||
'Language' => $sLanguage,
|
||||
|
|
@ -254,7 +257,7 @@ class Service
|
|||
\implode('~', array(
|
||||
\md5($this->oActions->Config()->Get('cache', 'index', '')),
|
||||
$this->oActions->Plugins()->Hash(),
|
||||
APP_WEB_PATH, APP_VERSION
|
||||
$this->oServiceActions->WebVersionPath(), APP_VERSION
|
||||
)).
|
||||
\implode('~', $aTemplateParameters)
|
||||
);
|
||||
|
|
|
|||
|
|
@ -675,7 +675,7 @@ class ServiceActions
|
|||
|
||||
if (\file_exists($sThemeFile) && \file_exists($sThemeTemplateFile) && \file_exists($sThemeValuesFile))
|
||||
{
|
||||
$aResult[] = '@base: "'.($bCustomTheme ? '' : APP_WEB_PATH).'themes/'.$sRealTheme.'/";';
|
||||
$aResult[] = '@base: "'.($bCustomTheme ? $this->WebPath() : $this->WebVersionPath()).'themes/'.$sRealTheme.'/";';
|
||||
$aResult[] = \file_get_contents($sThemeValuesFile);
|
||||
$aResult[] = \file_get_contents($sThemeFile);
|
||||
$aResult[] = \file_get_contents($sThemeTemplateFile);
|
||||
|
|
@ -779,7 +779,7 @@ class ServiceActions
|
|||
|
||||
@\header('Content-Type: text/html; charset=utf-8');
|
||||
return \strtr(\file_get_contents(APP_VERSION_ROOT_PATH.'app/templates/BadBrowser.html'), array(
|
||||
'{{BaseWebStaticPath}}' => APP_WEB_STATIC_PATH,
|
||||
'{{BaseWebStaticPath}}' => $this->WebStaticPath(),
|
||||
'{{ErrorTitle}}' => $sTitle,
|
||||
'{{ErrorHeader}}' => $sTitle,
|
||||
'{{ErrorDesc}}' => $sDesc
|
||||
|
|
@ -1051,6 +1051,58 @@ class ServiceActions
|
|||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sTitle
|
||||
* @param string $sDesc
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function ErrorTemplates($sTitle, $sDesc, $bShowBackLink = true)
|
||||
{
|
||||
return strtr(file_get_contents(APP_VERSION_ROOT_PATH.'app/templates/Error.html'), array(
|
||||
'{{BaseWebStaticPath}}' => $this->WebStaticPath(),
|
||||
'{{ErrorTitle}}' => $sTitle,
|
||||
'{{ErrorHeader}}' => $sTitle,
|
||||
'{{ErrorDesc}}' => $sDesc,
|
||||
'{{BackLinkVisibilityStyle}}' => $bShowBackLink ? 'display:inline-block' : 'display:none',
|
||||
'{{BackLink}}' => $this->oActions->StaticI18N('STATIC/BACK_LINK'),
|
||||
'{{BackHref}}' => './'
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function WebPath()
|
||||
{
|
||||
if (isset($_ENV['RAINLOOP_OWNCLOUD']) && $_ENV['RAINLOOP_OWNCLOUD'])
|
||||
{
|
||||
$sUrl = $this->oHttp->GetUrl();
|
||||
if ($sUrl && \preg_match('/\/index\.php\/apps\/rainloop/', $sUrl))
|
||||
{
|
||||
$sUrl = \preg_replace('/\/index\.php\/apps\/rainloop.+$/', '/', $sUrl);
|
||||
return \rtrim(\trim($sUrl), '\//').'/apps/rainloop/app/';
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function WebVersionPath()
|
||||
{
|
||||
return $this->WebPath().'rainloop/v/'.APP_VERSION.'/';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function WebStaticPath()
|
||||
{
|
||||
return $this->WebVersionPath().'static/';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sTitle
|
||||
* @param string $sDesc
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ class Utils
|
|||
$sToken = \RainLoop\Utils::GetCookie($sKey, null);
|
||||
if (null === $sToken)
|
||||
{
|
||||
$sToken = \md5(\rand(10000, 99999).\microtime(true).APP_SALT);
|
||||
$sToken = \MailSo\Base\Utils::Md5Rand(APP_SALT);
|
||||
\RainLoop\Utils::SetCookie($sKey, $sToken, \time() + 60 * 60 * 24 * 30, '/', null, null, true);
|
||||
}
|
||||
|
||||
|
|
@ -97,7 +97,7 @@ class Utils
|
|||
$sToken = \RainLoop\Utils::GetCookie($sKey, null);
|
||||
if (null === $sToken)
|
||||
{
|
||||
$sToken = \md5(\rand(10000, 99999).\microtime(true).APP_SALT);
|
||||
$sToken = \MailSo\Base\Utils::Md5Rand(APP_SALT);
|
||||
\RainLoop\Utils::SetCookie($sKey, $sToken, 0, '/', null, null, true);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -138,5 +138,18 @@
|
|||
}"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!--
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<div data-bind="component: {
|
||||
name: 'Checkbox',
|
||||
params: {
|
||||
label: 'Allow templates',
|
||||
value: capaTemplates
|
||||
}
|
||||
}"></div>
|
||||
</div>
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -16,13 +16,15 @@
|
|||
</div>
|
||||
<br />
|
||||
<div class="control-group" data-bind="css: {'error': name.error}">
|
||||
<label class="i18n" data-i18n-text="POPUPS_ADD_TEMPLATE/LABEL_NAME"></label>
|
||||
<input type="text" class="inputName span6" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
|
||||
data-bind="textInput: name, onEnter: addTemplateCommand, hasfocus: name.focus" />
|
||||
<label class="i18n control-label" data-i18n-text="POPUPS_ADD_TEMPLATE/LABEL_NAME"></label>
|
||||
<div class="controls">
|
||||
<input type="text" class="inputName input-xlarge" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
|
||||
data-bind="textInput: name, onEnter: addTemplateCommand, hasfocus: name.focus" />
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
<div class="control-group" data-bind="css: {'error': body.error}">
|
||||
<label class="i18n" data-i18n-text="POPUPS_ADD_TEMPLATE/LABEL_TEXT"></label>
|
||||
<div class="e-body-place" data-bind="initDom: signatureDom"></div>
|
||||
<div class="e-template-place" data-bind="initDom: signatureDom"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -26,9 +26,9 @@ Options -Indexes
|
|||
if (file_exists(APP_INDEX_ROOT_PATH.'include.php'))
|
||||
{
|
||||
include_once APP_INDEX_ROOT_PATH.'include.php';
|
||||
$sCustomDataPath = function_exists('__get_custom_data_full_path') ? rtrim(trim(__get_custom_data_full_path()), '\\/') : '';
|
||||
}
|
||||
|
||||
$sCustomDataPath = function_exists('__get_custom_data_full_path') ? rtrim(trim(__get_custom_data_full_path()), '\\/') : '';
|
||||
define('APP_DATA_FOLDER_PATH', 0 === strlen($sCustomDataPath) ? APP_INDEX_ROOT_PATH.'data/' : $sCustomDataPath.'/');
|
||||
unset($sCustomDataPath);
|
||||
|
||||
|
|
@ -58,8 +58,6 @@ Options -Indexes
|
|||
define('APP_REP_PATH', 'http://repository.rainloop.net/v1/');
|
||||
define('APP_REPO_CORE_FILE', 'http://repository.rainloop.net/v2/core.{{channel}}.json');
|
||||
define('APP_STATUS_PATH', 'http://status.rainloop.net/');
|
||||
define('APP_WEB_PATH', 'rainloop/v/'.APP_VERSION.'/');
|
||||
define('APP_WEB_STATIC_PATH', APP_WEB_PATH.'static/');
|
||||
define('APP_DATA_FOLDER_PATH_UNIX', str_replace('\\', '/', APP_DATA_FOLDER_PATH));
|
||||
|
||||
$sSalt = @file_get_contents(APP_DATA_FOLDER_PATH.'SALT.php');
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue