diff --git a/dev/App/Abstract.js b/dev/App/Abstract.js index c23d6c5c4..594c45e7e 100644 --- a/dev/App/Abstract.js +++ b/dev/App/Abstract.js @@ -202,6 +202,20 @@ } }; + /** + * @param {string} sKey + */ + AbstractApp.prototype.setClientSideToken = function (sKey) + { + if (window.__rlah_set) + { + window.__rlah_set(sKey); + + require('Storage/Settings').settingsSet('AuthAccountHash', sKey); + require('Common/Links').populateAuthSuffix(); + } + }; + /** * @param {boolean=} bAdmin = false * @param {boolean=} bLogout = false diff --git a/dev/App/User.js b/dev/App/User.js index 238016086..2988b4331 100644 --- a/dev/App/User.js +++ b/dev/App/User.js @@ -1463,7 +1463,7 @@ } else { - this.bootstartLoginScreen(); + this.loginAndLogoutReload(false, true); } }, self)); diff --git a/dev/Common/Links.js b/dev/Common/Links.js index ecabdc80b..dee0181d9 100644 --- a/dev/Common/Links.js +++ b/dev/Common/Links.js @@ -19,12 +19,17 @@ this.sServer = './?'; this.sVersion = Settings.settingsGet('Version'); - this.sSpecSuffix = Settings.settingsGet('AuthAccountHash') || '0'; + this.sAuthSuffix = Settings.settingsGet('AuthAccountHash') || '0'; this.sWebPrefix = Settings.settingsGet('WebPath') || ''; this.sVersionPrefix = Settings.settingsGet('WebVersionPath') || 'rainloop/v/' + this.sVersion + '/'; this.sStaticPrefix = this.sVersionPrefix + 'static/'; } + Links.prototype.populateAuthSuffix = function () + { + this.sAuthSuffix = require('Storage/Settings').settingsGet('AuthAccountHash') || '0'; + }; + /** * @return {string} */ @@ -64,7 +69,7 @@ */ Links.prototype.attachmentDownload = function (sDownload, sCustomSpecSuffix) { - sCustomSpecSuffix = Utils.isUnd(sCustomSpecSuffix) ? this.sSpecSuffix : sCustomSpecSuffix; + sCustomSpecSuffix = Utils.isUnd(sCustomSpecSuffix) ? this.sAuthSuffix : sCustomSpecSuffix; return this.sServer + '/Raw/' + this.subQueryPrefix() + '/' + sCustomSpecSuffix + '/Download/' + this.subQueryPrefix() + '/' + sDownload; }; @@ -76,7 +81,7 @@ */ Links.prototype.attachmentPreview = function (sDownload, sCustomSpecSuffix) { - sCustomSpecSuffix = Utils.isUnd(sCustomSpecSuffix) ? this.sSpecSuffix : sCustomSpecSuffix; + sCustomSpecSuffix = Utils.isUnd(sCustomSpecSuffix) ? this.sAuthSuffix : sCustomSpecSuffix; return this.sServer + '/Raw/' + this.subQueryPrefix() + '/' + sCustomSpecSuffix + '/View/' + this.subQueryPrefix() + '/' + sDownload; }; @@ -88,7 +93,7 @@ */ Links.prototype.attachmentThumbnailPreview = function (sDownload, sCustomSpecSuffix) { - sCustomSpecSuffix = Utils.isUnd(sCustomSpecSuffix) ? this.sSpecSuffix : sCustomSpecSuffix; + sCustomSpecSuffix = Utils.isUnd(sCustomSpecSuffix) ? this.sAuthSuffix : sCustomSpecSuffix; return this.sServer + '/Raw/' + this.subQueryPrefix() + '/' + sCustomSpecSuffix + '/ViewThumbnail/' + this.subQueryPrefix() + '/' + sDownload; }; @@ -100,7 +105,7 @@ */ Links.prototype.attachmentPreviewAsPlain = function (sDownload, sCustomSpecSuffix) { - sCustomSpecSuffix = Utils.isUnd(sCustomSpecSuffix) ? this.sSpecSuffix : sCustomSpecSuffix; + sCustomSpecSuffix = Utils.isUnd(sCustomSpecSuffix) ? this.sAuthSuffix : sCustomSpecSuffix; return this.sServer + '/Raw/' + this.subQueryPrefix() + '/' + sCustomSpecSuffix + '/ViewAsPlain/' + this.subQueryPrefix() + '/' + sDownload; }; @@ -112,7 +117,7 @@ */ Links.prototype.attachmentFramed = function (sDownload, sCustomSpecSuffix) { - sCustomSpecSuffix = Utils.isUnd(sCustomSpecSuffix) ? this.sSpecSuffix : sCustomSpecSuffix; + sCustomSpecSuffix = Utils.isUnd(sCustomSpecSuffix) ? this.sAuthSuffix : sCustomSpecSuffix; return this.sServer + '/Raw/' + this.subQueryPrefix() + '/' + sCustomSpecSuffix + '/FramedView/' + this.subQueryPrefix() + '/' + sDownload; }; @@ -122,7 +127,7 @@ */ Links.prototype.upload = function () { - return this.sServer + '/Upload/' + this.subQueryPrefix() + '/' + this.sSpecSuffix + '/'; + return this.sServer + '/Upload/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/'; }; /** @@ -130,7 +135,7 @@ */ Links.prototype.uploadContacts = function () { - return this.sServer + '/UploadContacts/' + this.subQueryPrefix() + '/' + this.sSpecSuffix + '/'; + return this.sServer + '/UploadContacts/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/'; }; /** @@ -138,7 +143,7 @@ */ Links.prototype.uploadBackground = function () { - return this.sServer + '/UploadBackground/' + this.subQueryPrefix() + '/' + this.sSpecSuffix + '/'; + return this.sServer + '/UploadBackground/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/'; }; /** @@ -146,7 +151,7 @@ */ Links.prototype.append = function () { - return this.sServer + '/Append/' + this.subQueryPrefix() + '/' + this.sSpecSuffix + '/'; + return this.sServer + '/Append/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/'; }; /** @@ -155,7 +160,7 @@ */ Links.prototype.change = function (sEmail) { - return this.sServer + '/Change/' + this.subQueryPrefix() + '/' + this.sSpecSuffix + '/' + Utils.encodeURIComponent(sEmail) + '/'; + return this.sServer + '/Change/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/' + Utils.encodeURIComponent(sEmail) + '/'; }; /** @@ -164,7 +169,7 @@ */ Links.prototype.ajax = function (sAdd) { - return this.sServer + '/Ajax/' + this.subQueryPrefix() + '/' + this.sSpecSuffix + '/' + sAdd; + return this.sServer + '/Ajax/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/' + sAdd; }; /** @@ -173,7 +178,7 @@ */ Links.prototype.messageViewLink = function (sRequestHash) { - return this.sServer + '/Raw/' + this.subQueryPrefix() + '/' + this.sSpecSuffix + '/ViewAsPlain/' + this.subQueryPrefix() + '/' + sRequestHash; + return this.sServer + '/Raw/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/ViewAsPlain/' + this.subQueryPrefix() + '/' + sRequestHash; }; /** @@ -182,7 +187,7 @@ */ Links.prototype.messageDownloadLink = function (sRequestHash) { - return this.sServer + '/Raw/' + this.subQueryPrefix() + '/' + this.sSpecSuffix + '/Download/' + this.subQueryPrefix() + '/' + sRequestHash; + return this.sServer + '/Raw/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/Download/' + this.subQueryPrefix() + '/' + sRequestHash; }; /** @@ -209,7 +214,7 @@ */ Links.prototype.userBackground = function (sHash) { - return this.sServer + '/Raw/' + this.subQueryPrefix() + '/' + this.sSpecSuffix + + return this.sServer + '/Raw/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/UserBackground/' + this.subQueryPrefix() + '/' + sHash; }; @@ -327,7 +332,7 @@ */ Links.prototype.exportContactsVcf = function () { - return this.sServer + '/Raw/' + this.subQueryPrefix() + '/' + this.sSpecSuffix + '/ContactsVcf/'; + return this.sServer + '/Raw/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/ContactsVcf/'; }; /** @@ -335,7 +340,7 @@ */ Links.prototype.exportContactsCsv = function () { - return this.sServer + '/Raw/' + this.subQueryPrefix() + '/' + this.sSpecSuffix + '/ContactsCsv/'; + return this.sServer + '/Raw/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/ContactsCsv/'; }; /** @@ -392,7 +397,7 @@ */ Links.prototype.socialGoogle = function () { - return this.sServer + 'SocialGoogle' + ('' !== this.sSpecSuffix ? '/' + this.subQueryPrefix() + '/' + this.sSpecSuffix + '/' : ''); + return this.sServer + 'SocialGoogle' + ('' !== this.sAuthSuffix ? '/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/' : ''); }; /** @@ -400,7 +405,7 @@ */ Links.prototype.socialTwitter = function () { - return this.sServer + 'SocialTwitter' + ('' !== this.sSpecSuffix ? '/' + this.subQueryPrefix() + '/' + this.sSpecSuffix + '/' : ''); + return this.sServer + 'SocialTwitter' + ('' !== this.sAuthSuffix ? '/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/' : ''); }; /** @@ -408,7 +413,7 @@ */ Links.prototype.socialFacebook = function () { - return this.sServer + 'SocialFacebook' + ('' !== this.sSpecSuffix ? '/' + this.subQueryPrefix() + '/' + this.sSpecSuffix + '/' : ''); + return this.sServer + 'SocialFacebook' + ('' !== this.sAuthSuffix ? '/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/' : ''); }; module.exports = new Links(); diff --git a/dev/Promises/AbstractAjax.js b/dev/Promises/AbstractAjax.js index b4418e34d..20d51b54d 100644 --- a/dev/Promises/AbstractAjax.js +++ b/dev/Promises/AbstractAjax.js @@ -10,6 +10,7 @@ Consts = require('Common/Consts'), Enums = require('Common/Enums'), + Globals = require('Common/Globals'), Utils = require('Common/Utils'), Links = require('Common/Links'), Plugins = require('Common/Plugins'), @@ -86,7 +87,7 @@ 'global': true }).always(function (oData, sTextStatus) { - var bCached = false, sType = Enums.StorageResultType.Error; + var bCached = false, oErrorData = null, sType = Enums.StorageResultType.Error; if (oData && oData['Time']) { bCached = Utils.pInt(oData['Time']) > Utils.microtime() - iStart; @@ -115,15 +116,18 @@ } else if (oData && oData.Action) { + oErrorData = oData; oDeferred.reject(oData.ErrorCode ? oData.ErrorCode : Enums.Notification.AjaxFalse); } else { + oErrorData = oData; oDeferred.reject(Enums.Notification.AjaxParse); } } else if ('timeout' === sTextStatus) { + oErrorData = oData; oDeferred.reject(Enums.Notification.AjaxTimeout); } else if ('abort' === sTextStatus) @@ -135,6 +139,7 @@ } else { + oErrorData = oData; oDeferred.reject(Enums.Notification.AjaxParse); } @@ -145,6 +150,45 @@ } self.setTrigger(fTrigger, false); + + if (oErrorData) + { + if (-1 < Utils.inArray(oErrorData.ErrorCode, [ + Enums.Notification.AuthError, Enums.Notification.AccessError, + Enums.Notification.ConnectionError, Enums.Notification.DomainNotAllowed, Enums.Notification.AccountNotAllowed, + Enums.Notification.MailServerError, Enums.Notification.UnknownNotification, Enums.Notification.UnknownError + ])) + { + Globals.iAjaxErrorCount++; + } + + if (Enums.Notification.InvalidToken === oErrorData.ErrorCode) + { + Globals.iTokenErrorCount++; + } + + if (Consts.Values.TokenErrorLimit < Globals.iTokenErrorCount) + { + if (Globals.__APP__ && Globals.__APP__.loginAndLogoutReload) + { + Globals.__APP__.loginAndLogoutReload(false, true); + } + } + + if (oErrorData.ClearAuth || oErrorData.Logout || Consts.Values.AjaxErrorLimit < Globals.iAjaxErrorCount) + { + if (Globals.__APP__ && Globals.__APP__.clearClientSideToken) + { + Globals.__APP__.clearClientSideToken(); + } + + if (Globals.__APP__ && !oErrorData.ClearAuth && Globals.__APP__.loginAndLogoutReload) + { + Globals.__APP__.loginAndLogoutReload(false, true); + } + } + } + }); if (oH) diff --git a/dev/Settings/User/ChangePassword.js b/dev/Settings/User/ChangePassword.js index 8a53619c4..b6fb723e6 100644 --- a/dev/Settings/User/ChangePassword.js +++ b/dev/Settings/User/ChangePassword.js @@ -103,6 +103,8 @@ this.passwordUpdateSuccess(true); this.currentPassword.error(false); + + require('App/User').setClientSideToken(oData.Result); } else { diff --git a/dev/Styles/AdminGeneral.less b/dev/Styles/AdminGeneral.less index 68ee6dd23..6158c72e5 100644 --- a/dev/Styles/AdminGeneral.less +++ b/dev/Styles/AdminGeneral.less @@ -9,7 +9,7 @@ border-bottom: 1px dashed #555; cursor: pointer; - padding: 2px; + padding: 2px 0px; &:focus { outline: 1px; diff --git a/dev/Styles/SettingsGeneral.less b/dev/Styles/SettingsGeneral.less index f8761567a..d4cf39586 100644 --- a/dev/Styles/SettingsGeneral.less +++ b/dev/Styles/SettingsGeneral.less @@ -20,9 +20,10 @@ } .flag-name { + border-bottom: 1px dashed #555; cursor: pointer; - padding: 2px; + padding: 2px 0px; &:focus { outline: 1px; diff --git a/dev/Styles/Ui.less b/dev/Styles/Ui.less index 067883e27..1ac9744da 100644 --- a/dev/Styles/Ui.less +++ b/dev/Styles/Ui.less @@ -196,7 +196,7 @@ e-spinner { color: #333; border-bottom: 1px dashed #333; cursor: pointer; - padding: 2px; + padding: 2px 0px; &:focus { outline: 1px; 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 183b635b6..61a4549c9 100644 --- a/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php +++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php @@ -4811,12 +4811,14 @@ class Actions */ public function DoChangePassword() { + $mResult = false; + $oAccount = $this->getAccountFromToken(); if ($oAccount) { try { - $this->ChangePasswordProvider()->ChangePassword( + $mResult = $this->ChangePasswordProvider()->ChangePassword( $oAccount, $this->GetActionParam('PrevPassword', ''), $this->GetActionParam('NewPassword', '') @@ -4831,7 +4833,7 @@ class Actions } } - return $this->TrueResponse(__FUNCTION__); + return $this->DefaultResponse(__FUNCTION__, $mResult); } /** diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/ChangePassword.php b/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/ChangePassword.php index b344b227c..180b7afc1 100644 --- a/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/ChangePassword.php +++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/ChangePassword.php @@ -53,6 +53,8 @@ class ChangePassword extends \RainLoop\Providers\AbstractProvider */ public function ChangePassword(\RainLoop\Account $oAccount, $sPrevPassword, $sNewPassword) { + $mResult = false; + if ($this->oDriver instanceof \RainLoop\Providers\ChangePassword\ChangePasswordInterface && $this->PasswordChangePossibility($oAccount)) { @@ -79,11 +81,15 @@ class ChangePassword extends \RainLoop\Providers\AbstractProvider $oAccount->SetPassword($sNewPassword); $this->oActions->SetAuthToken($oAccount); + + $mResult = $this->oActions->GetSpecAuthToken(); } else { throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CouldNotSaveNewPassword); } + + return $mResult; } /** diff --git a/rainloop/v/0.0.0/langs/admin/de.ini b/rainloop/v/0.0.0/langs/admin/de.ini index 1c16e126b..694662848 100644 --- a/rainloop/v/0.0.0/langs/admin/de.ini +++ b/rainloop/v/0.0.0/langs/admin/de.ini @@ -130,7 +130,7 @@ LABEL_ENABLE_TWITTER = "Twitter-Integration aktivieren (Autorisierung)" LABEL_TWITTER_CONSUMER_KEY = "Consumer-Schlüssel" LABEL_TWITTER_CONSUMER_SECRET = "Consumer-Geheimnis" LEGEND_DROPBOX = "Dropbox" -LABEL_ENABLE_DROPBOX = "Dropbox-Integration aktivieren (Erstellen-Ansicht)" +LABEL_ENABLE_DROPBOX = "Dropbox-Integration aktivieren" LABEL_DROPBOX_API_KEY = "API-Schlüssel" TOP_ALERT = "Detaillierte Informationen zur Integration von Social-Diensten finden Sie unter" diff --git a/rainloop/v/0.0.0/langs/admin/en.ini b/rainloop/v/0.0.0/langs/admin/en.ini index 6e50110af..99aebd1f7 100644 --- a/rainloop/v/0.0.0/langs/admin/en.ini +++ b/rainloop/v/0.0.0/langs/admin/en.ini @@ -131,7 +131,7 @@ LABEL_ENABLE_TWITTER = "Enable Twitter Integration (Authorization)" LABEL_TWITTER_CONSUMER_KEY = "Consumer Key" LABEL_TWITTER_CONSUMER_SECRET = "Consumer Secret" LEGEND_DROPBOX = "Dropbox" -LABEL_ENABLE_DROPBOX = "Enable Dropbox Integration (Compose view)" +LABEL_ENABLE_DROPBOX = "Enable Dropbox Integration" LABEL_DROPBOX_API_KEY = "Api Key" TOP_ALERT = "Detailed information on social integration is found at" diff --git a/rainloop/v/0.0.0/langs/admin/pt-br.ini b/rainloop/v/0.0.0/langs/admin/pt-br.ini index 5546c4443..1a47abdb4 100644 --- a/rainloop/v/0.0.0/langs/admin/pt-br.ini +++ b/rainloop/v/0.0.0/langs/admin/pt-br.ini @@ -131,7 +131,7 @@ LABEL_ENABLE_TWITTER = "Habilitar integração com o Twitter (Autenticação)" LABEL_TWITTER_CONSUMER_KEY = "Consumer Key" LABEL_TWITTER_CONSUMER_SECRET = "Consumer Secret" LEGEND_DROPBOX = "Dropbox" -LABEL_ENABLE_DROPBOX = "Habilitar integração com o Dropbox (Anexos)" +LABEL_ENABLE_DROPBOX = "Habilitar integração com o Dropbox" LABEL_DROPBOX_API_KEY = "Api Key" TOP_ALERT = "Informações detalhadas sobre as integrações em" diff --git a/rainloop/v/0.0.0/langs/admin/ru.ini b/rainloop/v/0.0.0/langs/admin/ru.ini index 915c6b9ad..6b19fee55 100644 --- a/rainloop/v/0.0.0/langs/admin/ru.ini +++ b/rainloop/v/0.0.0/langs/admin/ru.ini @@ -130,7 +130,7 @@ LABEL_ENABLE_TWITTER = "Включить Twitter интеграцию (Авто LABEL_TWITTER_CONSUMER_KEY = "Consumer Key" LABEL_TWITTER_CONSUMER_SECRET = "Consumer Secret" LEGEND_DROPBOX = "Dropbox" -LABEL_ENABLE_DROPBOX = "Включить Dropbox интеграцию (Экран нового сообщения)" +LABEL_ENABLE_DROPBOX = "Включить Dropbox интеграцию" LABEL_DROPBOX_API_KEY = "Api Key" TOP_ALERT = "Подробная информация о социальной интеграции находится на"