Many fixes

New ownCloud package with a built-in webmail
This commit is contained in:
RainLoop Team 2015-02-12 01:39:27 +04:00
parent 323dd34c8b
commit 6116597f6f
56 changed files with 1137 additions and 232 deletions

View file

@ -263,7 +263,6 @@ class Http
*/
public function GetHeader($sHeader)
{
$sResultHeader = '';
$sServerKey = 'HTTP_'.\strtoupper(\str_replace('-', '_', $sHeader));
$sResultHeader = $this->GetServer($sServerKey, '');

View file

@ -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;
}

View file

@ -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

View file

@ -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;

View file

@ -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]));

View file

@ -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.'>';
}
/**

View file

@ -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

View file

@ -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,

View file

@ -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)

View file

@ -15,4 +15,5 @@ class Capa
const FILTERS = 'FILTERS';
const ATTACHMENT_THUMBNAILS = 'ATTACHMENT_THUMBNAILS';
const ADDITIONAL_ACCOUNTS = 'ADDITIONAL_ACCOUNTS';
const TEMPLATES = 'TEMPLATES';
}

View 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);
}
}

View file

@ -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();
}
/**

View file

@ -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
*/

View file

@ -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

View file

@ -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)
);

View file

@ -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

View file

@ -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);
}

View file

@ -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>

View file

@ -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>

View file

@ -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');