mirror of
https://github.com/nuxsmin/sysPass.git
synced 2026-03-07 17:06:54 +01:00
* [MOD] IMPORTANT: Plugins are no longer shipped within sysPass, please download from their own repository.
* [MOD] Improved JS actions for plugins
This commit is contained in:
@@ -1,349 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* sysPass
|
||||
*
|
||||
* @author nuxsmin
|
||||
* @link http://syspass.org
|
||||
* @copyright 2012-2017, 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 Plugins\Authenticator;
|
||||
|
||||
use Defuse\Crypto\Exception\EnvironmentIsBrokenException;
|
||||
use SP\Controller\ItemControllerInterface;
|
||||
use SP\Controller\RequestControllerTrait;
|
||||
use SP\Core\Exceptions\SPException;
|
||||
use SP\Core\Messages\LogMessage;
|
||||
use SP\Core\Plugin\PluginDataStore;
|
||||
use SP\Core\Session as CoreSession;
|
||||
use SP\DataModel\PluginData;
|
||||
use SP\Http\Request;
|
||||
use SP\Log\Email;
|
||||
use SP\Mgmt\Plugins\Plugin;
|
||||
use SP\Util\ArrayUtil;
|
||||
use SP\Util\Checks;
|
||||
use SP\Util\Json;
|
||||
use SP\Util\Util;
|
||||
|
||||
/**
|
||||
* Class ActionController
|
||||
*
|
||||
* @package Plugins\Authenticator
|
||||
*/
|
||||
class ActionController implements ItemControllerInterface
|
||||
{
|
||||
const ACTION_TWOFA_SAVE = 1;
|
||||
const ACTION_TWOFA_CHECKCODE = 2;
|
||||
|
||||
use RequestControllerTrait;
|
||||
|
||||
/**
|
||||
* @var AuthenticatorPlugin
|
||||
*/
|
||||
protected $Plugin;
|
||||
|
||||
/**
|
||||
* ActionController constructor.
|
||||
*
|
||||
* @throws \SP\Core\Exceptions\SPException
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->Plugin = new AuthenticatorPlugin();
|
||||
|
||||
PluginDataStore::load($this->Plugin);
|
||||
|
||||
$this->init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Realizar la acción solicitada en la la petición HTTP
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
* @throws \SP\Core\Exceptions\SPException
|
||||
*/
|
||||
public function doAction()
|
||||
{
|
||||
try {
|
||||
switch ($this->actionId) {
|
||||
case ActionController::ACTION_TWOFA_SAVE:
|
||||
$this->save();
|
||||
break;
|
||||
case ActionController::ACTION_TWOFA_CHECKCODE:
|
||||
$this->checkCode();
|
||||
break;
|
||||
default:
|
||||
$this->invalidAction();
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$this->JsonResponse->setDescription($e->getMessage());
|
||||
Json::returnJson($this->JsonResponse);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Guardar los datos del plugin
|
||||
*
|
||||
* @throws \SP\Core\Exceptions\SPException
|
||||
* @throws \InvalidArgumentException
|
||||
* @throws \SP\Core\Exceptions\InvalidClassException
|
||||
*/
|
||||
protected function save()
|
||||
{
|
||||
$pin = Request::analyze('security_pin');
|
||||
$twofa_enabled = Request::analyze('security_2faenabled', 0, false, 1);
|
||||
|
||||
$AuthenticatorData = Session::getUserData();
|
||||
|
||||
$twoFa = new Authenticator($this->itemId, CoreSession::getUserData()->getUserLogin(), $AuthenticatorData->getIV());
|
||||
|
||||
if (!$twoFa->verifyKey($pin)) {
|
||||
$this->JsonResponse->setDescription(_t('authenticator', 'Código incorrecto'));
|
||||
Json::returnJson($this->JsonResponse);
|
||||
}
|
||||
|
||||
if (Checks::demoIsEnabled()) {
|
||||
$this->JsonResponse->setDescription(_t('authenticator', 'Ey, esto es una DEMO!!'));
|
||||
Json::returnJson($this->JsonResponse);
|
||||
}
|
||||
|
||||
$data = $this->Plugin->getData();
|
||||
|
||||
if ($twofa_enabled) {
|
||||
/** @var AuthenticatorData $AuthenticatorData */
|
||||
$AuthenticatorData->setUserId($this->itemId);
|
||||
$AuthenticatorData->setTwofaEnabled($twofa_enabled);
|
||||
$AuthenticatorData->setExpireDays(Request::analyze('expiredays', 0));
|
||||
$AuthenticatorData->setDate(time());
|
||||
|
||||
try {
|
||||
$AuthenticatorData->setRecoveryCodes($this->generateRecoveryCodes());
|
||||
} catch (EnvironmentIsBrokenException $e) {
|
||||
debugLog($e->getMessage());
|
||||
}
|
||||
|
||||
$data[$this->itemId] = $AuthenticatorData;
|
||||
} elseif (!$twofa_enabled) {
|
||||
unset($data[$this->itemId]);
|
||||
}
|
||||
|
||||
$this->savePluginUserData($AuthenticatorData);
|
||||
|
||||
$PluginData = new PluginData();
|
||||
$PluginData->setPluginName($this->Plugin->getName());
|
||||
$PluginData->setPluginEnabled(1);
|
||||
$PluginData->setPluginData(serialize($data));
|
||||
|
||||
Plugin::getItem($PluginData)->update();
|
||||
|
||||
$this->JsonResponse->setStatus(0);
|
||||
$this->JsonResponse->setDescription(_t('authenticator', 'Preferencias actualizadas'));
|
||||
|
||||
Json::returnJson($this->JsonResponse);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generar códigos de recuperación
|
||||
*
|
||||
* @return array
|
||||
* @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException
|
||||
*/
|
||||
protected function generateRecoveryCodes()
|
||||
{
|
||||
$codes = [];
|
||||
$i = 1;
|
||||
|
||||
do {
|
||||
$codes[] = Util::generateRandomBytes(10);
|
||||
$i++;
|
||||
} while ($i <= 10);
|
||||
|
||||
return $codes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Guardar datos del Plugin
|
||||
*
|
||||
* @param AuthenticatorData $AuthenticatorData
|
||||
* @return bool
|
||||
*/
|
||||
protected function savePluginUserData(AuthenticatorData $AuthenticatorData)
|
||||
{
|
||||
$data = $this->Plugin->getData();
|
||||
$data[$AuthenticatorData->getUserId()] = $AuthenticatorData;
|
||||
|
||||
$PluginData = new PluginData();
|
||||
$PluginData->setPluginName($this->Plugin->getName());
|
||||
$PluginData->setPluginEnabled(1);
|
||||
$PluginData->setPluginData(serialize($data));
|
||||
|
||||
try {
|
||||
Plugin::getItem($PluginData)->update();
|
||||
} catch (SPException $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Comprobar el código 2FA
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
* @throws \SP\Core\Exceptions\SPException
|
||||
*/
|
||||
protected function checkCode()
|
||||
{
|
||||
$userId = Request::analyze('itemId', 0);
|
||||
$pin = Request::analyze('security_pin');
|
||||
$codeReset = Request::analyze('code_reset', false, false, true);
|
||||
|
||||
// Buscar al usuario en los datos del plugin
|
||||
/** @var AuthenticatorData $AuthenticatorData */
|
||||
$AuthenticatorData = ArrayUtil::searchInObject($this->Plugin->getData(), 'userId', $userId, new AuthenticatorData());
|
||||
|
||||
if (strlen($pin) === 20 && $this->useRecoveryCode($AuthenticatorData, $pin)) {
|
||||
Session::setTwoFApass(true);
|
||||
CoreSession::setAuthCompleted(true);
|
||||
|
||||
$this->JsonResponse->setDescription(_t('authenticator', 'Código correcto'));
|
||||
$this->JsonResponse->setStatus(0);
|
||||
|
||||
Json::returnJson($this->JsonResponse);
|
||||
}
|
||||
|
||||
if ($codeReset && $this->sendResetEmail($AuthenticatorData)) {
|
||||
Session::setTwoFApass(false);
|
||||
CoreSession::setAuthCompleted(false);
|
||||
|
||||
$this->JsonResponse->setDescription(_t('authenticator', 'Email de recuperación enviado'));
|
||||
$this->JsonResponse->setStatus(0);
|
||||
|
||||
Json::returnJson($this->JsonResponse);
|
||||
}
|
||||
|
||||
$TwoFa = new Authenticator($userId, CoreSession::getUserData()->getUserLogin(), $AuthenticatorData->getIV());
|
||||
|
||||
if ($userId
|
||||
&& $pin
|
||||
&& $TwoFa->verifyKey($pin)
|
||||
) {
|
||||
Session::setTwoFApass(true);
|
||||
CoreSession::setAuthCompleted(true);
|
||||
|
||||
$this->JsonResponse->setDescription(_t('authenticator', 'Código correcto'));
|
||||
$this->JsonResponse->setStatus(0);
|
||||
} else {
|
||||
Session::setTwoFApass(false);
|
||||
CoreSession::setAuthCompleted(false);
|
||||
|
||||
$this->JsonResponse->setDescription(_t('authenticator', 'Código incorrecto'));
|
||||
}
|
||||
|
||||
Json::returnJson($this->JsonResponse);
|
||||
}
|
||||
|
||||
/**
|
||||
* Envial email con código de recuperación
|
||||
*
|
||||
* @param AuthenticatorData $AuthenticatorData
|
||||
* @return bool
|
||||
*/
|
||||
protected function sendResetEmail(AuthenticatorData $AuthenticatorData)
|
||||
{
|
||||
$email = CoreSession::getUserData()->getUserEmail();
|
||||
|
||||
if (!empty($email)) {
|
||||
|
||||
$code = $this->pickRecoveryCode($AuthenticatorData);
|
||||
|
||||
if ($code !== false) {
|
||||
$LogMessage = new LogMessage();
|
||||
$LogMessage->setAction(_t('authenticator', 'Recuperación de Código 2FA'));
|
||||
$LogMessage->addDescriptionHtml(_t('authenticator', 'Se ha solicitado un código de recuperación para 2FA.'));
|
||||
$LogMessage->addDescriptionLine();
|
||||
$LogMessage->addDescription(sprintf(_t('authenticator', 'El código de recuperación es: %s'), $code));
|
||||
|
||||
return Email::sendEmail($LogMessage, $email);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Devolver un código de recuperación
|
||||
*
|
||||
* @param AuthenticatorData $AuthenticatorData
|
||||
* @return mixed
|
||||
*/
|
||||
protected function pickRecoveryCode(AuthenticatorData $AuthenticatorData)
|
||||
{
|
||||
if ($AuthenticatorData->getLastRecoveryTime() === 0) {
|
||||
try {
|
||||
$codes = $this->generateRecoveryCodes();
|
||||
} catch (EnvironmentIsBrokenException $e) {
|
||||
debugLog($e->getMessage());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$AuthenticatorData->setRecoveryCodes($codes);
|
||||
$AuthenticatorData->setLastRecoveryTime(time());
|
||||
|
||||
if ($this->savePluginUserData($AuthenticatorData) === false) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$codes = $AuthenticatorData->getRecoveryCodes();
|
||||
}
|
||||
|
||||
$numCodes = count($codes);
|
||||
|
||||
if ($numCodes > 0) {
|
||||
return $codes[$numCodes - 1];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Usar un código de recuperación y deshabilitar 2FA
|
||||
*
|
||||
* @param AuthenticatorData $AuthenticatorData
|
||||
* @param $code
|
||||
* @return bool|string
|
||||
*/
|
||||
protected function useRecoveryCode(AuthenticatorData $AuthenticatorData, $code)
|
||||
{
|
||||
$codes = $AuthenticatorData->getRecoveryCodes();
|
||||
|
||||
if ($key = array_search($code, $codes) !== false) {
|
||||
|
||||
unset($codes[$key]);
|
||||
|
||||
$AuthenticatorData->setTwofaEnabled(false);
|
||||
$AuthenticatorData->setRecoveryCodes($codes);
|
||||
$AuthenticatorData->setLastRecoveryTime(time());
|
||||
|
||||
return $this->savePluginUserData($AuthenticatorData);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,169 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* sysPass
|
||||
*
|
||||
* @author nuxsmin
|
||||
* @link http://syspass.org
|
||||
* @copyright 2012-2017, 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 Plugins\Authenticator;
|
||||
|
||||
use Exts\Base2n;
|
||||
use SP\Core\Exceptions\SPException;
|
||||
use SP\Mgmt\Users\UserPass;
|
||||
use SP\Util\Util;
|
||||
|
||||
defined('APP_ROOT') || die();
|
||||
|
||||
/**
|
||||
* Class Auth2FA
|
||||
*
|
||||
* @package SP\Auth
|
||||
*/
|
||||
class Authenticator
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $timestamp = 0;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $initializationKey = '';
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $totp = '';
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $userId = 0;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $userLogin = '';
|
||||
|
||||
/**
|
||||
* @param int $userId El Id de usuario
|
||||
* @param string $userLogin El login de usuario
|
||||
* @param string $IV
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct($userId, $userLogin = null, $IV = null)
|
||||
{
|
||||
$this->userId = $userId;
|
||||
$this->userLogin = $userLogin;
|
||||
$this->initializationKey = $this->genUserInitializationKey($IV);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generar una clave de inicialización codificada en Base32
|
||||
*
|
||||
* @param string $IV
|
||||
* @return string
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
private function genUserInitializationKey($IV = null)
|
||||
{
|
||||
$userIV = $IV === null ? UserPass::getUserIVById($this->userId) : $IV;
|
||||
$base32 = new Base2n(5, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', false, true, true);
|
||||
|
||||
return substr($base32->encode($userIV), 0, 16);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $userId
|
||||
*/
|
||||
public function setUserId($userId)
|
||||
{
|
||||
$this->userId = $userId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $userLogin
|
||||
*/
|
||||
public function setUserLogin($userLogin)
|
||||
{
|
||||
$this->userLogin = $userLogin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verificar el código de 2FA
|
||||
*
|
||||
* @param $key
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function verifyKey($key)
|
||||
{
|
||||
return Google2FA::verify_key($this->initializationKey, $key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Devolver el código QR de la peticíón HTTP en base64
|
||||
*
|
||||
* @return bool|string
|
||||
*/
|
||||
public function getUserQRCode()
|
||||
{
|
||||
try {
|
||||
$data = Util::getDataFromUrl($this->getUserQRUrl());
|
||||
return base64_encode($data);
|
||||
} catch (SPException $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Devolver la cadena con la URL para solicitar el código QR
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getUserQRUrl()
|
||||
{
|
||||
$qrUrl = 'https://www.google.com/chart?chs=150x150&chld=M|0&cht=qr&chl=';
|
||||
$qrUrl .= urlencode('otpauth://totp/sysPass:syspass/' . $this->userLogin . '?secret=' . $this->initializationKey . '&issuer=sysPass');
|
||||
|
||||
return $qrUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Comprobar el token del usuario
|
||||
*
|
||||
* @param int $userToken EL código del usuario
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function checkUserToken($userToken)
|
||||
{
|
||||
$timeStamp = Google2FA::get_timestamp();
|
||||
$secretkey = Google2FA::base32_decode($this->initializationKey);
|
||||
$totp = Google2FA::oath_totp($secretkey, $timeStamp);
|
||||
|
||||
return ($totp === $userToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getInitializationKey()
|
||||
{
|
||||
return $this->initializationKey;
|
||||
}
|
||||
}
|
||||
@@ -1,184 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* sysPass
|
||||
*
|
||||
* @author nuxsmin
|
||||
* @link http://syspass.org
|
||||
* @copyright 2012-2017, 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 Plugins\Authenticator;
|
||||
|
||||
/**
|
||||
* Class AuthenticatorData
|
||||
*
|
||||
* @package Plugins\Authenticator
|
||||
*/
|
||||
class AuthenticatorData
|
||||
{
|
||||
/**
|
||||
* Id de usuario
|
||||
*
|
||||
* @var
|
||||
*/
|
||||
public $userId;
|
||||
/**
|
||||
* Si está habilitado 2FA
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $twofaEnabled = 0;
|
||||
/**
|
||||
* Fecha de activación
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $date;
|
||||
/**
|
||||
* Días de caducidad
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $expireDays;
|
||||
/**
|
||||
* Vector de inicialización
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $IV;
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $recoveryCodes = [];
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $lastRecoveryTime = 0;
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getUserId()
|
||||
{
|
||||
return (int)$this->userId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $userId
|
||||
*/
|
||||
public function setUserId($userId)
|
||||
{
|
||||
$this->userId = (int)$userId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isTwofaEnabled()
|
||||
{
|
||||
return (bool)$this->twofaEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $twofaEnabled
|
||||
*/
|
||||
public function setTwofaEnabled($twofaEnabled)
|
||||
{
|
||||
$this->twofaEnabled = (int)$twofaEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getDate()
|
||||
{
|
||||
return $this->date;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $date
|
||||
*/
|
||||
public function setDate($date)
|
||||
{
|
||||
$this->date = $date;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getExpireDays()
|
||||
{
|
||||
return $this->expireDays;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $expireDays
|
||||
*/
|
||||
public function setExpireDays($expireDays)
|
||||
{
|
||||
$this->expireDays = $expireDays;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getIV()
|
||||
{
|
||||
return $this->IV;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $IV
|
||||
*/
|
||||
public function setIV($IV)
|
||||
{
|
||||
$this->IV = $IV;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getRecoveryCodes()
|
||||
{
|
||||
return $this->recoveryCodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $recoveryCodes
|
||||
*/
|
||||
public function setRecoveryCodes(array $recoveryCodes)
|
||||
{
|
||||
$this->recoveryCodes = $recoveryCodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getLastRecoveryTime()
|
||||
{
|
||||
return $this->lastRecoveryTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $lastRecoveryTime
|
||||
*/
|
||||
public function setLastRecoveryTime($lastRecoveryTime)
|
||||
{
|
||||
$this->lastRecoveryTime = $lastRecoveryTime;
|
||||
}
|
||||
}
|
||||
@@ -1,172 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* sysPass
|
||||
*
|
||||
* @author nuxsmin
|
||||
* @link http://syspass.org
|
||||
* @copyright 2012-2017, 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 Plugins\Authenticator;
|
||||
|
||||
use SP\Core\DiFactory;
|
||||
use SP\Core\Plugin\PluginBase;
|
||||
use SplSubject;
|
||||
|
||||
/**
|
||||
* Class Plugin
|
||||
*
|
||||
* @package Plugins\Authenticator
|
||||
*/
|
||||
class AuthenticatorPlugin extends PluginBase
|
||||
{
|
||||
const PLUGIN_NAME = 'Authenticator';
|
||||
|
||||
/**
|
||||
* Receive update from subject
|
||||
*
|
||||
* @link http://php.net/manual/en/splobserver.update.php
|
||||
* @param SplSubject $subject <p>
|
||||
* The <b>SplSubject</b> notifying the observer of an update.
|
||||
* </p>
|
||||
* @return void
|
||||
* @since 5.1.0
|
||||
*/
|
||||
public function update(SplSubject $subject)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Inicialización del plugin
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
if (!is_array($this->data)) {
|
||||
$this->data = [];
|
||||
}
|
||||
|
||||
$this->base = __DIR__;
|
||||
$this->themeDir = __DIR__ . DIRECTORY_SEPARATOR . 'themes' . DIRECTORY_SEPARATOR . DiFactory::getTheme()->getThemeName();
|
||||
|
||||
$this->setLocales();
|
||||
}
|
||||
|
||||
/**
|
||||
* Evento de actualización
|
||||
*
|
||||
* @param string $event Nombre del evento
|
||||
* @param mixed $object
|
||||
* @throws \SP\Core\Exceptions\FileNotFoundException
|
||||
* @throws \SP\Core\Exceptions\SPException
|
||||
*/
|
||||
public function updateEvent($event, $object)
|
||||
{
|
||||
switch ($event){
|
||||
case 'user.preferences':
|
||||
$Controller = new PreferencesController($object, $this);
|
||||
$Controller->getSecurityTab();
|
||||
break;
|
||||
case 'main.prelogin.2fa':
|
||||
$Controller = new LoginController($this);
|
||||
$Controller->get2FA($object);
|
||||
break;
|
||||
case 'login.preferences':
|
||||
$Controller = new LoginController($this);
|
||||
$Controller->checkLogin();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Devuelve los eventos que implementa el observador
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getEvents()
|
||||
{
|
||||
return ['user.preferences', 'main.prelogin.2fa', 'login.preferences'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Devuelve los recursos JS y CSS necesarios para el plugin
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getJsResources()
|
||||
{
|
||||
return ['plugin.min.js'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Devuelve el autor del plugin
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAuthor()
|
||||
{
|
||||
return 'Rubén D.';
|
||||
}
|
||||
|
||||
/**
|
||||
* Devuelve la versión del plugin
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getVersion()
|
||||
{
|
||||
return [1, 1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Devuelve la versión compatible de sysPass
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleVersion()
|
||||
{
|
||||
return [2, 0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Devuelve los recursos CSS necesarios para el plugin
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getCssResources()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Devuelve el nombre del plugin
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return self::PLUGIN_NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|AuthenticatorData[]
|
||||
*/
|
||||
public function getData()
|
||||
{
|
||||
return (array)parent::getData();
|
||||
}
|
||||
}
|
||||
@@ -1,215 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* sysPass
|
||||
*
|
||||
* @author nuxsmin
|
||||
* @link http://syspass.org
|
||||
* @copyright 2012-2017, 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/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* PHP Google two-factor authentication module.
|
||||
*
|
||||
* See http://www.idontplaydarts.com/2011/07/google-totp-two-factor-authentication-for-php/
|
||||
* for more details
|
||||
*
|
||||
* @author Phil
|
||||
**/
|
||||
|
||||
namespace Plugins\Authenticator;
|
||||
|
||||
/**
|
||||
* Class Google2FA
|
||||
*
|
||||
* @package SP\Auth
|
||||
*/
|
||||
class Google2FA
|
||||
{
|
||||
/**
|
||||
* Interval between key regeneration
|
||||
*/
|
||||
const keyRegeneration = 30;
|
||||
/**
|
||||
* Length of the Token generated
|
||||
*/
|
||||
const otpLength = 6;
|
||||
|
||||
/**
|
||||
* Lookup needed for Base32 encoding
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $lut = [ // Lookup needed for Base32 encoding
|
||||
'A' => 0, 'B' => 1,
|
||||
'C' => 2, 'D' => 3,
|
||||
'E' => 4, 'F' => 5,
|
||||
'G' => 6, 'H' => 7,
|
||||
'I' => 8, 'J' => 9,
|
||||
'K' => 10, 'L' => 11,
|
||||
'M' => 12, 'N' => 13,
|
||||
'O' => 14, 'P' => 15,
|
||||
'Q' => 16, 'R' => 17,
|
||||
'S' => 18, 'T' => 19,
|
||||
'U' => 20, 'V' => 21,
|
||||
'W' => 22, 'X' => 23,
|
||||
'Y' => 24, 'Z' => 25,
|
||||
'2' => 26, '3' => 27,
|
||||
'4' => 28, '5' => 29,
|
||||
'6' => 30, '7' => 31
|
||||
];
|
||||
|
||||
/**
|
||||
* Generates a 16 digit secret key in base32 format
|
||||
*
|
||||
* @param int $length
|
||||
* @return string
|
||||
*/
|
||||
public static function generate_secret_key($length = 16)
|
||||
{
|
||||
$b32 = '234567QWERTYUIOPASDFGHJKLZXCVBNM';
|
||||
$s = '';
|
||||
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$s .= $b32[mt_rand(0, 31)];
|
||||
}
|
||||
|
||||
return $s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifys a user inputted key against the current timestamp. Checks $window
|
||||
* keys either side of the timestamp.
|
||||
*
|
||||
* @param string $b32seed
|
||||
* @param string $key - User specified key
|
||||
* @param integer $window
|
||||
* @param boolean $useTimeStamp
|
||||
* @return boolean
|
||||
* @throws \Exception
|
||||
**/
|
||||
public static function verify_key($b32seed, $key, $window = 4, $useTimeStamp = true)
|
||||
{
|
||||
|
||||
$timeStamp = ($useTimeStamp !== true) ? (int)$useTimeStamp : self::get_timestamp();
|
||||
|
||||
$binarySeed = self::base32_decode($b32seed);
|
||||
|
||||
for ($ts = $timeStamp - $window; $ts <= $timeStamp + $window; $ts++) {
|
||||
if (self::oath_totp($binarySeed, $ts) == $key) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current Unix Timestamp devided by the keyRegeneration
|
||||
* period.
|
||||
*
|
||||
* @return integer
|
||||
**/
|
||||
public static function get_timestamp()
|
||||
{
|
||||
return floor(microtime(true) / self::keyRegeneration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes a base32 string into a binary string.
|
||||
**/
|
||||
public static function base32_decode($b32)
|
||||
{
|
||||
|
||||
$b32 = strtoupper($b32);
|
||||
|
||||
if (!preg_match('/^[ABCDEFGHIJKLMNOPQRSTUVWXYZ234567]+$/', $b32, $match)) {
|
||||
throw new \Exception('Invalid characters in the base32 string.');
|
||||
}
|
||||
|
||||
$l = strlen($b32);
|
||||
$n = 0;
|
||||
$j = 0;
|
||||
$binary = '';
|
||||
|
||||
for ($i = 0; $i < $l; $i++) {
|
||||
$n <<= 5; // Move buffer left by 5 to make room
|
||||
$n += self::$lut[$b32[$i]]; // Add value into buffer
|
||||
$j += 5; // Keep track of number of bits in buffer
|
||||
|
||||
if ($j >= 8) {
|
||||
$j -= 8;
|
||||
$binary .= chr(($n & (0xFF << $j)) >> $j);
|
||||
}
|
||||
}
|
||||
|
||||
return $binary;
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes the secret key and the timestamp and returns the one time
|
||||
* password.
|
||||
*
|
||||
* @param string $key - Secret key in binary form.
|
||||
* @param int $counter - Timestamp as returned by get_timestamp.
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function oath_totp($key, $counter)
|
||||
{
|
||||
if (strlen($key) < 8) {
|
||||
throw new \Exception('Secret key is too short. Must be at least 16 base 32 characters');
|
||||
}
|
||||
|
||||
$bin_counter = pack('N*', 0) . pack('N*', $counter); // Counter must be 64-bit int
|
||||
$hash = hash_hmac('sha1', $bin_counter, $key, true);
|
||||
|
||||
return str_pad(self::oath_truncate($hash), self::otpLength, '0', STR_PAD_LEFT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the OTP from the SHA1 hash.
|
||||
*
|
||||
* @param string $hash
|
||||
* @return integer
|
||||
**/
|
||||
public static function oath_truncate($hash)
|
||||
{
|
||||
$offset = ord($hash[19]) & 0xf;
|
||||
|
||||
return (
|
||||
((ord($hash[$offset + 0]) & 0x7f) << 24) |
|
||||
((ord($hash[$offset + 1]) & 0xff) << 16) |
|
||||
((ord($hash[$offset + 2]) & 0xff) << 8) |
|
||||
(ord($hash[$offset + 3]) & 0xff)
|
||||
) % pow(10, self::otpLength);
|
||||
}
|
||||
}
|
||||
@@ -1,169 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* sysPass
|
||||
*
|
||||
* @author nuxsmin
|
||||
* @link http://syspass.org
|
||||
* @copyright 2012-2017, 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 Plugins\Authenticator;
|
||||
|
||||
use SP\Controller\ControllerBase;
|
||||
use SP\Core\Init;
|
||||
use SP\Core\Messages\NoticeMessage;
|
||||
use SP\Core\Plugin\PluginBase;
|
||||
use SP\Core\Session as CoreSession;
|
||||
use SP\Http\JsonResponse;
|
||||
use SP\Http\Request;
|
||||
use SP\Mgmt\Notices\Notice;
|
||||
use SP\Util\Json;
|
||||
|
||||
/**
|
||||
* Class LoginController
|
||||
*
|
||||
* @package Plugins\Authenticator
|
||||
*/
|
||||
class LoginController
|
||||
{
|
||||
const WARNING_TIME = 432000;
|
||||
|
||||
/**
|
||||
* @var PluginBase
|
||||
*/
|
||||
protected $Plugin;
|
||||
|
||||
/**
|
||||
* Controller constructor.
|
||||
*
|
||||
* @param PluginBase $Plugin
|
||||
*/
|
||||
public function __construct(PluginBase $Plugin)
|
||||
{
|
||||
$this->Plugin = $Plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtener los datos para el interface de autentificación en 2 pasos
|
||||
*
|
||||
* @param ControllerBase $Controller
|
||||
* @throws \SP\Core\Exceptions\FileNotFoundException
|
||||
* @throws \SP\Core\Exceptions\SPException
|
||||
* @throws \SP\Core\Exceptions\InvalidClassException
|
||||
*/
|
||||
public function get2FA(ControllerBase $Controller)
|
||||
{
|
||||
$Controller->view->addTemplate('body-header');
|
||||
|
||||
if (Request::analyze('f', 0) === 1) {
|
||||
$base = $this->Plugin->getThemeDir() . DIRECTORY_SEPARATOR . 'views' . DIRECTORY_SEPARATOR . 'main';
|
||||
|
||||
$Controller->view->addTemplate('login-2fa', $base);
|
||||
|
||||
$Controller->view->assign('action', Request::analyze('a'));
|
||||
$Controller->view->assign('userId', Request::analyze('i', 0));
|
||||
$Controller->view->assign('time', Request::analyze('t', 0));
|
||||
|
||||
$Controller->view->assign('actionId', ActionController::ACTION_TWOFA_CHECKCODE);
|
||||
|
||||
$this->checkExpireTime();
|
||||
} else {
|
||||
$Controller->showError(ControllerBase::ERR_UNAVAILABLE, false);
|
||||
}
|
||||
|
||||
$Controller->view->addTemplate('body-footer');
|
||||
$Controller->view->addTemplate('body-end');
|
||||
|
||||
$Controller->view();
|
||||
exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Comprobar la caducidad del código
|
||||
*
|
||||
* @throws \SP\Core\Exceptions\SPException
|
||||
* @throws \SP\Core\Exceptions\InvalidClassException
|
||||
*/
|
||||
protected function checkExpireTime()
|
||||
{
|
||||
/** @var AuthenticatorData[] $data */
|
||||
$data = $this->Plugin->getData();
|
||||
|
||||
$userId = Request::analyze('i', 0);
|
||||
|
||||
if (!isset($data[$userId]) || empty($data[$userId]->getExpireDays())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (count(Notice::getItem()->getByUserCurrentDate()) > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$expireTime = $data[$userId]->getDate() + ($data[$userId]->getExpireDays() * 86400);
|
||||
$timeRemaining = $expireTime - time();
|
||||
|
||||
$NoticeData = Notice::getItem()->getItemData();
|
||||
$NoticeData->setNoticeComponent($this->Plugin->getName());
|
||||
$NoticeData->setNoticeUserId($userId);
|
||||
$NoticeData->setNoticeType(_t('authenticator', 'Aviso Caducidad'));
|
||||
|
||||
$Message = new NoticeMessage();
|
||||
|
||||
if ($timeRemaining <= self::WARNING_TIME) {
|
||||
$Message->addDescription(sprintf(_t('authenticator', 'El código 2FA se ha de restablecer en %d días'), $timeRemaining / 86400));
|
||||
|
||||
$NoticeData->setNoticeDescription($Message);
|
||||
|
||||
Notice::getItem($NoticeData)->add();
|
||||
} elseif (time() > $expireTime) {
|
||||
$Message->addDescription(_t('authenticator', 'El código 2FA ha caducado. Es necesario restablecerlo desde las preferencias'));
|
||||
|
||||
$NoticeData->setNoticeDescription($Message);
|
||||
|
||||
Notice::getItem($NoticeData)->add();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Comprobar 2FA en el login
|
||||
*
|
||||
* @throws \SP\Core\Exceptions\SPException
|
||||
*/
|
||||
public function checkLogin()
|
||||
{
|
||||
/** @var AuthenticatorData[] $data */
|
||||
$data = $this->Plugin->getData();
|
||||
|
||||
$userId = CoreSession::getUserData()->getUserId();
|
||||
|
||||
if (isset($data[$userId]) && $data[$userId]->isTwofaEnabled()) {
|
||||
Session::setTwoFApass(false);
|
||||
CoreSession::setAuthCompleted(false);
|
||||
|
||||
$data = ['url' => Init::$WEBURI . '/index.php?a=2fa&i=' . $userId . '&t=' . time() . '&f=1'];
|
||||
|
||||
$JsonResponse = new JsonResponse();
|
||||
$JsonResponse->setData($data);
|
||||
$JsonResponse->setStatus(0);
|
||||
|
||||
Json::returnJson($JsonResponse);
|
||||
} else {
|
||||
Session::setTwoFApass(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* sysPass
|
||||
*
|
||||
* @author nuxsmin
|
||||
* @link http://syspass.org
|
||||
* @copyright 2012-2017, 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 Plugins\Authenticator;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use SP\Controller\TabControllerBase;
|
||||
use SP\Core\OldCrypt;
|
||||
use SP\Core\Plugin\PluginBase;
|
||||
use SP\Core\Plugin\PluginInterface;
|
||||
use SP\Util\ArrayUtil;
|
||||
use SP\Util\Util;
|
||||
|
||||
/**
|
||||
* Class Controller
|
||||
*
|
||||
* @package Plugins\Authenticator
|
||||
*/
|
||||
class PreferencesController
|
||||
{
|
||||
/**
|
||||
* @var TabControllerBase
|
||||
*/
|
||||
protected $Controller;
|
||||
/**
|
||||
* @var PluginBase
|
||||
*/
|
||||
protected $Plugin;
|
||||
|
||||
/**
|
||||
* Controller constructor.
|
||||
*
|
||||
* @param TabControllerBase $Controller
|
||||
* @param PluginInterface $Plugin
|
||||
*/
|
||||
public function __construct(TabControllerBase $Controller, PluginInterface $Plugin)
|
||||
{
|
||||
$this->Controller = $Controller;
|
||||
$this->Plugin = $Plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtener la pestaña de seguridad
|
||||
*/
|
||||
public function getSecurityTab()
|
||||
{
|
||||
$base = $this->Plugin->getThemeDir() . DIRECTORY_SEPARATOR . 'views' . DIRECTORY_SEPARATOR . 'userpreferences';
|
||||
|
||||
// Datos del usuario de la sesión
|
||||
$UserData = $this->Controller->getUserData();
|
||||
|
||||
// Buscar al usuario en los datos del plugin
|
||||
/** @var AuthenticatorData $AuthenticatorData */
|
||||
$AuthenticatorData = ArrayUtil::searchInObject($this->Plugin->getData(), 'userId', $UserData->getUserId(), new AuthenticatorData());
|
||||
|
||||
$this->Controller->view->addTemplate('preferences-security', $base);
|
||||
|
||||
try {
|
||||
$IV = null;
|
||||
|
||||
if (!$AuthenticatorData->isTwofaEnabled()) {
|
||||
$IV = Util::generateRandomBytes();
|
||||
$AuthenticatorData->setIV($IV);
|
||||
} else {
|
||||
$IV = $AuthenticatorData->getIV();
|
||||
}
|
||||
|
||||
Session::setUserData($AuthenticatorData);
|
||||
|
||||
$twoFa = new Authenticator($UserData->getUserId(), $UserData->getUserLogin(), $IV);
|
||||
|
||||
$this->Controller->view->assign('qrCode', !$AuthenticatorData->isTwofaEnabled() ? $twoFa->getUserQRCode() : '');
|
||||
$this->Controller->view->assign('userId', $UserData->getUserId());
|
||||
$this->Controller->view->assign('chk2FAEnabled', $AuthenticatorData->isTwofaEnabled());
|
||||
$this->Controller->view->assign('expireDays', $AuthenticatorData->getExpireDays());
|
||||
|
||||
$this->Controller->view->assign('tabIndex', $this->Controller->addTab(_t('authenticator', 'Seguridad')), 'security');
|
||||
$this->Controller->view->assign('actionId', ActionController::ACTION_TWOFA_SAVE, 'security');
|
||||
} catch (InvalidArgumentException $e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* sysPass
|
||||
*
|
||||
* @author nuxsmin
|
||||
* @link http://syspass.org
|
||||
* @copyright 2012-2017, 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/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: rdb
|
||||
* Date: 4/01/17
|
||||
* Time: 8:32
|
||||
*/
|
||||
|
||||
namespace Plugins\Authenticator;
|
||||
|
||||
use SP\Core\Session as CoreSession;
|
||||
|
||||
/**
|
||||
* Class Session
|
||||
*
|
||||
* @package Plugins\Authenticator
|
||||
*/
|
||||
class Session
|
||||
{
|
||||
/**
|
||||
* Establecer el estado de 2FA del usuario
|
||||
*
|
||||
* @param bool $pass
|
||||
*/
|
||||
public static function setTwoFApass($pass)
|
||||
{
|
||||
CoreSession::setPluginKey(AuthenticatorPlugin::PLUGIN_NAME, 'twofapass', $pass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Devolver el estado de 2FA del usuario
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function getTwoFApass()
|
||||
{
|
||||
return CoreSession::getPluginKey(AuthenticatorPlugin::PLUGIN_NAME, 'twofapass');
|
||||
}
|
||||
|
||||
/**
|
||||
* Establecer los datos del usuario
|
||||
*
|
||||
* @param AuthenticatorData $data
|
||||
*/
|
||||
public static function setUserData(AuthenticatorData $data)
|
||||
{
|
||||
CoreSession::setPluginKey(AuthenticatorPlugin::PLUGIN_NAME, 'userdata', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Devolver los datos del usuario
|
||||
*
|
||||
* @return AuthenticatorData
|
||||
*/
|
||||
public static function getUserData()
|
||||
{
|
||||
return CoreSession::getPluginKey(AuthenticatorPlugin::PLUGIN_NAME, 'userdata');
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* sysPass
|
||||
*
|
||||
* @author nuxsmin
|
||||
* @link http://syspass.org
|
||||
* @copyright 2012-2017, 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/>.
|
||||
*/
|
||||
|
||||
use Plugins\Authenticator\ActionController;
|
||||
use SP\Http\Request;
|
||||
|
||||
define('APP_ROOT', '../../../..');
|
||||
|
||||
require_once APP_ROOT . DIRECTORY_SEPARATOR . 'inc' . DIRECTORY_SEPARATOR . 'Base.php';
|
||||
|
||||
Request::checkReferer('POST');
|
||||
|
||||
$Controller = new ActionController();
|
||||
$Controller->doAction();
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* sysPass
|
||||
*
|
||||
* @author nuxsmin
|
||||
* @link http://syspass.org
|
||||
* @copyright 2012-2017, 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/>.
|
||||
*/
|
||||
|
||||
sysPass.Plugin.Authenticator = function (Common) {
|
||||
"use strict";
|
||||
|
||||
var log = Common.log;
|
||||
var base = "/inc/Plugins/Authenticator";
|
||||
|
||||
var twofa = {
|
||||
check: function ($obj) {
|
||||
log.info("Authenticator:twofa:check");
|
||||
|
||||
var opts = Common.appRequests().getRequestOpts();
|
||||
opts.url = base + "/ajax/ajax_actions.php";
|
||||
opts.data = $obj.serialize();
|
||||
|
||||
Common.appRequests().getActionCall(opts, function (json) {
|
||||
Common.msg.out(json);
|
||||
|
||||
if (json.status == 0) {
|
||||
setTimeout(function () {
|
||||
Common.redirect("index.php");
|
||||
}, 1000);
|
||||
}
|
||||
});
|
||||
},
|
||||
save: function ($obj) {
|
||||
log.info("Authenticator:twofa:save");
|
||||
|
||||
var opts = Common.appRequests().getRequestOpts();
|
||||
opts.url = base + "/ajax/ajax_actions.php";
|
||||
opts.data = $obj.serialize();
|
||||
|
||||
Common.appRequests().getActionCall(opts, function (json) {
|
||||
Common.msg.out(json);
|
||||
|
||||
if (json.status === 0) {
|
||||
Common.appActions().doAction({
|
||||
actionId: $obj.data("nextaction-id"),
|
||||
itemId: $obj.data("activetab")
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
var init = function () {
|
||||
|
||||
};
|
||||
|
||||
init();
|
||||
|
||||
return {
|
||||
twofa: twofa
|
||||
};
|
||||
};
|
||||
2
inc/Plugins/Authenticator/js/plugin.min.js
vendored
2
inc/Plugins/Authenticator/js/plugin.min.js
vendored
@@ -1,2 +0,0 @@
|
||||
sysPass.Plugin.Authenticator=function(b){var d=b.log;return{twofa:{check:function(c){d.info("Authenticator:twofa:check");var a=b.appRequests().getRequestOpts();a.url="/inc/Plugins/Authenticator/ajax/ajax_actions.php";a.data=c.serialize();b.appRequests().getActionCall(a,function(a){b.msg.out(a);0==a.status&&setTimeout(function(){b.redirect("index.php")},1E3)})},save:function(c){d.info("Authenticator:twofa:save");var a=b.appRequests().getRequestOpts();a.url="/inc/Plugins/Authenticator/ajax/ajax_actions.php";
|
||||
a.data=c.serialize();b.appRequests().getActionCall(a,function(a){b.msg.out(a);0===a.status&&b.appActions().doAction({actionId:c.data("nextaction-id"),itemId:c.data("activetab")})})}}}};
|
||||
Binary file not shown.
@@ -1,128 +0,0 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: sysPass\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2017-02-03 22:10+0100\n"
|
||||
"PO-Revision-Date: 2017-02-03 22:10+0100\n"
|
||||
"Last-Translator: nuxsmin <nuxsmin@syspass.org>\n"
|
||||
"Language-Team: <language@syspass.org>\n"
|
||||
"Language: ca_ES\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 1.6.10\n"
|
||||
"X-Poedit-SourceCharset: UTF-8\n"
|
||||
"X-Poedit-Basepath: .\n"
|
||||
"X-Poedit-KeywordsList: _t:2\n"
|
||||
"X-Poedit-SearchPath-0: ../../..\n"
|
||||
|
||||
#: ../../../ActionController.class.php:112
|
||||
#: ../../../ActionController.class.php:178
|
||||
msgid "Código incorrecto"
|
||||
msgstr "Codi incorrecte"
|
||||
|
||||
#: ../../../ActionController.class.php:117
|
||||
msgid "Ey, esto es una DEMO!!"
|
||||
msgstr "Ey, això és una DEMO!!"
|
||||
|
||||
#: ../../../ActionController.class.php:143
|
||||
msgid "Preferencias actualizadas"
|
||||
msgstr "Preferències actualitzades"
|
||||
|
||||
#: ../../../ActionController.class.php:172
|
||||
msgid "Código correcto"
|
||||
msgstr "Codi correcte"
|
||||
|
||||
#: ../../../LoginController.class.php:126
|
||||
#, fuzzy
|
||||
msgid "Aviso Caducidad"
|
||||
msgstr "Data Edició"
|
||||
|
||||
#: ../../../LoginController.class.php:131
|
||||
#, php-format
|
||||
msgid "El código 2FA se ha de restablecer en %d días"
|
||||
msgstr "El codi 2FA s'ha de restablir en %d dies."
|
||||
|
||||
#: ../../../LoginController.class.php:137
|
||||
msgid ""
|
||||
"El código 2FA ha caducado. Es necesario restablecerlo desde las preferencias"
|
||||
msgstr ""
|
||||
"El codi 2FA ha caducat. Es necessari restablir-ho des de les preferències."
|
||||
|
||||
#: ../../../PreferencesController.class.php:97
|
||||
msgid "Seguridad"
|
||||
msgstr "Seguretat"
|
||||
|
||||
#: ../../../themes/material-blue/views/main/login-2fa.inc:7
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:40
|
||||
msgid "Autentificación en 2 pasos"
|
||||
msgstr "Autenticació en 2 passos"
|
||||
|
||||
#: ../../../themes/material-blue/views/main/login-2fa.inc:13
|
||||
msgid "Introducir código"
|
||||
msgstr "Introduir codi"
|
||||
|
||||
#: ../../../themes/material-blue/views/main/login-2fa.inc:27
|
||||
msgid "Volver a iniciar sesión"
|
||||
msgstr "Tornar a iniciar sessió"
|
||||
|
||||
#: ../../../themes/material-blue/views/main/login-2fa.inc:28
|
||||
msgid "Volver"
|
||||
msgstr "Tornar"
|
||||
|
||||
#: ../../../themes/material-blue/views/main/login-2fa.inc:32
|
||||
msgid "Acceder"
|
||||
msgstr "Accedir"
|
||||
|
||||
#: ../../../themes/material-blue/views/main/login-2fa.inc:34
|
||||
msgid "Solicitar"
|
||||
msgstr "Sol·licitar"
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:29
|
||||
msgid "Autentificación"
|
||||
msgstr "Autenticació"
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:45
|
||||
msgid ""
|
||||
"Habilita la autentificación en 2 pasos que requiere de la introducción de un "
|
||||
"token generado por una aplicación como Google Authenticator."
|
||||
msgstr ""
|
||||
"Habilita l'autenticació en 2 passos que requereix de la introducció d'un "
|
||||
"token generat per una aplicació com Google Authenticator."
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:49
|
||||
msgid ""
|
||||
"Escanee el código QR proporcionado y a continuación introduzca la clave de 6 "
|
||||
"dígitos."
|
||||
msgstr ""
|
||||
"Escanegi el codi QR proporcionat i a continuació introdueixi la clau de 6 "
|
||||
"dígits."
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:58
|
||||
msgid "Activar"
|
||||
msgstr "Activar"
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:64
|
||||
msgid "Error al obtener el código QR. Inténtelo de nuevo"
|
||||
msgstr "Error en obtenir el codi QR. Intenti-ho de nou"
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:74
|
||||
msgid "Código"
|
||||
msgstr "Codi"
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:80
|
||||
msgid ""
|
||||
"Una vez activada, sólo es posible acceder si se dispone del dispositivo "
|
||||
"generador de códigos asociado."
|
||||
msgstr ""
|
||||
"Una vegada activada, només és possible accedir si es disposa del dispositiu "
|
||||
"generador de codis associat."
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:84
|
||||
#, fuzzy
|
||||
msgid "Días Caducidad"
|
||||
msgstr "Data Edició"
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:91
|
||||
msgid "Días"
|
||||
msgstr "Dies"
|
||||
Binary file not shown.
@@ -1,147 +0,0 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: sysPass\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2017-08-16 02:42+0100\n"
|
||||
"PO-Revision-Date: 2017-08-16 02:42+0100\n"
|
||||
"Last-Translator: nuxsmin <nuxsmin@syspass.org>\n"
|
||||
"Language-Team: <language@syspass.org>\n"
|
||||
"Language: de_DE\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 1.6.10\n"
|
||||
"X-Poedit-SourceCharset: UTF-8\n"
|
||||
"X-Poedit-Basepath: .\n"
|
||||
"X-Poedit-KeywordsList: _t:2\n"
|
||||
"X-Poedit-SearchPath-0: ../../..\n"
|
||||
|
||||
#: ../../../ActionController.class.php:116
|
||||
#: ../../../ActionController.class.php:255
|
||||
msgid "Código incorrecto"
|
||||
msgstr "Falscher Code"
|
||||
|
||||
#: ../../../ActionController.class.php:121
|
||||
msgid "Ey, esto es una DEMO!!"
|
||||
msgstr "Hey, dies ist eine DEMO!!"
|
||||
|
||||
#: ../../../ActionController.class.php:155
|
||||
msgid "Preferencias actualizadas"
|
||||
msgstr "Einstellungen aktualisiert"
|
||||
|
||||
#: ../../../ActionController.class.php:224
|
||||
#: ../../../ActionController.class.php:249
|
||||
msgid "Código correcto"
|
||||
msgstr "Code bestätigt"
|
||||
|
||||
#: ../../../ActionController.class.php:234
|
||||
msgid "Email de recuperación enviado"
|
||||
msgstr ""
|
||||
|
||||
#: ../../../ActionController.class.php:277
|
||||
msgid "Recuperación de Código 2FA"
|
||||
msgstr ""
|
||||
|
||||
#: ../../../ActionController.class.php:278
|
||||
msgid "Se ha solicitado un código de recuperación para 2FA."
|
||||
msgstr ""
|
||||
|
||||
#: ../../../ActionController.class.php:280
|
||||
#, php-format
|
||||
msgid "El código de recuperación es: %s"
|
||||
msgstr ""
|
||||
|
||||
#: ../../../LoginController.class.php:123
|
||||
#, fuzzy
|
||||
msgid "Aviso Caducidad"
|
||||
msgstr "Änderungsdatum"
|
||||
|
||||
#: ../../../LoginController.class.php:128
|
||||
#, php-format
|
||||
msgid "El código 2FA se ha de restablecer en %d días"
|
||||
msgstr "Der 2FA-Code muss innerhalb von %d Tagen zurückgesetzt werden"
|
||||
|
||||
#: ../../../LoginController.class.php:134
|
||||
msgid ""
|
||||
"El código 2FA ha caducado. Es necesario restablecerlo desde las preferencias"
|
||||
msgstr ""
|
||||
"Der 2FA Code ist abgelaufen. Du musst es auf der Registerkarte Einstellungen "
|
||||
"zurücksetzen"
|
||||
|
||||
#: ../../../PreferencesController.class.php:98
|
||||
msgid "Seguridad"
|
||||
msgstr "Sicherheit"
|
||||
|
||||
#: ../../../themes/material-blue/views/main/login-2fa.inc:7
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:40
|
||||
msgid "Autentificación en 2 pasos"
|
||||
msgstr "Zwei-Faktor Authentifizierung"
|
||||
|
||||
#: ../../../themes/material-blue/views/main/login-2fa.inc:13
|
||||
msgid "Introducir código"
|
||||
msgstr "Code eingeben"
|
||||
|
||||
#: ../../../themes/material-blue/views/main/login-2fa.inc:17
|
||||
msgid "Olvidé mi código"
|
||||
msgstr ""
|
||||
|
||||
#: ../../../themes/material-blue/views/main/login-2fa.inc:30
|
||||
msgid "Volver a iniciar sesión"
|
||||
msgstr "Zurück zur Anmeldung"
|
||||
|
||||
#: ../../../themes/material-blue/views/main/login-2fa.inc:31
|
||||
msgid "Volver"
|
||||
msgstr "Zurück"
|
||||
|
||||
#: ../../../themes/material-blue/views/main/login-2fa.inc:35
|
||||
msgid "Acceder"
|
||||
msgstr "Anmeldung"
|
||||
|
||||
#: ../../../themes/material-blue/views/main/login-2fa.inc:37
|
||||
msgid "Solicitar"
|
||||
msgstr "Anfrage"
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:29
|
||||
msgid "Autentificación"
|
||||
msgstr "Authentifizierung"
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:45
|
||||
msgid ""
|
||||
"Habilita la autentificación en 2 pasos que requiere de la introducción de un "
|
||||
"token generado por una aplicación como Google Authenticator."
|
||||
msgstr "Aktiviert Zwei-Faktor-Authentifizierung"
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:49
|
||||
msgid ""
|
||||
"Escanee el código QR proporcionado y a continuación introduzca la clave de 6 "
|
||||
"dígitos."
|
||||
msgstr "Scanne den angegebenen QR-Code und gib den sechs stelligen Code ein."
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:58
|
||||
msgid "Activar"
|
||||
msgstr "Aktivieren"
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:64
|
||||
msgid "Error al obtener el código QR. Inténtelo de nuevo"
|
||||
msgstr "Fehler beim Abrufen des QR-Codes. Bitte erneut versuchen."
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:74
|
||||
msgid "Código"
|
||||
msgstr "Code"
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:80
|
||||
msgid ""
|
||||
"Una vez activada, sólo es posible acceder si se dispone del dispositivo "
|
||||
"generador de códigos asociado."
|
||||
msgstr ""
|
||||
"Sobald aktiviert, kannst du dich nur mit dem Codegenerator verbundenen Gerät "
|
||||
"anmelden."
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:84
|
||||
#, fuzzy
|
||||
msgid "Días Caducidad"
|
||||
msgstr "Änderungsdatum"
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:91
|
||||
msgid "Días"
|
||||
msgstr "Tage"
|
||||
Binary file not shown.
@@ -1,145 +0,0 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Authenticator\n"
|
||||
"POT-Creation-Date: 2017-08-16 02:43+0100\n"
|
||||
"PO-Revision-Date: 2017-08-16 02:43+0100\n"
|
||||
"Last-Translator: nuxsmin <nuxsmin@syspass.org>\n"
|
||||
"Language-Team: nuxsmin@syspass.org\n"
|
||||
"Language: en_US\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 1.6.10\n"
|
||||
"X-Poedit-Basepath: .\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Poedit-SourceCharset: UTF-8\n"
|
||||
"X-Poedit-KeywordsList: _t:2\n"
|
||||
"X-Poedit-SearchPath-0: ../../..\n"
|
||||
|
||||
#: ../../../ActionController.class.php:116
|
||||
#: ../../../ActionController.class.php:255
|
||||
msgid "Código incorrecto"
|
||||
msgstr "Wrong code"
|
||||
|
||||
#: ../../../ActionController.class.php:121
|
||||
msgid "Ey, esto es una DEMO!!"
|
||||
msgstr "Ey, this is a DEMO!!"
|
||||
|
||||
#: ../../../ActionController.class.php:155
|
||||
msgid "Preferencias actualizadas"
|
||||
msgstr "Preferences updated"
|
||||
|
||||
#: ../../../ActionController.class.php:224
|
||||
#: ../../../ActionController.class.php:249
|
||||
msgid "Código correcto"
|
||||
msgstr "Correct code"
|
||||
|
||||
#: ../../../ActionController.class.php:234
|
||||
msgid "Email de recuperación enviado"
|
||||
msgstr "Recovery email has been sent"
|
||||
|
||||
#: ../../../ActionController.class.php:277
|
||||
msgid "Recuperación de Código 2FA"
|
||||
msgstr "2FA Code Recovery"
|
||||
|
||||
#: ../../../ActionController.class.php:278
|
||||
msgid "Se ha solicitado un código de recuperación para 2FA."
|
||||
msgstr "A 2FA recovery code has been requested."
|
||||
|
||||
#: ../../../ActionController.class.php:280
|
||||
#, php-format
|
||||
msgid "El código de recuperación es: %s"
|
||||
msgstr "The recovery code is: %s"
|
||||
|
||||
#: ../../../LoginController.class.php:123
|
||||
msgid "Aviso Caducidad"
|
||||
msgstr "Expire Notice"
|
||||
|
||||
#: ../../../LoginController.class.php:128
|
||||
#, php-format
|
||||
msgid "El código 2FA se ha de restablecer en %d días"
|
||||
msgstr "The 2FA code will need to be reset within %d days"
|
||||
|
||||
#: ../../../LoginController.class.php:134
|
||||
msgid ""
|
||||
"El código 2FA ha caducado. Es necesario restablecerlo desde las preferencias"
|
||||
msgstr "The 2FA code is expired. You need to reset it on preferences tab"
|
||||
|
||||
#: ../../../PreferencesController.class.php:98
|
||||
msgid "Seguridad"
|
||||
msgstr "Security"
|
||||
|
||||
#: ../../../themes/material-blue/views/main/login-2fa.inc:7
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:40
|
||||
msgid "Autentificación en 2 pasos"
|
||||
msgstr "Two Factor Authentication"
|
||||
|
||||
#: ../../../themes/material-blue/views/main/login-2fa.inc:13
|
||||
msgid "Introducir código"
|
||||
msgstr "Enter code"
|
||||
|
||||
#: ../../../themes/material-blue/views/main/login-2fa.inc:17
|
||||
msgid "Olvidé mi código"
|
||||
msgstr "Forgot my code"
|
||||
|
||||
#: ../../../themes/material-blue/views/main/login-2fa.inc:30
|
||||
msgid "Volver a iniciar sesión"
|
||||
msgstr "Back to log in"
|
||||
|
||||
#: ../../../themes/material-blue/views/main/login-2fa.inc:31
|
||||
msgid "Volver"
|
||||
msgstr "Back"
|
||||
|
||||
#: ../../../themes/material-blue/views/main/login-2fa.inc:35
|
||||
msgid "Acceder"
|
||||
msgstr "Log in"
|
||||
|
||||
#: ../../../themes/material-blue/views/main/login-2fa.inc:37
|
||||
msgid "Solicitar"
|
||||
msgstr "Request"
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:29
|
||||
msgid "Autentificación"
|
||||
msgstr "Authentication"
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:45
|
||||
msgid ""
|
||||
"Habilita la autentificación en 2 pasos que requiere de la introducción de un "
|
||||
"token generado por una aplicación como Google Authenticator."
|
||||
msgstr ""
|
||||
"Enables the two factor authentication that requires entering a token that is "
|
||||
"generated by an application like Google Authenticator."
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:49
|
||||
msgid ""
|
||||
"Escanee el código QR proporcionado y a continuación introduzca la clave de 6 "
|
||||
"dígitos."
|
||||
msgstr "Please, scan the provided QR code and then enter the 6 digits key."
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:58
|
||||
msgid "Activar"
|
||||
msgstr "Enable"
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:64
|
||||
msgid "Error al obtener el código QR. Inténtelo de nuevo"
|
||||
msgstr "Error while getting the QR code. Please, try it again"
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:74
|
||||
msgid "Código"
|
||||
msgstr "Code"
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:80
|
||||
msgid ""
|
||||
"Una vez activada, sólo es posible acceder si se dispone del dispositivo "
|
||||
"generador de códigos asociado."
|
||||
msgstr ""
|
||||
"Once enabled, you wil only be able to log in by using the code generator "
|
||||
"linked device."
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:84
|
||||
msgid "Días Caducidad"
|
||||
msgstr "Expiry Days"
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:91
|
||||
msgid "Días"
|
||||
msgstr "Days"
|
||||
Binary file not shown.
@@ -1,146 +0,0 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Authenticator\n"
|
||||
"POT-Creation-Date: 2017-08-16 02:43+0100\n"
|
||||
"PO-Revision-Date: 2017-08-16 02:43+0100\n"
|
||||
"Last-Translator: nuxsmin <nuxsmin@syspass.org>\n"
|
||||
"Language-Team: language@syspass.org\n"
|
||||
"Language: en_US\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 1.6.10\n"
|
||||
"X-Poedit-Basepath: .\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Poedit-SourceCharset: UTF-8\n"
|
||||
"X-Poedit-KeywordsList: _t:2\n"
|
||||
"X-Contributors: wojtek\n"
|
||||
"X-Poedit-SearchPath-0: ../../..\n"
|
||||
|
||||
#: ../../../ActionController.class.php:116
|
||||
#: ../../../ActionController.class.php:255
|
||||
msgid "Código incorrecto"
|
||||
msgstr "Zły kod"
|
||||
|
||||
#: ../../../ActionController.class.php:121
|
||||
msgid "Ey, esto es una DEMO!!"
|
||||
msgstr "Ej, to jest demo!!"
|
||||
|
||||
#: ../../../ActionController.class.php:155
|
||||
msgid "Preferencias actualizadas"
|
||||
msgstr "Ustawienia zaktualizowane"
|
||||
|
||||
#: ../../../ActionController.class.php:224
|
||||
#: ../../../ActionController.class.php:249
|
||||
msgid "Código correcto"
|
||||
msgstr "Prawidłowy kod"
|
||||
|
||||
#: ../../../ActionController.class.php:234
|
||||
msgid "Email de recuperación enviado"
|
||||
msgstr ""
|
||||
|
||||
#: ../../../ActionController.class.php:277
|
||||
msgid "Recuperación de Código 2FA"
|
||||
msgstr ""
|
||||
|
||||
#: ../../../ActionController.class.php:278
|
||||
msgid "Se ha solicitado un código de recuperación para 2FA."
|
||||
msgstr ""
|
||||
|
||||
#: ../../../ActionController.class.php:280
|
||||
#, php-format
|
||||
msgid "El código de recuperación es: %s"
|
||||
msgstr ""
|
||||
|
||||
#: ../../../LoginController.class.php:123
|
||||
msgid "Aviso Caducidad"
|
||||
msgstr "Powiadomienie o wygaśnięciu"
|
||||
|
||||
#: ../../../LoginController.class.php:128
|
||||
#, php-format
|
||||
msgid "El código 2FA se ha de restablecer en %d días"
|
||||
msgstr "2FA kod będzie musiał być zresetowany w ciągu %d dni"
|
||||
|
||||
#: ../../../LoginController.class.php:134
|
||||
msgid ""
|
||||
"El código 2FA ha caducado. Es necesario restablecerlo desde las preferencias"
|
||||
msgstr "Kod 2FA wygasł. Zresetuj go w zakładce z ustawieniami"
|
||||
|
||||
#: ../../../PreferencesController.class.php:98
|
||||
msgid "Seguridad"
|
||||
msgstr "Bezpieczeństwo"
|
||||
|
||||
#: ../../../themes/material-blue/views/main/login-2fa.inc:7
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:40
|
||||
msgid "Autentificación en 2 pasos"
|
||||
msgstr "Dwustopniowe logowanie"
|
||||
|
||||
#: ../../../themes/material-blue/views/main/login-2fa.inc:13
|
||||
msgid "Introducir código"
|
||||
msgstr "Wprowadź kod"
|
||||
|
||||
#: ../../../themes/material-blue/views/main/login-2fa.inc:17
|
||||
msgid "Olvidé mi código"
|
||||
msgstr ""
|
||||
|
||||
#: ../../../themes/material-blue/views/main/login-2fa.inc:30
|
||||
msgid "Volver a iniciar sesión"
|
||||
msgstr "Wróć do logowania"
|
||||
|
||||
#: ../../../themes/material-blue/views/main/login-2fa.inc:31
|
||||
msgid "Volver"
|
||||
msgstr "Wróć"
|
||||
|
||||
#: ../../../themes/material-blue/views/main/login-2fa.inc:35
|
||||
msgid "Acceder"
|
||||
msgstr "Logowanie"
|
||||
|
||||
#: ../../../themes/material-blue/views/main/login-2fa.inc:37
|
||||
msgid "Solicitar"
|
||||
msgstr "Żądanie"
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:29
|
||||
msgid "Autentificación"
|
||||
msgstr "Poświadczenie"
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:45
|
||||
msgid ""
|
||||
"Habilita la autentificación en 2 pasos que requiere de la introducción de un "
|
||||
"token generado por una aplicación como Google Authenticator."
|
||||
msgstr ""
|
||||
"Włącza dwustopniowe logowanie, które wymag podania tokenu generowanego przez "
|
||||
"aplikację, np. Google Authenticator"
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:49
|
||||
msgid ""
|
||||
"Escanee el código QR proporcionado y a continuación introduzca la clave de 6 "
|
||||
"dígitos."
|
||||
msgstr "Zeskanuj wyświetlony kod QR i wprowadź 6 cyfr."
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:58
|
||||
msgid "Activar"
|
||||
msgstr "Włącz"
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:64
|
||||
msgid "Error al obtener el código QR. Inténtelo de nuevo"
|
||||
msgstr "Błąd pobierania kodu QR. Spróbuj ponownie"
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:74
|
||||
msgid "Código"
|
||||
msgstr "Kod"
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:80
|
||||
msgid ""
|
||||
"Una vez activada, sólo es posible acceder si se dispone del dispositivo "
|
||||
"generador de códigos asociado."
|
||||
msgstr ""
|
||||
"Po włączeniu będziesz mógł się zalogować tylko z użyciem kodu wygenerowanego "
|
||||
"przez podłączone urządzenie."
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:84
|
||||
msgid "Días Caducidad"
|
||||
msgstr "Dni do wygaśnięcia"
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:91
|
||||
msgid "Días"
|
||||
msgstr "Dni"
|
||||
Binary file not shown.
@@ -1,144 +0,0 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: sysPass\n"
|
||||
"POT-Creation-Date: 2017-08-16 02:43+0100\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: nuxsmin <nuxsmin@syspass.org>\n"
|
||||
"Language-Team: Alexander Titov,Alex Us\n"
|
||||
"Language: ru\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 1.6.10\n"
|
||||
"X-Poedit-SourceCharset: UTF-8\n"
|
||||
"X-Poedit-Basepath: .\n"
|
||||
"X-Poedit-KeywordsList: _t:2\n"
|
||||
"X-Poedit-SearchPath-0: ../../..\n"
|
||||
|
||||
#: ../../../ActionController.class.php:116
|
||||
#: ../../../ActionController.class.php:255
|
||||
msgid "Código incorrecto"
|
||||
msgstr "Неправильный код"
|
||||
|
||||
#: ../../../ActionController.class.php:121
|
||||
msgid "Ey, esto es una DEMO!!"
|
||||
msgstr "Эй, это Демо-версия!!"
|
||||
|
||||
#: ../../../ActionController.class.php:155
|
||||
msgid "Preferencias actualizadas"
|
||||
msgstr "Настройки изменены"
|
||||
|
||||
#: ../../../ActionController.class.php:224
|
||||
#: ../../../ActionController.class.php:249
|
||||
msgid "Código correcto"
|
||||
msgstr "Правильный код"
|
||||
|
||||
#: ../../../ActionController.class.php:234
|
||||
msgid "Email de recuperación enviado"
|
||||
msgstr ""
|
||||
|
||||
#: ../../../ActionController.class.php:277
|
||||
msgid "Recuperación de Código 2FA"
|
||||
msgstr ""
|
||||
|
||||
#: ../../../ActionController.class.php:278
|
||||
msgid "Se ha solicitado un código de recuperación para 2FA."
|
||||
msgstr ""
|
||||
|
||||
#: ../../../ActionController.class.php:280
|
||||
#, php-format
|
||||
msgid "El código de recuperación es: %s"
|
||||
msgstr ""
|
||||
|
||||
#: ../../../LoginController.class.php:123
|
||||
#, fuzzy
|
||||
msgid "Aviso Caducidad"
|
||||
msgstr "Действует до"
|
||||
|
||||
#: ../../../LoginController.class.php:128
|
||||
#, php-format
|
||||
msgid "El código 2FA se ha de restablecer en %d días"
|
||||
msgstr "2FA код будет сброшен через %d дней."
|
||||
|
||||
#: ../../../LoginController.class.php:134
|
||||
msgid ""
|
||||
"El código 2FA ha caducado. Es necesario restablecerlo desde las preferencias"
|
||||
msgstr "2FA код просрочен. Вам нужно сбросить его на странице настроек"
|
||||
|
||||
#: ../../../PreferencesController.class.php:98
|
||||
msgid "Seguridad"
|
||||
msgstr "Безопасность"
|
||||
|
||||
#: ../../../themes/material-blue/views/main/login-2fa.inc:7
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:40
|
||||
msgid "Autentificación en 2 pasos"
|
||||
msgstr "Двухфакторная аутентификация"
|
||||
|
||||
#: ../../../themes/material-blue/views/main/login-2fa.inc:13
|
||||
msgid "Introducir código"
|
||||
msgstr "Введите код"
|
||||
|
||||
#: ../../../themes/material-blue/views/main/login-2fa.inc:17
|
||||
msgid "Olvidé mi código"
|
||||
msgstr ""
|
||||
|
||||
#: ../../../themes/material-blue/views/main/login-2fa.inc:30
|
||||
msgid "Volver a iniciar sesión"
|
||||
msgstr "Назад ко входу"
|
||||
|
||||
#: ../../../themes/material-blue/views/main/login-2fa.inc:31
|
||||
msgid "Volver"
|
||||
msgstr "Назад"
|
||||
|
||||
#: ../../../themes/material-blue/views/main/login-2fa.inc:35
|
||||
msgid "Acceder"
|
||||
msgstr "Войти"
|
||||
|
||||
#: ../../../themes/material-blue/views/main/login-2fa.inc:37
|
||||
msgid "Solicitar"
|
||||
msgstr "Запрос"
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:29
|
||||
msgid "Autentificación"
|
||||
msgstr "Аутентификация"
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:45
|
||||
msgid ""
|
||||
"Habilita la autentificación en 2 pasos que requiere de la introducción de un "
|
||||
"token generado por una aplicación como Google Authenticator."
|
||||
msgstr "Включает двухфакторную аутентификацию, например Google Authenticator."
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:49
|
||||
msgid ""
|
||||
"Escanee el código QR proporcionado y a continuación introduzca la clave de 6 "
|
||||
"dígitos."
|
||||
msgstr "Отсканируйте QR-код и затем введите шестизначный пароль."
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:58
|
||||
msgid "Activar"
|
||||
msgstr "Активировать"
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:64
|
||||
msgid "Error al obtener el código QR. Inténtelo de nuevo"
|
||||
msgstr "Ошибка получения QR-кода. Попробуйте еще раз."
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:74
|
||||
msgid "Código"
|
||||
msgstr "Пароль"
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:80
|
||||
msgid ""
|
||||
"Una vez activada, sólo es posible acceder si se dispone del dispositivo "
|
||||
"generador de códigos asociado."
|
||||
msgstr ""
|
||||
"После включения, Вы можете получить доступ только при наличии привязанного "
|
||||
"устройства."
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:84
|
||||
#, fuzzy
|
||||
msgid "Días Caducidad"
|
||||
msgstr "Действует до"
|
||||
|
||||
#: ../../../themes/material-blue/views/userpreferences/preferences-security.inc:91
|
||||
msgid "Días"
|
||||
msgstr "Дни"
|
||||
@@ -1,42 +0,0 @@
|
||||
<main class="mdl-layout__content">
|
||||
<div id="actions">
|
||||
<form id="frmPass2fa" action="" method="post" class="form-action"
|
||||
data-onsubmit="twofa/check"
|
||||
data-plugin="Authenticator">
|
||||
<fieldset id="resetdata">
|
||||
<legend><?php echo _t('authenticator', 'Autentificación en 2 pasos'); ?></legend>
|
||||
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
|
||||
<input id="security_pin" name="security_pin" type="text"
|
||||
pattern="([0-9]{6}|[0-9a-f]{20})" class="mdl-textfield__input mdl-color-text--indigo-400" maxlength="20"
|
||||
required/>
|
||||
<label class="mdl-textfield__label"
|
||||
for="security_pin"><?php echo _t('authenticator', 'Introducir código'); ?></label>
|
||||
</div>
|
||||
<label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect" for="code_reset">
|
||||
<input type="checkbox" name="code_reset" id="code_reset" class="mdl-checkbox__input">
|
||||
<span class="mdl-checkbox__label"><?php echo _t('authenticator', 'Olvidé mi código'); ?></span>
|
||||
</label>
|
||||
<input type="hidden" name="actionId" value="<?php echo $actionId; ?>"/>
|
||||
<input type="hidden" name="itemId" value="<?php echo $userId; ?>"/>
|
||||
<input type="hidden" name="time" value="<?php echo $time; ?>"/>
|
||||
<input type="hidden" name="sk" value=""/>
|
||||
<input type="hidden" name="isAjax" value="1"/>
|
||||
</fieldset>
|
||||
|
||||
<div class="buttons">
|
||||
<button id="btnBack" type="button"
|
||||
class="mdl-button mdl-js-button mdl-button--raised mdl-button--primary">
|
||||
<i class="material-icons"
|
||||
title="<?php echo _t('authenticator', 'Volver a iniciar sesión'); ?>"><?php echo $icons->getIconBack()->getIcon(); ?></i>
|
||||
<?php echo _t('authenticator', 'Volver'); ?>
|
||||
</button>
|
||||
|
||||
<button id="btnLogin" class="mdl-button mdl-js-button mdl-button--raised mdl-button--primary">
|
||||
<?php echo _t('authenticator', 'Acceder'); ?>
|
||||
<i class="material-icons"
|
||||
title="<?php echo _t('authenticator', 'Solicitar'); ?>"><?php echo $icons->getIconPlay()->getIcon(); ?></i>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</main>
|
||||
@@ -1,115 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* sysPass
|
||||
*
|
||||
* @author nuxsmin
|
||||
* @link http://syspass.org
|
||||
* @copyright 2012-2017, 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/>.
|
||||
*/ /** @var $icons \Theme\Icons */ ?>
|
||||
|
||||
<!-- Start Tab - Security -->
|
||||
<div id="tabs-<?php echo $security_tabIndex; ?>" class="mdl-tabs__panel">
|
||||
<div class="tab-data">
|
||||
<div id="title" class="midroundup titleNormal">
|
||||
<?php echo _t('authenticator', 'Autentificación'); ?>
|
||||
</div>
|
||||
|
||||
<form method="post" name="frmSecurity" id="frmSecurity" class="form-action"
|
||||
data-onsubmit="twofa/save"
|
||||
data-plugin="Authenticator"
|
||||
data-nextaction-id="<?php echo \SP\Core\ActionsInterface::ACTION_USR_PREFERENCES_SECURITY; ?>"
|
||||
data-activetab="<?php echo $security_tabIndex; ?>">
|
||||
<table id="tblSite" class="data tblConfig round">
|
||||
<tr>
|
||||
<td class="descField">
|
||||
<?php echo _t('authenticator', 'Autentificación en 2 pasos'); ?>
|
||||
<div id="help-security_2fa"
|
||||
class="icon material-icons <?php echo $icons->getIconHelp()->getClass(); ?>"><?php echo $icons->getIconHelp()->getIcon(); ?></div>
|
||||
<div class="mdl-tooltip mdl-tooltip--large" for="help-security_2fa">
|
||||
<p>
|
||||
<?php echo _t('authenticator', 'Habilita la autentificación en 2 pasos que requiere de la introducción de un token generado por una aplicación como Google Authenticator.'); ?>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<?php echo _t('authenticator', 'Escanee el código QR proporcionado y a continuación introduzca la clave de 6 dígitos.'); ?>
|
||||
</p>
|
||||
</div>
|
||||
</td>
|
||||
<td class="valField">
|
||||
<label class="mdl-switch mdl-js-switch mdl-js-ripple-effect" for="security_2faenabled">
|
||||
<input type="checkbox" id="security_2faenabled"
|
||||
class="mdl-switch__input mdl-color-text--indigo-400"
|
||||
name="security_2faenabled" <?php echo $chk2FAEnabled ? 'checked' : ''; ?>/>
|
||||
<span class="mdl-switch__label"><?php echo _t('authenticator', 'Activar'); ?></span>
|
||||
</label>
|
||||
<?php if (!$chk2FAEnabled && $qrCode): ?>
|
||||
<br><br>
|
||||
<img id="security_qrcode" src="data:image/gif;base64,<?php echo $qrCode; ?>" alt="QR Code"/>
|
||||
<?php elseif ($qrCode === false): ?>
|
||||
<p class="ui-state-error"><?php echo _t('authenticator', 'Error al obtener el código QR. Inténtelo de nuevo'); ?></p>
|
||||
<?php endif; ?>
|
||||
<br><br>
|
||||
|
||||
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
|
||||
<input id="security_pin" name="security_pin" type="text"
|
||||
pattern="[0-9]{6}" class="mdl-textfield__input mdl-color-text--indigo-400"
|
||||
maxlength="6"
|
||||
required/>
|
||||
<label class="mdl-textfield__label"
|
||||
for="security_pin"><?php echo _t('authenticator', 'Código'); ?></label>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<div
|
||||
class="icon material-icons <?php echo $icons->getIconWarning()->getClass(); ?>"><?php echo $icons->getIconWarning()->getIcon(); ?></div>
|
||||
<?php echo _t('authenticator', 'Una vez activada, sólo es posible acceder si se dispone del dispositivo generador de códigos asociado.'); ?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="descField"><?php echo _t('authenticator', 'Días Caducidad'); ?></td>
|
||||
<td class="valField">
|
||||
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
|
||||
<input id="expiredays" name="expiredays" type="number" step="1"
|
||||
min="0" max="720" class="mdl-textfield__input mdl-color-text--indigo-400"
|
||||
value="<?php echo $expireDays ?: 90; ?>" required/>
|
||||
<label class="mdl-textfield__label"
|
||||
for="expiredays"><?php echo _t('authenticator', 'Días'); ?></label>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<input type="hidden" name="itemId" value="<?php echo $userId; ?>"/>
|
||||
<input type="hidden" name="actionId" value="<?php echo $security_actionId; ?>"/>
|
||||
<input type="hidden" name="isAjax" value="1"/>
|
||||
<input type="hidden" name="sk" value="">
|
||||
|
||||
</form>
|
||||
<div class="tab-actions">
|
||||
<ul>
|
||||
<li>
|
||||
<button form="frmSecurity" type="submit"
|
||||
class="mdl-button mdl-js-button mdl-button--fab mdl-button--mini-fab mdl-button--colored <?php echo $icons->getIconSave()->getClassButton(); ?>"
|
||||
title="<?php echo $icons->getIconSave()->getTitle(); ?>">
|
||||
<i class="material-icons"><?php echo $icons->getIconSave()->getIcon(); ?></i>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div> <!-- End Tab - Security -->
|
||||
@@ -483,11 +483,16 @@ sysPass.Theme = function (Common) {
|
||||
* @type {{getList: html.getList}}
|
||||
*/
|
||||
var html = {
|
||||
getList: function (items) {
|
||||
getList: function (items, icon) {
|
||||
var $ul = $("<ul class=\"ldap-list-item mdl-list\"></ul>");
|
||||
var $li = $("<li class=\"mdl-list__item\"></li>");
|
||||
var $span = $("<span class=\"mdl-list__item-primary-content\"></span>");
|
||||
var icon = "<i class=\"material-icons mdl-list__item-icon\">person</i>";
|
||||
|
||||
if (icon === undefined) {
|
||||
icon = "<i class=\"material-icons mdl-list__item-icon\">person</i>";
|
||||
} else {
|
||||
icon = "<i class=\"material-icons mdl-list__item-icon\">" + icon + "</i>";
|
||||
}
|
||||
|
||||
items.forEach(function (value) {
|
||||
var $spanClone = $span.clone();
|
||||
|
||||
30
inc/themes/material-blue/js/app-theme.min.js
vendored
30
inc/themes/material-blue/js/app-theme.min.js
vendored
@@ -1,20 +1,20 @@
|
||||
var $jscomp={scope:{},findInternal:function(a,f,c){a instanceof String&&(a=String(a));for(var g=a.length,h=0;h<g;h++){var l=a[h];if(f.call(c,l,h,a))return{i:h,v:l}}return{i:-1,v:void 0}}};$jscomp.defineProperty="function"==typeof Object.defineProperties?Object.defineProperty:function(a,f,c){if(c.get||c.set)throw new TypeError("ES3 does not support getters and setters.");a!=Array.prototype&&a!=Object.prototype&&(a[f]=c.value)};
|
||||
$jscomp.getGlobal=function(a){return"undefined"!=typeof window&&window===a?a:"undefined"!=typeof global?global:a};$jscomp.global=$jscomp.getGlobal(this);$jscomp.polyfill=function(a,f,c,g){if(f){c=$jscomp.global;a=a.split(".");for(g=0;g<a.length-1;g++){var h=a[g];h in c||(c[h]={});c=c[h]}a=a[a.length-1];g=c[a];f=f(g);f!=g&&null!=f&&$jscomp.defineProperty(c,a,{configurable:!0,writable:!0,value:f})}};
|
||||
var $jscomp={scope:{},findInternal:function(a,e,c){a instanceof String&&(a=String(a));for(var g=a.length,k=0;k<g;k++){var l=a[k];if(e.call(c,l,k,a))return{i:k,v:l}}return{i:-1,v:void 0}}};$jscomp.defineProperty="function"==typeof Object.defineProperties?Object.defineProperty:function(a,e,c){if(c.get||c.set)throw new TypeError("ES3 does not support getters and setters.");a!=Array.prototype&&a!=Object.prototype&&(a[e]=c.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.polyfill=function(a,e,c,g){if(e){c=$jscomp.global;a=a.split(".");for(g=0;g<a.length-1;g++){var k=a[g];k in c||(c[k]={});c=c[k]}a=a[a.length-1];g=c[a];e=e(g);e!=g&&null!=e&&$jscomp.defineProperty(c,a,{configurable:!0,writable:!0,value:e})}};
|
||||
$jscomp.polyfill("Array.prototype.find",function(a){return a?a:function(a,c){return $jscomp.findInternal(this,a,c).v}},"es6-impl","es3");
|
||||
sysPass.Theme=function(a){var f=a.log,c={elems:{$wrap:$("#wrap-loading"),$loading:$("#loading")},show:function(a){void 0!==a&&!0===a&&c.elems.$wrap.addClass("overlay-full");c.elems.$wrap.show();c.elems.$loading.addClass("is-active")},hide:function(){c.elems.$wrap.removeClass("overlay-full").hide();c.elems.$loading.removeClass("is-active")},upgradeFull:function(){c.elems.$wrap.addClass("overlay-full")}},g=function(b){var m=0,d="",e="";a.passwordData.complexity.symbols&&(d+="!\"\\\u00b7@|#$~%&/()=?'\u00bf\u00a1^*[]\u00b7;,_-{}<>");
|
||||
a.passwordData.complexity.numbers&&(d+="1234567890");a.passwordData.complexity.chars&&(d+="abcdefghijklmnopqrstuvwxyz",a.passwordData.complexity.uppercase&&(d+="ABCDEFGHIJKLMNOPQRSTUVWXYZ"));for(;m++<=a.passwordData.complexity.numlength;)e+=d.charAt(Math.floor(Math.random()*(d.length-1)+0));$("#viewPass").attr("title",e);var c=zxcvbn(e);a.passwordData.passLength=e.length;b?(m=b.parent(),d=$("#"+b.attr("id")+"R"),a.outputResult(c,b),b=new MaterialTextfield,m.find("input:password").val(e),m.addClass(b.CssClasses_.IS_DIRTY).removeClass(b.CssClasses_.IS_INVALID),
|
||||
0<d.length&&(d.val(e).parent().addClass(b.CssClasses_.IS_DIRTY).removeClass(b.CssClasses_.IS_INVALID),a.encryptFormValue(d)),m.find("#passLevel").show(500)):(a.outputResult(c),$("input:password, input.password").val(e),$("#passLevel").show(500))},h=function(){var b='<div id="box-complexity"><div><label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect" for="checkbox-chars"><input type="checkbox" id="checkbox-chars" class="mdl-checkbox__input" name="checkbox-chars" checked/><span class="mdl-checkbox__label">'+
|
||||
sysPass.Theme=function(a){var e=a.log,c={elems:{$wrap:$("#wrap-loading"),$loading:$("#loading")},show:function(a){void 0!==a&&!0===a&&c.elems.$wrap.addClass("overlay-full");c.elems.$wrap.show();c.elems.$loading.addClass("is-active")},hide:function(){c.elems.$wrap.removeClass("overlay-full").hide();c.elems.$loading.removeClass("is-active")},upgradeFull:function(){c.elems.$wrap.addClass("overlay-full")}},g=function(b){var f=0,d="",h="";a.passwordData.complexity.symbols&&(d+="!\"\\\u00b7@|#$~%&/()=?'\u00bf\u00a1^*[]\u00b7;,_-{}<>");
|
||||
a.passwordData.complexity.numbers&&(d+="1234567890");a.passwordData.complexity.chars&&(d+="abcdefghijklmnopqrstuvwxyz",a.passwordData.complexity.uppercase&&(d+="ABCDEFGHIJKLMNOPQRSTUVWXYZ"));for(;f++<=a.passwordData.complexity.numlength;)h+=d.charAt(Math.floor(Math.random()*(d.length-1)+0));$("#viewPass").attr("title",h);var c=zxcvbn(h);a.passwordData.passLength=h.length;b?(f=b.parent(),d=$("#"+b.attr("id")+"R"),a.outputResult(c,b),b=new MaterialTextfield,f.find("input:password").val(h),f.addClass(b.CssClasses_.IS_DIRTY).removeClass(b.CssClasses_.IS_INVALID),
|
||||
0<d.length&&(d.val(h).parent().addClass(b.CssClasses_.IS_DIRTY).removeClass(b.CssClasses_.IS_INVALID),a.encryptFormValue(d)),f.find("#passLevel").show(500)):(a.outputResult(c),$("input:password, input.password").val(h),$("#passLevel").show(500))},k=function(){var b='<div id="box-complexity"><div><label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect" for="checkbox-chars"><input type="checkbox" id="checkbox-chars" class="mdl-checkbox__input" name="checkbox-chars" checked/><span class="mdl-checkbox__label">'+
|
||||
a.config().LANG[63]+'</span></label><label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect" for="checkbox-numbers"><input type="checkbox" id="checkbox-numbers" class="mdl-checkbox__input" name="checkbox-numbers" checked/><span class="mdl-checkbox__label">'+a.config().LANG[35]+'</span></label><label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect" for="checkbox-uppercase"><input type="checkbox" id="checkbox-uppercase" class="mdl-checkbox__input" name="checkbox-uppercase"/><span class="mdl-checkbox__label">'+
|
||||
a.config().LANG[36]+'</span></label><label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect" for="checkbox-symbols"><input type="checkbox" id="checkbox-symbols" class="mdl-checkbox__input" name="checkbox-symbols"/><span class="mdl-checkbox__label">'+a.config().LANG[37]+'</span></label><div class="mdl-textfield mdl-js-textfield textfield-passlength"><input class="mdl-textfield__input" type="number" pattern="[0-9]*" id="passlength" /><label class="mdl-textfield__label" for="passlength">'+a.config().LANG[38]+
|
||||
"</label></div></div></div>";mdlDialog().show({title:a.config().LANG[29],text:b,negative:{title:a.config().LANG[44]},positive:{title:a.config().LANG[43],onClick:function(b){b.preventDefault();a.passwordData.complexity.chars=$("#checkbox-chars").is(":checked");a.passwordData.complexity.numbers=$("#checkbox-numbers").is(":checked");a.passwordData.complexity.uppercase=$("#checkbox-uppercase").is(":checked");a.passwordData.complexity.symbols=$("#checkbox-symbols").is(":checked");a.passwordData.complexity.numlength=
|
||||
parseInt($("#passlength").val())}},cancelable:!0,contentStyle:{"max-width":"300px"},onLoaded:function(){$("#checkbox-chars").prop("checked",a.passwordData.complexity.chars);$("#checkbox-numbers").prop("checked",a.passwordData.complexity.numbers);$("#checkbox-uppercase").prop("checked",a.passwordData.complexity.uppercase);$("#checkbox-symbols").prop("checked",a.passwordData.complexity.symbols);$("#passlength").val(a.passwordData.complexity.numlength)}})},l=function(b){b.find(".passwordfield__input").each(function(){var b=
|
||||
$(this);if("true"!==b.attr("data-pass-upgraded")){var d=b.parent(),c=b.attr("id"),k='<button id="menu-speed-'+c+'" class="mdl-button mdl-js-button mdl-button--icon" type="button" title="'+a.config().LANG[27]+'"><i class="material-icons">more_vert</i></button>',k=k+('<ul class="mdl-menu mdl-js-menu" for="menu-speed-'+c+'">')+('<li class="mdl-menu__item passGen"><i class="material-icons">settings</i>'+a.config().LANG[28]+"</li>"),k=k+('<li class="mdl-menu__item passComplexity"><i class="material-icons">vpn_key</i>'+
|
||||
a.config().LANG[29]+"</li>"),k=k+('<li class="mdl-menu__item reset"><i class="material-icons">refresh</i>'+a.config().LANG[30]+"</li>");d.after('<div class="password-actions" />');d.next(".password-actions").prepend('<span class="passLevel passLevel-'+c+' fullround" title="'+a.config().LANG[31]+'"></span>').prepend('<i class="showpass material-icons" title="'+a.config().LANG[32]+'">remove_red_eye</i>').prepend(k);b.on("keyup",function(){a.checkPassLevel(b)});d=b.parent().next();d.find(".passGen").on("click",
|
||||
function(){g(b);b.focus()});d.find(".passComplexity").on("click",function(){h()});d.find(".showpass").on("mouseover",function(){$(this).attr("title",b.val())});d.find(".reset").on("click",function(){b.val("");var a=$("#"+c+"R");0<a.length&&a.val("");componentHandler.upgradeDom()});b.attr("data-pass-upgraded","true")}});b.find(".passwordfield__input-show").each(function(){var b=$(this),d=$('<i class="showpass material-icons" title="'+a.config().LANG[32]+'">remove_red_eye</i>');if(1===b.data("clipboard")){var c=
|
||||
$('<i class="clip-pass-icon material-icons" title="'+a.config().LANG[34]+'" data-clipboard-target="#'+b.attr("id")+'">content_paste</i>');b.parent().after(c).after(d)}else b.parent().after(d);d.on("mouseover",function(){d.attr("title",b.val())})})},n=function(b){f.info("setupDatePicker");var c={format:"YYYY-MM-DD",lang:a.config().LOCALE.substr(0,2),time:!1,cancelText:a.config().LANG[44],okText:a.config().LANG[43],clearText:a.config().LANG[30],nowText:a.config().LANG[56],minDate:new Date,triggerEvent:"dateIconClick"};
|
||||
"</label></div></div></div>";mdlDialog().show({title:a.config().LANG[29],text:b,negative:{title:a.config().LANG[44]},positive:{title:a.config().LANG[43],onClick:function(f){f.preventDefault();a.passwordData.complexity.chars=$("#checkbox-chars").is(":checked");a.passwordData.complexity.numbers=$("#checkbox-numbers").is(":checked");a.passwordData.complexity.uppercase=$("#checkbox-uppercase").is(":checked");a.passwordData.complexity.symbols=$("#checkbox-symbols").is(":checked");a.passwordData.complexity.numlength=
|
||||
parseInt($("#passlength").val())}},cancelable:!0,contentStyle:{"max-width":"300px"},onLoaded:function(){$("#checkbox-chars").prop("checked",a.passwordData.complexity.chars);$("#checkbox-numbers").prop("checked",a.passwordData.complexity.numbers);$("#checkbox-uppercase").prop("checked",a.passwordData.complexity.uppercase);$("#checkbox-symbols").prop("checked",a.passwordData.complexity.symbols);$("#passlength").val(a.passwordData.complexity.numlength)}})},l=function(b){b.find(".passwordfield__input").each(function(){var f=
|
||||
$(this);if("true"!==f.attr("data-pass-upgraded")){var d=f.parent(),b=f.attr("id"),c='<button id="menu-speed-'+b+'" class="mdl-button mdl-js-button mdl-button--icon" type="button" title="'+a.config().LANG[27]+'"><i class="material-icons">more_vert</i></button>',c=c+('<ul class="mdl-menu mdl-js-menu" for="menu-speed-'+b+'">')+('<li class="mdl-menu__item passGen"><i class="material-icons">settings</i>'+a.config().LANG[28]+"</li>"),c=c+('<li class="mdl-menu__item passComplexity"><i class="material-icons">vpn_key</i>'+
|
||||
a.config().LANG[29]+"</li>"),c=c+('<li class="mdl-menu__item reset"><i class="material-icons">refresh</i>'+a.config().LANG[30]+"</li>");d.after('<div class="password-actions" />');d.next(".password-actions").prepend('<span class="passLevel passLevel-'+b+' fullround" title="'+a.config().LANG[31]+'"></span>').prepend('<i class="showpass material-icons" title="'+a.config().LANG[32]+'">remove_red_eye</i>').prepend(c);f.on("keyup",function(){a.checkPassLevel(f)});d=f.parent().next();d.find(".passGen").on("click",
|
||||
function(){g(f);f.focus()});d.find(".passComplexity").on("click",function(){k()});d.find(".showpass").on("mouseover",function(){$(this).attr("title",f.val())});d.find(".reset").on("click",function(){f.val("");var a=$("#"+b+"R");0<a.length&&a.val("");componentHandler.upgradeDom()});f.attr("data-pass-upgraded","true")}});b.find(".passwordfield__input-show").each(function(){var b=$(this),d=$('<i class="showpass material-icons" title="'+a.config().LANG[32]+'">remove_red_eye</i>');if(1===b.data("clipboard")){var c=
|
||||
$('<i class="clip-pass-icon material-icons" title="'+a.config().LANG[34]+'" data-clipboard-target="#'+b.attr("id")+'">content_paste</i>');b.parent().after(c).after(d)}else b.parent().after(d);d.on("mouseover",function(){d.attr("title",b.val())})})},m=function(b){e.info("setupDatePicker");var c={format:"YYYY-MM-DD",lang:a.config().LOCALE.substr(0,2),time:!1,cancelText:a.config().LANG[44],okText:a.config().LANG[43],clearText:a.config().LANG[30],nowText:a.config().LANG[56],minDate:new Date,triggerEvent:"dateIconClick"};
|
||||
b.find(".password-datefield__input").each(function(){var b=$(this);b.bootstrapMaterialDatePicker(c);b.parent().append("<input type='hidden' name='passworddatechange_unix' value='"+moment.tz(b.val(),a.config().TIMEZONE).format("X")+"' />");b.parent().next("i").on("click",function(){b.trigger("dateIconClick")});b.on("change",function(){var c;c=moment.tz(b.val(),a.config().TIMEZONE).format("X");b.parent().find("input[name='passworddatechange_unix']").val(c)})})};return{passwordDetect:l,password:g,viewsTriggers:{main:function(){var a=
|
||||
document.querySelector(".mdl-layout");$(".mdl-layout__drawer").find("a").click(function(){a.MaterialLayout.toggleDrawer()})},search:function(){var b=$("#frmSearch"),c=$("#res-content");b.find("button.btn-clear").on("click",function(a){$(".icon-searchfav").find("i").removeClass("mdl-color-text--amber-A200")});b.find(".icon-searchfav").on("click",function(){var c=$(this).find("i"),d=b.find("input[name='searchfav']");0==d.val()?(c.addClass("mdl-color-text--amber-A200"),c.attr("title",a.config().LANG[53]),
|
||||
d.val(1)):(c.removeClass("mdl-color-text--amber-A200"),c.attr("title",a.config().LANG[52]),d.val(0));b.submit()});var d=b.find("#tags")[0],e=b.find(".search-filters-tags"),k=b.find("i.show-filter");c.on("click","#data-search-header .sort-down,#data-search-header .sort-up",function(){var b=$(this);b.parent().find("a").addClass("filterOn");a.appActions().account.sort(b)}).on("click","#search-rows i.icon-favorite",function(){var b=$(this);a.appActions().account.savefavorite(b,function(){"on"===b.data("status")?
|
||||
(b.addClass("mdl-color-text--amber-A100"),b.attr("title",a.config().LANG[50]),b.html("star")):(b.removeClass("mdl-color-text--amber-A100"),b.attr("title",a.config().LANG[49]),b.html("star_border"))})}).on("click","#search-rows span.tag",function(){e.is(":hidden")&&k.trigger("click");d.selectize.addItem($(this).data("tag-id"))});k.on("click",function(){var a=$(this);e.is(":hidden")?(e.slideDown("slow"),a.html(a.data("icon-up"))):(e.slideUp("slow"),a.html(a.data("icon-down")))});0<d.selectedIndex&&
|
||||
k.trigger("click")},common:function(a){l(a);n(a)}},loading:c,ajax:{complete:function(){f.info("ajax:complete");componentHandler.upgradeDom()}},html:{getList:function(a){var b=$('<ul class="ldap-list-item mdl-list"></ul>'),c=$('<li class="mdl-list__item"></li>'),e=$('<span class="mdl-list__item-primary-content"></span>');a.forEach(function(a){var d=e.clone();d.append('<i class="material-icons mdl-list__item-icon">person</i>');d.append(a);a=c.clone().append(d);b.append(a)});return b},tabs:{add:function(a,
|
||||
c,d,e){a=$(a);var b="";1===e&&(a.parent().find("#tabs-"+c).addClass("is-active"),b="is-active");a.append('<a href="#tabs-'+c+'" class="mdl-tabs__tab '+b+'">'+d+"</a>")}}}}};
|
||||
d.val(1)):(c.removeClass("mdl-color-text--amber-A200"),c.attr("title",a.config().LANG[52]),d.val(0));b.submit()});var d=b.find("#tags")[0],h=b.find(".search-filters-tags"),e=b.find("i.show-filter");c.on("click","#data-search-header .sort-down,#data-search-header .sort-up",function(){var b=$(this);b.parent().find("a").addClass("filterOn");a.appActions().account.sort(b)}).on("click","#search-rows i.icon-favorite",function(){var b=$(this);a.appActions().account.savefavorite(b,function(){"on"===b.data("status")?
|
||||
(b.addClass("mdl-color-text--amber-A100"),b.attr("title",a.config().LANG[50]),b.html("star")):(b.removeClass("mdl-color-text--amber-A100"),b.attr("title",a.config().LANG[49]),b.html("star_border"))})}).on("click","#search-rows span.tag",function(){h.is(":hidden")&&e.trigger("click");d.selectize.addItem($(this).data("tag-id"))});e.on("click",function(){var a=$(this);h.is(":hidden")?(h.slideDown("slow"),a.html(a.data("icon-up"))):(h.slideUp("slow"),a.html(a.data("icon-down")))});0<d.selectedIndex&&
|
||||
e.trigger("click")},common:function(a){l(a);m(a)}},loading:c,ajax:{complete:function(){e.info("ajax:complete");componentHandler.upgradeDom()}},html:{getList:function(a,c){var b=$('<ul class="ldap-list-item mdl-list"></ul>'),f=$('<li class="mdl-list__item"></li>'),e=$('<span class="mdl-list__item-primary-content"></span>');c=void 0===c?'<i class="material-icons mdl-list__item-icon">person</i>':'<i class="material-icons mdl-list__item-icon">'+c+"</i>";a.forEach(function(a){var d=e.clone();d.append(c);
|
||||
d.append(a);a=f.clone().append(d);b.append(a)});return b},tabs:{add:function(a,c,d,e){a=$(a);var b="";1===e&&(a.parent().find("#tabs-"+c).addClass("is-active"),b="is-active");a.append('<a href="#tabs-'+c+'" class="mdl-tabs__tab '+b+'">'+d+"</a>")}}}}};
|
||||
|
||||
@@ -80,7 +80,15 @@ sysPass.Triggers = function (Common) {
|
||||
*/
|
||||
var btnAction = function ($obj) {
|
||||
var onclick = $obj.data("onclick").split("/");
|
||||
var actions = Common.appActions();
|
||||
var actions;
|
||||
|
||||
var plugin = $obj.data("plugin");
|
||||
|
||||
if (typeof plugin !== "undefined") {
|
||||
actions = sysPass.Plugin[plugin](Common);
|
||||
} else {
|
||||
actions = Common.appActions();
|
||||
}
|
||||
|
||||
if (onclick.length === 2) {
|
||||
actions[onclick[0]][onclick[1]]($obj);
|
||||
|
||||
10
js/app-triggers.min.js
vendored
10
js/app-triggers.min.js
vendored
@@ -1,7 +1,7 @@
|
||||
var $jscomp={scope:{},findInternal:function(b,d,e){b instanceof String&&(b=String(b));for(var a=b.length,c=0;c<a;c++){var f=b[c];if(d.call(e,f,c,b))return{i:c,v:f}}return{i:-1,v:void 0}}};$jscomp.defineProperty="function"==typeof Object.defineProperties?Object.defineProperty:function(b,d,e){if(e.get||e.set)throw new TypeError("ES3 does not support getters and setters.");b!=Array.prototype&&b!=Object.prototype&&(b[d]=e.value)};
|
||||
$jscomp.getGlobal=function(b){return"undefined"!=typeof window&&window===b?b:"undefined"!=typeof global?global:b};$jscomp.global=$jscomp.getGlobal(this);$jscomp.polyfill=function(b,d,e,a){if(d){e=$jscomp.global;b=b.split(".");for(a=0;a<b.length-1;a++){var c=b[a];c in e||(e[c]={});e=e[c]}b=b[b.length-1];a=e[b];d=d(a);d!=a&&null!=d&&$jscomp.defineProperty(e,b,{configurable:!0,writable:!0,value:d})}};
|
||||
$jscomp.getGlobal=function(b){return"undefined"!=typeof window&&window===b?b:"undefined"!=typeof global&&null!=global?global:b};$jscomp.global=$jscomp.getGlobal(this);$jscomp.polyfill=function(b,d,e,a){if(d){e=$jscomp.global;b=b.split(".");for(a=0;a<b.length-1;a++){var c=b[a];c in e||(e[c]={});e=e[c]}b=b[b.length-1];a=e[b];d=d(a);d!=a&&null!=d&&$jscomp.defineProperty(e,b,{configurable:!0,writable:!0,value:d})}};
|
||||
$jscomp.polyfill("Array.prototype.find",function(b){return b?b:function(b,e){return $jscomp.findInternal(this,b,e).v}},"es6-impl","es3");
|
||||
sysPass.Triggers=function(b){var d=b.log,e=function(a){var c={valueField:"id",labelField:"name",searchField:["name"]};a.find(".select-box").each(function(a){var d=$(this);c.plugins=d.hasClass("select-box-deselect")?{clear_selection:{title:b.config().LANG[51]}}:{};if(d.data("onchange")){var f=d.data("onchange").split("/");c.onChange=function(a){if(0<a)if(2===f.length)sysPassApp.actions()[f[0]][f[1]](d);else sysPassApp.actions()[f[0]](d)}}d.selectize(c)});a.find("#allowed_exts").selectize({create:function(a){return{value:a.toUpperCase(),
|
||||
sysPass.Triggers=function(b){var d=b.log,e=function(a){var c={valueField:"id",labelField:"name",searchField:["name"]};a.find(".select-box").each(function(a){var f=$(this);c.plugins=f.hasClass("select-box-deselect")?{clear_selection:{title:b.config().LANG[51]}}:{};if(f.data("onchange")){var d=f.data("onchange").split("/");c.onChange=function(a){if(0<a)if(2===d.length)sysPassApp.actions()[d[0]][d[1]](f);else sysPassApp.actions()[d[0]](f)}}f.selectize(c)});a.find("#allowed_exts").selectize({create:function(a){return{value:a.toUpperCase(),
|
||||
text:a.toUpperCase()}},createFilter:/^[a-z0-9]{1,4}$/i,plugins:["remove_button"]});a.find("#wikifilter").selectize({create:!0,createFilter:/^[a-z0-9:._-]+$/i,plugins:["remove_button"]})};return{views:{main:function(){d.info("views:main");clipboard.isSupported()||b.msg.info(b.config().LANG[65]);$(".btn-menu").click(function(){var a=$(this);"1"===a.attr("data-history-reset")&&b.appRequests().history.reset();b.appActions().doAction({actionId:a.data("action-id")},a.data("view"))});$("#btnLogout").click(function(a){b.appActions().main.logout()});
|
||||
$("#btnPrefs").click(function(a){b.appActions().doAction({actionId:$(this).data("action-id")})});b.appActions().doAction({actionId:1},"search");"function"===typeof b.appTheme().viewsTriggers.main&&b.appTheme().viewsTriggers.main()},search:function(){d.info("views:search");var a=$("#frmSearch");0!==a.length&&(a.find("input[name='search']").on("keyup",function(b){b.preventDefault();13!==b.which&&13!==b.keyCode||a.submit()}),a.find("select, #rpp").on("change",function(){a.submit()}),a.find("button.btn-clear").on("click",
|
||||
function(b){b.preventDefault();a.find('input[name="searchfav"]').val(0);a[0].reset()}),a.find("input:text:visible:first").focus(),$("#globalSearch").click(function(){var b=1==$(this).prop("checked")?1:0;a.find("input[name='gsearch']").val(b);a.submit()}),"function"===typeof b.appTheme().viewsTriggers.search&&b.appTheme().viewsTriggers.search())},login:function(){d.info("views:login")},passreset:function(){d.info("views:passreset");var a=$("#frmPassReset");b.appTheme().passwordDetect(a)},footer:function(){d.info("views:footer")},
|
||||
@@ -9,6 +9,6 @@ common:function(a){d.info("views:common");e(a);"function"===typeof b.appTheme().
|
||||
c.beforeSendAction=function(){c.setRequestData({sk:b.sk.get(),csvDelimiter:$("#csvDelimiter").val(),importPwd:$("#importPwd").val(),importMasterPwd:$("#importMasterPwd").val(),import_defaultuser:$("#import_defaultuser").val(),import_defaultgroup:$("#import_defaultgroup").val()})}}},account:function(){d.info("views:account");var a=$("#list-account-files");0<a.length&&b.appActions().account.getfiles(a);var c=$("#drop-account-files");0<c.length&&(c=b.fileUpload(c),c.url=b.appActions().ajaxUrl.file,c.requestDoneAction=
|
||||
function(){b.appActions().account.getfiles(a)});c=$(".show-extra-info");if(0<c.length)c.on("click",function(){var a=$(this),b=$(a.data("target"));b.is(":hidden")?(b.slideDown("slow"),a.html(a.data("icon-up"))):(b.slideUp("slow"),a.html(a.data("icon-down")))});c=$("#selParentAccount");0<c.length&&(c.on("change",function(){var a=$(this),b=$("#accountpass,#accountpassR");0<a[0].value?b.each(function(){$(this).prop("disabled","true");$(this).prop("required","false")}):b.each(function(){$(this).prop("disabled",
|
||||
"");$(this).prop("required","true")})}),b.appActions().items.get(c))},install:function(){d.info("views:install");var a=$("#frmInstall");b.appTheme().passwordDetect(a);e(a)}},selectDetect:e,updateSk:function(){$("#content").find("[data-sk]").each(function(){d.info("updateSk");$(this).data("sk",b.sk.get())})},updateFormHash:function(a){d.info("updateFormHash");a=void 0!==a?a.find(".form-action[data-hash]"):$(".form-action[data-hash]");0<a.length&&a.each(function(){var a=$(this);a.attr("data-hash",SparkMD5.hash(a.serialize(),
|
||||
!1))})},bodyHooks:function(){d.info("bodyHooks");$("body").on("click",".btn-action[data-onclick],.btn-action-pager[data-onclick]",function(){var a=$(this),c=a.data("onclick").split("/"),d=b.appActions();if(2===c.length)d[c[0]][c[1]](a);else d[c[0]](a)}).on("click",".btn-back",function(){var a=b.appRequests();if(0<a.history.length()){d.info("back");var c=a.history.del();a.getActionCall(c,c.callback)}}).on("submit",".form-action",function(a){a.preventDefault();a=$(this);d.info("formAction");var c=a.attr("data-hash"),
|
||||
e=SparkMD5.hash(a.serialize(),!1);if(c===e)b.msg.ok(b.config().LANG[55]);else if(c=a.data("plugin"),c="undefined"!==typeof c?sysPass.Plugin[c](b):b.appActions(),e=a.data("onsubmit").split("/"),a.find("input[name='sk']").val(b.sk.get()),2===e.length)c[e[0]][e[1]](a);else c[e[0]](a)}).on("click",".btn-help",function(){var a=$(this),a=$("#"+a.data("help")).html();mdlDialog().show({title:b.config().LANG[54],text:a,positive:{title:b.config().LANG[43]}})}).on("reset",".form-action",function(a){a.preventDefault();
|
||||
d.info("reset");a=$(this);a.find("input:text, input:password, input:file, textarea").val("").parent("div").removeClass("is-dirty");a.find("input:radio, input:checkbox").prop("checked",!1).prop("selected",!1);a.find("input[name='start'], input[name='skey'], input[name='sorder']").val(0);a.find("select").each(function(){$(this)[0].selectize.clear(!0)});a.submit()}).on("click",".btn-popup-close",function(a){$.magnificPopup.close()})}}};
|
||||
!1))})},bodyHooks:function(){d.info("bodyHooks");$("body").on("click",".btn-action[data-onclick],.btn-action-pager[data-onclick]",function(){var a=$(this),c=a.data("onclick").split("/"),d;d=a.data("plugin");d="undefined"!==typeof d?sysPass.Plugin[d](b):b.appActions();if(2===c.length)d[c[0]][c[1]](a);else d[c[0]](a)}).on("click",".btn-back",function(){var a=b.appRequests();if(0<a.history.length()){d.info("back");var c=a.history.del();a.getActionCall(c,c.callback)}}).on("submit",".form-action",function(a){a.preventDefault();
|
||||
a=$(this);d.info("formAction");var c=a.attr("data-hash"),e=SparkMD5.hash(a.serialize(),!1);if(c===e)b.msg.ok(b.config().LANG[55]);else if(c=a.data("plugin"),c="undefined"!==typeof c?sysPass.Plugin[c](b):b.appActions(),e=a.data("onsubmit").split("/"),a.find("input[name='sk']").val(b.sk.get()),2===e.length)c[e[0]][e[1]](a);else c[e[0]](a)}).on("click",".btn-help",function(){var a=$(this),a=$("#"+a.data("help")).html();mdlDialog().show({title:b.config().LANG[54],text:a,positive:{title:b.config().LANG[43]}})}).on("reset",
|
||||
".form-action",function(a){a.preventDefault();d.info("reset");a=$(this);a.find("input:text, input:password, input:file, textarea").val("").parent("div").removeClass("is-dirty");a.find("input:radio, input:checkbox").prop("checked",!1).prop("selected",!1);a.find("input[name='start'], input[name='skey'], input[name='sorder']").val(0);a.find("select").each(function(){$(this)[0].selectize.clear(!0)});a.submit()}).on("click",".btn-popup-close",function(a){$.magnificPopup.close()})}}};
|
||||
|
||||
Reference in New Issue
Block a user