diff --git a/CHANGELOG b/CHANGELOG index 54552236..8aa6585a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,8 @@ +=== ** v1.2.0.0-rc3 === + +* [ADD] New user preferences available +* [MOD] CSS fonts are now stored locally for Material Blue theme + === ** v1.2.0.0-rc2 === * [ADD] Switched to BCRYPT for hashing passwords and key derivation. WARNING: Master password should be reentered by users (you can use a temporary password) diff --git a/CHANGELOG-ES b/CHANGELOG-ES index 986abc2b..7a503047 100644 --- a/CHANGELOG-ES +++ b/CHANGELOG-ES @@ -1,3 +1,8 @@ +=== ** v1.2.0.0-rc3 === + +* [ADD] Nuevas preferencias de usuario disponibles +* [MOD] Las fuentes CSS son ahora almacenadas localmente para el tema Material Blue + === ** v1.2.0.0-rc2 === * [ADD] Cambiado a BCRYPT para generar el hash de las claves y derivaciones. AVISO: La clave maestra debe de ser introducida por los usuarios (es posible usar una clave temporal) diff --git a/README.md b/README.md index ae243cc2..0318bbff 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ In order to update from 1.1 you need to follow the steps at http://wiki.syspass. ---------------- -### sysPass - Sysadmin Password Manager +### sysPass - Systems Password Manager ---------------- diff --git a/ajax/ajax_doLogin.php b/ajax/ajax_doLogin.php index 37419670..01c1885d 100644 --- a/ajax/ajax_doLogin.php +++ b/ajax/ajax_doLogin.php @@ -176,10 +176,9 @@ if ($User->getUserMPass()) { SP\Common::printJSON(_('Error interno')); } -$userPrefs = new \SP\UserPreferences(); -$prefs = $userPrefs->getPreferences($User->getUserId()); +$UserPrefs = \SP\UserPreferences::getPreferences($User->getUserId()); -if ($prefs->isUse2Fa()) { +if ($UserPrefs->isUse2Fa()) { SP\Session::set2FApassed(false); $url = SP\Init::$WEBURI . '/index.php?a=2fa&i=' . $User->getUserId() . '&t=' . time() . '&f=1'; SP\Common::printJSON($url, 0); @@ -187,6 +186,10 @@ if ($prefs->isUse2Fa()) { SP\Session::set2FApassed(true); } +SP\Language::setLanguage(true); +SP\Themes::setTheme(true); +SP\Session::setUserPreferences($UserPrefs); + $params = array(); // Comprobar si existen parámetros adicionales en URL via POST para pasarlos por GET diff --git a/ajax/ajax_getContent.php b/ajax/ajax_getContent.php index f046e694..4060f19a 100644 --- a/ajax/ajax_getContent.php +++ b/ajax/ajax_getContent.php @@ -24,6 +24,7 @@ */ use SP\Request; +use SP\Themes; define('APP_ROOT', '..'); @@ -54,7 +55,7 @@ $tpl->assign('userId', SP\Session::getUserId()); $tpl->assign('userGroupId', SP\Session::getUserGroupId()); $tpl->assign('userIsAdminApp', SP\Session::getUserIsAdminApp()); $tpl->assign('userIsAdminAcc', SP\Session::getUserIsAdminAcc()); -$tpl->assign('themeUri', \SP\Init::$THEMEURI); +$tpl->assign('themeUri', Themes::$themeUri); // Control de ruta de acciones if ($actionId != \SP\Controller\ActionsInterface::ACTION_ACC_SEARCH) { @@ -160,10 +161,12 @@ switch ($actionId) { $controller->getEventlog(); break; case \SP\Controller\ActionsInterface::ACTION_USR_PREFERENCES: + case \SP\Controller\ActionsInterface::ACTION_USR_PREFERENCES_GENERAL: case \SP\Controller\ActionsInterface::ACTION_USR_PREFERENCES_SECURITY: $tpl->addTemplate('tabs-start'); $controller = new \SP\Controller\UsersPrefsC($tpl); + $controller->getPreferencesTab(); $controller->getSecurityTab(); $tpl->addTemplate('tabs-end'); diff --git a/ajax/ajax_userPrefsSave.php b/ajax/ajax_userPrefsSave.php index 6cf908bb..34e5bda3 100644 --- a/ajax/ajax_userPrefsSave.php +++ b/ajax/ajax_userPrefsSave.php @@ -50,11 +50,37 @@ $activeTab = SP\Request::analyze('activeTab', 0); // Acción al cerrar la vista $doActionOnClose = "sysPassUtil.Common.doAction($actionId,'',$activeTab);"; -if ($actionId === SP\Controller\ActionsInterface::ACTION_USR_PREFERENCES_SECURITY) { - if (SP\Util::demoIsEnabled() && \SP\Session::getUserLogin() == 'demo') { - SP\Common::printJSON(_('Ey, esto es una DEMO!!')); +if (SP\Util::demoIsEnabled() && \SP\Session::getUserLogin() === 'demo') { + SP\Common::printJSON(_('Ey, esto es una DEMO!!')); +} + +if ($actionId === SP\Controller\ActionsInterface::ACTION_USR_PREFERENCES_GENERAL) { + $userLang = SP\Request::analyze('userlang'); + $userTheme = SP\Request::analyze('usertheme', 'material-blue'); + $resultsPerPage = SP\Request::analyze('resultsperpage', 12); + $accountLink = SP\Request::analyze('account_link', false, false, true); + + // No se instancia la clase ya que es necesario guardar los atributos ya guardados + $UserPrefs = \SP\UserPreferences::getPreferences($itemId); + $UserPrefs->setId($itemId); + $UserPrefs->setLang($userLang); + $UserPrefs->setTheme($userTheme); + $UserPrefs->setResultsPerPage($resultsPerPage); + $UserPrefs->setAccountLink($accountLink); + + if (!$UserPrefs->updatePreferences()) { + SP\Common::printJSON(_('Error al actualizar preferencias')); } + // Forzar la detección del lenguaje tras actualizar + SP\Language::setLanguage(true); + SP\Themes::setTheme(true); + // Actualizar las preferencias en la sesión y recargar la página + SP\Session::setUserPreferences($UserPrefs); + SP\Util::reload(); + + SP\Common::printJSON(_('Preferencias actualizadas'), 0, $doActionOnClose); +} else if ($actionId === SP\Controller\ActionsInterface::ACTION_USR_PREFERENCES_SECURITY) { // Variables POST del formulario $twoFaEnabled = SP\Request::analyze('security_2faenabled', 0, false, 1); $pin = SP\Request::analyze('security_pin', 0); @@ -66,11 +92,12 @@ if ($actionId === SP\Controller\ActionsInterface::ACTION_USR_PREFERENCES_SECURIT SP\Common::printJSON(_('Código incorrecto')); } - $preferences = new \SP\UserPreferences(); - $preferences->setId($itemId); - $preferences->setUse2Fa(\SP\Util::boolval($twoFaEnabled)); + // No se instancia la clase ya que es necesario guardar los atributos ya guardados + $UserPrefs = \SP\UserPreferences::getPreferences($itemId); + $UserPrefs->setId($itemId); + $UserPrefs->setUse2Fa(\SP\Util::boolval($twoFaEnabled)); - if (!$preferences->updatePreferences()) { + if (!$UserPrefs->updatePreferences()) { SP\Common::printJSON(_('Error al actualizar preferencias')); } diff --git a/css/css.php b/css/css.php index 968dda60..c7b8b376 100644 --- a/css/css.php +++ b/css/css.php @@ -23,11 +23,13 @@ * */ +use SP\Themes; + define('APP_ROOT', '..'); require_once APP_ROOT . DIRECTORY_SEPARATOR . 'inc' . DIRECTORY_SEPARATOR . 'Base.php'; -$themeCssPath = VIEW_PATH . DIRECTORY_SEPARATOR . \SP\Init::$THEME . DIRECTORY_SEPARATOR . 'css' . DIRECTORY_SEPARATOR . 'css.php'; +$themeCssPath = VIEW_PATH . DIRECTORY_SEPARATOR . Themes::$theme . DIRECTORY_SEPARATOR . 'css' . DIRECTORY_SEPARATOR . 'css.php'; $cssFilesBase = array( array('href' => 'css/reset.css', 'min' => true), diff --git a/inc/AccountSearch.class.php b/inc/AccountSearch.class.php index 07cd3101..0002da5f 100644 --- a/inc/AccountSearch.class.php +++ b/inc/AccountSearch.class.php @@ -84,7 +84,9 @@ class AccountSearch */ function __construct() { - $this->setLimitCount(Config::getValue('account_count')); + $userResultsPerPage = Session::getUserPreferences()->getResultsPerPage(); + + $this->setLimitCount(($userResultsPerPage > 0) ? $userResultsPerPage : Config::getValue('account_count')); } /** diff --git a/inc/ActionsInterface.class.php b/inc/ActionsInterface.class.php index b1b9cce3..3f11c142 100644 --- a/inc/ActionsInterface.class.php +++ b/inc/ActionsInterface.class.php @@ -82,7 +82,8 @@ interface ActionsInterface { const ACTION_USR_PROFILES_EDIT = 732; const ACTION_USR_PROFILES_DELETE = 733; const ACTION_USR_PREFERENCES = 740; - const ACTION_USR_PREFERENCES_SECURITY = 741; + const ACTION_USR_PREFERENCES_GENERAL = 741; + const ACTION_USR_PREFERENCES_SECURITY = 742; const ACTION_CFG = 80; const ACTION_CFG_GENERAL = 81; const ACTION_CFG_ENCRYPTION = 82; diff --git a/inc/Base.php b/inc/Base.php index 02647571..1b582d24 100644 --- a/inc/Base.php +++ b/inc/Base.php @@ -27,7 +27,9 @@ define('MODEL_PATH', __DIR__); define('CONTROLLER_PATH', __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'web'); define('VIEW_PATH', __DIR__ . DIRECTORY_SEPARATOR . 'themes'); define('EXTENSIONS_PATH', __DIR__ . DIRECTORY_SEPARATOR . 'ext'); -define('DEBUG', false); +define('LOCALES_PATH', __DIR__ . DIRECTORY_SEPARATOR . 'locales'); + +define('DEBUG', true); require MODEL_PATH . DIRECTORY_SEPARATOR . 'Init.class.php'; diff --git a/inc/Config.class.php b/inc/Config.class.php index 15364928..2cc87955 100644 --- a/inc/Config.class.php +++ b/inc/Config.class.php @@ -314,7 +314,7 @@ class Config self::setValue('ldap_userattr', ''); self::setValue('mail_server', ''); self::setValue('mail_from', ''); - self::setValue('site_lang', str_replace('.utf8', '', Init::$LANG)); + self::setValue('site_lang', str_replace('.utf8', '', Language::$globalLang)); self::setValue('session_timeout', '300'); self::setValue('account_link', 1); self::setValue('account_count', 12); diff --git a/inc/Init.class.php b/inc/Init.class.php index 884674d4..2bbb1fec 100644 --- a/inc/Init.class.php +++ b/inc/Init.class.php @@ -56,31 +56,11 @@ class Init */ public static $WEBURI = ''; - /** - * @var string Language used/detected - */ - public static $LANG = ''; - /** * @var bool True if sysPass has been updated. Only for notices. */ public static $UPDATED = false; - /** - * @var string - */ - public static $THEMEURI = ''; - - /** - * @var string - */ - public static $THEMEPATH = ''; - - /** - * @var string - */ - public static $THEME = ''; - /** * @var string */ @@ -175,10 +155,10 @@ class Init self::setPaths(); // Cargar el lenguaje - self::selectLang(); + Language::setLanguage(); // Establecer el tema de sysPass - self::selectTheme(); + Themes::setTheme(); // Comprobar si es necesario inicialización if (self::checkInitSourceInclude()) { @@ -226,7 +206,7 @@ class Init } // Manejar la redirección para usuarios logeados - if (isset($_REQUEST['redirect_url']) && self::isLoggedIn()) { + if (Request::analyze('redirect_url', '', true) && self::isLoggedIn()) { $location = 'index.php'; // Denegar la regirección si la URL contiene una @ @@ -351,48 +331,6 @@ class Init self::$WEBURI .= $protocol . $_SERVER['HTTP_HOST'] . self::$WEBROOT; } - /** - * Establece el lenguaje de la aplicación. - * Esta función establece el lenguaje según esté definido en la configuración o en el navegador. - */ - private static function selectLang() - { - $browserLang = str_replace("-", "_", substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 5)); - $configLang = Config::getValue('sitelang'); - $localesDir = self::$SERVERROOT . DIRECTORY_SEPARATOR . 'inc' . DIRECTORY_SEPARATOR . 'locales'; - - // Establecer a en_US si no existe la traducción o no es español - if (!file_exists($localesDir . DIRECTORY_SEPARATOR . $browserLang) - && !preg_match('/^es_.*/i', $browserLang) - && !$configLang - ) { - self::$LANG = 'en_US'; - } else { - self::$LANG = ($configLang) ? $configLang : $browserLang; - } - - self::$LANG = self::$LANG . ".utf8"; - - putenv("LANG=" . self::$LANG); - setlocale(LC_MESSAGES, self::$LANG); - setlocale(LC_ALL, self::$LANG); - bindtextdomain("messages", $localesDir); - textdomain("messages"); - bind_textdomain_codeset("messages", 'UTF-8'); - } - - /** - * Establecer el tema visual de sysPass desde la configuración - */ - private static function selectTheme() - { - self::$THEME = Config::getValue('sitetheme', 'material-blue'); - self::$THEMEURI = self::$WEBURI . '/inc/themes/' . self::$THEME; - self::$THEMEPATH = DIRECTORY_SEPARATOR . 'inc' . DIRECTORY_SEPARATOR . 'themes' . DIRECTORY_SEPARATOR . self::$THEME; - - Session::setTheme(self::$THEME); - } - /** * Comprobar el archivo que realiza el include necesita inicialización. * diff --git a/inc/Language.class.php b/inc/Language.class.php new file mode 100644 index 00000000..663bbb3b --- /dev/null +++ b/inc/Language.class.php @@ -0,0 +1,158 @@ +. + * + */ + +namespace SP; + +defined('APP_ROOT') || die(_('No es posible acceder directamente a este archivo')); + +/** + * Class Language para el manejo del languaje utilizado por la aplicación + * + * @package SP + */ +class Language +{ + /** + * Lenguaje del usuario + * + * @var string + */ + public static $userLang = ''; + /** + * Lenguaje global de la Aplicación + * + * @var string + */ + public static $globalLang = ''; + + /** + * Establecer el lenguaje a utilizar + * + * @param bool $force Forzar la detección del lenguaje para los inicios de sesión + */ + public static function setLanguage($force = false) + { + $lang = Session::getLocale(); + + if (empty($lang) || $force === true) { + $Language = new Language(); + + self::$userLang = $Language->getUserLang(); + self::$globalLang = $Language->getGlobalLang(); + + $lang = (self::$userLang) ? self::$userLang : self::$globalLang; + + Session::setLocale($lang); + } + + self::setLocales($lang); + } + + /** + * Devuelve el lenguaje del usuario + * + * @return bool + */ + private function getUserLang() + { + return (Session::getUserId() > 0) ? UserPreferences::getPreferences(Session::getUserId())->getLang() : ''; + } + + /** + * Establece el lenguaje de la aplicación. + * Esta función establece el lenguaje según esté definido en la configuración o en el navegador. + */ + private function getGlobalLang() + { + $browserLang = $this->getBrowserLang(); + $configLang = Config::getValue('sitelang'); + + // Establecer a en_US si no existe la traducción o no es español + if (!$configLang + && !$this->checkLangFile($browserLang) + && !preg_match('/^es_.*/i', $browserLang) + ) { + $lang = 'en_US'; + } else { + $lang = ($configLang) ? $configLang : $browserLang; + } + + return $lang; + } + + /** + * Devolver el lenguaje que acepta el navegador + * + * @return mixed + */ + private function getBrowserLang() + { + return str_replace("-", "_", substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 5)); + } + + /** + * Comprobar si el archivo de lenguaje existe + * + * @param string $lang El lenguaje a comprobar + * @return bool + */ + private function checkLangFile($lang) + { + return file_exists(LOCALES_PATH . DIRECTORY_SEPARATOR . $lang); + } + + /** + * Establecer las locales de gettext + * + * @param string $lang El lenguaje a utilizar + */ + private static function setLocales($lang) + { + $lang .= '.utf8'; + + putenv("LANG=" . $lang); + setlocale(LC_MESSAGES, $lang); + setlocale(LC_ALL, $lang); + bindtextdomain("messages", LOCALES_PATH); + textdomain("messages"); + bind_textdomain_codeset("messages", 'UTF-8'); + } + + /** + * Devolver los lenguajes disponibles + * + * @return array + */ + public static function getAvailableLanguages() + { + return array( + 'Español' => 'es_ES', + 'English' => 'en_US', + 'Deutsch' => 'de_DE', + 'Magyar' => 'hu_HU', + 'Français' => 'fr_FR' + ); + } +} \ No newline at end of file diff --git a/inc/Session.class.php b/inc/Session.class.php index a50f4c25..4b937bce 100644 --- a/inc/Session.class.php +++ b/inc/Session.class.php @@ -597,4 +597,44 @@ class Session { self::setSessionKey('pubkey', $key); } + + /** + * Establecer el lenguaje de la sesión + * + * @param $locale + */ + public static function setLocale($locale) + { + self::setSessionKey('locale', $locale); + } + + /** + * Devuelve el lenguaje de la sesión + * + * @return string + */ + public static function getLocale() + { + return self::getSessionKey('locale'); + } + + /** + * Obtiene el objeto de preferencias de usuario de la sesión. + * + * @return UserPreferences + */ + public static function getUserPreferences() + { + return self::getSessionKey('usrpreferences'); + } + + /** + * Establece el objeto de preferencias de usuario en la sesión. + * + * @param \SP\UserPreferences $preferences + */ + public static function setUserPreferences(\SP\UserPreferences $preferences) + { + self::setSessionKey('usrpreferences', $preferences); + } } \ No newline at end of file diff --git a/inc/Template.class.php b/inc/Template.class.php index d8adb4f6..184b0abc 100644 --- a/inc/Template.class.php +++ b/inc/Template.class.php @@ -83,7 +83,7 @@ class Template */ private function checkTemplate($file) { - $template = VIEW_PATH . DIRECTORY_SEPARATOR . Init::$THEME . DIRECTORY_SEPARATOR . $file . '.inc'; + $template = VIEW_PATH . DIRECTORY_SEPARATOR . Themes::$theme . DIRECTORY_SEPARATOR . $file . '.inc'; if (!is_readable($template)) { throw new InvalidArgumentException(sprintf(_('No es posible obtener la plantilla "%s" : %s'), $file, $template)); diff --git a/inc/Themes.class.php b/inc/Themes.class.php new file mode 100644 index 00000000..fa5359bf --- /dev/null +++ b/inc/Themes.class.php @@ -0,0 +1,133 @@ +. + * + */ + +namespace SP; + +defined('APP_ROOT') || die(_('No es posible acceder directamente a este archivo')); + +/** + * Class Themes para el manejo de los temas visuales + * + * @package SP + */ +class Themes +{ + /** + * @var string + */ + public static $themeUri = ''; + /** + * @var string + */ + public static $themePath = ''; + /** + * @var string + */ + public static $theme = ''; + + /** + * Obtener los temas disponibles desde el directorio de temas + * + * @return array Con la información del tema + */ + public static function getThemesAvailable() + { + $themesAvailable = array(); + + $dirThemes = dir(VIEW_PATH); + + while (false !== ($theme = $dirThemes->read())) { + if ($theme != '.' && $theme != '..') { + $themeFile = VIEW_PATH . DIRECTORY_SEPARATOR . $theme . DIRECTORY_SEPARATOR . 'index.php'; + + if (file_exists($themeFile)) { + include $themeFile; + + $themesAvailable[$theme] = $themeInfo['name']; + } + } + } + + $dirThemes->close(); + + return $themesAvailable; + } + + /** + * Establecer el tema visual a utilizar + * + * @param bool $force Forzar la detección del tema para los inicios de sesión + */ + public static function setTheme($force = false) + { + $theme = Session::getTheme(); + + if (empty($theme) || $force === true) { + $Theme = new Themes(); + + $userTheme = $Theme->getUserTheme(); + $globalTheme = $Theme->getGlobalTheme(); + + $theme = ($userTheme) ? $userTheme : $globalTheme; + + Session::setLocale($theme); + } + + self::setThemePaths($theme); + Session::setTheme($theme); + } + + /** + * Obtener el tema visual del usuario + * + * @return string + */ + private function getUserTheme() + { + return (Session::getUserId() > 0) ? UserPreferences::getPreferences(Session::getUserId())->getTheme() : ''; + } + + /** + * Devolver el tema visual de sysPass desde la configuración + */ + private function getGlobalTheme() + { + self::$theme = Config::getValue('sitetheme', 'material-blue'); + + return self::$theme; + } + + /** + * Establecer las variables de rutas para el tema visual + * + * @param string $theme El tema a utilizar + */ + private static function setThemePaths($theme) + { + self::$theme = $theme; + self::$themeUri = Init::$WEBURI . '/inc/themes/' . $theme; + self::$themePath = DIRECTORY_SEPARATOR . 'inc' . DIRECTORY_SEPARATOR . 'themes' . DIRECTORY_SEPARATOR . $theme; + } +} \ No newline at end of file diff --git a/inc/UserPreferences.class.php b/inc/UserPreferences.class.php index 03591913..7c9a6625 100644 --- a/inc/UserPreferences.class.php +++ b/inc/UserPreferences.class.php @@ -38,13 +38,32 @@ class UserPreferences * @var int */ private $_id = 0; - /** * Usar autentificación en 2 pasos * * @var bool */ private $_use2Fa = false; + /** + * Lenguaje del usuario + * + * @var string + */ + private $_lang = ''; + /** + * Tema del usuario + * + * @var string + */ + private $_theme = ''; + /** + * @var int + */ + private $_resultsPerPage = 0; + /** + * @var bool + */ + private $_accountLink = null; /** * Obtener las preferencas de un usuario @@ -75,6 +94,70 @@ class UserPreferences return $preferences; } + /** + * @return int + */ + public function getResultsPerPage() + { + return $this->_resultsPerPage; + } + + /** + * @param int $resultsPerPage + */ + public function setResultsPerPage($resultsPerPage) + { + $this->_resultsPerPage = $resultsPerPage; + } + + /** + * @return boolean + */ + public function isAccountLink() + { + return $this->_accountLink; + } + + /** + * @param boolean $accountLink + */ + public function setAccountLink($accountLink) + { + $this->_accountLink = $accountLink; + } + + /** + * @return string + */ + public function getTheme() + { + return $this->_theme; + } + + /** + * @param string $theme + */ + public function setTheme($theme) + { + $this->_theme = $theme; + } + + /** + * @return string + */ + public function getLang() + { + return $this->_lang; + } + + /** + * @param string $lang + */ + public function setLang($lang) + { + $this->_lang = $lang; + } + /** * @return boolean */ diff --git a/inc/Util.class.php b/inc/Util.class.php index e8df02f2..d580f627 100644 --- a/inc/Util.class.php +++ b/inc/Util.class.php @@ -199,7 +199,7 @@ class Util */ public static function getVersionString() { - return '1.2-rc2'; + return '1.2-rc3'; } /** @@ -316,7 +316,7 @@ class Util */ public static function getVersion($retBuild = false) { - $build = '02'; + $build = '03'; $version = array(1, 2, 0); if ($retBuild) { diff --git a/inc/locales/de_DE/LC_MESSAGES/messages.mo b/inc/locales/de_DE/LC_MESSAGES/messages.mo index 9a0893a7..adb76bfa 100644 Binary files a/inc/locales/de_DE/LC_MESSAGES/messages.mo and b/inc/locales/de_DE/LC_MESSAGES/messages.mo differ diff --git a/inc/locales/de_DE/LC_MESSAGES/messages.po b/inc/locales/de_DE/LC_MESSAGES/messages.po index f926c2d2..2f1460fb 100644 --- a/inc/locales/de_DE/LC_MESSAGES/messages.po +++ b/inc/locales/de_DE/LC_MESSAGES/messages.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: sysPass\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-09-30 03:00+0100\n" -"PO-Revision-Date: 2015-09-30 03:01+0100\n" +"PO-Revision-Date: 2015-10-01 01:54+0100\n" "Last-Translator: nuxsmin \n" "Language-Team: \n" "Language: de_DE\n" diff --git a/inc/themes/classic/css/css.php b/inc/themes/classic/css/css.php index bc90160f..f1ec517d 100644 --- a/inc/themes/classic/css/css.php +++ b/inc/themes/classic/css/css.php @@ -23,11 +23,13 @@ * */ +use SP\Themes; + $cssFilesTheme = array( - array('href' => \SP\Init::$THEMEPATH . '/css/jquery-ui.theme.min.css', 'min' => true), - array('href' => \SP\Init::$THEMEPATH . '/css/styles.css', 'min' => true) + array('href' => Themes::$themePath . '/css/jquery-ui.theme.min.css', 'min' => true), + array('href' => Themes::$themePath . '/css/styles.css', 'min' => true) ); if (!SP\Util::resultsCardsIsEnabled()) { - array_push($cssFilesTheme, array('href' => \SP\Init::$THEMEPATH . '/css/search-grid.css', 'min' => true)); + array_push($cssFilesTheme, array('href' => Themes::$themePath . '/css/search-grid.css', 'min' => true)); } \ No newline at end of file diff --git a/inc/themes/classic/js/js.php b/inc/themes/classic/js/js.php index 5dae3852..60513353 100644 --- a/inc/themes/classic/js/js.php +++ b/inc/themes/classic/js/js.php @@ -23,6 +23,8 @@ * */ +use SP\Themes; + $jsFilesTheme = array( - array('href' => \SP\Init::$THEMEPATH . '/js/functions.js', 'min' => true) + array('href' => Themes::$themePath . '/js/functions.js', 'min' => true) ); \ No newline at end of file diff --git a/inc/themes/classic/preferences.inc b/inc/themes/classic/preferences.inc new file mode 100644 index 00000000..f0ee17c6 --- /dev/null +++ b/inc/themes/classic/preferences.inc @@ -0,0 +1,83 @@ + +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + /> +
+ + + + + + +
+ + + + + + +
+
+ +
+
\ No newline at end of file diff --git a/inc/themes/material-blue/css/Roboto_300.woff2 b/inc/themes/material-blue/css/Roboto_300.woff2 new file mode 100644 index 00000000..c34c1280 Binary files /dev/null and b/inc/themes/material-blue/css/Roboto_300.woff2 differ diff --git a/inc/themes/material-blue/css/Roboto_400.woff2 b/inc/themes/material-blue/css/Roboto_400.woff2 new file mode 100644 index 00000000..120796bb Binary files /dev/null and b/inc/themes/material-blue/css/Roboto_400.woff2 differ diff --git a/inc/themes/material-blue/css/Roboto_500.woff2 b/inc/themes/material-blue/css/Roboto_500.woff2 new file mode 100644 index 00000000..5f96609d Binary files /dev/null and b/inc/themes/material-blue/css/Roboto_500.woff2 differ diff --git a/inc/themes/material-blue/css/Roboto_600.woff2 b/inc/themes/material-blue/css/Roboto_600.woff2 new file mode 100644 index 00000000..11cde5d0 Binary files /dev/null and b/inc/themes/material-blue/css/Roboto_600.woff2 differ diff --git a/inc/themes/material-blue/css/css.php b/inc/themes/material-blue/css/css.php index e52c73ba..449370ce 100644 --- a/inc/themes/material-blue/css/css.php +++ b/inc/themes/material-blue/css/css.php @@ -23,13 +23,14 @@ * */ +use SP\Themes; + $cssFilesTheme = array( -// array('href' => 'https://fonts.googleapis.com/icon?family=Material+Icons', 'min' => false), - array('href' => 'https://fonts.googleapis.com/css?family=Roboto:300,400,500,700', 'min' => false), - array('href' => \SP\Init::$THEMEPATH . '/css/material.min.css', 'min' => false), - array('href' => \SP\Init::$THEMEPATH . '/css/material-custom.css', 'min' => true), - array('href' => \SP\Init::$THEMEPATH . '/css/jquery-ui.theme.css', 'min' => true), - array('href' => \SP\Init::$THEMEPATH . '/css/styles.css', 'min' => true), - array('href' => \SP\Init::$THEMEPATH . '/css/search-grid.css', 'min' => true), - array('href' => \SP\Init::$THEMEPATH . '/css/alertify.custom.css', 'min' => true) + array('href' => Themes::$themePath . '/css/fonts.css', 'min' => true), + array('href' => Themes::$themePath . '/css/material.min.css', 'min' => false), + array('href' => Themes::$themePath . '/css/material-custom.css', 'min' => true), + array('href' => Themes::$themePath . '/css/jquery-ui.theme.css', 'min' => true), + array('href' => Themes::$themePath . '/css/styles.css', 'min' => true), + array('href' => Themes::$themePath . '/css/search-grid.css', 'min' => true), + array('href' => Themes::$themePath . '/css/alertify.custom.css', 'min' => true) ); \ No newline at end of file diff --git a/inc/themes/material-blue/css/fonts.css b/inc/themes/material-blue/css/fonts.css new file mode 100644 index 00000000..81d617ba --- /dev/null +++ b/inc/themes/material-blue/css/fonts.css @@ -0,0 +1,24 @@ +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 300; + src: local('Roboto Light'), local('Roboto-Light'), url('../inc/themes/material-blue/css/Roboto_300.woff2') format('woff2'); +} +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 400; + src: local('Roboto'), local('Roboto-Regular'), url('../inc/themes/material-blue/css/Roboto_400.woff2') format('woff2'); +} +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 500; + src: local('Roboto Medium'), local('Roboto-Medium'), url('../inc/themes/material-blue/css/Roboto_500.woff2') format('woff2'); +} +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 700; + src: local('Roboto Bold'), local('Roboto-Bold'), url('../inc/themes/material-blue/css/Roboto_600.woff2') format('woff2'); +} \ No newline at end of file diff --git a/inc/themes/material-blue/css/styles.css b/inc/themes/material-blue/css/styles.css index 978f0b2a..d73afc6d 100644 --- a/inc/themes/material-blue/css/styles.css +++ b/inc/themes/material-blue/css/styles.css @@ -1055,13 +1055,6 @@ a:hover, a:active, a:focus { font-size: 18px; color: white; background-color: rgb(96, 125, 139); - /*background-color: #536dfe;*/ - /*background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #536dfe), color-stop(90%, #536dfe));*/ - /*background-image: -webkit-linear-gradient(#536dfe 20%, #536dfe 90%);*/ - /*background-image: -moz-linear-gradient(#536dfe 20%, #536dfe 90%);*/ - /*background-image: -o-linear-gradient(#536dfe 20%, #536dfe 90%);*/ - /*background-image: linear-gradient(#536dfe 20%, #536dfe 90%);*/ - /*background: #536dfe url("../inc/themes/material-blue/css/images/ui-bg_highlight-hard_100_536DFE_1x100.png") repeat-x scroll 50% 50%;*/ margin: 0 0 20px 0; padding: .5em 0; line-height: 1em; diff --git a/inc/themes/material-blue/js/js.php b/inc/themes/material-blue/js/js.php index 26dacc3e..57d49ea8 100644 --- a/inc/themes/material-blue/js/js.php +++ b/inc/themes/material-blue/js/js.php @@ -23,7 +23,9 @@ * */ +use SP\Themes; + $jsFilesTheme = array( - array('href' => \SP\Init::$THEMEPATH . '/js/material.min.js', 'min' => false), - array('href' => \SP\Init::$THEMEPATH . '/js/functions.js', 'min' => true), + array('href' => Themes::$themePath . '/js/material.min.js', 'min' => false), + array('href' => Themes::$themePath . '/js/functions.js', 'min' => true), ); \ No newline at end of file diff --git a/inc/themes/material-blue/preferences.inc b/inc/themes/material-blue/preferences.inc new file mode 100644 index 00000000..b8ca986c --- /dev/null +++ b/inc/themes/material-blue/preferences.inc @@ -0,0 +1,87 @@ + +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + +
+

+ +

+
+
+ +
+ +
help_outline
+
+

+ +

+
+
+
+ + +
+
+ + + + + + +
+
+ +
+
\ No newline at end of file diff --git a/js/functions.js b/js/functions.js index 11a71999..6a0b5a0e 100644 --- a/js/functions.js +++ b/js/functions.js @@ -562,6 +562,9 @@ sysPass.Util.Common = function () { url = '/ajax/ajax_migrate.php'; break; + case "preferences": + url = '/ajax/ajax_userPrefsSave.php'; + break; default: return; } diff --git a/js/js.php b/js/js.php index ce0adace..ed74da68 100644 --- a/js/js.php +++ b/js/js.php @@ -23,11 +23,13 @@ * */ +use SP\Themes; + define('APP_ROOT', '..'); require APP_ROOT . DIRECTORY_SEPARATOR . 'inc' . DIRECTORY_SEPARATOR . 'Base.php'; -$themeJsPath = VIEW_PATH . DIRECTORY_SEPARATOR . \SP\Init::$THEME . DIRECTORY_SEPARATOR . 'js' . DIRECTORY_SEPARATOR . 'js.php'; +$themeJsPath = VIEW_PATH . DIRECTORY_SEPARATOR . Themes::$theme . DIRECTORY_SEPARATOR . 'js' . DIRECTORY_SEPARATOR . 'js.php'; $jsFilesBase = array( array('href' => 'js/jquery-1.11.2.min.js', 'min' => false), diff --git a/web/ConfigC.class.php b/web/ConfigC.class.php index 2c5c0d21..e6643197 100644 --- a/web/ConfigC.class.php +++ b/web/ConfigC.class.php @@ -26,7 +26,9 @@ namespace SP\Controller; use SP\Config; +use SP\Language; use SP\Session; +use SP\Themes; defined('APP_ROOT') || die(_('No es posible acceder directamente a este archivo')); @@ -67,34 +69,11 @@ class ConfigC extends Controller implements ActionsInterface return; } - $themesAvailable = array(); - - $dirThemes = dir(VIEW_PATH); - - while (false !== ($theme = $dirThemes->read())) { - if($theme != '.' && $theme != '..') { - include VIEW_PATH . DIRECTORY_SEPARATOR . $theme . DIRECTORY_SEPARATOR . 'index.php'; - - $themesAvailable[$theme] = $themeInfo['name']; - } - } - - $dirThemes->close(); - $this->view->addTemplate('config'); - $this->view->assign('langsAvailable', - array( - 'Español' => 'es_ES', - 'English' => 'en_US', - 'Deutsch' => 'de_DE', - 'Magyar' => 'hu_HU', - 'Français' => 'fr_FR' - ) - ); - + $this->view->assign('langsAvailable',Language::getAvailableLanguages()); $this->view->assign('currentLang', \SP\Config::getValue('sitelang')); - $this->view->assign('themesAvailable', $themesAvailable); + $this->view->assign('themesAvailable', Themes::getThemesAvailable()); $this->view->assign('currentTheme', \SP\Config::getValue('sitetheme')); $this->view->assign('chkLog', (\SP\Config::getValue('log_enabled')) ? 'checked="checked"' : ''); $this->view->assign('chkDebug', (\SP\Config::getValue('debug')) ? 'checked="checked"' : ''); diff --git a/web/SearchC.class.php b/web/SearchC.class.php index 3153d746..b08b0d73 100644 --- a/web/SearchC.class.php +++ b/web/SearchC.class.php @@ -25,6 +25,7 @@ namespace SP\Controller; +use SP\Session; use SP\UserUtil; defined('APP_ROOT') || die(_('No es posible acceder directamente a este archivo')); @@ -125,7 +126,6 @@ class SearchC extends Controller implements ActionsInterface */ private function processSearchResults(&$results) { - // Variables para la barra de navegación $this->view->assign('firstPage', ceil(($this->view->limitStart + 1) / $this->view->limitCount)); $this->view->assign('lastPage', ceil(\SP\AccountSearch::$queryNumRows / $this->view->limitCount)); @@ -141,8 +141,10 @@ class SearchC extends Controller implements ActionsInterface 'next' => 'sysPassUtil.Common.searchSort(' . $this->view->searchKey . ',' . ($this->view->limitStart + $this->view->limitCount) . ',1)', )); + $accountLink = Session::getUserPreferences()->isAccountLink(); + // Variables de configuración - $this->view->assign('accountLink', \SP\Config::getValue('account_link', 0)); + $this->view->assign('accountLink', (is_null($accountLink) ? \SP\Config::getValue('account_link', 0) : $accountLink)); $this->view->assign('requestEnabled', \SP\Util::mailrequestIsEnabled()); $this->view->assign('isDemoMode', \SP\Util::demoIsEnabled()); $maxTextLength = (\SP\Util::resultsCardsIsEnabled()) ? 40 : 60; diff --git a/web/UsersPrefsC.class.php b/web/UsersPrefsC.class.php index 04c6ff45..d54cc3e9 100644 --- a/web/UsersPrefsC.class.php +++ b/web/UsersPrefsC.class.php @@ -26,7 +26,9 @@ namespace SP\Controller; use SP\Auth\Auth2FA; +use SP\Language; use SP\Session; +use SP\Themes; use SP\UserPreferences; defined('APP_ROOT') || die(_('No es posible acceder directamente a este archivo')); @@ -38,7 +40,19 @@ defined('APP_ROOT') || die(_('No es posible acceder directamente a este archivo' */ class UsersPrefsC extends Controller implements ActionsInterface { + /** + * @var int + */ private $_tabIndex = 0; + /** + * @var UserPreferences + */ + private $_userPrefs; + /** + * @var int + */ + private $_userId; + /** * Constructor @@ -49,8 +63,11 @@ class UsersPrefsC extends Controller implements ActionsInterface { parent::__construct($template); + $this->view->assign('tabs', array()); $this->view->assign('sk', \SP\Common::getSessionKey(true)); + $this->_userId = Session::getUserId(); + $this->_userPrefs = UserPreferences::getPreferences($this->_userId); } /** @@ -60,32 +77,45 @@ class UsersPrefsC extends Controller implements ActionsInterface { $this->setAction(self::ACTION_USR_PREFERENCES_SECURITY); -// if (!$this->checkAccess()) { -// $this->showError(self::ERR_PAGE_NO_PERMISSION); -// return; -// } - $this->view->addTemplate('security'); - $userId = Session::getUserId(); - $userPrefs = UserPreferences::getPreferences($userId); + $twoFa = new Auth2FA($this->_userId, Session::getUserLogin()); - $twoFa = new Auth2FA($userId, Session::getUserLogin()); - - $this->view->assign('userId', $userId); - - if (!$userPrefs->isUse2Fa()) { + if (!$this->_userPrefs->isUse2Fa()) { $this->view->assign('qrCode', $twoFa->getUserQRCode()); } - $this->view->assign('chk2FAEnabled', $userPrefs->isUse2Fa()); + $this->view->assign('userId', $this->_userId); + $this->view->assign('chk2FAEnabled', $this->_userPrefs->isUse2Fa()); $this->view->append('tabs', array('title' => _('Seguridad'))); $this->view->assign('tabIndex', $this->getTabIndex(), 'security'); $this->view->assign('actionId', $this->getAction(), 'security'); } + /** + * Obtener la pestaña de preferencias + */ + public function getPreferencesTab() + { + $this->setAction(self::ACTION_USR_PREFERENCES_GENERAL); + + $this->view->addTemplate('preferences'); + + $this->view->assign('userId', $this->_userId); + $this->view->assign('langsAvailable',Language::getAvailableLanguages()); + $this->view->assign('currentLang', $this->_userPrefs->getLang()); + $this->view->assign('themesAvailable', Themes::getThemesAvailable()); + $this->view->assign('currentTheme', ($this->_userPrefs->getTheme()) ? $this->_userPrefs->getTheme() : \SP\Config::getValue('sitetheme')); + $this->view->assign('chkAccountLink', ($this->_userPrefs->isAccountLink()) ? 'checked="checked"' : ''); + $this->view->assign('resultsPerPage', ($this->_userPrefs->getResultsPerPage()) ? $this->_userPrefs->getResultsPerPage() : \SP\Config::getValue('account_count')); + + $this->view->append('tabs', array('title' => _('Preferencias'))); + $this->view->assign('tabIndex', $this->getTabIndex(), 'preferences'); + $this->view->assign('actionId', $this->getAction(), 'preferences'); + } + /** * Obtener el índice actual de las pestañas *