From 308de72605d7ca8b5a68a771e76ffab6c6d5d787 Mon Sep 17 00:00:00 2001 From: nuxsmin Date: Mon, 19 Dec 2016 18:14:21 +0100 Subject: [PATCH 1/2] * [DEV] Auth (work in progress) --- ajax/ajax_accViewPass.php | 2 +- ajax/ajax_configSave.php | 2 +- css/magnific-popup.min.css | 2 +- inc/SP/Api/ApiBase.class.php | 5 +- inc/SP/Auth/Auth.class.php | 8 +- inc/SP/Auth/Ldap/LdapBase.class.php | 4 +- inc/SP/Controller/AccountController.class.php | 2 +- inc/SP/Controller/LoginController.class.php | 72 +++++++++----- inc/SP/Core/Plugin/PluginAwareBase.class.php | 15 +++ inc/SP/Mgmt/Users/UserPass.class.php | 96 ++++++++++++------- inc/themes/material-blue/js/app-theme.js | 3 - inc/themes/material-blue/js/app-theme.min.js | 2 +- .../js/mdl-jquery-modal-dialog.min.js | 2 +- inc/themes/material-blue/views/main/login.inc | 11 +++ js/app-actions.js | 9 ++ js/app-actions.min.js | 14 +-- js/app-main.min.js | 2 +- js/app-triggers.min.js | 2 +- js/jquery.magnific-popup.min.js | 2 +- 19 files changed, 170 insertions(+), 85 deletions(-) diff --git a/ajax/ajax_accViewPass.php b/ajax/ajax_accViewPass.php index 4e3c4312..3f35511b 100644 --- a/ajax/ajax_accViewPass.php +++ b/ajax/ajax_accViewPass.php @@ -75,7 +75,7 @@ $Acl->setAccountData($Account->getAccountDataForACL()); if (!Acl::checkUserAccess(Acl::ACTION_ACC_VIEW_PASS) || !$Acl->checkAccountAccess()) { Response::printJson(_('No tiene permisos para acceder a esta cuenta')); -} elseif (!UserPass::checkUserUpdateMPass(Session::getUserData()->getUserId())) { +} elseif (!UserPass::getItem(Session::getUserData())->checkUserUpdateMPass()) { Response::printJson(_('Clave maestra actualizada') . '
' . _('Reinicie la sesión para cambiarla')); } diff --git a/ajax/ajax_configSave.php b/ajax/ajax_configSave.php index 05559535..a3180653 100644 --- a/ajax/ajax_configSave.php +++ b/ajax/ajax_configSave.php @@ -363,7 +363,7 @@ if ($actionId === ActionsInterface::ACTION_CFG_GENERAL $confirmPassChange = Request::analyze('confirmPassChange', 0, false, 1); $noAccountPassChange = Request::analyze('chkNoAccountChange', 0, false, 1); - if (!UserPass::checkUserUpdateMPass(Session::getUserData()->getUserId())) { + if (!UserPass::getItem(Session::getUserData())->checkUserUpdateMPass()) { $Json->setDescription(_('Clave maestra actualizada')); $Json->addMessage(_('Reinicie la sesión para cambiarla')); Json::returnJson($Json); diff --git a/css/magnific-popup.min.css b/css/magnific-popup.min.css index 364a2307..e19f0a4c 100644 --- a/css/magnific-popup.min.css +++ b/css/magnific-popup.min.css @@ -1 +1 @@ -.mfp-bg{top:0;left:0;width:100%;height:100%;z-index:1042;overflow:hidden;position:fixed;background:#0b0b0b;opacity:.5}.mfp-wrap{top:0;left:0;width:100%;height:100%;z-index:1043;position:fixed;outline:none !important;-webkit-backface-visibility:hidden}.mfp-container{text-align:center;position:absolute;width:100%;height:100%;left:0;top:0;padding:0 8px;box-sizing:border-box}.mfp-container:before{content:'';display:inline-block;height:100%;vertical-align:middle}.mfp-align-top .mfp-container:before{display:none}.mfp-content{position:relative;display:inline-block;vertical-align:middle;margin:0 auto;text-align:left;z-index:1045}.mfp-inline-holder .mfp-content,.mfp-ajax-holder .mfp-content{width:100%;cursor:auto}.mfp-ajax-cur{cursor:progress}.mfp-zoom-out-cur,.mfp-zoom-out-cur .mfp-image-holder .mfp-close{cursor:-moz-zoom-out;cursor:-webkit-zoom-out;cursor:zoom-out}.mfp-zoom{cursor:pointer;cursor:-webkit-zoom-in;cursor:-moz-zoom-in;cursor:zoom-in}.mfp-auto-cursor .mfp-content{cursor:auto}.mfp-close,.mfp-arrow,.mfp-preloader,.mfp-counter{-webkit-user-select:none;-moz-user-select:none;user-select:none}.mfp-loading.mfp-figure{display:none}.mfp-hide{display:none !important}.mfp-preloader{color:#CCC;position:absolute;top:50%;width:auto;text-align:center;margin-top:-0.8em;left:8px;right:8px;z-index:1044}.mfp-preloader a{color:#CCC}.mfp-preloader a:hover{color:#FFF}.mfp-s-ready .mfp-preloader{display:none}.mfp-s-error .mfp-content{display:none}button.mfp-close,button.mfp-arrow{overflow:visible;cursor:pointer;background:transparent;border:0;-webkit-appearance:none;display:block;outline:0;padding:0;z-index:1046;box-shadow:none;touch-action:manipulation}button::-moz-focus-inner{padding:0;border:0}.mfp-close{width:44px;height:44px;line-height:44px;position:absolute;right:0;top:0;text-decoration:none;text-align:center;opacity:.65;padding:0 0 18px 10px;color:#FFF;font-style:normal;font-size:28px;font-family:Arial,Baskerville,monospace}.mfp-close:hover,.mfp-close:focus{opacity:1}.mfp-close:active{top:1px}.mfp-close-btn-in .mfp-close{color:#333}.mfp-image-holder .mfp-close,.mfp-iframe-holder .mfp-close{color:#FFF;right:-6px;text-align:right;padding-right:6px;width:100%}.mfp-counter{position:absolute;top:0;right:0;color:#CCC;font-size:12px;line-height:18px;white-space:nowrap}.mfp-arrow{position:absolute;opacity:.65;margin:0;top:50%;margin-top:-55px;padding:0;width:90px;height:110px;-webkit-tap-highlight-color:transparent}.mfp-arrow:active{margin-top:-54px}.mfp-arrow:hover,.mfp-arrow:focus{opacity:1}.mfp-arrow:before,.mfp-arrow:after{content:'';display:block;width:0;height:0;position:absolute;left:0;top:0;margin-top:35px;margin-left:35px;border:medium inset transparent}.mfp-arrow:after{border-top-width:13px;border-bottom-width:13px;top:8px}.mfp-arrow:before{border-top-width:21px;border-bottom-width:21px;opacity:.7}.mfp-arrow-left{left:0}.mfp-arrow-left:after{border-right:17px solid #FFF;margin-left:31px}.mfp-arrow-left:before{margin-left:25px;border-right:27px solid #3f3f3f}.mfp-arrow-right{right:0}.mfp-arrow-right:after{border-left:17px solid #FFF;margin-left:39px}.mfp-arrow-right:before{border-left:27px solid #3f3f3f}.mfp-iframe-holder{padding-top:40px;padding-bottom:40px}.mfp-iframe-holder .mfp-content{line-height:0;width:100%;max-width:900px}.mfp-iframe-holder .mfp-close{top:-40px}.mfp-iframe-scaler{width:100%;height:0;overflow:hidden;padding-top:56.25%}.mfp-iframe-scaler iframe{position:absolute;display:block;top:0;left:0;width:100%;height:100%;box-shadow:0 0 8px rgba(0,0,0,0.6);background:#000}img.mfp-img{width:auto;max-width:100%;height:auto;display:block;line-height:0;box-sizing:border-box;padding:40px 0 40px;margin:0 auto}.mfp-figure{line-height:0}.mfp-figure:after{content:'';position:absolute;left:0;top:40px;bottom:40px;display:block;right:0;width:auto;height:auto;z-index:-1;box-shadow:0 0 8px rgba(0,0,0,0.6);background:#444}.mfp-figure small{color:#bdbdbd;display:block;font-size:12px;line-height:14px}.mfp-figure figure{margin:0}.mfp-bottom-bar{margin-top:-36px;position:absolute;top:100%;left:0;width:100%;cursor:auto}.mfp-title{text-align:left;line-height:18px;color:#f3f3f3;word-wrap:break-word;padding-right:36px}.mfp-image-holder .mfp-content{max-width:100%}.mfp-gallery .mfp-image-holder .mfp-figure{cursor:pointer}@media screen and (max-width:800px) and (orientation:landscape),screen and (max-height:300px){.mfp-img-mobile .mfp-image-holder{padding-left:0;padding-right:0}.mfp-img-mobile img.mfp-img{padding:0}.mfp-img-mobile .mfp-figure:after{top:0;bottom:0}.mfp-img-mobile .mfp-figure small{display:inline;margin-left:5px}.mfp-img-mobile .mfp-bottom-bar{background:rgba(0,0,0,0.6);bottom:0;margin:0;top:auto;padding:3px 5px;position:fixed;box-sizing:border-box}.mfp-img-mobile .mfp-bottom-bar:empty{padding:0}.mfp-img-mobile .mfp-counter{right:5px;top:3px}.mfp-img-mobile .mfp-close{top:0;right:0;width:35px;height:35px;line-height:35px;background:rgba(0,0,0,0.6);position:fixed;text-align:center;padding:0}}@media all and (max-width:900px){.mfp-arrow{-webkit-transform:scale(0.75);transform:scale(0.75)}.mfp-arrow-left{-webkit-transform-origin:0 0;transform-origin:0 0}.mfp-arrow-right{-webkit-transform-origin:100%;transform-origin:100%}.mfp-container{padding-left:6px;padding-right:6px}} \ No newline at end of file +.mfp-bg{top:0;left:0;width:100%;height:100%;z-index:1042;overflow:hidden;position:fixed;background:#0b0b0b;opacity:.5}.mfp-wrap{top:0;left:0;width:100%;height:100%;z-index:1043;position:fixed;outline:none!important;-webkit-backface-visibility:hidden}.mfp-container{text-align:center;position:absolute;width:100%;height:100%;left:0;top:0;padding:0 8px;box-sizing:border-box}.mfp-container:before{content:'';display:inline-block;height:100%;vertical-align:middle}.mfp-align-top .mfp-container:before{display:none}.mfp-content{position:relative;display:inline-block;vertical-align:middle;margin:0 auto;text-align:left;z-index:1045}.mfp-inline-holder .mfp-content,.mfp-ajax-holder .mfp-content{width:100%;cursor:auto}.mfp-ajax-cur{cursor:progress}.mfp-zoom-out-cur,.mfp-zoom-out-cur .mfp-image-holder .mfp-close{cursor:-moz-zoom-out;cursor:-webkit-zoom-out;cursor:zoom-out}.mfp-zoom{cursor:pointer;cursor:-webkit-zoom-in;cursor:-moz-zoom-in;cursor:zoom-in}.mfp-auto-cursor .mfp-content{cursor:auto}.mfp-close,.mfp-arrow,.mfp-preloader,.mfp-counter{-webkit-user-select:none;-moz-user-select:none;user-select:none}.mfp-loading.mfp-figure{display:none}.mfp-hide{display:none!important}.mfp-preloader{color:#CCC;position:absolute;top:50%;width:auto;text-align:center;margin-top:-0.8em;left:8px;right:8px;z-index:1044}.mfp-preloader a{color:#CCC}.mfp-preloader a:hover{color:#FFF}.mfp-s-ready .mfp-preloader{display:none}.mfp-s-error .mfp-content{display:none}button.mfp-close,button.mfp-arrow{overflow:visible;cursor:pointer;background:transparent;border:0;-webkit-appearance:none;display:block;outline:0;padding:0;z-index:1046;box-shadow:none;touch-action:manipulation}button::-moz-focus-inner{padding:0;border:0}.mfp-close{width:44px;height:44px;line-height:44px;position:absolute;right:0;top:0;text-decoration:none;text-align:center;opacity:.65;padding:0 0 18px 10px;color:#FFF;font-style:normal;font-size:28px;font-family:Arial,Baskerville,monospace}.mfp-close:hover,.mfp-close:focus{opacity:1}.mfp-close:active{top:1px}.mfp-close-btn-in .mfp-close{color:#333}.mfp-image-holder .mfp-close,.mfp-iframe-holder .mfp-close{color:#FFF;right:-6px;text-align:right;padding-right:6px;width:100%}.mfp-counter{position:absolute;top:0;right:0;color:#CCC;font-size:12px;line-height:18px;white-space:nowrap}.mfp-arrow{position:absolute;opacity:.65;margin:0;top:50%;margin-top:-55px;padding:0;width:90px;height:110px;-webkit-tap-highlight-color:transparent}.mfp-arrow:active{margin-top:-54px}.mfp-arrow:hover,.mfp-arrow:focus{opacity:1}.mfp-arrow:before,.mfp-arrow:after{content:'';display:block;width:0;height:0;position:absolute;left:0;top:0;margin-top:35px;margin-left:35px;border:medium inset transparent}.mfp-arrow:after{border-top-width:13px;border-bottom-width:13px;top:8px}.mfp-arrow:before{border-top-width:21px;border-bottom-width:21px;opacity:.7}.mfp-arrow-left{left:0}.mfp-arrow-left:after{border-right:17px solid #FFF;margin-left:31px}.mfp-arrow-left:before{margin-left:25px;border-right:27px solid #3f3f3f}.mfp-arrow-right{right:0}.mfp-arrow-right:after{border-left:17px solid #FFF;margin-left:39px}.mfp-arrow-right:before{border-left:27px solid #3f3f3f}.mfp-iframe-holder{padding-top:40px;padding-bottom:40px}.mfp-iframe-holder .mfp-content{line-height:0;width:100%;max-width:900px}.mfp-iframe-holder .mfp-close{top:-40px}.mfp-iframe-scaler{width:100%;height:0;overflow:hidden;padding-top:56.25%}.mfp-iframe-scaler iframe{position:absolute;display:block;top:0;left:0;width:100%;height:100%;box-shadow:0 0 8px rgba(0,0,0,0.6);background:#000}img.mfp-img{width:auto;max-width:100%;height:auto;display:block;line-height:0;box-sizing:border-box;padding:40px 0 40px;margin:0 auto}.mfp-figure{line-height:0}.mfp-figure:after{content:'';position:absolute;left:0;top:40px;bottom:40px;display:block;right:0;width:auto;height:auto;z-index:-1;box-shadow:0 0 8px rgba(0,0,0,0.6);background:#444}.mfp-figure small{color:#bdbdbd;display:block;font-size:12px;line-height:14px}.mfp-figure figure{margin:0}.mfp-bottom-bar{margin-top:-36px;position:absolute;top:100%;left:0;width:100%;cursor:auto}.mfp-title{text-align:left;line-height:18px;color:#f3f3f3;word-wrap:break-word;padding-right:36px}.mfp-image-holder .mfp-content{max-width:100%}.mfp-gallery .mfp-image-holder .mfp-figure{cursor:pointer}@media screen and (max-width:800px) and (orientation:landscape),screen and (max-height:300px){.mfp-img-mobile .mfp-image-holder{padding-left:0;padding-right:0}.mfp-img-mobile img.mfp-img{padding:0}.mfp-img-mobile .mfp-figure:after{top:0;bottom:0}.mfp-img-mobile .mfp-figure small{display:inline;margin-left:5px}.mfp-img-mobile .mfp-bottom-bar{background:rgba(0,0,0,0.6);bottom:0;margin:0;top:auto;padding:3px 5px;position:fixed;box-sizing:border-box}.mfp-img-mobile .mfp-bottom-bar:empty{padding:0}.mfp-img-mobile .mfp-counter{right:5px;top:3px}.mfp-img-mobile .mfp-close{top:0;right:0;width:35px;height:35px;line-height:35px;background:rgba(0,0,0,0.6);position:fixed;text-align:center;padding:0}}@media all and (max-width:900px){.mfp-arrow{-webkit-transform:scale(0.75);transform:scale(0.75)}.mfp-arrow-left{-webkit-transform-origin:0 0;transform-origin:0 0}.mfp-arrow-right{-webkit-transform-origin:100%;transform-origin:100%}.mfp-container{padding-left:6px;padding-right:6px}} \ No newline at end of file diff --git a/inc/SP/Api/ApiBase.class.php b/inc/SP/Api/ApiBase.class.php index 86e79692..55ecc96f 100644 --- a/inc/SP/Api/ApiBase.class.php +++ b/inc/SP/Api/ApiBase.class.php @@ -102,11 +102,12 @@ abstract class ApiBase User::getItem($UserData)->getById($this->userId); $UserPass = UserPass::getItem($UserData); + $Auth = new Auth($UserData); if (!$UserData->isUserIsDisabled() - && Auth::authUserMySQL($UserData) + && $Auth->doAuth() && $UserPass->loadUserMPass() - && UserPass::checkUserUpdateMPass($UserData->getUserId()) + && $UserPass->checkUserUpdateMPass() ) { $this->mPass = $UserPass->getClearUserMPass(); SessionUtil::loadUserSession($UserData); diff --git a/inc/SP/Auth/Auth.class.php b/inc/SP/Auth/Auth.class.php index b8fcbba2..f39cf07d 100644 --- a/inc/SP/Auth/Auth.class.php +++ b/inc/SP/Auth/Auth.class.php @@ -125,12 +125,12 @@ class Auth extends PluginAwareBase $Ldap = Config::getConfig()->isLdapAds() ? new LdapMsAds() : new LdapStd(); - if (!$Ldap->authenticate($this->UserData)) { - return false; - } - $LdapAuthData = $Ldap->getLdapAuthData(); + if (!$Ldap->authenticate($this->UserData)) { + return $LdapAuthData->getAuthenticated() === 1 ? $LdapAuthData : false; + } + // Comprobamos si la cuenta está bloqueada o expirada if ($LdapAuthData->getExpire() > 0) { $LdapAuthData->setStatusCode(701); diff --git a/inc/SP/Auth/Ldap/LdapBase.class.php b/inc/SP/Auth/Ldap/LdapBase.class.php index a0869a96..ab364c2d 100644 --- a/inc/SP/Auth/Ldap/LdapBase.class.php +++ b/inc/SP/Auth/Ldap/LdapBase.class.php @@ -173,6 +173,8 @@ abstract class LdapBase implements LdapInterface, AuthInterface $Log->addDetails('LDAP DN', $dn); $Log->writeLog(); + $this->getLdapAuthData()->setAuthenticated(1); + throw new SPException(SPException::SP_ERROR, $Log->getDescription()); } @@ -642,7 +644,7 @@ abstract class LdapBase implements LdapInterface, AuthInterface $error = ldap_error($this->ldapHandler); $errno = ldap_errno($this->ldapHandler); - $this->LdapAuthData->setAuthenticated($error); + $this->LdapAuthData->setAuthenticated(0); $this->LdapAuthData->setStatusCode($errno); return sprintf('%s (%d)', $error, $errno); diff --git a/inc/SP/Controller/AccountController.class.php b/inc/SP/Controller/AccountController.class.php index 971972e4..a5869398 100644 --- a/inc/SP/Controller/AccountController.class.php +++ b/inc/SP/Controller/AccountController.class.php @@ -152,7 +152,7 @@ class AccountController extends ControllerBase implements ActionsInterface if (!Acl::checkUserAccess($this->getAction())) { $this->showError(self::ERR_PAGE_NO_PERMISSION); return false; - } elseif (!UserPass::checkUserUpdateMPass($this->UserData->getUserId())) { + } elseif (!UserPass::getItem($this->UserData)->checkUserUpdateMPass()) { $this->showError(self::ERR_UPDATE_MPASS); return false; } elseif ($this->id > 0) { diff --git a/inc/SP/Controller/LoginController.class.php b/inc/SP/Controller/LoginController.class.php index c6ab0076..bb5832c5 100644 --- a/inc/SP/Controller/LoginController.class.php +++ b/inc/SP/Controller/LoginController.class.php @@ -60,6 +60,12 @@ use SP\Util\Util; */ class LoginController { + const STATUS_INVALID_LOGIN = 1; + const STATUS_INVALID_MASTER_PASS = 2; + const STATUS_USER_DISABLED = 3; + const STATUS_INTERNAL_ERROR = 4; + const STATUS_NEED_OLD_PASS = 5; + /** * @var JsonResponse */ @@ -108,11 +114,12 @@ class LoginController $result = $Auth->doAuth(); if ($result !== false) { - foreach ($result as $auth){ + // Ejecutar la acción asociada al tipo de autentificación + foreach ($result as $auth) { $this->{$auth['auth']}($auth['data']); } } else { - throw new AuthException(SPException::SP_INFO, _('Usuario/Clave incorrectos')); + throw new AuthException(SPException::SP_INFO, _('Usuario/Clave incorrectos'), '', self::STATUS_INVALID_LOGIN); } $this->getUserData($userPass); @@ -122,6 +129,8 @@ class LoginController $this->loadUserPreferences(); } catch (SPException $e) { $this->jsonResponse->setDescription($e->getMessage()); + $this->jsonResponse->setStatus($e->getCode()); + Json::returnJson($this->jsonResponse); } @@ -149,7 +158,7 @@ class LoginController $this->Log->addDescription(_('Error al obtener los datos del usuario de la BBDD')); $this->Log->writeLog(); - throw new AuthException(SPException::SP_ERROR, _('Error interno')); + throw new AuthException(SPException::SP_ERROR, _('Error interno'), '', self::STATUS_INTERNAL_ERROR); } } @@ -168,7 +177,7 @@ class LoginController $this->Log->addDetails(_('Usuario'), $this->UserData->getUserLogin()); $this->Log->writeLog(); - throw new AuthException(SPException::SP_INFO, _('Usuario deshabilitado')); + throw new AuthException(SPException::SP_INFO, _('Usuario deshabilitado'), '', self::STATUS_USER_DISABLED); } return false; @@ -225,7 +234,7 @@ class LoginController $this->Log->addDescription(_('Error al obtener la clave maestra del usuario')); $this->Log->writeLog(); - throw new AuthException(SPException::SP_ERROR, _('Error interno')); + throw new AuthException(SPException::SP_ERROR, _('Error interno'), '', self::STATUS_INTERNAL_ERROR); } } @@ -239,17 +248,11 @@ class LoginController $this->Log->resetDescription(); $masterPass = Request::analyzeEncrypted('mpass'); + $oldPass = Request::analyzeEncrypted('oldpass'); $UserPass = UserPass::getItem($this->UserData); - // Comprobamos que la clave maestra del usuario es correcta y está actualizada - if (!$masterPass - && (!$UserPass->loadUserMPass() || !UserPass::checkUserUpdateMPass($this->UserData->getUserId())) - ) { - $this->jsonResponse->setStatus(2); - - throw new AuthException(SPException::SP_INFO, _('La clave maestra no ha sido guardada o es incorrecta')); - } elseif ($masterPass) { + if ($masterPass) { if (CryptMasterPass::checkTempMasterPass($masterPass)) { $masterPass = CryptMasterPass::getTempMasterPass($masterPass); } @@ -258,9 +261,24 @@ class LoginController $this->Log->addDescription(_('Clave maestra incorrecta')); $this->Log->writeLog(); - $this->jsonResponse->setStatus(2); + throw new AuthException(SPException::SP_INFO, _('Clave maestra incorrecta'), '', self::STATUS_INVALID_MASTER_PASS); + } + } else if ($oldPass) { + if (!$UserPass->updateMasterPass($oldPass)) { + $this->Log->addDescription(_('Clave maestra incorrecta')); + $this->Log->writeLog(); - throw new AuthException(SPException::SP_INFO, _('Clave maestra incorrecta')); + throw new AuthException(SPException::SP_INFO, _('Clave maestra incorrecta'), '', self::STATUS_INVALID_MASTER_PASS); + } + } else { + $loadMPass = $UserPass->loadUserMPass(); + + // Comprobar si es necesario actualizar la clave maestra + if ($loadMPass === false) { + throw new AuthException(SPException::SP_INFO, _('Es necesaria su clave anterior'), '', self::STATUS_NEED_OLD_PASS); + // La clave no está establecida o se ha sido cambiada por el administrador + } else if ($loadMPass === null || !$UserPass->checkUserUpdateMPass()) { + throw new AuthException(SPException::SP_INFO, _('La clave maestra no ha sido guardada o es incorrecta'), '', self::STATUS_INVALID_MASTER_PASS); } } @@ -309,17 +327,25 @@ class LoginController if ($LdapAuthData->getStatusCode() === 49) { $this->Log->addDescription(_('Login incorrecto')); + $this->Log->writeLog(); + + throw new AuthException(SPException::SP_INFO, $this->Log->getDescription(), '', self::STATUS_INVALID_LOGIN); } elseif ($LdapAuthData->getStatusCode() === 701) { $this->Log->addDescription(_('Cuenta expirada')); + $this->Log->writeLog(); + + throw new AuthException(SPException::SP_INFO, $this->Log->getDescription(), '', self::STATUS_USER_DISABLED); } else if ($LdapAuthData->getStatusCode() === 702) { $this->Log->addDescription(_('El usuario no tiene grupos asociados')); + $this->Log->writeLog(); + + throw new AuthException(SPException::SP_INFO, $this->Log->getDescription(), '', self::STATUS_USER_DISABLED); } else { $this->Log->addDescription(_('Error interno')); + $this->Log->writeLog(); + + throw new AuthException(SPException::SP_INFO, $this->Log->getDescription(), '', self::STATUS_INTERNAL_ERROR); } - - $this->Log->writeLog(); - - throw new AuthException(SPException::SP_INFO, $this->Log->getDescription()); } $this->UserData->setUserName($LdapAuthData->getName()); @@ -342,7 +368,7 @@ class LoginController $this->Log->addDescription($e->getMessage()); $this->Log->writeLog(); - throw new AuthException(SPException::SP_ERROR, _('Error interno')); + throw new AuthException(SPException::SP_ERROR, _('Error interno'), '', self::STATUS_INTERNAL_ERROR); } return true; @@ -365,7 +391,7 @@ class LoginController $this->Log->addDetails(_('Usuario'), $this->UserData->getUserLogin()); $this->Log->writeLog(); - throw new AuthException(SPException::SP_INFO, _('Usuario/Clave incorrectos')); + throw new AuthException(SPException::SP_INFO, _('Usuario/Clave incorrectos'), '', self::STATUS_INVALID_LOGIN); } $this->Log->addDetails(_('Tipo'), __FUNCTION__); @@ -388,10 +414,10 @@ class LoginController $this->Log->addDescription(_('Login incorrecto')); $this->Log->addDetails(_('Tipo'), __FUNCTION__); $this->Log->addDetails(_('Usuario'), $this->UserData->getUserLogin()); - $this->Log->addDetails(_('Autentificación'), sprintf('%s (%s)', AuthUtil::getServerAuthType(), AuthUtil::getServerAuthUser())); + $this->Log->addDetails(_('Autentificación'), sprintf('%s (%s)', AuthUtil::getServerAuthType(), $AuthData->getName())); $this->Log->writeLog(); - throw new AuthException(SPException::SP_INFO, _('Usuario/Clave incorrectos')); + throw new AuthException(SPException::SP_INFO, _('Usuario/Clave incorrectos'), '', self::STATUS_INVALID_LOGIN); } return true; diff --git a/inc/SP/Core/Plugin/PluginAwareBase.class.php b/inc/SP/Core/Plugin/PluginAwareBase.class.php index 748056fb..d93982d2 100644 --- a/inc/SP/Core/Plugin/PluginAwareBase.class.php +++ b/inc/SP/Core/Plugin/PluginAwareBase.class.php @@ -36,6 +36,10 @@ use SplSubject; */ abstract class PluginAwareBase implements SplSubject { + /** + * @var string + */ + protected $state; /** * @var SplObserver[] */ @@ -93,4 +97,15 @@ abstract class PluginAwareBase implements SplSubject $observer->update($this); } } + + /** + * Notificar un estado + * + * @param $state + */ + protected function notifyState($state) + { + $this->state = $state; + $this->notify(); + } } \ No newline at end of file diff --git a/inc/SP/Mgmt/Users/UserPass.class.php b/inc/SP/Mgmt/Users/UserPass.class.php index 194c7251..2f430788 100644 --- a/inc/SP/Mgmt/Users/UserPass.class.php +++ b/inc/SP/Mgmt/Users/UserPass.class.php @@ -62,34 +62,6 @@ class UserPass extends UserBase parent::__construct($itemData); } - /** - * Comprobar si el usuario tiene actualizada la clave maestra actual. - * - * @param string $userId El id del usuario - * @return bool - */ - public static function checkUserUpdateMPass($userId) - { - $configMPassTime = ConfigDB::getValue('lastupdatempass'); - - if ($configMPassTime === false) { - return false; - } - - $query = /** @lang SQL */ - 'SELECT user_lastUpdateMPass FROM usrData WHERE user_id = ? LIMIT 1'; - - $Data = new QueryData(); - $Data->setMapClassName('SP\DataModel\UserPassData'); - $Data->setQuery($query); - $Data->addParam($userId); - - /** @var UserPassData $queryRes */ - $queryRes = DB::getResults($Data); - - return ($queryRes !== false && $queryRes->getUserLastUpdateMPass() > $configMPassTime); - } - /** * Obtener el IV del usuario a partir del Id. * @@ -114,6 +86,33 @@ class UserPass extends UserBase return $queryRes->user_mIV; } + /** + * Comprobar si el usuario tiene actualizada la clave maestra actual. + * + * @return bool + */ + public function checkUserUpdateMPass() + { + $configMPassTime = ConfigDB::getValue('lastupdatempass'); + + if ($configMPassTime === false) { + return false; + } + + $query = /** @lang SQL */ + 'SELECT user_lastUpdateMPass FROM usrData WHERE user_id = ? LIMIT 1'; + + $Data = new QueryData(); + $Data->setMapClassName('SP\DataModel\UserPassData'); + $Data->setQuery($query); + $Data->addParam($this->itemData->getUserId()); + + /** @var UserPassData $queryRes */ + $queryRes = DB::getResults($Data); + + return ($queryRes !== false && $queryRes->getUserLastUpdateMPass() > $configMPassTime); + } + /** * Modificar la clave de un usuario. * @@ -137,8 +136,8 @@ class UserPass extends UserBase $Data = new QueryData(); $Data->setQuery($query); - $Data->addParam($passdata['pass'], 'pass'); - $Data->addParam($passdata['salt'], 'hashSalt'); + $Data->addParam($passdata['pass']); + $Data->addParam($passdata['salt']); $Data->addParam($userId); if (DB::getQuery($Data) === false) { @@ -182,6 +181,8 @@ class UserPass extends UserBase || null === $configHashMPass ) { return false; + } elseif ($userMPass === null) { + return null; } // Comprobamos el hash de la clave del usuario con la guardada @@ -196,9 +197,10 @@ class UserPass extends UserBase /** * Desencriptar la clave maestra del usuario para la sesión. * + * @param string $cypher Clave de cifrado * @return false|string Devuelve bool se hay error o string si se devuelve la clave */ - public function getUserMPass() + public function getUserMPass($cypher = null) { $query = /** @lang SQL */ 'SELECT user_mPass, user_mIV FROM usrData WHERE user_id = ? LIMIT 1'; @@ -207,25 +209,30 @@ class UserPass extends UserBase $Data->setQuery($query); $Data->addParam($this->itemData->getUserId()); - /** @var UserPassData $queryRes */ $queryRes = DB::getResults($Data); if ($queryRes === false) { return false; + } elseif ($queryRes->user_mPass === null + || $queryRes->user_mIV === null + ) { + return null; } - return Crypt::getDecrypt($queryRes->user_mPass, $queryRes->user_mIV, $this->getCypherPass()); -// return ($showPass === true) ? $clearMasterPass : SessionUtil::saveSessionMPass($clearMasterPass); + return Crypt::getDecrypt($queryRes->user_mPass, $queryRes->user_mIV, $this->getCypherPass($cypher)); } /** * Obtener una clave de cifrado basada en la clave del usuario y un salt. * + * @param string $cypher Clave de cifrado * @return string con la clave de cifrado */ - private function getCypherPass() + private function getCypherPass($cypher = null) { - return Crypt::generateAesKey($this->itemData->getUserPass() . $this->itemData->getUserLogin()); + $pass = $cypher === null ? $this->itemData->getUserPass() : $cypher; + + return Crypt::generateAesKey($pass . $this->itemData->getUserLogin()); } /** @@ -278,4 +285,21 @@ class UserPass extends UserBase { return $this->clearUserMPass; } + + /** + * Actualizar la clave maestra con la clave anterior del usuario + * + * @param $oldUserPass + * @return bool + */ + public function updateMasterPass($oldUserPass) + { + $masterPass = $this->getUserMPass($oldUserPass); + + if ($masterPass) { + return $this->updateUserMPass($masterPass); + } + + return false; + } } \ No newline at end of file diff --git a/inc/themes/material-blue/js/app-theme.js b/inc/themes/material-blue/js/app-theme.js index 30005d20..90480701 100644 --- a/inc/themes/material-blue/js/app-theme.js +++ b/inc/themes/material-blue/js/app-theme.js @@ -37,9 +37,6 @@ sysPass.Theme = function (Common) { // Actualizar componentes de MDL cargados con AJAX componentHandler.upgradeDom(); - - // Activar tooltips - //activeTooltip(); } }; diff --git a/inc/themes/material-blue/js/app-theme.min.js b/inc/themes/material-blue/js/app-theme.min.js index 2254968f..e69654d8 100644 --- a/inc/themes/material-blue/js/app-theme.min.js +++ b/inc/themes/material-blue/js/app-theme.min.js @@ -1,5 +1,5 @@ var $jscomp={scope:{},findInternal:function(a,f,d){a instanceof String&&(a=String(a));for(var g=a.length,h=0;h=c)continue;if(58<=c&&64>=c)continue;if(91<=c&&96>=c)continue;if(123<=c&&126>=c)continue}!a.passwordData.complexity.numbers&&48<=c&&57>=c|| !a.passwordData.complexity.uppercase&&65<=c&&90>=c||(l++,e+=String.fromCharCode(c))}$("#viewPass").attr("title",e);var k=zxcvbn(e);a.passwordData.passLength=e.length;b?(l=b.parent(),c=$("#"+b.attr("id")+"R"),a.outputResult(k,b),b=new MaterialTextfield,l.find("input:password").val(e),l.addClass(b.CssClasses_.IS_DIRTY).removeClass(b.CssClasses_.IS_INVALID),c.val(e).parent().addClass(b.CssClasses_.IS_DIRTY).removeClass(b.CssClasses_.IS_INVALID),a.encryptFormValue(c),l.find("#passLevel").show(500)):(a.outputResult(k), diff --git a/inc/themes/material-blue/js/mdl-jquery-modal-dialog.min.js b/inc/themes/material-blue/js/mdl-jquery-modal-dialog.min.js index 6b53a48b..689fd15e 100644 --- a/inc/themes/material-blue/js/mdl-jquery-modal-dialog.min.js +++ b/inc/themes/material-blue/js/mdl-jquery-modal-dialog.min.js @@ -1,5 +1,5 @@ var $jscomp={scope:{},findInternal:function(a,c,b){a instanceof String&&(a=String(a));for(var e=a.length,d=0;d
').appendTo("body");componentHandler.upgradeElements($(".mdl-spinner").get());setTimeout(function(){$("#orrsLoader").css({opacity:1})},1)} function hideLoading(){$("#orrsLoader").css({opacity:0});setTimeout(function(){$("#orrsLoader").remove()},400)} function showDialog(a){a=$.extend({id:"orrsDiag",title:null,text:null,neutral:!1,negative:!1,positive:!1,cancelable:!0,contentStyle:null,onLoaded:!1,hideOther:!0},a);a.hideOther&&($(".dialog-container").remove(),$(document).unbind("keyup.dialog"));$('
').appendTo("body");var c=$("#"+a.id),b=c.find(".mdl-card");null!=a.contentStyle&&b.css(a.contentStyle);null!=a.title&&$("
"+a.title+ diff --git a/inc/themes/material-blue/views/main/login.inc b/inc/themes/material-blue/views/main/login.inc index 024084a4..1bea262d 100644 --- a/inc/themes/material-blue/views/main/login.inc +++ b/inc/themes/material-blue/views/main/login.inc @@ -63,6 +63,17 @@ + + ";showDialog({text:b,negative:{title:c.config().LANG[44], -onClick:function(a){a.preventDefault();c.msg.error(c.config().LANG[44])}},positive:{title:c.config().LANG[43],onClick:function(b){b=c.appRequests().getRequestOpts();b.url=e.account.save;b.data={itemId:a.data("item-id"),actionId:a.data("action-id"),sk:c.sk.get()};c.appRequests().getActionCall(b,function(a){c.msg.out(a);l.search()})}}})},showpass:function(a){d.info("account:showpass");var b=c.appRequests().getRequestOpts();b.url=e.account.showPass;b.data={itemId:a.data("item-id"),isHistory:a.data("history"), -isFull:a.data("full"),isAjax:1};c.appRequests().getActionCall(b,function(a){if(10===a.status)p.logout();else{var b;$("
").dialog({modal:!0,title:c.config().LANG[47],width:"auto",open:function(){b=$(this);var g,d="";g='";var e='",d=a.useimage,k='

'+a.acclogin+"

";0===a.status?(0===d?d='

'+a.accpass+"

":(d='";showDialog({text:b,negative:{title:c.config().LANG[44],onClick:function(a){a.preventDefault();c.msg.error(c.config().LANG[44])}},positive:{title:c.config().LANG[43],onClick:function(b){b=c.appRequests().getRequestOpts();b.url=e.account.save;b.data={itemId:a.data("item-id"),actionId:a.data("action-id"),sk:c.sk.get()};c.appRequests().getActionCall(b,function(a){c.msg.out(a); +l.search()})}}})},showpass:function(a){d.info("account:showpass");var b=c.appRequests().getRequestOpts();b.url=e.account.showPass;b.data={itemId:a.data("item-id"),isHistory:a.data("history"),isFull:a.data("full"),isAjax:1};c.appRequests().getActionCall(b,function(a){if(10===a.status)p.logout();else{var b;$("
").dialog({modal:!0,title:c.config().LANG[47],width:"auto",open:function(){b=$(this);var g,d="";g='";var e='",d=a.useimage,k='

'+a.acclogin+"

";0===a.status?(0===d?d='

'+a.accpass+"

":(d='',e=""),g=k+d+'
'+g+e+"
"):(g=''+a.description+"",b.dialog("option","buttons",[{text:"Ok",icons:{primary:"ui-icon-close"},click:function(){b.dialog("close")}}]));b.html(g);b.dialog("option","position","center");b.parent().on("mouseleave",function(){clearTimeout(h);h=setTimeout(function(){b.dialog("close")},3E4)})},close:function(){clearTimeout(h);b.dialog("destroy")}})}})},copypass:function(a){d.info("account:copypass"); var b=c.appRequests().getRequestOpts();b.url=e.account.showPass;b.async=!1;b.data={itemId:a.data("item-id"),isHistory:a.data("history"),isAjax:1};return c.appRequests().getActionCall(b)},copy:function(a){d.info("account:copy");f({actionId:a.data("action-id"),itemId:a.data("item-id")})},savefavorite:function(a,b){d.info("account:saveFavorite");var g="on"===a.data("status"),k={actionId:g?a.data("action-id-off"):a.data("action-id-on"),itemId:a.data("item-id"),sk:c.sk.get(),isAjax:1},f=c.appRequests().getRequestOpts(); f.url=e.account.saveFavorite;f.data=k;c.appRequests().getActionCall(f,function(d){c.msg.out(d);0===d.status&&(a.data("status",g?"off":"on"),"function"===typeof b&&b())})},request:function(a){d.info("account:request");var b=c.appRequests().getRequestOpts();b.url=e.account.request;b.data=a.serialize();c.appRequests().getActionCall(b,function(a){c.msg.out(a)})},menu:function(a){a.hide();a.parent().children(".actions-optional").show(250)},sort:function(a){d.info("account:sort");var c=$("#frmSearch"); diff --git a/js/app-main.min.js b/js/app-main.min.js index ed5a296f..ce335136 100644 --- a/js/app-main.min.js +++ b/js/app-main.min.js @@ -1,4 +1,4 @@ -var $jscomp={scope:{}};$jscomp.defineProperty="function"==typeof Object.defineProperties?Object.defineProperty:function(a,f,e){if(e.get||e.set)throw new TypeError("ES3 does not support getters and setters.");a!=Array.prototype&&a!=Object.prototype&&(a[f]=e.value)};$jscomp.getGlobal=function(a){return"undefined"!=typeof window&&window===a?a:"undefined"!=typeof global?global:a};$jscomp.global=$jscomp.getGlobal(this);$jscomp.SYMBOL_PREFIX="jscomp_symbol_"; +var $jscomp={scope:{}};$jscomp.defineProperty="function"==typeof Object.defineProperties?Object.defineProperty:function(a,f,e){if(e.get||e.set)throw new TypeError("ES3 does not support getters and setters.");a!=Array.prototype&&a!=Object.prototype&&(a[f]=e.value)};$jscomp.getGlobal=function(a){return"undefined"!=typeof window&&window===a?a:"undefined"!=typeof global&&null!=global?global:a};$jscomp.global=$jscomp.getGlobal(this);$jscomp.SYMBOL_PREFIX="jscomp_symbol_"; $jscomp.initSymbol=function(){$jscomp.initSymbol=function(){};$jscomp.global.Symbol||($jscomp.global.Symbol=$jscomp.Symbol)};$jscomp.symbolCounter_=0;$jscomp.Symbol=function(a){return $jscomp.SYMBOL_PREFIX+(a||"")+$jscomp.symbolCounter_++}; $jscomp.initSymbolIterator=function(){$jscomp.initSymbol();var a=$jscomp.global.Symbol.iterator;a||(a=$jscomp.global.Symbol.iterator=$jscomp.global.Symbol("iterator"));"function"!=typeof Array.prototype[a]&&$jscomp.defineProperty(Array.prototype,a,{configurable:!0,writable:!0,value:function(){return $jscomp.arrayIterator(this)}});$jscomp.initSymbolIterator=function(){}};$jscomp.arrayIterator=function(a){var f=0;return $jscomp.iteratorPrototype(function(){return f Date: Tue, 20 Dec 2016 10:58:30 +0100 Subject: [PATCH 2/2] * [DEV] Auth (work in progress) --- inc/SP/Controller/LoginController.class.php | 12 +++++--- .../material-blue/views/main/passreset.inc | 9 +----- js/app-main.js | 4 +++ js/app-main.min.js | 28 +++++++++---------- 4 files changed, 27 insertions(+), 26 deletions(-) diff --git a/inc/SP/Controller/LoginController.class.php b/inc/SP/Controller/LoginController.class.php index bb5832c5..57e2ad66 100644 --- a/inc/SP/Controller/LoginController.class.php +++ b/inc/SP/Controller/LoginController.class.php @@ -119,7 +119,7 @@ class LoginController $this->{$auth['auth']}($auth['data']); } } else { - throw new AuthException(SPException::SP_INFO, _('Usuario/Clave incorrectos'), '', self::STATUS_INVALID_LOGIN); + throw new AuthException(SPException::SP_INFO, _('Login incorrecto'), '', self::STATUS_INVALID_LOGIN); } $this->getUserData($userPass); @@ -262,6 +262,8 @@ class LoginController $this->Log->writeLog(); throw new AuthException(SPException::SP_INFO, _('Clave maestra incorrecta'), '', self::STATUS_INVALID_MASTER_PASS); + } else { + Log::writeNewLog(_('Login'), _('Clave maestra actualizada')); } } else if ($oldPass) { if (!$UserPass->updateMasterPass($oldPass)) { @@ -269,6 +271,8 @@ class LoginController $this->Log->writeLog(); throw new AuthException(SPException::SP_INFO, _('Clave maestra incorrecta'), '', self::STATUS_INVALID_MASTER_PASS); + } else { + Log::writeNewLog(_('Login'), _('Clave maestra actualizada')); } } else { $loadMPass = $UserPass->loadUserMPass(); @@ -276,7 +280,7 @@ class LoginController // Comprobar si es necesario actualizar la clave maestra if ($loadMPass === false) { throw new AuthException(SPException::SP_INFO, _('Es necesaria su clave anterior'), '', self::STATUS_NEED_OLD_PASS); - // La clave no está establecida o se ha sido cambiada por el administrador + // La clave no está establecida o se ha sido cambiada por el administrador } else if ($loadMPass === null || !$UserPass->checkUserUpdateMPass()) { throw new AuthException(SPException::SP_INFO, _('La clave maestra no ha sido guardada o es incorrecta'), '', self::STATUS_INVALID_MASTER_PASS); } @@ -391,7 +395,7 @@ class LoginController $this->Log->addDetails(_('Usuario'), $this->UserData->getUserLogin()); $this->Log->writeLog(); - throw new AuthException(SPException::SP_INFO, _('Usuario/Clave incorrectos'), '', self::STATUS_INVALID_LOGIN); + throw new AuthException(SPException::SP_INFO, $this->Log->getDescription(), '', self::STATUS_INVALID_LOGIN); } $this->Log->addDetails(_('Tipo'), __FUNCTION__); @@ -417,7 +421,7 @@ class LoginController $this->Log->addDetails(_('Autentificación'), sprintf('%s (%s)', AuthUtil::getServerAuthType(), $AuthData->getName())); $this->Log->writeLog(); - throw new AuthException(SPException::SP_INFO, _('Usuario/Clave incorrectos'), '', self::STATUS_INVALID_LOGIN); + throw new AuthException(SPException::SP_INFO, $this->Log->getDescription(), '', self::STATUS_INVALID_LOGIN); } return true; diff --git a/inc/themes/material-blue/views/main/passreset.inc b/inc/themes/material-blue/views/main/passreset.inc index b648e329..4d1ec635 100644 --- a/inc/themes/material-blue/views/main/passreset.inc +++ b/inc/themes/material-blue/views/main/passreset.inc @@ -72,11 +72,4 @@ - - \ No newline at end of file + \ No newline at end of file diff --git a/js/app-main.js b/js/app-main.js index 9158c642..2b983180 100644 --- a/js/app-main.js +++ b/js/app-main.js @@ -140,6 +140,10 @@ sysPass.Main = function () { if ($("footer").length > 0) { appTriggers.views.footer(); } + + $('#btnBack').click(function () { + redirect("index.php"); + }); }; // Mostrar mensaje de aviso diff --git a/js/app-main.min.js b/js/app-main.min.js index ce335136..fae27f96 100644 --- a/js/app-main.min.js +++ b/js/app-main.min.js @@ -5,17 +5,17 @@ $jscomp.iteratorPrototype=function(a){$jscomp.initSymbolIterator();a={next:a};a[ $jscomp.polyfill=function(a,f,e,c){if(f){e=$jscomp.global;a=a.split(".");for(c=0;c"+ -a.messages.join("
"));switch(b){case 0:l.ok(d);break;case 1:case 2:l.error(d);break;case 3:l.warn(d);break;case 10:g.main.logout()}}},html:{error:function(b){return'

Oops...
'+a.LANG[1]+"
"+b+"

"}}},w=function(b){h.info("getEnvironment");var k=window.location.pathname.split("/"),d=window.location.protocol+"//"+window.location.host+function(){for(var a="",b=1;b<=k.length-2;b++)a+="/"+k[b];return a}(),n=m.getRequestOpts();n.url=d+"/ajax/ajax_getEnvironment.php";n.method= -"get";n.async=!1;n.useLoading=!1;n.data={isAjax:1};m.getActionCall(n,function(d){a.APP_ROOT=d.app_root;a.LANG=d.lang;a.PK=d.pk;a.CHECK_UPDATES=d.check_updates;a.CRYPT.setPublicKey(d.pk);a.TIMEZONE=d.timezone;a.LOCALE=d.locale;a.DEBUG=d.debug;"function"===typeof b&&b()})},u={get:function(){h.info("sk:get");return $("#container").attr("data-sk")},set:function(a){h.info("sk:set");$("#container").attr("data-sk",a)}},x=function(){var a=$("#container");if(!a.hasClass("content-no-auto-resize")){var k=$("#content").height()+ -200;a.css("height",k)}},y=function(){$("html, body").animate({scrollTop:0},"slow")},z=function(a){window.location.replace(a)},A=function(b){var k=function(){return{actionId:b.data("action-id"),itemId:b.data("item-id"),sk:u.get()}},d={requestDoneAction:"",requestData:function(a){k=function(){return a}},beforeSendAction:"",url:""},n=function(a){if("undefined"===typeof d.url||""===d.url)return!1;var b=new FormData;b.append("inFile",a);b.append("isAjax",1);var p=k();Object.keys(p).forEach(function(a){h.info(a); -b.append(a,p[a])});a=m.getRequestOpts();a.url=d.url;a.processData=!1;a.contentType=!1;a.data=b;m.getActionCall(a,function(a){var b=a.status;a=a.description;0===b?("function"===typeof d.requestDoneAction&&d.requestDoneAction(),l.ok(a)):10===b?g.main.logout():l.error(a)})},c=function(d){if(5a.MAX_FILE_SIZE)l.error(a.LANG[18]+"
"+p.name+" (Max: "+a.MAX_FILE_SIZE+")");else{var c;a:{c=p.name;for(var e= -b.data("files-ext").toLowerCase().split(","),f=0;f<=e.length;f++)if(-1!==c.indexOf(e[f])){c=!0;break a}c=!1}c?n(d[k]):l.error(a.LANG[19]+"
"+p.name)}}},e=function(a){var b=$("#fileUploadForm");!1===a&&b.hide();a=b.find("input[type='file']");a.on("change",function(){"function"===typeof d.beforeSendAction&&d.beforeSendAction();c(this.files)});return a};window.File&&window.FileList&&window.FileReader?function(){h.info("fileUpload:init");var a=e(!1);b.on("dragover dragenter",function(a){h.info("fileUpload:drag"); -a.stopPropagation();a.preventDefault()});b.on("drop",function(a){h.info("fileUpload:drop");a.stopPropagation();a.preventDefault();"function"===typeof d.beforeSendAction&&d.beforeSendAction();c(a.dataTransfer.files)});b.on("click",function(){a.click()})}():e(!0);return d},B=function(a){h.info("checkPassLevel");f.passLength=a.val().length;v(zxcvbn(a.val()),a)},v=function(b,k){h.info("outputResult");var d=$(".passLevel-"+k.attr("id")),c=b.score;d.show();d.removeClass("weak good strong strongest");0=== -f.passLength?d.attr("title","").empty():f.passLengtha.secondary?a.calc=a.main/a.rel:a.maina.secondary&&(a.main*=a.factor,g(a));return a},l=function(){f.main= -b;f.secondary=c;var d=g(f);a.css({width:d.main,height:d.calc});e.width=d.main;e.height=d.calc},m=function(){f.main=c;f.secondary=b;var d=g(f);a.css({width:d.calc,height:d.main});e.width=d.calc;e.height=d.main};e.width>b?l():e.height>c&&(h.info("height"),m());return e},H=function(){return $.extend({log:h,config:function(){return a},appTheme:function(){return e},appActions:function(){return g},appTriggers:function(){return c},appRequests:function(){return m},evalAction:F,resizeImage:G},r)},I=function(){return{actions:function(){return g}, -triggers:function(){return c},theme:function(){return e},sk:u,msg:l,log:h,passToClip:0,passwordData:f,outputResult:v,checkboxDetect:C,checkPassLevel:B,encryptFormValue:t,fileUpload:A,redirect:z,scrollUp:y,setContentSize:x}};(function(){h.info("init");r=I();q=H();c=sysPass.Triggers(q);g=sysPass.Actions(q);m=sysPass.Requests(q);w(function(){""!==a.PK&&E();"function"===typeof sysPass.Theme&&(e=sysPass.Theme(q));!0===a.CHECK_UPDATES&&g.main.getUpdates();D();h.info("setupCallbacks");switch($("#container").data("page")){case "login":c.views.login(); -break;case "2fa":c.views.twofa();break;case "passreset":c.views.passreset()}0<$("footer").length&&c.views.footer()})})();return r}; +positionClass:"toast-top-center",preventDuplicates:!1,onclick:null,showDuration:"300",hideDuration:"1000",timeOut:"5000",extendedTimeOut:"1000",showEasing:"swing",hideEasing:"linear",showMethod:"fadeIn",hideMethod:"fadeOut"};var x=function(){h.info("setupCallbacks");switch($("#container").data("page")){case "login":c.views.login();break;case "2fa":c.views.twofa();break;case "passreset":c.views.passreset()}0<$("footer").length&&c.views.footer();$("#btnBack").click(function(){u("index.php")})},l={ok:function(a){toastr.success(a)}, +error:function(a){toastr.error(a)},warn:function(a){toastr.warning(a)},info:function(a){toastr.info(a)},out:function(a){if("object"===typeof a){var b=a.status,d=a.description;"undefined"!==typeof a.messages&&0"+a.messages.join("
"));switch(b){case 0:l.ok(d);break;case 1:case 2:l.error(d);break;case 3:l.warn(d);break;case 10:g.main.logout()}}},html:{error:function(b){return'

Oops...
'+a.LANG[1]+"
"+b+"

"}}},y=function(b){h.info("getEnvironment"); +var k=window.location.pathname.split("/"),d=window.location.protocol+"//"+window.location.host+function(){for(var a="",b=1;b<=k.length-2;b++)a+="/"+k[b];return a}(),n=m.getRequestOpts();n.url=d+"/ajax/ajax_getEnvironment.php";n.method="get";n.async=!1;n.useLoading=!1;n.data={isAjax:1};m.getActionCall(n,function(d){a.APP_ROOT=d.app_root;a.LANG=d.lang;a.PK=d.pk;a.CHECK_UPDATES=d.check_updates;a.CRYPT.setPublicKey(d.pk);a.TIMEZONE=d.timezone;a.LOCALE=d.locale;a.DEBUG=d.debug;"function"===typeof b&&b()})}, +v={get:function(){h.info("sk:get");return $("#container").attr("data-sk")},set:function(a){h.info("sk:set");$("#container").attr("data-sk",a)}},z=function(){var a=$("#container");if(!a.hasClass("content-no-auto-resize")){var k=$("#content").height()+200;a.css("height",k)}},A=function(){$("html, body").animate({scrollTop:0},"slow")},u=function(a){window.location.replace(a)},B=function(b){var k=function(){return{actionId:b.data("action-id"),itemId:b.data("item-id"),sk:v.get()}},d={requestDoneAction:"", +requestData:function(a){k=function(){return a}},beforeSendAction:"",url:""},n=function(a){if("undefined"===typeof d.url||""===d.url)return!1;var b=new FormData;b.append("inFile",a);b.append("isAjax",1);var p=k();Object.keys(p).forEach(function(a){h.info(a);b.append(a,p[a])});a=m.getRequestOpts();a.url=d.url;a.processData=!1;a.contentType=!1;a.data=b;m.getActionCall(a,function(a){var b=a.status;a=a.description;0===b?("function"===typeof d.requestDoneAction&&d.requestDoneAction(),l.ok(a)):10===b?g.main.logout(): +l.error(a)})},c=function(d){if(5a.MAX_FILE_SIZE)l.error(a.LANG[18]+"
"+p.name+" (Max: "+a.MAX_FILE_SIZE+")");else{var c;a:{c=p.name;for(var e=b.data("files-ext").toLowerCase().split(","),f=0;f<=e.length;f++)if(-1!==c.indexOf(e[f])){c=!0;break a}c=!1}c?n(d[k]):l.error(a.LANG[19]+"
"+p.name)}}},e=function(a){var b=$("#fileUploadForm");!1===a&&b.hide();a=b.find("input[type='file']");a.on("change", +function(){"function"===typeof d.beforeSendAction&&d.beforeSendAction();c(this.files)});return a};window.File&&window.FileList&&window.FileReader?function(){h.info("fileUpload:init");var a=e(!1);b.on("dragover dragenter",function(a){h.info("fileUpload:drag");a.stopPropagation();a.preventDefault()});b.on("drop",function(a){h.info("fileUpload:drop");a.stopPropagation();a.preventDefault();"function"===typeof d.beforeSendAction&&d.beforeSendAction();c(a.dataTransfer.files)});b.on("click",function(){a.click()})}(): +e(!0);return d},C=function(a){h.info("checkPassLevel");f.passLength=a.val().length;w(zxcvbn(a.val()),a)},w=function(b,k){h.info("outputResult");var d=$(".passLevel-"+k.attr("id")),c=b.score;d.show();d.removeClass("weak good strong strongest");0===f.passLength?d.attr("title","").empty():f.passLengtha.secondary?a.calc=a.main/a.rel:a.maina.secondary&&(a.main*=a.factor,g(a));return a},l=function(){f.main=b;f.secondary=c;var d=g(f);a.css({width:d.main,height:d.calc});e.width=d.main;e.height=d.calc},m=function(){f.main=c;f.secondary=b;var d=g(f);a.css({width:d.calc,height:d.main});e.width=d.calc;e.height=d.main};e.width>b?l():e.height>c&&(h.info("height"), +m());return e},I=function(){return $.extend({log:h,config:function(){return a},appTheme:function(){return e},appActions:function(){return g},appTriggers:function(){return c},appRequests:function(){return m},evalAction:G,resizeImage:H},r)},J=function(){return{actions:function(){return g},triggers:function(){return c},theme:function(){return e},sk:v,msg:l,log:h,passToClip:0,passwordData:f,outputResult:w,checkboxDetect:D,checkPassLevel:C,encryptFormValue:t,fileUpload:B,redirect:u,scrollUp:A,setContentSize:z}}; +(function(){h.info("init");r=J();q=I();c=sysPass.Triggers(q);g=sysPass.Actions(q);m=sysPass.Requests(q);y(function(){""!==a.PK&&F();"function"===typeof sysPass.Theme&&(e=sysPass.Theme(q));!0===a.CHECK_UPDATES&&g.main.getUpdates();E();x()})})();return r};