diff --git a/dev/App/Abstract.jsx b/dev/App/Abstract.jsx index 69edd66b3..3791a03b1 100644 --- a/dev/App/Abstract.jsx +++ b/dev/App/Abstract.jsx @@ -271,7 +271,7 @@ class AbstractApp extends AbstractBoot ko.components.register('TextArea', require('Component/TextArea')); ko.components.register('x-script', require('Component/Script')); - ko.components.register('svg-icon', require('Component/SvgIcon')); +// ko.components.register('svg-icon', require('Component/SvgIcon')); if (/**false && /**/Settings.settingsGet('MaterialDesign') && Globals.bAnimationSupported) { diff --git a/dev/App/User.jsx b/dev/App/User.jsx index 20e453a58..df8dbe5ce 100644 --- a/dev/App/User.jsx +++ b/dev/App/User.jsx @@ -15,7 +15,6 @@ import Translator from 'Common/Translator'; import Momentor from 'Common/Momentor'; import Cache from 'Common/Cache'; - import SocialStore from 'Stores/Social'; import SettingsStore from 'Stores/User/Settings'; import AccountStore from 'Stores/User/Account'; @@ -514,7 +513,7 @@ class AppUser extends AbstractApp Utils.delegateRunOnDestroy(AccountStore.accounts()); - AccountStore.accounts(_.map(oData.Result['Accounts'], + AccountStore.accounts(_.map(oData.Result['Accounts'], (sValue) => new AccountModel(sValue, sValue !== sParentEmail, aCounts[sValue] || 0))); } @@ -914,7 +913,7 @@ class AppUser extends AbstractApp Remote.suggestions((result, data) => { if (Enums.StorageResultType.Success === result && data && Utils.isArray(data.Result)) { - callback(_.compact(_.map(data.Result, + callback(_.compact(_.map(data.Result, (item) => item && item[0] ? new EmailModel(item[0], item[1]) : null))); } else if (Enums.StorageResultType.Abort !== result) @@ -1401,7 +1400,7 @@ class AppUser extends AbstractApp fallback: false }); - Events.sub('mailbox.inbox-unread-count', + Events.sub('mailbox.inbox-unread-count', (iCount) => Tinycon.setBubble(0 < iCount ? (99 < iCount ? 99 : iCount) : 0)); } } diff --git a/dev/Common/Translator.jsx b/dev/Common/Translator.jsx index 1cf3afa02..ce8b4fe6c 100644 --- a/dev/Common/Translator.jsx +++ b/dev/Common/Translator.jsx @@ -233,11 +233,23 @@ class Translator return message; } + defCode = defCode ? (window.parseInt(defCode, 10)) || 0 : 0; return _.isUndefined(this.notificationI18N[code]) ? ( defCode && _.isUndefined(this.notificationI18N[defCode]) ? this.notificationI18N[defCode] : '' ) : this.notificationI18N[code]; } + /** + * @param {object} response + * @param {number} defCode = Notification.UnknownNotification + * @return {string} + */ + getNotificationFromResponse(response, defCode = Notification.UnknownNotification) { + return response && response.ErrorCode ? + this.getNotification(Utils.pInt(response.ErrorCode), response.ErrorMessage || '') : + this.getNotification(defCode); + } + /** * @param {*} code * @return {string} diff --git a/dev/Component/SvgIcon.jsx b/dev/Component/SvgIcon.jsx index b653056be..47d740f14 100644 --- a/dev/Component/SvgIcon.jsx +++ b/dev/Component/SvgIcon.jsx @@ -6,7 +6,7 @@ let getUtl = () => { if (!cachedUrl) { - const version = $('#rlAppVersion').attr('content') || '0.0.0'; + const version = $('#rlAppVersion').attr('content') || '0.0.0'; // TODO cachedUrl = `rainloop/v/${version}/static/css/svg/icons.svg`; } diff --git a/dev/Settings/User/ChangePassword.js b/dev/Settings/User/ChangePassword.js index e2ca86bd8..e132a6b63 100644 --- a/dev/Settings/User/ChangePassword.js +++ b/dev/Settings/User/ChangePassword.js @@ -114,8 +114,8 @@ } this.passwordUpdateError(true); - this.errorDescription(oData && oData.ErrorCode ? Translator.getNotification(oData.ErrorCode) : - Translator.getNotification(Enums.Notification.CouldNotSaveNewPassword)); + this.errorDescription( + Translator.getNotificationFromResponse(oData, Enums.Notification.CouldNotSaveNewPassword)); } }; diff --git a/dev/View/User/Login.js b/dev/View/User/Login.js index 9b73befb6..3c267e397 100644 --- a/dev/View/User/Login.js +++ b/dev/View/User/Login.js @@ -230,7 +230,7 @@ oData.ErrorCode = Enums.Notification.AuthError; } - this.submitError(Translator.getNotification(oData.ErrorCode)); + this.submitError(Translator.getNotificationFromResponse(oData)); if ('' === this.submitError()) { @@ -344,6 +344,11 @@ return bF || bG || bT; }, this); + if (Settings.settingsGet('AdditionalLoginError') && !this.submitError()) + { + this.submitError(Settings.settingsGet('AdditionalLoginError')); + } + kn.constructorEnd(this); } 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 aced6b6bf..adecf41a9 100644 --- a/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php +++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php @@ -12,8 +12,8 @@ class Actions const AUTH_MAILTO_TOKEN_KEY = 'rlmailtoauth'; const AUTH_SPEC_TOKEN_KEY = 'rlspecauth'; const AUTH_SPEC_LOGOUT_TOKEN_KEY = 'rlspeclogout'; + const AUTH_SPEC_LOGOUT_CUSTOM_MSG_KEY = 'rlspeclogoutcmk'; const AUTH_ADMIN_TOKEN_KEY = 'rlaauth'; - const AUTH_LAST_ERROR = 'rllasterrorcode'; /** * @var \MailSo\Base\Http @@ -644,6 +644,28 @@ class Actions return $sResult; } + /** + * @return string + */ + public function GetSpecLogoutCustomMgsWithDeletion() + { + $sResult = \RainLoop\Utils::GetCookie(self::AUTH_SPEC_LOGOUT_CUSTOM_MSG_KEY, ''); + if (0 < strlen($sResult)) + { + \RainLoop\Utils::ClearCookie(self::AUTH_SPEC_LOGOUT_CUSTOM_MSG_KEY); + } + + return $sResult; + } + + /** + * @return string + */ + public function SetSpecLogoutCustomMgsWithDeletion($sMessage) + { + \RainLoop\Utils::SetCookie(self::AUTH_SPEC_LOGOUT_CUSTOM_MSG_KEY, $sMessage, 0); + } + /** * @return void */ @@ -1597,6 +1619,11 @@ class Actions $aResult['WelcomePageDisplay'] = ''; $aResult['StartupUrl'] = ''; + + if (empty($aResult['AdditionalLoginError'])) + { + $aResult['AdditionalLoginError'] = $this->GetSpecLogoutCustomMgsWithDeletion(); + } } $aResult['AllowGoogleSocial'] = (bool) $oConfig->Get('social', 'google_enable', false); diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/Exceptions/ClientException.php b/rainloop/v/0.0.0/app/libraries/RainLoop/Exceptions/ClientException.php index e15961ea3..7b726bf26 100644 --- a/rainloop/v/0.0.0/app/libraries/RainLoop/Exceptions/ClientException.php +++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Exceptions/ClientException.php @@ -9,17 +9,29 @@ namespace RainLoop\Exceptions; class ClientException extends Exception { /** - * + * @var boolen + */ + private $bLogoutOnException; + + /** * @var string */ private $sAdditionalMessage; - public function __construct($iCode, $oPrevious = null, $sAdditionalMessage = '') + /** + * @param int $iCode + * @param \Exception $oPrevious = null + * @param string $sAdditionalMessage = '' + * @param boolean $bLogoutOnException = false + */ + public function __construct($iCode, $oPrevious = null, $sAdditionalMessage = '', $bLogoutOnException = false) { parent::__construct(\RainLoop\Notifications::GetNotificationsMessage($iCode, $oPrevious), $iCode, $oPrevious); $this->sAdditionalMessage = $sAdditionalMessage; + + $this->setLogoutOnException($bLogoutOnException); } /** @@ -29,4 +41,27 @@ class ClientException extends Exception { return $this->sAdditionalMessage; } + + /** + * @return boolen + */ + public function getLogoutOnException() + { + return $this->bLogoutOnException; + } + + /** + * @param boolean $bLogoutOnException + * @param string $sAdditionalLogoutMessage = '' + * + * @return ClientException + */ + public function setLogoutOnException($bLogoutOnException, $sAdditionalLogoutMessage = '') + { + $this->bLogoutOnException = !!$bLogoutOnException; + + $this->sAdditionalMessage = $sAdditionalLogoutMessage; + + return $this; + } } diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/Service.php b/rainloop/v/0.0.0/app/libraries/RainLoop/Service.php index 0ec0bc0a0..7fcffbf1a 100644 --- a/rainloop/v/0.0.0/app/libraries/RainLoop/Service.php +++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Service.php @@ -192,14 +192,14 @@ class Service } $sResult .= '