Warning! Breaking change!

Removed "additional Login field" on login page (Security reason) (Closes #206)
Added "custom-login-mapping" plugin
This commit is contained in:
RainLoop Team 2014-06-25 20:36:46 +04:00
parent 9643c621f1
commit 81e25b4235
24 changed files with 246 additions and 303 deletions

View file

@ -7,7 +7,6 @@ function AdminLogin()
{
var oData = RL.data();
this.allowCustomLogin = oData.allowCustomLogin;
this.determineUserLanguage = oData.determineUserLanguage;
this.defaultDomain = ko.observable(RL.settingsGet('LoginDefaultDomain'));
@ -31,12 +30,6 @@ AdminLogin.prototype.onBuild = function ()
});
});
self.allowCustomLogin.subscribe(function (bValue) {
RL.remote().saveAdminConfig(null, {
'AllowCustomLogin': bValue ? '1' : '0'
});
});
self.allowLanguagesOnLogin.subscribe(function (bValue) {
RL.remote().saveAdminConfig(null, {
'AllowLanguagesOnLogin': bValue ? '1' : '0'

View file

@ -775,7 +775,6 @@ Utils.initDataConstructorBySettings = function (oData)
Globals.sAnimationType = Enums.InterfaceAnimation.Full;
oData.capaThemes = ko.observable(false);
oData.allowCustomLogin = ko.observable(false);
oData.allowLanguagesOnSettings = ko.observable(true);
oData.allowLanguagesOnLogin = ko.observable(true);

View file

@ -91,7 +91,6 @@ AbstractData.prototype.populateDataOnStart = function()
this.determineUserLanguage(!!RL.settingsGet('DetermineUserLanguage'));
this.capaThemes(RL.capa(Enums.Capa.Themes));
this.allowCustomLogin(!!RL.settingsGet('AllowCustomLogin'));
this.allowLanguagesOnLogin(!!RL.settingsGet('AllowLanguagesOnLogin'));
this.allowLanguagesOnSettings(!!RL.settingsGet('AllowLanguagesOnSettings'));

View file

@ -30,7 +30,6 @@ function WebMailDataStorage()
;
this.devEmail = '';
this.devLogin = '';
this.devPassword = '';
this.accountEmail = ko.observable('');
@ -488,7 +487,6 @@ WebMailDataStorage.prototype.populateDataOnStart = function()
this.remoteSuggestions = !!RL.settingsGet('RemoteSuggestions');
this.devEmail = RL.settingsGet('DevEmail');
this.devLogin = RL.settingsGet('DevLogin');
this.devPassword = RL.settingsGet('DevPassword');
};

View file

@ -25,6 +25,6 @@
textarea {
width: 400px;
height: 50px;
height: 70px;
}
}

View file

@ -11,7 +11,6 @@ function LoginViewModel()
var oData = RL.data();
this.email = ko.observable('');
this.login = ko.observable('');
this.password = ko.observable('');
this.signMe = ko.observable(false);
@ -26,11 +25,9 @@ function LoginViewModel()
this.logoCss = Utils.trim(RL.settingsGet('LoginCss'));
this.emailError = ko.observable(false);
this.loginError = ko.observable(false);
this.passwordError = ko.observable(false);
this.emailFocus = ko.observable(false);
this.loginFocus = ko.observable(false);
this.submitFocus = ko.observable(false);
this.email.subscribe(function () {
@ -39,10 +36,6 @@ function LoginViewModel()
this.additionalCode.visibility(false);
}, this);
this.login.subscribe(function () {
this.loginError(false);
}, this);
this.password.subscribe(function () {
this.passwordError(false);
}, this);
@ -58,7 +51,6 @@ function LoginViewModel()
this.submitRequest = ko.observable(false);
this.submitError = ko.observable('');
this.allowCustomLogin = oData.allowCustomLogin;
this.allowLanguagesOnLogin = oData.allowLanguagesOnLogin;
this.langRequest = ko.observable(false);
@ -136,7 +128,7 @@ function LoginViewModel()
this.submitError(Utils.getNotification(Enums.Notification.UnknownError));
}
}, this), this.email(), this.allowCustomLogin() ? this.login() : '', this.password(), !!this.signMe(),
}, this), this.email(), '', this.password(), !!this.signMe(),
this.bSendLanguage ? this.mainLanguage() : '',
this.additionalCode.visibility() ? this.additionalCode() : '',
this.additionalCode.visibility() ? !!this.additionalCodeSignMe() : false
@ -181,13 +173,6 @@ function LoginViewModel()
return !this.submitRequest() && this.twitterLoginEnabled();
});
this.loginFocus.subscribe(function (bValue) {
if (bValue && '' === this.login() && '' !== this.email())
{
this.login(this.email());
}
}, this);
this.socialLoginEnabled = ko.computed(function () {
var
@ -270,7 +255,6 @@ LoginViewModel.prototype.onBuild = function ()
}
this.email(RL.data().devEmail);
this.login(RL.data().devLogin);
this.password(RL.data().devPassword);
if (this.googleLoginEnabled())

View file

@ -9,32 +9,23 @@ function PopupsAddAccountViewModel()
KnoinAbstractViewModel.call(this, 'Popups', 'PopupsAddAccount');
this.email = ko.observable('');
this.login = ko.observable('');
this.password = ko.observable('');
this.emailError = ko.observable(false);
this.loginError = ko.observable(false);
this.passwordError = ko.observable(false);
this.email.subscribe(function () {
this.emailError(false);
}, this);
this.login.subscribe(function () {
this.loginError(false);
}, this);
this.password.subscribe(function () {
this.passwordError(false);
}, this);
this.allowCustomLogin = RL.data().allowCustomLogin;
this.submitRequest = ko.observable(false);
this.submitError = ko.observable('');
this.emailFocus = ko.observable(false);
this.loginFocus = ko.observable(false);
this.addAccountCommand = Utils.createCommand(this, function () {
@ -68,7 +59,7 @@ function PopupsAddAccountViewModel()
this.submitError(Utils.getNotification(Enums.Notification.UnknownError));
}
}, this), this.email(), this.allowCustomLogin() ? this.login() : '', this.password());
}, this), this.email(), '', this.password());
return true;
@ -76,13 +67,6 @@ function PopupsAddAccountViewModel()
return !this.submitRequest();
});
this.loginFocus.subscribe(function (bValue) {
if (bValue && '' === this.login() && '' !== this.email())
{
this.login(this.email());
}
}, this);
Knoin.constructorEnd(this);
}
@ -91,11 +75,9 @@ Utils.extendAsViewModel('PopupsAddAccountViewModel', PopupsAddAccountViewModel);
PopupsAddAccountViewModel.prototype.clearPopup = function ()
{
this.email('');
this.login('');
this.password('');
this.emailError(false);
this.loginError(false);
this.passwordError(false);
this.submitRequest(false);

View file

@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2014 RainLoop Team
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View file

@ -0,0 +1 @@
1.0

View file

@ -0,0 +1,53 @@
<?php
class CustomLoginMappingPlugin extends \RainLoop\Plugins\AbstractPlugin
{
public function Init()
{
$this->addHook('filter.login-credentials', 'FilterLoginСredentials');
}
/**
* @param string $sEmail
* @param string $sLogin
* @param string $sPassword
*
* @throws \RainLoop\Exceptions\ClientException
*/
public function FilterLoginСredentials(&$sEmail, &$sLogin, &$sPassword)
{
$sMapping = \trim($this->Config()->Get('plugin', 'mapping', ''));
if (!empty($sMapping))
{
$aLines = \explode("\n", \preg_replace('/[\r\n\t\s]+/', "\n", $sMapping));
foreach ($aLines as $sLine)
{
if (false !== strpos($sLine, ':'))
{
$aData = \explode(':', $sLine, 2);
if (is_array($aData) && !empty($aData[0]) && isset($aData[1]))
{
$aData = \array_map('trim', $aData);
if ($sEmail === $aData[0] && 0 < strlen($aData[1]))
{
$sLogin = $aData[1];
}
}
}
}
}
}
/**
* @return array
*/
public function configMapping()
{
return array(
\RainLoop\Plugins\Property::NewInstance('mapping')->SetLabel('Mapping')
->SetType(\RainLoop\Enumerations\PluginPropertyType::STRING_TEXT)
->SetDescription('email:login mapping')
->SetDefaultValue("user@domain.com:user.bob\nadmin@domain.com:user.john")
);
}
}

View file

@ -40,18 +40,16 @@ class Account
* @param string $sPassword
* @param \RainLoop\Domain $oDomain
* @param string $sSignMeToken = ''
* @param string $sParentEmail = '';
*
* @return void
*/
protected function __construct($sEmail, $sLogin, $sPassword, \RainLoop\Domain $oDomain, $sSignMeToken = '', $sParentEmail = '')
protected function __construct($sEmail, $sLogin, $sPassword, \RainLoop\Domain $oDomain, $sSignMeToken = '')
{
$this->sEmail = \MailSo\Base\Utils::IdnToAscii($sEmail, true);
$this->sLogin = \MailSo\Base\Utils::IdnToAscii($sLogin);
$this->sPassword = $sPassword;
$this->oDomain = $oDomain;
$this->sSignMeToken = $sSignMeToken;
$this->sParentEmail = \MailSo\Base\Utils::IdnToAscii($sParentEmail, true);
}
/**
@ -60,13 +58,12 @@ class Account
* @param string $sPassword
* @param \RainLoop\Domain $oDomain
* @param string $sSignMeToken = ''
* @param string $sParentEmail = ''
*
* @return \RainLoop\Account
*/
public static function NewInstance($sEmail, $sLogin, $sPassword, \RainLoop\Domain $oDomain, $sSignMeToken = '', $sParentEmail = '')
public static function NewInstance($sEmail, $sLogin, $sPassword, \RainLoop\Domain $oDomain, $sSignMeToken = '')
{
return new self($sEmail, $sLogin, $sPassword, $oDomain, $sSignMeToken, $sParentEmail);
return new self($sEmail, $sLogin, $sPassword, $oDomain, $sSignMeToken);
}
/**

View file

@ -1018,7 +1018,6 @@ class Actions
'MailToEmail' => '',
'Email' => '',
'DevEmail' => '',
'DevLogin' => '',
'DevPassword' => '',
'Title' => 'RainLoop Webmail',
'LoadingDescription' => 'RainLoop',
@ -1031,7 +1030,6 @@ class Actions
'AllowHtmlEditorSourceButton' => (bool) $oConfig->Get('labs', 'allow_html_editor_source_button', false),
'CustomLoginLink' => $oConfig->Get('labs', 'custom_login_link', ''),
'CustomLogoutLink' => $oConfig->Get('labs', 'custom_logout_link', ''),
'AllowCustomLogin' => (bool) $oConfig->Get('login', 'allow_custom_login', false),
'LoginDefaultDomain' => $oConfig->Get('login', 'default_domain', ''),
'DetermineUserLanguage' => (bool) $oConfig->Get('login', 'determine_user_language', true),
'ContactsIsAllowed' => false,
@ -1116,7 +1114,6 @@ class Actions
else
{
$aResult['DevEmail'] = $oConfig->Get('labs', 'dev_email', '');
$aResult['DevLogin'] = $oConfig->Get('labs', 'dev_login', '');
$aResult['DevPassword'] = $oConfig->Get('labs', 'dev_password', '');
}
@ -1216,7 +1213,6 @@ class Actions
$aResult['Languages'] = $this->GetLanguages();
$aResult['AllowLanguagesOnSettings'] = (bool) $oConfig->Get('webmail', 'allow_languages_on_settings', true);
$aResult['AllowLanguagesOnLogin'] = (bool) $oConfig->Get('login', 'allow_languages_on_login', true);
$aResult['AllowCustomLogin'] = (bool) $oConfig->Get('login', 'allow_custom_login', false);
$aResult['AttachmentLimit'] = ((int) $oConfig->Get('webmail', 'attachment_size_limit', 10)) * 1024 * 1024;
$aResult['SignMe'] = (string) $oConfig->Get('login', 'sign_me_auto', \RainLoop\Enumerations\SignMeType::DEFAILT_OFF);
@ -1333,7 +1329,6 @@ class Actions
$aResult['ParentEmail'] = \MailSo\Base\Utils::IdnToUtf8($aResult['ParentEmail']);
$aResult['MailToEmail'] = \MailSo\Base\Utils::IdnToUtf8($aResult['MailToEmail']);
$aResult['DevEmail'] = \MailSo\Base\Utils::IdnToUtf8($aResult['DevEmail']);
$aResult['DevLogin'] = \MailSo\Base\Utils::IdnToUtf8($aResult['DevLogin']);
$this->Plugins()->InitAppData($bAdmin, $aResult);
@ -1439,11 +1434,6 @@ class Actions
$sEmail = $sEmail.'@'.\trim(\trim($this->Config()->Get('login', 'default_domain', '')), ' @');
}
if (!$this->Config()->Get('login', 'allow_custom_login', false) || 0 === \strlen($sLogin))
{
$sLogin = $sEmail;
}
if (0 === \strlen($sLogin))
{
$sLogin = $sEmail;
@ -1540,7 +1530,6 @@ class Actions
public function DoLogin()
{
$sEmail = \trim($this->GetActionParam('Email', ''));
$sLogin = \trim($this->GetActionParam('Login', ''));
$sPassword = $this->GetActionParam('Password', '');
$sLanguage = $this->GetActionParam('Language', '');
$bSignMe = '1' === (string) $this->GetActionParam('SignMe', '0');
@ -1554,6 +1543,7 @@ class Actions
try
{
$sLogin = '';
$oAccount = $this->LoginProcess($sEmail, $sLogin, $sPassword,
$bSignMe ? \md5(\microtime(true).APP_SALT.\rand(10000, 99999).$sEmail) : '',
$sAdditionalCode, $bAdditionalCodeSignMe);
@ -2184,7 +2174,6 @@ class Actions
$this->setConfigFromParams($oConfig, 'AllowLanguagesOnSettings', 'webmail', 'allow_languages_on_settings', 'bool');
$this->setConfigFromParams($oConfig, 'AllowLanguagesOnLogin', 'login', 'allow_languages_on_login', 'bool');
$this->setConfigFromParams($oConfig, 'AllowCustomLogin', 'login', 'allow_custom_login', 'bool');
$this->setConfigFromParams($oConfig, 'AttachmentLimit', 'webmail', 'attachment_size_limit', 'int');
$this->setConfigFromParams($oConfig, 'LoginDefaultDomain', 'login', 'default_domain', 'string');

View file

@ -112,9 +112,6 @@ class Application extends \RainLoop\Config\AbstractConfig
'login' => array(
'allow_custom_login' => array(false,
'Enable additional Login field on webmail login screen'),
'default_domain' => array('', ''),
'allow_languages_on_login' => array(true,
@ -249,7 +246,6 @@ Enables caching in the system'),
'fast_cache_memcache_port' => array(11211),
'fast_cache_memcache_expire' => array(43200),
'dev_email' => array(''),
'dev_login' => array(''),
'dev_password' => array('')
)
);

View file

@ -23,11 +23,6 @@
<i data-bind="css: determineUserLanguage() ? 'icon-checkbox-checked' : 'icon-checkbox-unchecked'"></i>
Try to determine user language
</label>
<br />
<label data-bind="click: function () { allowCustomLogin(!allowCustomLogin()); }">
<i data-bind="css: allowCustomLogin() ? 'icon-checkbox-checked' : 'icon-checkbox-unchecked'"></i>
Enable additional Login field on login screen
</label>
</div>
</div>
</div>

View file

@ -27,15 +27,6 @@
</span>
</div>
</div>
<div class="control-group" data-bind="css: {'error': loginError}, visible: allowCustomLogin()">
<div class="input-append">
<input type="email" class="i18n inputLogin span4" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
data-bind="value: login, hasFocus: loginFocus" data-i18n-placeholder="LOGIN/LABEL_LOGIN" />
<span class="add-on">
<i class="icon-user"></i>
</span>
</div>
</div>
<div class="control-group" data-bind="css: {'error': passwordError}">
<div class="input-append">
<input type="password" class="i18n inputPassword span4" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"

View file

@ -21,13 +21,6 @@
data-bind="value: email, valueUpdate: 'afterkeydown', onEnter: addAccountCommand, hasfocus: emailFocus" />
</div>
</div>
<div class="control-group" data-bind="css: {'error': loginError}, visible: allowCustomLogin()">
<label class="i18n control-label" data-i18n-text="LOGIN/LABEL_LOGIN"></label>
<div class="controls">
<input type="email" class="inputLogin input-large" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
data-bind="value: login, onEnter: addAccountCommand, hasfocus: loginFocus" />
</div>
</div>
<div class="control-group" data-bind="css: {'error': passwordError}">
<label class="i18n control-label" data-i18n-text="LOGIN/LABEL_PASSWORD"></label>
<div class="controls">

View file

@ -9203,7 +9203,7 @@ html.rl-message-fullscreen .messageView .b-content .buttonFull {
}
.b-plugin-content textarea {
width: 400px;
height: 50px;
height: 70px;
}
.b-admin-about .rl-logo {
display: inline-block;

File diff suppressed because one or more lines are too long

View file

@ -1572,7 +1572,6 @@ Utils.initDataConstructorBySettings = function (oData)
Globals.sAnimationType = Enums.InterfaceAnimation.Full;
oData.capaThemes = ko.observable(false);
oData.allowCustomLogin = ko.observable(false);
oData.allowLanguagesOnSettings = ko.observable(true);
oData.allowLanguagesOnLogin = ko.observable(true);
@ -6179,7 +6178,6 @@ function AdminLogin()
{
var oData = RL.data();
this.allowCustomLogin = oData.allowCustomLogin;
this.determineUserLanguage = oData.determineUserLanguage;
this.defaultDomain = ko.observable(RL.settingsGet('LoginDefaultDomain'));
@ -6203,12 +6201,6 @@ AdminLogin.prototype.onBuild = function ()
});
});
self.allowCustomLogin.subscribe(function (bValue) {
RL.remote().saveAdminConfig(null, {
'AllowCustomLogin': bValue ? '1' : '0'
});
});
self.allowLanguagesOnLogin.subscribe(function (bValue) {
RL.remote().saveAdminConfig(null, {
'AllowLanguagesOnLogin': bValue ? '1' : '0'
@ -7259,7 +7251,6 @@ AbstractData.prototype.populateDataOnStart = function()
this.determineUserLanguage(!!RL.settingsGet('DetermineUserLanguage'));
this.capaThemes(RL.capa(Enums.Capa.Themes));
this.allowCustomLogin(!!RL.settingsGet('AllowCustomLogin'));
this.allowLanguagesOnLogin(!!RL.settingsGet('AllowLanguagesOnLogin'));
this.allowLanguagesOnSettings(!!RL.settingsGet('AllowLanguagesOnSettings'));

File diff suppressed because one or more lines are too long

View file

@ -1575,7 +1575,6 @@ Utils.initDataConstructorBySettings = function (oData)
Globals.sAnimationType = Enums.InterfaceAnimation.Full;
oData.capaThemes = ko.observable(false);
oData.allowCustomLogin = ko.observable(false);
oData.allowLanguagesOnSettings = ko.observable(true);
oData.allowLanguagesOnLogin = ko.observable(true);
@ -11080,32 +11079,23 @@ function PopupsAddAccountViewModel()
KnoinAbstractViewModel.call(this, 'Popups', 'PopupsAddAccount');
this.email = ko.observable('');
this.login = ko.observable('');
this.password = ko.observable('');
this.emailError = ko.observable(false);
this.loginError = ko.observable(false);
this.passwordError = ko.observable(false);
this.email.subscribe(function () {
this.emailError(false);
}, this);
this.login.subscribe(function () {
this.loginError(false);
}, this);
this.password.subscribe(function () {
this.passwordError(false);
}, this);
this.allowCustomLogin = RL.data().allowCustomLogin;
this.submitRequest = ko.observable(false);
this.submitError = ko.observable('');
this.emailFocus = ko.observable(false);
this.loginFocus = ko.observable(false);
this.addAccountCommand = Utils.createCommand(this, function () {
@ -11139,7 +11129,7 @@ function PopupsAddAccountViewModel()
this.submitError(Utils.getNotification(Enums.Notification.UnknownError));
}
}, this), this.email(), this.allowCustomLogin() ? this.login() : '', this.password());
}, this), this.email(), '', this.password());
return true;
@ -11147,13 +11137,6 @@ function PopupsAddAccountViewModel()
return !this.submitRequest();
});
this.loginFocus.subscribe(function (bValue) {
if (bValue && '' === this.login() && '' !== this.email())
{
this.login(this.email());
}
}, this);
Knoin.constructorEnd(this);
}
@ -11162,11 +11145,9 @@ Utils.extendAsViewModel('PopupsAddAccountViewModel', PopupsAddAccountViewModel);
PopupsAddAccountViewModel.prototype.clearPopup = function ()
{
this.email('');
this.login('');
this.password('');
this.emailError(false);
this.loginError(false);
this.passwordError(false);
this.submitRequest(false);
@ -12088,7 +12069,6 @@ function LoginViewModel()
var oData = RL.data();
this.email = ko.observable('');
this.login = ko.observable('');
this.password = ko.observable('');
this.signMe = ko.observable(false);
@ -12103,11 +12083,9 @@ function LoginViewModel()
this.logoCss = Utils.trim(RL.settingsGet('LoginCss'));
this.emailError = ko.observable(false);
this.loginError = ko.observable(false);
this.passwordError = ko.observable(false);
this.emailFocus = ko.observable(false);
this.loginFocus = ko.observable(false);
this.submitFocus = ko.observable(false);
this.email.subscribe(function () {
@ -12116,10 +12094,6 @@ function LoginViewModel()
this.additionalCode.visibility(false);
}, this);
this.login.subscribe(function () {
this.loginError(false);
}, this);
this.password.subscribe(function () {
this.passwordError(false);
}, this);
@ -12135,7 +12109,6 @@ function LoginViewModel()
this.submitRequest = ko.observable(false);
this.submitError = ko.observable('');
this.allowCustomLogin = oData.allowCustomLogin;
this.allowLanguagesOnLogin = oData.allowLanguagesOnLogin;
this.langRequest = ko.observable(false);
@ -12213,7 +12186,7 @@ function LoginViewModel()
this.submitError(Utils.getNotification(Enums.Notification.UnknownError));
}
}, this), this.email(), this.allowCustomLogin() ? this.login() : '', this.password(), !!this.signMe(),
}, this), this.email(), '', this.password(), !!this.signMe(),
this.bSendLanguage ? this.mainLanguage() : '',
this.additionalCode.visibility() ? this.additionalCode() : '',
this.additionalCode.visibility() ? !!this.additionalCodeSignMe() : false
@ -12258,13 +12231,6 @@ function LoginViewModel()
return !this.submitRequest() && this.twitterLoginEnabled();
});
this.loginFocus.subscribe(function (bValue) {
if (bValue && '' === this.login() && '' !== this.email())
{
this.login(this.email());
}
}, this);
this.socialLoginEnabled = ko.computed(function () {
var
@ -12347,7 +12313,6 @@ LoginViewModel.prototype.onBuild = function ()
}
this.email(RL.data().devEmail);
this.login(RL.data().devLogin);
this.password(RL.data().devPassword);
if (this.googleLoginEnabled())
@ -15816,7 +15781,6 @@ AbstractData.prototype.populateDataOnStart = function()
this.determineUserLanguage(!!RL.settingsGet('DetermineUserLanguage'));
this.capaThemes(RL.capa(Enums.Capa.Themes));
this.allowCustomLogin(!!RL.settingsGet('AllowCustomLogin'));
this.allowLanguagesOnLogin(!!RL.settingsGet('AllowLanguagesOnLogin'));
this.allowLanguagesOnSettings(!!RL.settingsGet('AllowLanguagesOnSettings'));
@ -15888,7 +15852,6 @@ function WebMailDataStorage()
;
this.devEmail = '';
this.devLogin = '';
this.devPassword = '';
this.accountEmail = ko.observable('');
@ -16346,7 +16309,6 @@ WebMailDataStorage.prototype.populateDataOnStart = function()
this.remoteSuggestions = !!RL.settingsGet('RemoteSuggestions');
this.devEmail = RL.settingsGet('DevEmail');
this.devLogin = RL.settingsGet('DevLogin');
this.devPassword = RL.settingsGet('DevPassword');
};

File diff suppressed because one or more lines are too long