diff --git a/rainloop/v/0.0.0/app/libraries/MailSo/Base/HtmlUtils.php b/rainloop/v/0.0.0/app/libraries/MailSo/Base/HtmlUtils.php
index 38230505e..9fbd1dcc3 100644
--- a/rainloop/v/0.0.0/app/libraries/MailSo/Base/HtmlUtils.php
+++ b/rainloop/v/0.0.0/app/libraries/MailSo/Base/HtmlUtils.php
@@ -8,6 +8,8 @@ namespace MailSo\Base;
*/
class HtmlUtils
{
+ static $KOS = '@@_KOS_@@';
+
/**
* @access private
*/
@@ -261,14 +263,106 @@ class HtmlUtils
return \implode(';', $aOutStyles);
}
+ /**
+ * @param \DOMDocument $oDom
+ */
+ public static function FindLinksInDOM(&$oDom)
+ {
+ $aNodes = $oDom->getElementsByTagName('*');
+ foreach ($aNodes as /* @var $oElement \DOMElement */ $oElement)
+ {
+ $sTagNameLower = \strtolower($oElement->tagName);
+ $sParentTagNameLower = isset($oElement->parentNode) && isset($oElement->parentNode->tagName) ?
+ \strtolower($oElement->parentNode->tagName) : '';
+
+ if (!\in_array($sTagNameLower, array('html', 'meta', 'head', 'style', 'script', 'img', 'button', 'input', 'textarea', 'a')) &&
+ 'a' !== $sParentTagNameLower && $oElement->childNodes && 0 < $oElement->childNodes->length)
+ {
+ $oSubItem = null;
+ $aTextNodes = array();
+ $iIndex = $oElement->childNodes->length - 1;
+ while ($iIndex > -1)
+ {
+ $oSubItem = $oElement->childNodes->item($iIndex);
+ if ($oSubItem && XML_TEXT_NODE === $oSubItem->nodeType)
+ {
+ $aTextNodes[] = $oSubItem;
+ }
+
+ $iIndex--;
+ }
+
+ unset($oSubItem);
+
+ foreach ($aTextNodes as $oTextNode)
+ {
+ if ($oTextNode && 0 < \strlen($oTextNode->wholeText)/* && \preg_match('/http[s]?:\/\//i', $oTextNode->wholeText)*/)
+ {
+ $sText = \MailSo\Base\LinkFinder::NewInstance()
+ ->Text($oTextNode->wholeText)
+ ->UseDefaultWrappers(true)
+ ->CompileText()
+ ;
+
+ $oSubDom = \MailSo\Base\HtmlUtils::GetDomFromText('
'.$sText.'');
+ if ($oSubDom)
+ {
+ $oBodyNodes = $oSubDom->getElementsByTagName('body');
+ if ($oBodyNodes && 0 < $oBodyNodes->length)
+ {
+ $oBodyChildNodes = $oBodyNodes->item(0)->childNodes;
+ if ($oBodyChildNodes && $oBodyChildNodes->length)
+ {
+ for ($iIndex = 0, $iLen = $oBodyChildNodes->length; $iIndex < $iLen; $iIndex++)
+ {
+ $oSubItem = $oBodyChildNodes->item($iIndex);
+ if ($oSubItem)
+ {
+ if (XML_ELEMENT_NODE === $oSubItem->nodeType &&
+ 'a' === \strtolower($oSubItem->tagName))
+ {
+ $oLink = $oDom->createElement('a',
+ \str_replace(':', \MailSo\Base\HtmlUtils::$KOS, \htmlspecialchars($oSubItem->nodeValue)));
+
+ $sHref = $oSubItem->getAttribute('href');
+ if ($sHref)
+ {
+ $oLink->setAttribute('href', $sHref);
+ }
+
+ $oElement->insertBefore($oLink, $oTextNode);
+ }
+ else
+ {
+ $oElement->insertBefore($oDom->importNode($oSubItem), $oTextNode);
+ }
+ }
+ }
+
+ $oElement->removeChild($oTextNode);
+ }
+ }
+
+ unset($oBodyNodes);
+ }
+
+ unset($oSubDom, $sText);
+ }
+ }
+ }
+ }
+
+ unset($aNodes);
+ }
/**
* @param string $sHtml
* @param bool $bDoNotReplaceExternalUrl = false
+ * @param bool $bFindLinksInHtml = false
*
* @return string
*/
- public static function ClearHtmlSimple($sHtml, $bDoNotReplaceExternalUrl = false)
+ public static function ClearHtmlSimple($sHtml, $bDoNotReplaceExternalUrl = false, $bFindLinksInHtml = false)
{
$bHasExternals = false;
$aFoundCIDs = array();
@@ -276,7 +370,7 @@ class HtmlUtils
$aFoundedContentLocationUrls = array();
return \MailSo\Base\HtmlUtils::ClearHtml($sHtml, $bHasExternals, $aFoundCIDs,
- $aContentLocationUrls, $aFoundedContentLocationUrls, $bDoNotReplaceExternalUrl);
+ $aContentLocationUrls, $aFoundedContentLocationUrls, $bDoNotReplaceExternalUrl, $bFindLinksInHtml);
}
/**
@@ -286,11 +380,13 @@ class HtmlUtils
* @param array $aContentLocationUrls = array()
* @param array $aFoundedContentLocationUrls = array()
* @param bool $bDoNotReplaceExternalUrl = false
+ * @param bool $bFindLinksInHtml = false
*
* @return string
*/
public static function ClearHtml($sHtml, &$bHasExternals = false, &$aFoundCIDs = array(),
- $aContentLocationUrls = array(), &$aFoundedContentLocationUrls = array(), $bDoNotReplaceExternalUrl = false)
+ $aContentLocationUrls = array(), &$aFoundedContentLocationUrls = array(),
+ $bDoNotReplaceExternalUrl = false, $bFindLinksInHtml = false)
{
$sHtml = null === $sHtml ? '' : (string) $sHtml;
$sHtml = \trim($sHtml);
@@ -313,11 +409,16 @@ class HtmlUtils
if ($oDom)
{
+ if ($bFindLinksInHtml)
+ {
+ \MailSo\Base\HtmlUtils::FindLinksInDOM($oDom);
+ }
+
$aNodes = $oDom->getElementsByTagName('*');
foreach ($aNodes as /* @var $oElement \DOMElement */ $oElement)
{
$sTagNameLower = \strtolower($oElement->tagName);
-
+
// convert body attributes to styles
if ('body' === $sTagNameLower)
{
@@ -493,6 +594,8 @@ class HtmlUtils
$sResult = ''.$sResult.'
';
$sResult = ''.$sResult.'
';
+ $sResult = \str_replace(\MailSo\Base\HtmlUtils::$KOS, ':', $sResult);
+
return \trim($sResult);
}
@@ -658,8 +761,7 @@ class HtmlUtils
$sText = \MailSo\Base\LinkFinder::NewInstance()
->Text($sText)
->UseDefaultWrappers($bLinksWithTargetBlank)
-// ->CompileText(true, false);
- ->CompileText(true, true);
+ ->CompileText();
$sText = \str_replace("\r", '', $sText);
diff --git a/rainloop/v/0.0.0/app/libraries/MailSo/Base/LinkFinder.php b/rainloop/v/0.0.0/app/libraries/MailSo/Base/LinkFinder.php
index 6be013ba5..27a99989e 100644
--- a/rainloop/v/0.0.0/app/libraries/MailSo/Base/LinkFinder.php
+++ b/rainloop/v/0.0.0/app/libraries/MailSo/Base/LinkFinder.php
@@ -126,13 +126,8 @@ class LinkFinder
*/
public function UseDefaultWrappers($bAddTargetBlank = false)
{
- $this->fLinkWrapper = function ($sLink, $bShortLink = false) use ($bAddTargetBlank) {
-
- if ($bShortLink && \in_array(\strtolower($sLink), array('asp.net', 'vb.net', 'mailbee.net')))
- {
- return $sLink;
- }
-
+ $this->fLinkWrapper = function ($sLink) use ($bAddTargetBlank) {
+
$sNameLink = $sLink;
if (!\preg_match('/^[a-z]{3,5}\:\/\//i', \ltrim($sLink)))
{
@@ -151,11 +146,10 @@ class LinkFinder
/**
* @param bool $bUseHtmlSpecialChars = true
- * @param bool $bFindShortLinks = true
*
* @return string
*/
- public function CompileText($bUseHtmlSpecialChars = true, $bFindShortLinks = true)
+ public function CompileText($bUseHtmlSpecialChars = true)
{
$sText = \substr($this->sText, 0, $this->iOptimizationLimit);
$sSubText = \substr($this->sText, $this->iOptimizationLimit);
@@ -171,11 +165,6 @@ class LinkFinder
$sText = $this->findMails($sText, $this->fMailWrapper);
}
- if ($bFindShortLinks && null !== $this->fLinkWrapper && \is_callable($this->fLinkWrapper))
- {
- $sText = $this->findShortLinks($sText, $this->fLinkWrapper);
- }
-
$sResult = '';
if ($bUseHtmlSpecialChars)
{
@@ -259,46 +248,6 @@ class LinkFinder
return $sText;
}
- /**
- * @param string $sText
- * @param mixed $fWrapper
- *
- * @return string
- */
- private function findShortLinks($sText, $fWrapper)
- {
- $sPattern = '/([a-z0-9-\.]+\.(?:com|org|net|ru))([^a-z0-9-\.])/i';
-
- $aPrepearPlainStringUrls = $this->aPrepearPlainStringUrls;
- $sText = \preg_replace_callback($sPattern, function ($aMatch) use ($fWrapper, &$aPrepearPlainStringUrls) {
-
- if (\is_array($aMatch) && 2 < \count($aMatch) && isset($aMatch[1]) && 0 < \strlen($aMatch[1]))
- {
- $sLinkWithWrap = \call_user_func_array($fWrapper, array($aMatch[1], true));
- if (\is_string($sLinkWithWrap))
- {
- $aPrepearPlainStringUrls[] = \stripslashes($sLinkWithWrap);
- return \MailSo\Base\LinkFinder::OPEN_LINK.
- (\count($aPrepearPlainStringUrls) - 1).
- \MailSo\Base\LinkFinder::CLOSE_LINK.
- $aMatch[2];
- }
-
- return $aMatch[0];
- }
-
- return '';
-
- }, $sText);
-
- if (0 < \count($aPrepearPlainStringUrls))
- {
- $this->aPrepearPlainStringUrls = $aPrepearPlainStringUrls;
- }
-
- return $sText;
- }
-
/**
* @param string $sText
* @param mixed $fWrapper
diff --git a/rainloop/v/0.0.0/app/libraries/MailSo/Base/Utils.php b/rainloop/v/0.0.0/app/libraries/MailSo/Base/Utils.php
index 12700a058..201dd46e0 100644
--- a/rainloop/v/0.0.0/app/libraries/MailSo/Base/Utils.php
+++ b/rainloop/v/0.0.0/app/libraries/MailSo/Base/Utils.php
@@ -740,7 +740,7 @@ class Utils
{
$sResult = '';
$sContentType = \strtolower($sContentType);
- if (0 === strpos($sContentType, 'image/'))
+ if (0 === \strpos($sContentType, 'image/'))
{
$sResult = 'image';
}
@@ -847,7 +847,7 @@ class Utils
*/
public static function Php2js($mInput)
{
- return \json_encode($mInput, defined('JSON_UNESCAPED_UNICODE') ? JSON_UNESCAPED_UNICODE : 0);
+ return \json_encode($mInput, \defined('JSON_UNESCAPED_UNICODE') ? JSON_UNESCAPED_UNICODE : 0);
// if (\is_null($mInput))
// {
@@ -918,25 +918,25 @@ class Utils
*/
public static function RecRmDir($sDir)
{
- if (@is_dir($sDir))
+ if (@\is_dir($sDir))
{
- $aObjects = scandir($sDir);
+ $aObjects = \scandir($sDir);
foreach ($aObjects as $sObject)
{
if ('.' !== $sObject && '..' !== $sObject)
{
- if ('dir' === filetype($sDir.'/'.$sObject))
+ if ('dir' === \filetype($sDir.'/'.$sObject))
{
self::RecRmDir($sDir.'/'.$sObject);
}
else
{
- @unlink($sDir.'/'.$sObject);
+ @\unlink($sDir.'/'.$sObject);
}
}
}
- return @rmdir($sDir);
+ return @\rmdir($sDir);
}
return false;
diff --git a/rainloop/v/0.0.0/app/libraries/MailSo/Version.php b/rainloop/v/0.0.0/app/libraries/MailSo/Version.php
index e8263281c..9d45af44e 100644
--- a/rainloop/v/0.0.0/app/libraries/MailSo/Version.php
+++ b/rainloop/v/0.0.0/app/libraries/MailSo/Version.php
@@ -10,7 +10,7 @@ final class Version
/**
* @var string
*/
- const APP_VERSION = '1.2.2';
+ const APP_VERSION = '1.3.0';
/**
* @var string
diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php b/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php
index 666b46d21..bea6a42f8 100644
--- a/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php
+++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php
@@ -6264,7 +6264,7 @@ class Actions
protected function responseObject($mResponse, $sParent = '', $aParameters = array())
{
$mResult = $mResponse;
- if (is_object($mResponse))
+ if (\is_object($mResponse))
{
$bHook = true;
$sClassName = \get_class($mResponse);
@@ -6327,7 +6327,7 @@ class Actions
$sSubject = $mResult['Subject'];
$mResult['RequestHash'] = \RainLoop\Utils::EncodeKeyValues(array(
'V' => APP_VERSION,
- 'Account' => $oAccount ? md5($oAccount->Hash()) : '',
+ 'Account' => $oAccount ? \md5($oAccount->Hash()) : '',
'Folder' => $mResult['Folder'],
'Uid' => $mResult['Uid'],
'MimeType' => 'message/rfc822',
@@ -6372,12 +6372,12 @@ class Actions
}
$sPlain = '';
- $sHtml = $mResponse->Html();
+ $sHtml = \trim($mResponse->Html());
$bRtl = false;
if (0 === \strlen($sHtml))
{
- $sPlain = $mResponse->Plain();
+ $sPlain = \trim($mResponse->Plain());
$bRtl = \MailSo\Base\Utils::IsRTL($sPlain);
}
else
@@ -6389,7 +6389,8 @@ class Actions
$mResult['InReplyTo'] = $mResponse->InReplyTo();
$mResult['References'] = $mResponse->References();
$mResult['Html'] = 0 === \strlen($sHtml) ? '' : \MailSo\Base\HtmlUtils::ClearHtml(
- $sHtml, $bHasExternals, $mFoundedCIDs, $aContentLocationUrls, $mFoundedContentLocationUrls);
+ $sHtml, $bHasExternals, $mFoundedCIDs, $aContentLocationUrls, $mFoundedContentLocationUrls, false,
+ !!$this->Config()->Get('labs', 'allow_smart_html_links', true));
$mResult['PlainRaw'] = $sPlain;
$mResult['Plain'] = 0 === \strlen($sPlain) ? '' : \MailSo\Base\HtmlUtils::ConvertPlainToHtml($sPlain);
@@ -6418,7 +6419,7 @@ class Actions
try
{
$oReadReceipt = \MailSo\Mime\Email::Parse($mResult['ReadReceipt']);
- if ($oReadReceipt && \strtolower($oAccount->Email()) === \strtolower($oReadReceipt->GetEmail()))
+ if (!$oReadReceipt || ($oReadReceipt && \strtolower($oAccount->Email()) === \strtolower($oReadReceipt->GetEmail())))
{
$mResult['ReadReceipt'] = '';
}
@@ -6495,13 +6496,13 @@ class Actions
'CID' => $mResponse->Cid(),
'ContentLocation' => $mResponse->ContentLocation(),
'IsInline' => $mResponse->IsInline(),
- 'IsLinked' => ($mFoundedCIDs && \in_array(trim(trim($mResponse->Cid()), '<>'), $mFoundedCIDs)) ||
+ 'IsLinked' => ($mFoundedCIDs && \in_array(\trim(\trim($mResponse->Cid()), '<>'), $mFoundedCIDs)) ||
($mFoundedContentLocationUrls && \in_array(\trim($mResponse->ContentLocation()), $mFoundedContentLocationUrls))
));
$mResult['Download'] = \RainLoop\Utils::EncodeKeyValues(array(
'V' => APP_VERSION,
- 'Account' => $oAccount ? md5($oAccount->Hash()) : '',
+ 'Account' => $oAccount ? \md5($oAccount->Hash()) : '',
'Folder' => $mResult['Folder'],
'Uid' => $mResult['Uid'],
'MimeIndex' => $mResult['MimeIndex'],
@@ -6513,7 +6514,7 @@ class Actions
{
$aExtended = null;
$mStatus = $mResponse->Status();
- if (is_array($mStatus) && isset($mStatus['MESSAGES'], $mStatus['UNSEEN'], $mStatus['UIDNEXT']))
+ if (\is_array($mStatus) && isset($mStatus['MESSAGES'], $mStatus['UNSEEN'], $mStatus['UIDNEXT']))
{
$aExtended = array(
'MessageCount' => (int) $mStatus['MESSAGES'],
@@ -6524,7 +6525,7 @@ class Actions
);
}
- $mResult = array_merge($this->objectData($mResponse, $sParent, $aParameters), array(
+ $mResult = \array_merge($this->objectData($mResponse, $sParent, $aParameters), array(
'Name' => $mResponse->Name(),
'FullName' => $mResponse->FullName(),
'FullNameRaw' => $mResponse->FullNameRaw(),
@@ -6541,7 +6542,7 @@ class Actions
}
else if ('MailSo\Mail\MessageCollection' === $sClassName)
{
- $mResult = array_merge($this->objectData($mResponse, $sParent, $aParameters), array(
+ $mResult = \array_merge($this->objectData($mResponse, $sParent, $aParameters), array(
'MessageCount' => $mResponse->MessageCount,
'MessageUnseenCount' => $mResponse->MessageUnseenCount,
'MessageResultCount' => $mResponse->MessageResultCount,
@@ -6557,13 +6558,13 @@ class Actions
}
else if ('MailSo\Mail\AttachmentCollection' === $sClassName)
{
- $mResult = array_merge($this->objectData($mResponse, $sParent, $aParameters), array(
+ $mResult = \array_merge($this->objectData($mResponse, $sParent, $aParameters), array(
'InlineCount' => $mResponse->InlineCount()
));
}
else if ('MailSo\Mail\FolderCollection' === $sClassName)
{
- $mResult = array_merge($this->objectData($mResponse, $sParent, $aParameters), array(
+ $mResult = \array_merge($this->objectData($mResponse, $sParent, $aParameters), array(
'Namespace' => $mResponse->GetNamespace(),
'FoldersHash' => isset($mResponse->FoldersHash) ? $mResponse->FoldersHash : '',
'IsThreadsSupported' => $mResponse->IsThreadsSupported,
@@ -6579,7 +6580,7 @@ class Actions
}
else
{
- $mResult = '['.get_class($mResponse).']';
+ $mResult = '['.\get_class($mResponse).']';
$bHook = false;
}
@@ -6588,7 +6589,7 @@ class Actions
$this->Plugins()->RunHook('filter.response-object', array($sClassName, $mResult), false);
}
}
- else if (is_array($mResponse))
+ else if (\is_array($mResponse))
{
foreach ($mResponse as $iKey => $oItem)
{
diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/Config/Application.php b/rainloop/v/0.0.0/app/libraries/RainLoop/Config/Application.php
index be88bb8cd..d73706d22 100644
--- a/rainloop/v/0.0.0/app/libraries/RainLoop/Config/Application.php
+++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Config/Application.php
@@ -1,252 +1,253 @@
-Set('security', 'admin_password', \md5(APP_SALT.$sPassword.APP_SALT));
- }
-
- /**
- * @param string $sPassword
- *
- * @return bool
- */
- public function ValidatePassword($sPassword)
- {
- $sPassword = (string) $sPassword;
- $sConfigPassword = (string) $this->Get('security', 'admin_password', '');
-
- return 0 < \strlen($sPassword) &&
- ($sPassword === $sConfigPassword || \md5(APP_SALT.$sPassword.APP_SALT) === $sConfigPassword);
- }
-
- /**
- * @return bool
- */
- public function Save()
- {
- $this->Set('version', 'current', APP_VERSION);
- $this->Set('version', 'saved', \gmdate('r'));
-
- return parent::Save();
- }
-
- /**
- * @return array
- */
- protected function defaultValues()
- {
- return array(
- 'webmail' => array(
-
- 'title' => array('RainLoop Webmail', 'Text displayed as page title'),
- 'loading_description' => array('RainLoop', 'Text displayed on startup'),
-
- 'theme' => array('Default', 'Theme used by default'),
- 'allow_themes' => array(true, 'Allow theme selection on settings screen'),
- 'allow_custom_theme' => array(true, ''),
-
- 'language' => array('en', 'Language used by default'),
- 'allow_languages_on_settings' => array(true, 'Allow language selection on settings screen'),
-
- 'allow_additional_accounts' => array(true, ''),
- 'allow_identities' => array(true, ''),
-
- 'messages_per_page' => array(20, ' Number of messages displayed on page by default'),
-
- 'editor_default_type' => array('Html', 'Editor mode used by default (Html or Plain)'),
-
- 'attachment_size_limit' => array(5,
- 'File size limit (MB) for file upload on compose screen
-0 for unlimited.')
- ),
-
- 'branding' => array(
- 'login_logo' => array(''),
- 'login_desc' => array(''),
- 'login_css' => array(''),
- ),
-
- 'contacts' => array(
- 'enable' => array(false, 'Enable contacts'),
- 'allow_sharing' => array(true),
- 'allow_sync' => array(false),
- 'suggestions_limit' => array(30),
- 'type' => array('sqlite', ''),
- 'pdo_dsn' => array('mysql:host=127.0.0.1;port=3306;dbname=rainloop', ''),
- 'pdo_user' => array('root', ''),
- 'pdo_password' => array('', ''),
- ),
-
- 'security' => array(
- 'csrf_protection' => array(true,
- 'Enable CSRF protection (http://en.wikipedia.org/wiki/Cross-site_request_forgery)'),
-
- 'custom_server_signature' => array('RainLoop'),
- 'openpgp' => array(false),
- 'admin_login' => array('admin', 'Login and password for web admin panel'),
- 'admin_password' => array('12345'),
- 'allow_admin_panel' => array(true, 'Access settings'),
- 'admin_panel_host' => array(''),
- 'core_install_access_domains' => array('')
- ),
-
- 'login' => array(
-
- 'allow_custom_login' => array(false,
- 'Enable additional Login field on webmail login screen'),
-
- 'default_domain' => array('', ''),
-
- 'allow_languages_on_login' => array(true,
- 'Allow language selection on webmail login screen'),
-
- 'sign_me_auto' => array(\RainLoop\Enumerations\SignMeType::DEFAILT_OFF,
- 'This option allows webmail to remember the logged in user
-once they closed the browser window.
-
-Values:
- "DefaultOff" - can be used, disabled by default;
- "DefaultOn" - can be used, enabled by default;
- "Unused" - cannot be used')
- ),
-
- 'plugins' => array(
- 'enable' => array(false, 'Enable plugin support'),
- 'enabled_list' => array('', 'List of enabled plugins'),
- ),
-
- 'logs' => array(
-
- 'enable' => array(false, 'Enable logging'),
-
- 'write_on_error_only' => array(false, 'Logs entire request only if error occured'),
-
- 'filename' => array('log-{date:Y-m-d}.txt',
- 'Log filename.
-For security reasons, some characters are removed from filename.
-Allows for pattern-based folder creation (see examples below).
-
-Patterns:
- {date:Y-m-d} - Replaced by pattern-based date
- Detailed info: http://www.php.net/manual/en/function.date.php
- {user:email} - Replaced by user\'s email address
- If user is not logged in, value is set to "unknown"
- {user:login} - Replaced by user\'s login
- If user is not logged in, value is set to "unknown"
- {user:domain} - Replaced by user\'s domain name
- If user is not logged in, value is set to "unknown"
- {user:uid} - Replaced by user\'s UID regardless of account currently used
-
-Examples:
- filename = "log-{date:Y-m-d}.txt"
- filename = "{date:Y-m-d}/{user:domain}/{user:email}_{user:uid}.log"
- filename = "{user:email}-{date:Y-m-d}.txt"')
- ),
-
- 'debug' => array(
- 'enable' => array(false, 'Special option required for development purposes'),
- ),
-
- 'version' => array(
- 'current' => array(''),
- 'saved' => array('')
- ),
-
- 'social' => array(
- 'google_enable' => array(false, 'Google'),
- 'google_client_id' => array(''),
- 'google_client_secret' => array(''),
-
- 'fb_enable' => array(false, 'Facebook'),
- 'fb_app_id' => array(''),
- 'fb_app_secret' => array(''),
-
- 'twitter_enable' => array(false, 'Twitter'),
- 'twitter_consumer_key' => array(''),
- 'twitter_consumer_secret' => array(''),
-
- 'dropbox_enable' => array(false, 'Dropbox'),
- 'dropbox_api_key' => array(''),
- ),
-
- 'cache' => array(
- 'enable' => array(true,
- 'The section controls caching of the entire application.
-
-Enables caching in the system'),
-
- 'index' => array('v1', 'Additional caching key. If changed, cache is purged'),
-
- 'fast_cache_driver' => array('files', 'Can be: files, APC, memcache'),
- 'fast_cache_index' => array('v1', 'Additional caching key. If changed, fast cache is purged'),
-
- 'http' => array(true, 'Browser-level cache. If enabled, caching is maintainted without using files'),
- 'server_uids' => array(false, 'Caching message UIDs when searching and sorting (threading)')
- ),
-
- 'labs' => array(
- 'ignore_folders_subscription' => array(false,
- 'Experimental settings. Handle with care.
-'),
- 'sync_dav_digest_auth' => array(true),
- 'sync_dav_domain' => array(''),
- 'sync_use_dav_browser' => array(true),
- 'allow_message_append' => array(false),
- 'date_from_headers' => array(false),
- 'cache_system_data' => array(true),
- 'use_app_debug_js' => array(false),
- 'use_app_debug_css' => array(false),
- 'use_dav_digest_auth' => array(false),
- 'login_fault_delay' => array(1),
- 'log_ajax_response_write_limit' => array(300),
- 'determine_user_language' => array(true),
- 'use_imap_sort' => array(false),
- 'use_imap_force_selection' => array(false),
- 'use_imap_list_subscribe' => array(true),
- 'use_imap_thread' => array(true),
- 'use_imap_move' => array(true),
- 'use_imap_auth_plain' => array(false),
- 'imap_forwarded_flag' => array('$Forwarded'),
- 'imap_read_receipt_flag' => array('$ReadReceipt'),
- 'smtp_show_server_errors' => array(false),
- 'allow_prefetch' => array(true),
- 'autocreate_system_folders' => array(true),
- 'repo_type' => array('stable'),
- 'custom_repo' => array(''),
- 'additional_repo' => array(''),
- 'cdn_static_domain' => array(''),
- 'curl_proxy' => array(''),
- 'curl_proxy_auth' => array(''),
- 'in_iframe' => array(false),
- 'custom_login_link' => array(''),
- 'custom_logout_link' => array(''),
- 'allow_external_login' => array(false),
- 'fast_cache_memcache_host' => array('127.0.0.1'),
- 'fast_cache_memcache_port' => array(11211),
- 'fast_cache_memcache_expire' => array(43200),
- 'dev_email' => array(''),
- 'dev_login' => array(''),
- 'dev_password' => array('')
- )
- );
- }
-}
+Set('security', 'admin_password', \md5(APP_SALT.$sPassword.APP_SALT));
+ }
+
+ /**
+ * @param string $sPassword
+ *
+ * @return bool
+ */
+ public function ValidatePassword($sPassword)
+ {
+ $sPassword = (string) $sPassword;
+ $sConfigPassword = (string) $this->Get('security', 'admin_password', '');
+
+ return 0 < \strlen($sPassword) &&
+ ($sPassword === $sConfigPassword || \md5(APP_SALT.$sPassword.APP_SALT) === $sConfigPassword);
+ }
+
+ /**
+ * @return bool
+ */
+ public function Save()
+ {
+ $this->Set('version', 'current', APP_VERSION);
+ $this->Set('version', 'saved', \gmdate('r'));
+
+ return parent::Save();
+ }
+
+ /**
+ * @return array
+ */
+ protected function defaultValues()
+ {
+ return array(
+ 'webmail' => array(
+
+ 'title' => array('RainLoop Webmail', 'Text displayed as page title'),
+ 'loading_description' => array('RainLoop', 'Text displayed on startup'),
+
+ 'theme' => array('Default', 'Theme used by default'),
+ 'allow_themes' => array(true, 'Allow theme selection on settings screen'),
+ 'allow_custom_theme' => array(true, ''),
+
+ 'language' => array('en', 'Language used by default'),
+ 'allow_languages_on_settings' => array(true, 'Allow language selection on settings screen'),
+
+ 'allow_additional_accounts' => array(true, ''),
+ 'allow_identities' => array(true, ''),
+
+ 'messages_per_page' => array(20, ' Number of messages displayed on page by default'),
+
+ 'editor_default_type' => array('Html', 'Editor mode used by default (Html or Plain)'),
+
+ 'attachment_size_limit' => array(5,
+ 'File size limit (MB) for file upload on compose screen
+0 for unlimited.')
+ ),
+
+ 'branding' => array(
+ 'login_logo' => array(''),
+ 'login_desc' => array(''),
+ 'login_css' => array(''),
+ ),
+
+ 'contacts' => array(
+ 'enable' => array(false, 'Enable contacts'),
+ 'allow_sharing' => array(true),
+ 'allow_sync' => array(false),
+ 'suggestions_limit' => array(30),
+ 'type' => array('sqlite', ''),
+ 'pdo_dsn' => array('mysql:host=127.0.0.1;port=3306;dbname=rainloop', ''),
+ 'pdo_user' => array('root', ''),
+ 'pdo_password' => array('', ''),
+ ),
+
+ 'security' => array(
+ 'csrf_protection' => array(true,
+ 'Enable CSRF protection (http://en.wikipedia.org/wiki/Cross-site_request_forgery)'),
+
+ 'custom_server_signature' => array('RainLoop'),
+ 'openpgp' => array(false),
+ 'admin_login' => array('admin', 'Login and password for web admin panel'),
+ 'admin_password' => array('12345'),
+ 'allow_admin_panel' => array(true, 'Access settings'),
+ 'admin_panel_host' => array(''),
+ 'core_install_access_domains' => array('')
+ ),
+
+ 'login' => array(
+
+ 'allow_custom_login' => array(false,
+ 'Enable additional Login field on webmail login screen'),
+
+ 'default_domain' => array('', ''),
+
+ 'allow_languages_on_login' => array(true,
+ 'Allow language selection on webmail login screen'),
+
+ 'sign_me_auto' => array(\RainLoop\Enumerations\SignMeType::DEFAILT_OFF,
+ 'This option allows webmail to remember the logged in user
+once they closed the browser window.
+
+Values:
+ "DefaultOff" - can be used, disabled by default;
+ "DefaultOn" - can be used, enabled by default;
+ "Unused" - cannot be used')
+ ),
+
+ 'plugins' => array(
+ 'enable' => array(false, 'Enable plugin support'),
+ 'enabled_list' => array('', 'List of enabled plugins'),
+ ),
+
+ 'logs' => array(
+
+ 'enable' => array(false, 'Enable logging'),
+
+ 'write_on_error_only' => array(false, 'Logs entire request only if error occured'),
+
+ 'filename' => array('log-{date:Y-m-d}.txt',
+ 'Log filename.
+For security reasons, some characters are removed from filename.
+Allows for pattern-based folder creation (see examples below).
+
+Patterns:
+ {date:Y-m-d} - Replaced by pattern-based date
+ Detailed info: http://www.php.net/manual/en/function.date.php
+ {user:email} - Replaced by user\'s email address
+ If user is not logged in, value is set to "unknown"
+ {user:login} - Replaced by user\'s login
+ If user is not logged in, value is set to "unknown"
+ {user:domain} - Replaced by user\'s domain name
+ If user is not logged in, value is set to "unknown"
+ {user:uid} - Replaced by user\'s UID regardless of account currently used
+
+Examples:
+ filename = "log-{date:Y-m-d}.txt"
+ filename = "{date:Y-m-d}/{user:domain}/{user:email}_{user:uid}.log"
+ filename = "{user:email}-{date:Y-m-d}.txt"')
+ ),
+
+ 'debug' => array(
+ 'enable' => array(false, 'Special option required for development purposes'),
+ ),
+
+ 'version' => array(
+ 'current' => array(''),
+ 'saved' => array('')
+ ),
+
+ 'social' => array(
+ 'google_enable' => array(false, 'Google'),
+ 'google_client_id' => array(''),
+ 'google_client_secret' => array(''),
+
+ 'fb_enable' => array(false, 'Facebook'),
+ 'fb_app_id' => array(''),
+ 'fb_app_secret' => array(''),
+
+ 'twitter_enable' => array(false, 'Twitter'),
+ 'twitter_consumer_key' => array(''),
+ 'twitter_consumer_secret' => array(''),
+
+ 'dropbox_enable' => array(false, 'Dropbox'),
+ 'dropbox_api_key' => array(''),
+ ),
+
+ 'cache' => array(
+ 'enable' => array(true,
+ 'The section controls caching of the entire application.
+
+Enables caching in the system'),
+
+ 'index' => array('v1', 'Additional caching key. If changed, cache is purged'),
+
+ 'fast_cache_driver' => array('files', 'Can be: files, APC, memcache'),
+ 'fast_cache_index' => array('v1', 'Additional caching key. If changed, fast cache is purged'),
+
+ 'http' => array(true, 'Browser-level cache. If enabled, caching is maintainted without using files'),
+ 'server_uids' => array(false, 'Caching message UIDs when searching and sorting (threading)')
+ ),
+
+ 'labs' => array(
+ 'ignore_folders_subscription' => array(false,
+ 'Experimental settings. Handle with care.
+'),
+ 'allow_prefetch' => array(true),
+ 'allow_smart_html_links' => array(true),
+ 'cache_system_data' => array(true),
+ 'date_from_headers' => array(false),
+ 'autocreate_system_folders' => array(true),
+ 'allow_message_append' => array(false),
+ 'determine_user_language' => array(true),
+ 'login_fault_delay' => array(1),
+ 'log_ajax_response_write_limit' => array(300),
+ 'sync_dav_digest_auth' => array(true),
+ 'sync_dav_domain' => array(''),
+ 'sync_use_dav_browser' => array(true),
+ 'use_app_debug_js' => array(false),
+ 'use_app_debug_css' => array(false),
+ 'use_imap_sort' => array(false),
+ 'use_imap_force_selection' => array(false),
+ 'use_imap_list_subscribe' => array(true),
+ 'use_imap_thread' => array(true),
+ 'use_imap_move' => array(true),
+ 'use_imap_auth_plain' => array(false),
+ 'imap_forwarded_flag' => array('$Forwarded'),
+ 'imap_read_receipt_flag' => array('$ReadReceipt'),
+ 'smtp_show_server_errors' => array(false),
+ 'repo_type' => array('stable'),
+ 'custom_repo' => array(''),
+ 'additional_repo' => array(''),
+ 'cdn_static_domain' => array(''),
+ 'curl_proxy' => array(''),
+ 'curl_proxy_auth' => array(''),
+ 'in_iframe' => array(false),
+ 'custom_login_link' => array(''),
+ 'custom_logout_link' => array(''),
+ 'allow_external_login' => array(false),
+ 'in_iframe' => array(false),
+ 'fast_cache_memcache_host' => array('127.0.0.1'),
+ 'fast_cache_memcache_port' => array(11211),
+ 'fast_cache_memcache_expire' => array(43200),
+ 'dev_email' => array(''),
+ 'dev_login' => array(''),
+ 'dev_password' => array('')
+ )
+ );
+ }
+}