* [ADD] New user preferences available

* [MOD] CSS fonts are now stored locally for Material Blue theme
This commit is contained in:
nuxsmin
2015-10-01 14:26:30 +02:00
parent ac5ec0e0f5
commit 95f0214fd1
37 changed files with 761 additions and 149 deletions

View File

@@ -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)

View File

@@ -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)

View File

@@ -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
----------------

View File

@@ -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

View File

@@ -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');

View File

@@ -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'));
}

View File

@@ -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),

View File

@@ -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'));
}
/**

View File

@@ -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;

View File

@@ -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';

View File

@@ -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);

View File

@@ -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.
*

158
inc/Language.class.php Normal file
View File

@@ -0,0 +1,158 @@
<?php
/**
* sysPass
*
* @author nuxsmin
* @link http://syspass.org
* @copyright 2012-2015 Rubén Domínguez nuxsmin@syspass.org
*
* This file is part of sysPass.
*
* sysPass is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sysPass is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*
*/
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'
);
}
}

View File

@@ -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);
}
}

View File

@@ -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));

133
inc/Themes.class.php Normal file
View File

@@ -0,0 +1,133 @@
<?php
/**
* sysPass
*
* @author nuxsmin
* @link http://syspass.org
* @copyright 2012-2015 Rubén Domínguez nuxsmin@syspass.org
*
* This file is part of sysPass.
*
* sysPass is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sysPass is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*
*/
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;
}
}

View File

@@ -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
*/

View File

@@ -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) {

View File

@@ -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 <nuxsmin@syspass.org>\n"
"Language-Team: <language@syspass.org>\n"
"Language: de_DE\n"

View File

@@ -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));
}

View File

@@ -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)
);

View File

@@ -0,0 +1,83 @@
<!-- Start Tab - Preferences -->
<div id="tabs-<?php echo $preferences_tabIndex; ?>">
<div id="title" class="midroundup titleNormal">
<?php echo _('Sitio'); ?>
</div>
<form method="post" name="frmPreferences" id="frmPreferences"
onsubmit="sysPassUtil.Common.configMgmt('preferences', this); return false;">
<table id="tblSite" class="data tblConfig round">
<tr>
<td class="descField"><?php echo _('Idioma'); ?></td>
<td class="valField">
<select name="userlang" id="sel-userlang" size="1" class="sel-chosen-ns">
<?php foreach ($langsAvailable as $langName => $langValue): ?>
<option
value='<?php echo $langValue; ?>' <?php echo ($currentLang == $langValue) ? "SELECTED" : ""; ?>><?php echo $langName; ?></option>
<?php endforeach; ?>
</select>
</td>
</tr>
<tr>
<td class="descField"><?php echo _('Tema Visual'); ?></td>
<td class="valField">
<select name="usertheme" id="sel-usertheme" size="1"
class="sel-chosen-ns">
<?php foreach ($themesAvailable as $themeDir => $themeName): ?>
<option
value='<?php echo $themeDir; ?>' <?php echo ($currentTheme == $themeDir) ? "SELECTED" : ""; ?>><?php echo $themeName; ?></option>
<?php endforeach; ?>
</select>
</td>
</tr>
<tr>
<td class="descField">
<?php echo _('Nombre de cuenta como enlace'); ?>
<img src="imgs/help.png" title="" class="inputImgMini help-tooltip"/>
<div class="tooltip" for="help-account_link" style="display: none;">
<p>
<?php echo _('Habilita el nombre de la cuenta de la búsqueda, como enlace a los detalles de la cuenta.'); ?>
</p>
</div>
</td>
<td class="valField">
<label for="account_link"><?php echo ($chkAccountLink) ? 'SI' : 'NO'; ?></label>
<input type="checkbox" name="account_link" id="account_link"
class="checkbox" <?php echo $chkAccountLink; ?> />
</td>
</tr>
<tr>
<td class="descField">
<?php echo _('Resultados por página'); ?>
<img src="imgs/help.png" title="" class="inputImgMini help-tooltip"/>
<div class="tooltip" for="help-resultsperpage" style="display:none;">
<p>
<?php echo _('Número de resultados por página a mostrar, al realizar una búsqueda.'); ?>
</p>
</div>
</td>
<td class="valField">
<input type="number" name="resultsperpage" id="sel-resultsperpage" step="6" pattern="[0-9]{1,5}"
value="<?php echo $resultsPerPage; ?>"/>
</td>
</tr>
</table>
<input type="hidden" name="itemId" value="<?php echo $userId; ?>"/>
<input type="hidden" name="activeTab" value="<?php echo $preferences_tabIndex; ?>"/>
<input type="hidden" name="actionId" value="<?php echo $preferences_actionId; ?>"/>
<input type="hidden" name="isAjax" value="1"/>
<input type="hidden" name="sk" value="<?php echo $sk; ?>">
</form>
<div class="action">
<button type="submit" form="frmPreferences" title="<?php echo _('Guardar'); ?>" class="button-action">
<img src="<?php \SP\Init::$WEBURI; ?>imgs/check.png" alt="save"/>
</button>
</div>
</div> <!-- End Tab - Preferences -->

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -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)
);

View File

@@ -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');
}

View File

@@ -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;

View File

@@ -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),
);

View File

@@ -0,0 +1,87 @@
<!-- Start Tab - Preferences -->
<div id="tabs-<?php echo $preferences_tabIndex; ?>">
<div id="title" class="midroundup titleNormal">
<?php echo _('Sitio'); ?>
</div>
<form method="post" name="frmPreferences" id="frmPreferences"
onsubmit="sysPassUtil.Common.configMgmt('preferences', this); return false;">
<table id="tblSite" class="data tblConfig round">
<tr>
<td class="descField"><?php echo _('Idioma'); ?></td>
<td class="valField">
<select name="userlang" id="sel-userlang" size="1" class="sel-chosen-ns">
<?php foreach ($langsAvailable as $langName => $langValue): ?>
<option
value='<?php echo $langValue; ?>' <?php echo ($currentLang == $langValue) ? "SELECTED" : ""; ?>><?php echo $langName; ?></option>
<?php endforeach; ?>
</select>
</td>
</tr>
<tr>
<td class="descField"><?php echo _('Tema Visual'); ?></td>
<td class="valField">
<select name="usertheme" id="sel-usertheme" size="1"
class="sel-chosen-ns">
<?php foreach ($themesAvailable as $themeDir => $themeName): ?>
<option
value='<?php echo $themeDir; ?>' <?php echo ($currentTheme == $themeDir) ? "SELECTED" : ""; ?>><?php echo $themeName; ?></option>
<?php endforeach; ?>
</select>
</td>
</tr>
<tr>
<td class="descField">
<?php echo _('Nombre de cuenta como enlace'); ?>
<div id="help-account_link" class="icon material-icons fg-blue80">help_outline</div>
<div class="mdl-tooltip mdl-tooltip--large" for="help-account_link">
<p>
<?php echo _('Habilita el nombre de la cuenta de la búsqueda, como enlace a los detalles de la cuenta.'); ?>
</p>
</div>
</td>
<td class="valField">
<label class="mdl-switch mdl-js-switch mdl-js-ripple-effect" for="account_link">
<input type="checkbox" id="account_link" class="mdl-switch__input fg-blue100"
name="account_link" <?php echo $chkAccountLink; ?>/>
<span class="mdl-switch__label"></span>
</label>
</td>
</tr>
<tr>
<td class="descField">
<?php echo _('Resultados por página'); ?>
<div id="help-account_count" class="icon material-icons fg-blue80">help_outline</div>
<div class="mdl-tooltip mdl-tooltip--large" for="help-account_count">
<p>
<?php echo _('Número de resultados por página a mostrar, al realizar una búsqueda.'); ?>
</p>
</div>
</td>
<td class="valField">
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
<input id="resultsperpage" name="resultsperpage" type="number" step="6"
pattern="[0-9]{1,5}" class="mdl-textfield__input fg-blue100" maxlength="5"
value="<?php echo $resultsPerPage; ?>" required/>
<label class="mdl-textfield__label"
for="resultsperpage"><?php echo _('Número de resultados por página'); ?></label>
</div>
</td>
</tr>
</table>
<input type="hidden" name="itemId" value="<?php echo $userId; ?>"/>
<input type="hidden" name="activeTab" value="<?php echo $preferences_tabIndex; ?>"/>
<input type="hidden" name="actionId" value="<?php echo $preferences_actionId; ?>"/>
<input type="hidden" name="isAjax" value="1"/>
<input type="hidden" name="sk" value="<?php echo $sk; ?>">
</form>
<div class="action">
<button form="frmPreferences"
class="mdl-button mdl-js-button mdl-button--fab mdl-button--mini-fab mdl-button--colored bg-green80"
title="<?php echo _('Guardar'); ?>">
<i class="material-icons">save</i>
</button>
</div>
</div> <!-- End Tab - Preferences -->

View File

@@ -562,6 +562,9 @@ sysPass.Util.Common = function () {
url = '/ajax/ajax_migrate.php';
break;
case "preferences":
url = '/ajax/ajax_userPrefsSave.php';
break;
default:
return;
}

View File

@@ -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),

View File

@@ -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"' : '');

View File

@@ -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;

View File

@@ -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
*