mirror of
https://github.com/nuxsmin/sysPass.git
synced 2026-03-13 03:46:58 +01:00
* [MOD] Config module. Work in progress
* [MOD] Improved import module. Work in progress
This commit is contained in:
@@ -63,7 +63,9 @@ class BootstrapController extends SimpleControllerBase
|
||||
'plugins' => [],
|
||||
'loggedin' => $this->session->isLoggedIn(),
|
||||
'authbasic_autologin' => Browser::getServerAuthUser() && $configData->isAuthBasicAutoLoginEnabled(),
|
||||
'pk' => $this->session->getPublicKey() ?: (new CryptPKI())->getPublicKey()
|
||||
'pk' => $this->session->getPublicKey() ?: (new CryptPKI())->getPublicKey(),
|
||||
'import_allowed_exts' => ['CSV', 'XML'],
|
||||
'files_allowed_exts' => $configData->getFilesAllowedExts()
|
||||
];
|
||||
|
||||
Response::printJson($data, 0);
|
||||
|
||||
74
app/modules/web/Controllers/ConfigImportController.php
Normal file
74
app/modules/web/Controllers/ConfigImportController.php
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* sysPass
|
||||
*
|
||||
* @author nuxsmin
|
||||
* @link http://syspass.org
|
||||
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
|
||||
*
|
||||
* This file is part of sysPass.
|
||||
*
|
||||
* sysPass is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* sysPass is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace SP\Modules\Web\Controllers;
|
||||
|
||||
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
use SP\Http\JsonResponse;
|
||||
use SP\Http\Request;
|
||||
use SP\Modules\Web\Controllers\Traits\JsonTrait;
|
||||
use SP\Services\Import\FileImport;
|
||||
use SP\Services\Import\ImportParams;
|
||||
use SP\Services\Import\ImportService;
|
||||
|
||||
/**
|
||||
* Class ConfigImportController
|
||||
*
|
||||
* @package SP\Modules\Web\Controllers
|
||||
*/
|
||||
class ConfigImportController extends SimpleControllerBase
|
||||
{
|
||||
use JsonTrait;
|
||||
|
||||
/**
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
public function importAction()
|
||||
{
|
||||
if ($this->config->getConfigData()->isDemoEnabled()) {
|
||||
$this->returnJsonResponse(JsonResponse::JSON_WARNING, __u('Ey, esto es una DEMO!!'));
|
||||
}
|
||||
|
||||
$importParams = new ImportParams();
|
||||
$importParams->setDefaultUser(Request::analyze('import_defaultuser', $this->session->getUserData()->getId()));
|
||||
$importParams->setDefaultGroup(Request::analyze('import_defaultgroup', $this->session->getUserData()->getUserGroupId()));
|
||||
$importParams->setImportPwd(Request::analyzeEncrypted('importPwd'));
|
||||
$importParams->setImportMasterPwd(Request::analyzeEncrypted('importMasterPwd'));
|
||||
$importParams->setCsvDelimiter(Request::analyze('csvDelimiter'));
|
||||
|
||||
try {
|
||||
$importService = $this->dic->get(ImportService::class);
|
||||
$importService->doImport($importParams, new FileImport($this->router->request()->files()->get('inFile')));
|
||||
|
||||
$this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Importación finalizada'), [__u('Revise el registro de eventos para más detalles')]);
|
||||
} catch (\Exception $e) {
|
||||
processException($e);
|
||||
|
||||
$this->returnJsonResponseException($e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -72,8 +72,8 @@
|
||||
<div class="lowres-title"><?php echo __('Archivo'); ?></div>
|
||||
|
||||
<div id="drop-import-files" class="round active-tooltip dropzone"
|
||||
data-files-ext="csv,xml"
|
||||
title="<?php echo __('Soltar archivo aquí o click para seleccionar'); ?>">
|
||||
title="<?php echo __('Soltar archivo aquí o click para seleccionar'); ?>"
|
||||
data-action-route="configImport/import">
|
||||
<i class="material-icons md-60 mdl-color-text--teal-500">cloud_upload</i>
|
||||
</div>
|
||||
<form method="post" enctype="multipart/form-data" name="upload_form" id="fileUploadForm">
|
||||
|
||||
@@ -26,8 +26,6 @@ namespace SP\Controller;
|
||||
|
||||
use SP\Account\AccountCrypt;
|
||||
use SP\Account\AccountHistoryCrypt;
|
||||
use SP\Config\Config;
|
||||
use SP\Config\ConfigData;
|
||||
use SP\Config\ConfigDB;
|
||||
use SP\Core\ActionsInterface;
|
||||
use SP\Core\Backup;
|
||||
@@ -43,15 +41,14 @@ use SP\Core\TaskFactory;
|
||||
use SP\Core\Traits\InjectableTrait;
|
||||
use SP\Core\XmlExport;
|
||||
use SP\Http\Request;
|
||||
use SP\Import\Import;
|
||||
use SP\Import\ImportParams;
|
||||
use SP\Log\Email;
|
||||
use SP\Log\Log;
|
||||
use SP\Mgmt\CustomFields\CustomFieldsUtil;
|
||||
use SP\Mgmt\Users\UserPass;
|
||||
use SP\Mgmt\Users\UserUtil;
|
||||
use SP\Services\Import\ImportParams;
|
||||
use SP\Services\Import\ImportService;
|
||||
use SP\Storage\DbWrapper;
|
||||
use SP\Util\Checks;
|
||||
use SP\Util\Json;
|
||||
use SP\Util\Util;
|
||||
|
||||
@@ -710,7 +707,7 @@ class ConfigActionController implements ItemControllerInterface
|
||||
$ImportParams->setImportMasterPwd(Request::analyzeEncrypted('importMasterPwd'));
|
||||
$ImportParams->setCsvDelimiter(Request::analyze('csvDelimiter'));
|
||||
|
||||
$Import = new Import($ImportParams);
|
||||
$Import = new ImportService($ImportParams);
|
||||
$LogMessage = $Import->doImport($_FILES['inFile']);
|
||||
|
||||
$this->JsonResponse->setDescription($LogMessage->getHtmlDescription(true));
|
||||
|
||||
@@ -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/>.
|
||||
*/
|
||||
|
||||
namespace SP\Import;
|
||||
|
||||
use SP\Core\Exceptions\SPException;
|
||||
use SP\DataModel\AccountExtData;
|
||||
use SP\DataModel\CategoryData;
|
||||
use SP\DataModel\ClientData;
|
||||
|
||||
defined('APP_ROOT') || die();
|
||||
|
||||
/**
|
||||
* Clase CsvImportBase para base de clases de importación desde archivos CSV
|
||||
*
|
||||
* @package SP
|
||||
*/
|
||||
abstract class CsvImportBase extends ImportBase
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $numFields = 7;
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $mapFields = [];
|
||||
|
||||
/**
|
||||
* @param int $numFields
|
||||
*/
|
||||
public function setNumFields($numFields)
|
||||
{
|
||||
$this->numFields = $numFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $mapFields
|
||||
*/
|
||||
public function setMapFields($mapFields)
|
||||
{
|
||||
$this->mapFields = $mapFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtener los datos de las entradas de sysPass y crearlas
|
||||
*
|
||||
* @throws SPException
|
||||
*/
|
||||
protected function processAccounts()
|
||||
{
|
||||
$line = 0;
|
||||
|
||||
foreach ($this->file->getFileContent() as $data) {
|
||||
$line++;
|
||||
$fields = str_getcsv($data, $this->ImportParams->getCsvDelimiter(), '"');
|
||||
$numfields = count($fields);
|
||||
|
||||
// Comprobar el número de campos de la línea
|
||||
if ($numfields !== $this->numFields) {
|
||||
throw new SPException(
|
||||
sprintf(__('El número de campos es incorrecto (%d)', false), $numfields), SPException::CRITICAL, sprintf(__('Compruebe el formato del archivo CSV en línea %s', false), $line)
|
||||
);
|
||||
}
|
||||
|
||||
// Asignar los valores del array a variables
|
||||
list($accountName, $customerName, $categoryName, $url, $login, $password, $notes) = $fields;
|
||||
|
||||
// Obtener los ids de cliente y categoría
|
||||
$CustomerData = new ClientData(null, $customerName);
|
||||
$this->addCustomer($CustomerData);
|
||||
$CategoryData = new CategoryData(null, $categoryName);
|
||||
$this->addCategory($CategoryData);
|
||||
|
||||
// Crear la nueva cuenta
|
||||
$AccountData = new AccountExtData();
|
||||
$AccountData->setName($accountName);
|
||||
$AccountData->setLogin($login);
|
||||
$AccountData->setClientId($CustomerData->getId());
|
||||
$AccountData->setCategoryId($CategoryData->getId());
|
||||
$AccountData->setNotes($notes);
|
||||
$AccountData->setUrl($url);
|
||||
$AccountData->setPass($password);
|
||||
|
||||
try {
|
||||
$this->addAccount($AccountData);
|
||||
} catch (SPException $e) {
|
||||
$this->LogMessage->addDetails(__('Error importando cuenta', false), $accountName);
|
||||
$this->LogMessage->addDetails(__('Error procesando línea', false), $line);
|
||||
$this->LogMessage->addDetails(__('Error', false), $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,119 +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 SP\Import;
|
||||
|
||||
use SP\Core\Exceptions\SPException;
|
||||
use SP\Core\Messages\LogMessage;
|
||||
use SP\Log\Email;
|
||||
use SP\Log\Log;
|
||||
use SP\Storage\DbWrapper;
|
||||
|
||||
defined('APP_ROOT') || die();
|
||||
|
||||
/**
|
||||
* Esta clase es la encargada de importar cuentas.
|
||||
*/
|
||||
class Import
|
||||
{
|
||||
/**
|
||||
* @var ImportParams Parámetros de importación
|
||||
*/
|
||||
protected $ImportParams;
|
||||
|
||||
/**
|
||||
* Import constructor.
|
||||
*
|
||||
* @param ImportParams $ImportParams
|
||||
*/
|
||||
public function __construct(ImportParams $ImportParams)
|
||||
{
|
||||
$this->ImportParams = $ImportParams;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iniciar la importación de cuentas.
|
||||
*
|
||||
* @param array $fileData Los datos del archivo
|
||||
* @return LogMessage
|
||||
* @throws SPException
|
||||
*/
|
||||
public function doImport(&$fileData)
|
||||
{
|
||||
set_time_limit(0);
|
||||
|
||||
$LogMessage = new LogMessage();
|
||||
$LogMessage->setAction(__('Importar Cuentas', false));
|
||||
$Log = new Log($LogMessage);
|
||||
|
||||
try {
|
||||
$file = new FileImport($fileData);
|
||||
|
||||
switch ($file->getFileType()) {
|
||||
case 'text/csv':
|
||||
case 'application/vnd.ms-excel':
|
||||
$Import = new CsvImport($file, $this->ImportParams, $LogMessage);
|
||||
break;
|
||||
case 'text/xml':
|
||||
$Import = new XmlImport($file, $this->ImportParams, $LogMessage);
|
||||
break;
|
||||
default:
|
||||
throw new SPException(
|
||||
sprintf(__('Tipo mime no soportado ("%s")'), $file->getFileType()), SPException::WARNING, __('Compruebe el formato del archivo', false)
|
||||
);
|
||||
}
|
||||
|
||||
if (!DbWrapper::beginTransaction()) {
|
||||
throw new SPException(__('No es posible iniciar una transacción', false), SPException::ERROR);
|
||||
}
|
||||
|
||||
$Import->doImport();
|
||||
|
||||
if (!DbWrapper::endTransaction()) {
|
||||
throw new SPException(__('No es posible finalizar una transacción', false), SPException::ERROR);
|
||||
}
|
||||
|
||||
$LogMessage->addDetails(__('Cuentas importadas'), $Import->getCounter());
|
||||
} catch (SPException $e) {
|
||||
DbWrapper::rollbackTransaction();
|
||||
|
||||
$LogMessage->addDescription($e->getMessage());
|
||||
$LogMessage->addDetails(__('Ayuda', false), $e->getHint());
|
||||
$Log->setLogLevel(Log::ERROR);
|
||||
$Log->writeLog();
|
||||
|
||||
throw $e;
|
||||
}
|
||||
|
||||
$Log->writeLog(true);
|
||||
|
||||
Email::sendEmail($LogMessage);
|
||||
|
||||
$LogMessage->addDescription(__('Importación finalizada', false));
|
||||
$LogMessage->addDescription(__('Revise el registro de eventos para más detalles', false));
|
||||
|
||||
return $LogMessage;
|
||||
}
|
||||
}
|
||||
@@ -1,258 +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 SP\Import;
|
||||
|
||||
use SP\Account\Account;
|
||||
use SP\Account\AccountTags;
|
||||
use SP\Core\Crypt\Crypt;
|
||||
use SP\Core\Exceptions\SPException;
|
||||
use SP\Core\Messages\LogMessage;
|
||||
use SP\Core\OldCrypt;
|
||||
use SP\DataModel\AccountExtData;
|
||||
use SP\DataModel\CategoryData;
|
||||
use SP\DataModel\ClientData;
|
||||
use SP\DataModel\TagData;
|
||||
use SP\Log\Log;
|
||||
use SP\Mgmt\Categories\Category;
|
||||
use SP\Mgmt\Customers\Customer;
|
||||
use SP\Mgmt\Tags\Tag;
|
||||
|
||||
defined('APP_ROOT') || die();
|
||||
|
||||
/**
|
||||
* Class ImportBase abstracta para manejo de archivos de importación
|
||||
*
|
||||
* @package SP
|
||||
*/
|
||||
abstract class ImportBase implements ImportInterface
|
||||
{
|
||||
/**
|
||||
* @var ImportParams
|
||||
*/
|
||||
protected $ImportParams;
|
||||
/**
|
||||
* @var FileImport
|
||||
*/
|
||||
protected $file;
|
||||
/**
|
||||
* @var LogMessage
|
||||
*/
|
||||
protected $LogMessage;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $counter = 0;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $version = 0;
|
||||
/**
|
||||
* @var bool Indica si el hash de la clave suministrada es igual a la actual
|
||||
*/
|
||||
protected $mPassValidHash = false;
|
||||
|
||||
/**
|
||||
* ImportBase constructor.
|
||||
*
|
||||
* @param FileImport $File
|
||||
* @param ImportParams $ImportParams
|
||||
* @param LogMessage $LogMessage
|
||||
*/
|
||||
public function __construct(FileImport $File = null, ImportParams $ImportParams = null, LogMessage $LogMessage = null)
|
||||
{
|
||||
$this->file = $File;
|
||||
$this->ImportParams = $ImportParams;
|
||||
$this->LogMessage = null !== $LogMessage ? $LogMessage : new LogMessage(__('Importar Cuentas', false));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return LogMessage
|
||||
*/
|
||||
public function getLogMessage()
|
||||
{
|
||||
return $this->LogMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param LogMessage $LogMessage
|
||||
*/
|
||||
public function setLogMessage($LogMessage)
|
||||
{
|
||||
$this->LogMessage = $LogMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getCounter()
|
||||
{
|
||||
return $this->counter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ImportParams $ImportParams
|
||||
*/
|
||||
public function setImportParams($ImportParams)
|
||||
{
|
||||
$this->ImportParams = $ImportParams;
|
||||
}
|
||||
|
||||
/**
|
||||
* Añadir una cuenta desde un archivo importado.
|
||||
*
|
||||
* @param \SP\DataModel\AccountExtData $AccountData
|
||||
* @return bool
|
||||
*/
|
||||
protected function addAccount(AccountExtData $AccountData)
|
||||
{
|
||||
if ($AccountData->getCategoryId() === 0) {
|
||||
Log::writeNewLog(__FUNCTION__, __('Id de categoría no definido. No es posible importar cuenta.', false), Log::INFO);
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($AccountData->getClientId() === 0) {
|
||||
Log::writeNewLog(__FUNCTION__, __('Id de cliente no definido. No es posible importar cuenta.', false), Log::INFO);
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
$AccountData->setUserId($this->ImportParams->getDefaultUser());
|
||||
$AccountData->setUserGroupId($this->ImportParams->getDefaultGroup());
|
||||
|
||||
if ($this->mPassValidHash === false && $this->ImportParams->getImportMasterPwd() !== '') {
|
||||
if ($this->version >= 210) {
|
||||
$securedKey = Crypt::unlockSecuredKey($AccountData->getKey(), $this->ImportParams->getImportMasterPwd());
|
||||
$pass = Crypt::decrypt($AccountData->getPass(), $securedKey, $this->ImportParams->getImportMasterPwd());
|
||||
} else {
|
||||
$pass = OldCrypt::getDecrypt($AccountData->getPass(), $AccountData->getKey(), $this->ImportParams->getImportMasterPwd());
|
||||
}
|
||||
|
||||
$AccountData->setPass($pass);
|
||||
$AccountData->setKey('');
|
||||
}
|
||||
|
||||
$encrypt = $AccountData->getKey() === '';
|
||||
|
||||
$Account = new Account($AccountData);
|
||||
$Account->createAccount($encrypt);
|
||||
|
||||
$this->LogMessage->addDetails(__('Cuenta creada', false), $AccountData->getName());
|
||||
$this->counter++;
|
||||
} catch (SPException $e) {
|
||||
$this->LogMessage->addDetails($e->getMessage(), $AccountData->getName());
|
||||
$this->LogMessage->addDetails(__('Error', false), $e->getHint());
|
||||
} catch (\Exception $e) {
|
||||
$this->LogMessage->addDetails(__('Error', false), $e->getMessage());
|
||||
$this->LogMessage->addDetails(__('Cuenta', false), $AccountData->getName());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Añadir una categoría y devolver el Id
|
||||
*
|
||||
* @param CategoryData $CategoryData
|
||||
* @return Category|null
|
||||
*/
|
||||
protected function addCategory(CategoryData $CategoryData)
|
||||
{
|
||||
try {
|
||||
$Category = Category::getItem($CategoryData)->add();
|
||||
|
||||
$this->LogMessage->addDetails(__('Categoría creada', false), $CategoryData->getName());
|
||||
|
||||
return $Category;
|
||||
} catch (SPException $e) {
|
||||
$this->LogMessage->addDetails($e->getMessage(), $CategoryData->name);
|
||||
$this->LogMessage->addDetails(__('Error', false), $e->getHint());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Añadir un cliente y devolver el Id
|
||||
*
|
||||
* @param ClientData $CustomerData
|
||||
* @return Customer|null
|
||||
*/
|
||||
protected function addCustomer(ClientData $CustomerData)
|
||||
{
|
||||
try {
|
||||
$Customer = Customer::getItem($CustomerData)->add();
|
||||
|
||||
$this->LogMessage->addDetails(__('Cliente creado', false), $CustomerData->getName());
|
||||
|
||||
return $Customer;
|
||||
} catch (SPException $e) {
|
||||
$this->LogMessage->addDetails($e->getMessage(), $CustomerData->getName());
|
||||
$this->LogMessage->addDetails(__('Error', false), $e->getHint());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Añadir una etiqueta y devolver el Id
|
||||
*
|
||||
* @param TagData $TagData
|
||||
* @return Tag|null
|
||||
*/
|
||||
protected function addTag(TagData $TagData)
|
||||
{
|
||||
try {
|
||||
$Tag = Tag::getItem($TagData)->add();
|
||||
|
||||
$this->LogMessage->addDetails(__('Etiqueta creada', false), $TagData->getName());
|
||||
|
||||
return $Tag;
|
||||
} catch (SPException $e) {
|
||||
$this->LogMessage->addDetails($e->getMessage(), $TagData->getName());
|
||||
$this->LogMessage->addDetails(__('Error', false), $e->getHint());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Añadir las etiquetas de la cuenta
|
||||
*
|
||||
* @param AccountExtData $accountExtData
|
||||
* @param array $tags
|
||||
*/
|
||||
protected function addAccountTags(AccountExtData $accountExtData, array $tags)
|
||||
{
|
||||
try {
|
||||
$accountExtData->setTags($tags);
|
||||
|
||||
$AccountTags = new AccountTags();
|
||||
$AccountTags->addTags($accountExtData);
|
||||
} catch (SPException $e) {
|
||||
$this->LogMessage->addDetails($e->getMessage(), $accountExtData->getName());
|
||||
$this->LogMessage->addDetails(__('Error', false), $e->getHint());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,337 +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 SP\Import;
|
||||
|
||||
use DOMXPath;
|
||||
use SP\Config\ConfigDB;
|
||||
use SP\Core\Crypt\Crypt;
|
||||
use SP\Core\Crypt\Hash;
|
||||
use SP\Core\Exceptions\SPException;
|
||||
use SP\Core\OldCrypt;
|
||||
use SP\DataModel\AccountExtData;
|
||||
use SP\DataModel\CategoryData;
|
||||
use SP\DataModel\ClientData;
|
||||
use SP\DataModel\TagData;
|
||||
|
||||
defined('APP_ROOT') || die();
|
||||
|
||||
/**
|
||||
* Esta clase es la encargada de importar cuentas desde sysPass
|
||||
*/
|
||||
class SyspassImport extends ImportBase
|
||||
{
|
||||
use XmlImportTrait;
|
||||
|
||||
/**
|
||||
* Mapeo de etiquetas
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $tags = [];
|
||||
/**
|
||||
* Mapeo de categorías.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $categories = [];
|
||||
/**
|
||||
* Mapeo de clientes.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $customers = [];
|
||||
|
||||
/**
|
||||
* Iniciar la importación desde sysPass.
|
||||
*
|
||||
* @throws SPException
|
||||
*/
|
||||
public function doImport()
|
||||
{
|
||||
try {
|
||||
if ($this->ImportParams->getImportMasterPwd() !== '') {
|
||||
$this->mPassValidHash = Hash::checkHashKey($this->ImportParams->getImportMasterPwd(), ConfigDB::getValue('masterPwd'));
|
||||
}
|
||||
|
||||
$this->getXmlVersion();
|
||||
|
||||
if ($this->detectEncrypted()) {
|
||||
if ($this->ImportParams->getImportPwd() === '') {
|
||||
throw new SPException(__('Clave de encriptación no indicada', false), SPException::ERROR);
|
||||
}
|
||||
|
||||
$this->processEncrypted();
|
||||
}
|
||||
|
||||
$this->processCategories();
|
||||
$this->processCustomers();
|
||||
$this->processTags();
|
||||
$this->processAccounts();
|
||||
} catch (SPException $e) {
|
||||
throw $e;
|
||||
} catch (\Exception $e) {
|
||||
throw new SPException($e->getMessage(), SPException::CRITICAL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtener la versión del XML
|
||||
*/
|
||||
protected function getXmlVersion()
|
||||
{
|
||||
$DomXpath = new DOMXPath($this->xmlDOM);
|
||||
$this->version = (int)str_replace('.', '', $DomXpath->query('/Root/Meta/Version')->item(0)->nodeValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verificar si existen datos encriptados
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function detectEncrypted()
|
||||
{
|
||||
return ($this->xmlDOM->getElementsByTagName('Encrypted')->length > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Procesar los datos encriptados y añadirlos al árbol DOM desencriptados
|
||||
*
|
||||
* @throws \SP\Core\Exceptions\SPException
|
||||
* @throws \Defuse\Crypto\Exception\CryptoException
|
||||
*/
|
||||
protected function processEncrypted()
|
||||
{
|
||||
$hash = $this->xmlDOM->getElementsByTagName('Encrypted')->item(0)->getAttribute('hash');
|
||||
|
||||
if ($hash !== '' && !Hash::checkHashKey($this->ImportParams->getImportPwd(), $hash)) {
|
||||
throw new SPException(__('Clave de encriptación incorrecta', false), SPException::ERROR);
|
||||
}
|
||||
|
||||
foreach ($this->xmlDOM->getElementsByTagName('Data') as $node) {
|
||||
/** @var $node \DOMElement */
|
||||
$data = base64_decode($node->nodeValue);
|
||||
|
||||
if ($this->version >= 210) {
|
||||
$securedKey = Crypt::unlockSecuredKey($node->getAttribute('key'), $this->ImportParams->getImportPwd());
|
||||
$xmlDecrypted = Crypt::decrypt($data, $securedKey, $this->ImportParams->getImportPwd());
|
||||
} else {
|
||||
$xmlDecrypted = OldCrypt::getDecrypt($data, base64_decode($node->getAttribute('iv'), $this->ImportParams->getImportPwd()));
|
||||
}
|
||||
|
||||
$newXmlData = new \DOMDocument();
|
||||
// $newXmlData->preserveWhiteSpace = true;
|
||||
if (!$newXmlData->loadXML($xmlDecrypted)) {
|
||||
throw new SPException(__('Clave de encriptación incorrecta', false), SPException::ERROR);
|
||||
}
|
||||
|
||||
$newNode = $this->xmlDOM->importNode($newXmlData->documentElement, TRUE);
|
||||
|
||||
$this->xmlDOM->documentElement->appendChild($newNode);
|
||||
}
|
||||
|
||||
// Eliminar los datos encriptados tras desencriptar los mismos
|
||||
if ($this->xmlDOM->getElementsByTagName('Data')->length > 0) {
|
||||
$nodeData = $this->xmlDOM->getElementsByTagName('Encrypted')->item(0);
|
||||
$nodeData->parentNode->removeChild($nodeData);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtener las categorías y añadirlas a sysPass.
|
||||
*
|
||||
* @param \DOMElement $Category
|
||||
* @throws SPException
|
||||
* @throws \SP\Core\Exceptions\InvalidClassException
|
||||
*/
|
||||
protected function processCategories(\DOMElement $Category = null)
|
||||
{
|
||||
if ($Category === null) {
|
||||
$this->getNodesData('Categories', 'Category', __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
$CategoryData = new CategoryData();
|
||||
|
||||
foreach ($Category->childNodes as $categoryNode) {
|
||||
if (isset($categoryNode->tagName)) {
|
||||
switch ($categoryNode->tagName) {
|
||||
case 'name':
|
||||
$CategoryData->setName($categoryNode->nodeValue);
|
||||
break;
|
||||
case 'description':
|
||||
$CategoryData->setDescription($categoryNode->nodeValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->addCategory($CategoryData);
|
||||
|
||||
$this->categories[$Category->getAttribute('id')] = $CategoryData->getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtener los clientes y añadirlos a sysPass.
|
||||
*
|
||||
* @param \DOMElement $Customer
|
||||
* @throws SPException
|
||||
* @throws \SP\Core\Exceptions\InvalidClassException
|
||||
*/
|
||||
protected function processCustomers(\DOMElement $Customer = null)
|
||||
{
|
||||
if ($Customer === null) {
|
||||
$this->getNodesData('Customers', 'Customer', __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
$CustomerData = new ClientData();
|
||||
|
||||
foreach ($Customer->childNodes as $customerNode) {
|
||||
if (isset($customerNode->tagName)) {
|
||||
switch ($customerNode->tagName) {
|
||||
case 'name':
|
||||
$CustomerData->setName($customerNode->nodeValue);
|
||||
break;
|
||||
case 'description':
|
||||
$CustomerData->setDescription($customerNode->nodeValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->addCustomer($CustomerData);
|
||||
|
||||
$this->customers[$Customer->getAttribute('id')] = $CustomerData->getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtener las etiquetas y añadirlas a sysPass.
|
||||
*
|
||||
* @param \DOMElement $Tag
|
||||
* @throws SPException
|
||||
* @throws \SP\Core\Exceptions\InvalidClassException
|
||||
*/
|
||||
protected function processTags(\DOMElement $Tag = null)
|
||||
{
|
||||
if ($Tag === null) {
|
||||
$this->getNodesData('Tags', 'Tag', __FUNCTION__, false);
|
||||
return;
|
||||
}
|
||||
|
||||
$TagData = new TagData();
|
||||
|
||||
foreach ($Tag->childNodes as $tagNode) {
|
||||
if (isset($tagNode->tagName)) {
|
||||
switch ($tagNode->tagName) {
|
||||
case 'name':
|
||||
$TagData->setName($tagNode->nodeValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->addTag($TagData);
|
||||
|
||||
$this->tags[$Tag->getAttribute('id')] = $TagData->getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtener los datos de las cuentas de sysPass y crearlas.
|
||||
*
|
||||
* @param \DOMElement $Account
|
||||
* @throws SPException
|
||||
*/
|
||||
protected function processAccounts(\DOMElement $Account = null)
|
||||
{
|
||||
if ($Account === null) {
|
||||
$this->getNodesData('Accounts', 'Account', __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
$AccountData = new AccountExtData();
|
||||
|
||||
/** @var \DOMElement $accountNode */
|
||||
foreach ($Account->childNodes as $accountNode) {
|
||||
if (isset($accountNode->tagName)) {
|
||||
switch ($accountNode->tagName) {
|
||||
case 'name';
|
||||
$AccountData->setName($accountNode->nodeValue);
|
||||
break;
|
||||
case 'login';
|
||||
$AccountData->setLogin($accountNode->nodeValue);
|
||||
break;
|
||||
case 'categoryId';
|
||||
$AccountData->setCategoryId($this->categories[(int)$accountNode->nodeValue]);
|
||||
break;
|
||||
case 'customerId';
|
||||
$AccountData->setClientId($this->customers[(int)$accountNode->nodeValue]);
|
||||
break;
|
||||
case 'url';
|
||||
$AccountData->setUrl($accountNode->nodeValue);
|
||||
break;
|
||||
case 'pass';
|
||||
$AccountData->setPass($accountNode->nodeValue);
|
||||
break;
|
||||
case 'key';
|
||||
$AccountData->setKey($accountNode->nodeValue);
|
||||
break;
|
||||
case 'notes';
|
||||
$AccountData->setNotes($accountNode->nodeValue);
|
||||
break;
|
||||
case 'tags':
|
||||
$tags = $this->processAccountTags($accountNode->childNodes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->addAccount($AccountData);
|
||||
|
||||
if (isset($tags) && count($tags)) {
|
||||
$this->addAccountTags($AccountData, $tags);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Procesar las etiquetas de la cuenta
|
||||
*
|
||||
* @param \DOMNodeList $nodes
|
||||
* @return array
|
||||
*/
|
||||
protected function processAccountTags(\DOMNodeList $nodes)
|
||||
{
|
||||
$tags = [];
|
||||
|
||||
if ($nodes->length > 0) {
|
||||
/** @var \DOMElement $accountTagNode */
|
||||
foreach ($nodes as $accountTagNode) {
|
||||
if (isset($accountTagNode->tagName)) {
|
||||
$tags[] = $accountTagNode->getAttribute('id');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $tags;
|
||||
}
|
||||
}
|
||||
@@ -48,8 +48,6 @@ class CategoryRepository extends Repository implements RepositoryItemInterface
|
||||
* @param CategoryData $itemData
|
||||
* @return mixed
|
||||
* @throws SPException
|
||||
* @throws \SP\Core\Exceptions\ConstraintException
|
||||
* @throws \SP\Core\Exceptions\QueryException
|
||||
*/
|
||||
public function create($itemData)
|
||||
{
|
||||
|
||||
@@ -93,8 +93,6 @@ class CategoryService extends Service
|
||||
* @param $itemData
|
||||
* @return mixed
|
||||
* @throws SPException
|
||||
* @throws \SP\Core\Exceptions\ConstraintException
|
||||
* @throws \SP\Core\Exceptions\QueryException
|
||||
*/
|
||||
public function create($itemData)
|
||||
{
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
/**
|
||||
* sysPass
|
||||
*
|
||||
* @author nuxsmin
|
||||
* @link http://syspass.org
|
||||
* @author nuxsmin
|
||||
* @link http://syspass.org
|
||||
* @copyright 2012-2017, Rubén Domínguez nuxsmin@$syspass.org
|
||||
*
|
||||
* This file is part of sysPass.
|
||||
@@ -22,9 +22,7 @@
|
||||
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace SP\Import;
|
||||
|
||||
use SP\Core\Exceptions\SPException;
|
||||
namespace SP\Services\Import;
|
||||
|
||||
defined('APP_ROOT') || die();
|
||||
|
||||
@@ -33,7 +31,7 @@ defined('APP_ROOT') || die();
|
||||
*
|
||||
* @package SP
|
||||
*/
|
||||
class CsvImport extends CsvImportBase
|
||||
class CsvImport extends CsvImportBase implements ImportInterface
|
||||
{
|
||||
/**
|
||||
* Iniciar la importación desde XML.
|
||||
@@ -42,13 +40,10 @@ class CsvImport extends CsvImportBase
|
||||
*/
|
||||
public function doImport()
|
||||
{
|
||||
try {
|
||||
$this->LogMessage->addDescription(sprintf(__('Formato detectado: %s'), 'CSV'));
|
||||
// $this->LogMessage->addDescription(sprintf(__('Formato detectado: %s'), 'CSV'));
|
||||
$this->fileImport->readFileToArray();
|
||||
$this->processAccounts();
|
||||
|
||||
$this->file->readFileToArray();
|
||||
$this->processAccounts();
|
||||
} catch (SPException $e) {
|
||||
throw $e;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
149
lib/SP/Services/Import/CsvImportBase.php
Normal file
149
lib/SP/Services/Import/CsvImportBase.php
Normal file
@@ -0,0 +1,149 @@
|
||||
<?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 SP\Services\Import;
|
||||
|
||||
use SP\Account\AccountRequest;
|
||||
use SP\Bootstrap;
|
||||
use SP\DataModel\CategoryData;
|
||||
use SP\DataModel\ClientData;
|
||||
use SP\Services\Account\AccountService;
|
||||
use SP\Services\Category\CategoryService;
|
||||
use SP\Services\Client\ClientService;
|
||||
use SP\Services\Tag\TagService;
|
||||
|
||||
defined('APP_ROOT') || die();
|
||||
|
||||
/**
|
||||
* Clase CsvImportBase para base de clases de importación desde archivos CSV
|
||||
*
|
||||
* @package SP
|
||||
*/
|
||||
abstract class CsvImportBase
|
||||
{
|
||||
use ImportTrait;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $numFields = 7;
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $mapFields = [];
|
||||
/**
|
||||
* @var FileImport
|
||||
*/
|
||||
protected $fileImport;
|
||||
|
||||
/**
|
||||
* ImportBase constructor.
|
||||
*
|
||||
* @param FileImport $fileImport
|
||||
* @param ImportParams $importParams
|
||||
* @throws \Psr\Container\ContainerExceptionInterface
|
||||
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||
*/
|
||||
public function __construct(FileImport $fileImport, ImportParams $importParams)
|
||||
{
|
||||
$this->fileImport = $fileImport;
|
||||
$this->importParams = $importParams;
|
||||
|
||||
$dic = Bootstrap::getContainer();
|
||||
$this->accountService = $dic->get(AccountService::class);
|
||||
$this->categoryService = $dic->get(CategoryService::class);
|
||||
$this->clientService = $dic->get(ClientService::class);
|
||||
$this->tagService = $dic->get(TagService::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $numFields
|
||||
*/
|
||||
public function setNumFields($numFields)
|
||||
{
|
||||
$this->numFields = $numFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $mapFields
|
||||
*/
|
||||
public function setMapFields($mapFields)
|
||||
{
|
||||
$this->mapFields = $mapFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtener los datos de las entradas de sysPass y crearlas
|
||||
*
|
||||
* @throws ImportException
|
||||
*/
|
||||
protected function processAccounts()
|
||||
{
|
||||
$line = 0;
|
||||
|
||||
foreach ($this->fileImport->getFileContent() as $data) {
|
||||
$line++;
|
||||
$fields = str_getcsv($data, $this->importParams->getCsvDelimiter(), '"');
|
||||
$numfields = count($fields);
|
||||
|
||||
// Comprobar el número de campos de la línea
|
||||
if ($numfields !== $this->numFields) {
|
||||
throw new ImportException(
|
||||
sprintf(__('El número de campos es incorrecto (%d)'), $numfields),
|
||||
ImportException::ERROR,
|
||||
sprintf(__('Compruebe el formato del archivo CSV en línea %s'), $line)
|
||||
);
|
||||
}
|
||||
|
||||
// Asignar los valores del array a variables
|
||||
list($accountName, $clientName, $categoryName, $url, $login, $password, $notes) = $fields;
|
||||
|
||||
try {
|
||||
// Obtener los ids de cliente y categoría
|
||||
$clientData = new ClientData(null, $clientName);
|
||||
$this->addClient($clientData);
|
||||
|
||||
$categoryData = new CategoryData(null, $categoryName);
|
||||
$this->addCategory($categoryData);
|
||||
|
||||
// Crear la nueva cuenta
|
||||
$accountRequest = new AccountRequest();
|
||||
$accountRequest->name = $accountName;
|
||||
$accountRequest->login = $login;
|
||||
$accountRequest->clientId = $clientData->getId();
|
||||
$accountRequest->categoryId = $categoryData->getId();
|
||||
$accountRequest->notes = $notes;
|
||||
$accountRequest->url = $url;
|
||||
$accountRequest->pass = $password;
|
||||
|
||||
$this->addAccount($accountRequest);
|
||||
} catch (\Exception $e) {
|
||||
processException($e);
|
||||
// $this->LogMessage->addDetails(__('Error importando cuenta', false), $accountName);
|
||||
// $this->LogMessage->addDetails(__('Error procesando línea', false), $line);
|
||||
// $this->LogMessage->addDetails(__('Error', false), $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@
|
||||
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace SP\Import;
|
||||
namespace SP\Services\Import;
|
||||
|
||||
use SP\Core\Exceptions\SPException;
|
||||
use SP\Util\Util;
|
||||
@@ -63,7 +63,7 @@ class FileImport
|
||||
* @param array $fileData Datos del archivo a importar
|
||||
* @throws SPException
|
||||
*/
|
||||
public function __construct(&$fileData)
|
||||
public function __construct($fileData)
|
||||
{
|
||||
try {
|
||||
$this->checkFile($fileData);
|
||||
@@ -78,11 +78,14 @@ class FileImport
|
||||
* @param array $fileData con los datos del archivo
|
||||
* @throws SPException
|
||||
*/
|
||||
private function checkFile(&$fileData)
|
||||
private function checkFile($fileData)
|
||||
{
|
||||
if (!is_array($fileData)) {
|
||||
throw new SPException(
|
||||
__('Archivo no subido correctamente', false), SPException::CRITICAL, __('Verifique los permisos del usuario del servidor web', false));
|
||||
__u('Archivo no subido correctamente'),
|
||||
SPException::ERROR,
|
||||
__u('Verifique los permisos del usuario del servidor web')
|
||||
);
|
||||
}
|
||||
|
||||
if ($fileData['name']) {
|
||||
@@ -91,7 +94,9 @@ class FileImport
|
||||
|
||||
if ($fileExtension !== 'CSV' && $fileExtension !== 'XML') {
|
||||
throw new SPException(
|
||||
__('Tipo de archivo no soportado', false), SPException::CRITICAL, __('Compruebe la extensión del archivo', false)
|
||||
__u('Tipo de archivo no soportado'),
|
||||
SPException::ERROR,
|
||||
__u('Compruebe la extensión del archivo')
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -105,7 +110,9 @@ class FileImport
|
||||
Util::getMaxUpload();
|
||||
|
||||
throw new SPException(
|
||||
__('Error interno al leer el archivo', false), SPException::CRITICAL, __('Compruebe la configuración de PHP para subir archivos', false)
|
||||
__u('Error interno al leer el archivo'),
|
||||
SPException::ERROR,
|
||||
__u('Compruebe la configuración de PHP para subir archivos')
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -147,7 +154,9 @@ class FileImport
|
||||
|
||||
if ($this->fileContent === false) {
|
||||
throw new SPException(
|
||||
__('Error interno al leer el archivo', false), SPException::CRITICAL, __('Compruebe los permisos del directorio temporal', false)
|
||||
__u('Error interno al leer el archivo'),
|
||||
SPException::ERROR,
|
||||
__u('Compruebe los permisos del directorio temporal')
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -173,7 +182,9 @@ class FileImport
|
||||
|
||||
if ($this->fileContent === false) {
|
||||
throw new SPException(
|
||||
__('Error interno al leer el archivo', false), SPException::CRITICAL, __('Compruebe los permisos del directorio temporal', false)
|
||||
__u('Error interno al leer el archivo'),
|
||||
SPException::ERROR,
|
||||
__u('Compruebe los permisos del directorio temporal')
|
||||
);
|
||||
}
|
||||
}
|
||||
37
lib/SP/Services/Import/ImportException.php
Normal file
37
lib/SP/Services/Import/ImportException.php
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
/**
|
||||
* sysPass
|
||||
*
|
||||
* @author nuxsmin
|
||||
* @link http://syspass.org
|
||||
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
|
||||
*
|
||||
* This file is part of sysPass.
|
||||
*
|
||||
* sysPass is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* sysPass is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace SP\Services\Import;
|
||||
|
||||
use SP\Core\Exceptions\SPException;
|
||||
|
||||
/**
|
||||
* Class ImportException
|
||||
*
|
||||
* @package SP\Services\Import
|
||||
*/
|
||||
class ImportException extends SPException
|
||||
{
|
||||
|
||||
}
|
||||
@@ -22,7 +22,7 @@
|
||||
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace SP\Import;
|
||||
namespace SP\Services\Import;
|
||||
|
||||
/**
|
||||
* Interface ImportInterface
|
||||
@@ -33,6 +33,8 @@ interface ImportInterface
|
||||
{
|
||||
/**
|
||||
* Iniciar la importación
|
||||
*
|
||||
* @return ImportInterface
|
||||
*/
|
||||
public function doImport();
|
||||
|
||||
@@ -22,13 +22,13 @@
|
||||
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace SP\Import;
|
||||
namespace SP\Services\Import;
|
||||
|
||||
|
||||
/**
|
||||
* Class ImportParams
|
||||
*
|
||||
* @package SP\Import
|
||||
* @package SP\Services\Import
|
||||
*/
|
||||
class ImportParams
|
||||
{
|
||||
131
lib/SP/Services/Import/ImportService.php
Normal file
131
lib/SP/Services/Import/ImportService.php
Normal file
@@ -0,0 +1,131 @@
|
||||
<?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 SP\Services\Import;
|
||||
|
||||
use SP\Services\Service;
|
||||
use SP\Storage\Database;
|
||||
use SP\Storage\DbWrapper;
|
||||
|
||||
defined('APP_ROOT') || die();
|
||||
|
||||
/**
|
||||
* Esta clase es la encargada de importar cuentas.
|
||||
*/
|
||||
class ImportService extends Service
|
||||
{
|
||||
/**
|
||||
* @var ImportParams
|
||||
*/
|
||||
protected $importParams;
|
||||
/**
|
||||
* @var FileImport
|
||||
*/
|
||||
protected $fileImport;
|
||||
|
||||
/**
|
||||
* Iniciar la importación de cuentas.
|
||||
*
|
||||
* @param ImportParams $importParams
|
||||
* @param FileImport $fileImport
|
||||
* @throws \Exception
|
||||
* @throws \Psr\Container\ContainerExceptionInterface
|
||||
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||
*/
|
||||
public function doImport(ImportParams $importParams, FileImport $fileImport)
|
||||
{
|
||||
$this->importParams = $importParams;
|
||||
$this->fileImport = $fileImport;
|
||||
|
||||
// $LogMessage->setAction(__('Importar Cuentas', false));
|
||||
|
||||
$import = $this->selectImportType();
|
||||
|
||||
$db = $this->dic->get(Database::class);
|
||||
|
||||
try {
|
||||
if (!DbWrapper::beginTransaction($db)) {
|
||||
throw new ImportException(__u('No es posible iniciar una transacción'));
|
||||
}
|
||||
|
||||
$import->doImport();
|
||||
|
||||
if (!DbWrapper::endTransaction($db)) {
|
||||
throw new ImportException(__u('No es posible finalizar una transacción'));
|
||||
}
|
||||
|
||||
// $LogMessage->addDetails(__('Cuentas importadas'), $Import->getCounter());
|
||||
} catch (\Exception $e) {
|
||||
if (DbWrapper::rollbackTransaction($db)) {
|
||||
debugLog('Rollback');
|
||||
}
|
||||
|
||||
// $LogMessage->addDescription($e->getMessage());
|
||||
// $LogMessage->addDetails(__('Ayuda', false), $e->getHint());
|
||||
// $Log->setLogLevel(Log::ERROR);
|
||||
// $Log->writeLog();
|
||||
|
||||
throw $e;
|
||||
}
|
||||
|
||||
|
||||
// $LogMessage->addDescription(__('Importación finalizada', false));
|
||||
// $LogMessage->addDescription(__('Revise el registro de eventos para más detalles', false));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ImportInterface
|
||||
* @throws ImportException
|
||||
* @throws \Psr\Container\ContainerExceptionInterface
|
||||
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||
*/
|
||||
protected function selectImportType()
|
||||
{
|
||||
switch ($this->fileImport->getFileType()) {
|
||||
case 'text/csv':
|
||||
case 'application/vnd.ms-excel':
|
||||
return new CsvImport($this->fileImport, $this->importParams);
|
||||
break;
|
||||
case 'text/xml':
|
||||
return new XmlImport(new XmlFileImport($this->fileImport), $this->importParams);
|
||||
break;
|
||||
}
|
||||
|
||||
throw new ImportException(
|
||||
sprintf(__('Tipo mime no soportado ("%s")'), $this->fileImport->getFileType()),
|
||||
ImportException::ERROR,
|
||||
__u('Compruebe el formato del archivo')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Psr\Container\ContainerExceptionInterface
|
||||
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||
*/
|
||||
protected function initialize()
|
||||
{
|
||||
set_time_limit(0);
|
||||
}
|
||||
}
|
||||
164
lib/SP/Services/Import/ImportTrait.php
Normal file
164
lib/SP/Services/Import/ImportTrait.php
Normal file
@@ -0,0 +1,164 @@
|
||||
<?php
|
||||
/**
|
||||
* sysPass
|
||||
*
|
||||
* @author nuxsmin
|
||||
* @link http://syspass.org
|
||||
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
|
||||
*
|
||||
* This file is part of sysPass.
|
||||
*
|
||||
* sysPass is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* sysPass is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace SP\Services\Import;
|
||||
|
||||
use SP\Account\AccountRequest;
|
||||
use SP\Core\Crypt\Crypt;
|
||||
use SP\Core\Exceptions\SPException;
|
||||
use SP\Core\OldCrypt;
|
||||
use SP\DataModel\CategoryData;
|
||||
use SP\DataModel\ClientData;
|
||||
use SP\DataModel\TagData;
|
||||
use SP\Services\Account\AccountService;
|
||||
use SP\Services\Category\CategoryService;
|
||||
use SP\Services\Client\ClientService;
|
||||
use SP\Services\Tag\TagService;
|
||||
|
||||
/**
|
||||
* Trait ImportTrait
|
||||
*
|
||||
* @package SP\Services\Import
|
||||
*/
|
||||
trait ImportTrait
|
||||
{
|
||||
/**
|
||||
* @var ImportParams
|
||||
*/
|
||||
protected $importParams;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $version = 0;
|
||||
/**
|
||||
* @var bool Indica si el hash de la clave suministrada es igual a la actual
|
||||
*/
|
||||
protected $mPassValidHash = false;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $counter = 0;
|
||||
/**
|
||||
* @var AccountService
|
||||
*/
|
||||
private $accountService;
|
||||
/**
|
||||
* @var CategoryService
|
||||
*/
|
||||
private $categoryService;
|
||||
/**
|
||||
* @var ClientService
|
||||
*/
|
||||
private $clientService;
|
||||
/**
|
||||
* @var TagService
|
||||
*/
|
||||
private $tagService;
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getCounter()
|
||||
{
|
||||
return $this->counter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Añadir una cuenta desde un archivo importado.
|
||||
*
|
||||
* @param AccountRequest $accountRequest
|
||||
* @throws ImportException
|
||||
* @throws SPException
|
||||
* @throws \Defuse\Crypto\Exception\CryptoException
|
||||
* @throws \SP\Core\Dic\ContainerException
|
||||
* @throws \SP\Core\Exceptions\ConstraintException
|
||||
* @throws \SP\Core\Exceptions\QueryException
|
||||
*/
|
||||
protected function addAccount(AccountRequest $accountRequest)
|
||||
{
|
||||
if ($accountRequest->categoryId === 0) {
|
||||
throw new ImportException(__u('Id de categoría no definido. No es posible importar cuenta.'));
|
||||
}
|
||||
|
||||
if ($accountRequest->clientId === 0) {
|
||||
throw new ImportException(__u('Id de cliente no definido. No es posible importar cuenta.'));
|
||||
}
|
||||
|
||||
$accountRequest->userId = $this->importParams->getDefaultUser();
|
||||
$accountRequest->userGroupId = $this->importParams->getDefaultGroup();
|
||||
|
||||
if ($this->mPassValidHash === false && $this->importParams->getImportMasterPwd() !== '') {
|
||||
if ($this->version >= 210) {
|
||||
$securedKey = Crypt::unlockSecuredKey($accountRequest->key, $this->importParams->getImportMasterPwd());
|
||||
$pass = Crypt::decrypt($accountRequest->pass, $securedKey, $this->importParams->getImportMasterPwd());
|
||||
} else {
|
||||
$pass = OldCrypt::getDecrypt($accountRequest->pass, $accountRequest->key, $this->importParams->getImportMasterPwd());
|
||||
}
|
||||
|
||||
$accountRequest->pass = $pass;
|
||||
$accountRequest->key = '';
|
||||
}
|
||||
|
||||
$this->accountService->create($accountRequest);
|
||||
|
||||
// $this->LogMessage->addDetails(__('Cuenta creada', false), $accountRequest->name);
|
||||
$this->counter++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Añadir una categoría y devolver el Id
|
||||
*
|
||||
* @param CategoryData $categoryData
|
||||
* @return int
|
||||
* @throws SPException
|
||||
*/
|
||||
protected function addCategory(CategoryData $categoryData)
|
||||
{
|
||||
return $this->categoryService->create($categoryData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Añadir un cliente y devolver el Id
|
||||
*
|
||||
* @param ClientData $clientData
|
||||
* @return int
|
||||
* @throws SPException
|
||||
*/
|
||||
protected function addClient(ClientData $clientData)
|
||||
{
|
||||
return $this->clientService->create($clientData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Añadir una etiqueta y devolver el Id
|
||||
*
|
||||
* @param TagData $tagData
|
||||
* @return int
|
||||
* @throws SPException
|
||||
*/
|
||||
protected function addTag(TagData $tagData)
|
||||
{
|
||||
return $this->tagService->create($tagData);
|
||||
}
|
||||
}
|
||||
@@ -22,11 +22,11 @@
|
||||
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace SP\Import;
|
||||
namespace SP\Services\Import;
|
||||
|
||||
use DOMElement;
|
||||
use DOMXPath;
|
||||
use SP\DataModel\AccountExtData;
|
||||
use SP\Account\AccountRequest;
|
||||
use SP\DataModel\CategoryData;
|
||||
use SP\DataModel\ClientData;
|
||||
|
||||
@@ -35,53 +35,51 @@ defined('APP_ROOT') || die();
|
||||
/**
|
||||
* Esta clase es la encargada de importar cuentas desde KeePass
|
||||
*/
|
||||
class KeepassImport extends ImportBase
|
||||
class KeepassImport extends XmlImportBase implements ImportInterface
|
||||
{
|
||||
use XmlImportTrait;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $customerId = 0;
|
||||
|
||||
/**
|
||||
* Iniciar la importación desde KeePass
|
||||
*
|
||||
* @throws \SP\Core\Exceptions\SPException
|
||||
* @throws \SP\Core\Exceptions\InvalidClassException
|
||||
* @return ImportInterface
|
||||
*/
|
||||
public function doImport()
|
||||
{
|
||||
$customerData = new ClientData(null, 'KeePass');
|
||||
$this->addCustomer($customerData);
|
||||
|
||||
$this->customerId = $customerData->getId();
|
||||
|
||||
$this->process();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtener los grupos y procesar lan entradas de KeePass.
|
||||
*
|
||||
* @throws \SP\Core\Exceptions\SPException
|
||||
*/
|
||||
protected function process()
|
||||
{
|
||||
$clientId = $this->addClient(new ClientData(null, 'KeePass'));
|
||||
|
||||
foreach ($this->getItems() as $group => $entry) {
|
||||
$CategoryData = new CategoryData(null, $group);
|
||||
$this->addCategory($CategoryData);
|
||||
try {
|
||||
$categoryData = new CategoryData(null, $group);
|
||||
$this->addCategory($categoryData);
|
||||
|
||||
if (count($entry) > 0) {
|
||||
foreach ($entry as $account) {
|
||||
$AccountData = new AccountExtData();
|
||||
$AccountData->setNotes($account['Notes']);
|
||||
$AccountData->setPass($account['Password']);
|
||||
$AccountData->setName($account['Title']);
|
||||
$AccountData->setUrl($account['URL']);
|
||||
$AccountData->setLogin($account['UserName']);
|
||||
$AccountData->setCategoryId($CategoryData->getId());
|
||||
$AccountData->setClientId($this->customerId);
|
||||
if (count($entry) > 0) {
|
||||
foreach ($entry as $account) {
|
||||
$accountRequest = new AccountRequest();
|
||||
$accountRequest->notes = $account['Notes'];
|
||||
$accountRequest->pass = $account['Password'];
|
||||
$accountRequest->name = $account['Title'];
|
||||
$accountRequest->url = $account['URL'];
|
||||
$accountRequest->login = $account['UserName'];
|
||||
$accountRequest->categoryId = $categoryData->getId();
|
||||
$accountRequest->clientId = $clientId;
|
||||
|
||||
$this->addAccount($AccountData);
|
||||
$this->addAccount($accountRequest);
|
||||
}
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
processException($e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -94,11 +92,11 @@ class KeepassImport extends ImportBase
|
||||
protected function getItems()
|
||||
{
|
||||
$DomXpath = new DOMXPath($this->xmlDOM);
|
||||
$Tags = $DomXpath->query('/KeePassFile/Root/Group//Group|/KeePassFile/Root/Group//Entry');
|
||||
$tags = $DomXpath->query('/KeePassFile/Root/Group//Group|/KeePassFile/Root/Group//Entry');
|
||||
$items = [];
|
||||
|
||||
/** @var DOMElement[] $Tags */
|
||||
foreach ($Tags as $tag) {
|
||||
/** @var DOMElement[] $tags */
|
||||
foreach ($tags as $tag) {
|
||||
if ($tag->nodeType === 1) {
|
||||
if ($tag->nodeName === 'Entry') {
|
||||
$path = $tag->getNodePath();
|
||||
@@ -2,8 +2,8 @@
|
||||
/**
|
||||
* sysPass
|
||||
*
|
||||
* @author nuxsmin
|
||||
* @link http://syspass.org
|
||||
* @author nuxsmin
|
||||
* @link http://syspass.org
|
||||
* @copyright 2012-2017, Rubén Domínguez nuxsmin@$syspass.org
|
||||
*
|
||||
* This file is part of sysPass.
|
||||
@@ -22,10 +22,10 @@
|
||||
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace SP\Import;
|
||||
namespace SP\Services\Import;
|
||||
|
||||
use SimpleXMLElement;
|
||||
use SP\DataModel\AccountExtData;
|
||||
use SP\Account\AccountRequest;
|
||||
use SP\DataModel\CategoryData;
|
||||
use SP\DataModel\ClientData;
|
||||
|
||||
@@ -33,31 +33,30 @@ defined('APP_ROOT') || die();
|
||||
|
||||
/**
|
||||
* Esta clase es la encargada de importar cuentas desde KeePassX
|
||||
*
|
||||
* @todo Use xmlDOM
|
||||
*/
|
||||
class KeepassXImport extends ImportBase
|
||||
class KeepassXImport extends XmlImportBase implements ImportInterface
|
||||
{
|
||||
use XmlImportTrait;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $customerId = 0;
|
||||
protected $clientId;
|
||||
|
||||
/**
|
||||
* Iniciar la importación desde KeePassX.
|
||||
*
|
||||
* @throws \SP\Core\Exceptions\SPException
|
||||
* @return bool
|
||||
* @throws \SP\Core\Exceptions\InvalidClassException
|
||||
* @return ImportInterface
|
||||
*/
|
||||
public function doImport()
|
||||
{
|
||||
$customerData = new ClientData(null, 'KeePassX');
|
||||
$this->addCustomer($customerData);
|
||||
$this->clientId = $this->addClient(new ClientData(null, 'KeePassX'));
|
||||
|
||||
$this->customerId = $customerData->getId();
|
||||
$this->processCategories($this->xmlDOM);
|
||||
|
||||
$this->processCategories($this->xml);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -75,11 +74,8 @@ class KeepassXImport extends ImportBase
|
||||
// Analizar grupo
|
||||
if ($node->group->entry) {
|
||||
// Crear la categoría
|
||||
$CategoryData = new CategoryData(null, $group->title, 'KeePassX');
|
||||
$this->addCategory($CategoryData);
|
||||
|
||||
// Crear cuentas
|
||||
$this->processAccounts($group->entry, $CategoryData->getId());
|
||||
$this->processAccounts($group->entry, $this->addCategory(new CategoryData(null, $group->title, 'KeePassX')));
|
||||
}
|
||||
|
||||
if ($group->group) {
|
||||
@@ -90,11 +86,8 @@ class KeepassXImport extends ImportBase
|
||||
}
|
||||
|
||||
if ($node->entry) {
|
||||
$CategoryData = new CategoryData(null, $node->title, 'KeePassX');
|
||||
$this->addCategory($CategoryData);
|
||||
|
||||
// Crear cuentas
|
||||
$this->processAccounts($node->entry, $CategoryData->getId());
|
||||
$this->processAccounts($node->entry, $this->addCategory(new CategoryData(null, $node->title, 'KeePassX')));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -102,9 +95,8 @@ class KeepassXImport extends ImportBase
|
||||
/**
|
||||
* Obtener los datos de las entradas de KeePass.
|
||||
*
|
||||
* @param SimpleXMLElement $entries El objeto XML con las entradas
|
||||
* @param int $categoryId Id de la categoría
|
||||
* @throws \SP\Core\Exceptions\SPException
|
||||
* @param SimpleXMLElement $entries El objeto XML con las entradas
|
||||
* @param int $categoryId Id de la categoría
|
||||
*/
|
||||
protected function processAccounts(SimpleXMLElement $entries, $categoryId)
|
||||
{
|
||||
@@ -115,16 +107,20 @@ class KeepassXImport extends ImportBase
|
||||
$notes = isset($entry->comment) ? (string)$entry->comment : '';
|
||||
$username = isset($entry->username) ? (string)$entry->username : '';
|
||||
|
||||
$AccountData = new AccountExtData();
|
||||
$AccountData->setPass($password);
|
||||
$AccountData->setNotes($notes);
|
||||
$AccountData->setName($name);
|
||||
$AccountData->setUrl($url);
|
||||
$AccountData->setLogin($username);
|
||||
$AccountData->setClientId($this->customerId);
|
||||
$AccountData->setCategoryId($categoryId);
|
||||
$accountRequest = new AccountRequest();
|
||||
$accountRequest->pass = $password;
|
||||
$accountRequest->notes = $notes;
|
||||
$accountRequest->name = $name;
|
||||
$accountRequest->url = $url;
|
||||
$accountRequest->login = $username;
|
||||
$accountRequest->clientId = $this->clientId;
|
||||
$accountRequest->categoryId = $categoryId;
|
||||
|
||||
$this->addAccount($AccountData);
|
||||
try {
|
||||
$this->addAccount($accountRequest);
|
||||
} catch (\Exception $e) {
|
||||
processException($e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
375
lib/SP/Services/Import/SyspassImport.php
Normal file
375
lib/SP/Services/Import/SyspassImport.php
Normal file
@@ -0,0 +1,375 @@
|
||||
<?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 SP\Services\Import;
|
||||
|
||||
use Defuse\Crypto\Exception\CryptoException;
|
||||
use DOMXPath;
|
||||
use SP\Account\AccountRequest;
|
||||
use SP\Config\ConfigDB;
|
||||
use SP\Core\Crypt\Crypt;
|
||||
use SP\Core\Crypt\Hash;
|
||||
use SP\Core\OldCrypt;
|
||||
use SP\DataModel\CategoryData;
|
||||
use SP\DataModel\ClientData;
|
||||
use SP\DataModel\TagData;
|
||||
|
||||
defined('APP_ROOT') || die();
|
||||
|
||||
/**
|
||||
* Esta clase es la encargada de importar cuentas desde sysPass
|
||||
*/
|
||||
class SyspassImport extends XmlImportBase implements ImportInterface
|
||||
{
|
||||
/**
|
||||
* Mapeo de etiquetas
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $tags = [];
|
||||
/**
|
||||
* Mapeo de categorías.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $categories = [];
|
||||
/**
|
||||
* Mapeo de clientes.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $clients = [];
|
||||
|
||||
/**
|
||||
* Iniciar la importación desde sysPass.
|
||||
*
|
||||
* @throws ImportException
|
||||
* @return ImportInterface
|
||||
*/
|
||||
public function doImport()
|
||||
{
|
||||
try {
|
||||
if ($this->importParams->getImportMasterPwd() !== '') {
|
||||
$this->mPassValidHash = Hash::checkHashKey($this->importParams->getImportMasterPwd(), ConfigDB::getValue('masterPwd'));
|
||||
}
|
||||
|
||||
$this->version = $this->getXmlVersion();
|
||||
|
||||
if ($this->detectEncrypted()) {
|
||||
if ($this->importParams->getImportPwd() === '') {
|
||||
throw new ImportException(__u('Clave de encriptación no indicada'), ImportException::INFO);
|
||||
}
|
||||
|
||||
$this->processEncrypted();
|
||||
}
|
||||
|
||||
$this->processCategories();
|
||||
|
||||
if ($this->version >= 300) {
|
||||
$this->processClients();
|
||||
} else {
|
||||
$this->processCustomers();
|
||||
}
|
||||
|
||||
$this->processTags();
|
||||
$this->processAccounts();
|
||||
|
||||
return $this;
|
||||
} catch (ImportException $e) {
|
||||
throw $e;
|
||||
} catch (\Exception $e) {
|
||||
throw new ImportException($e->getMessage(), ImportException::CRITICAL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtener la versión del XML
|
||||
*/
|
||||
protected function getXmlVersion()
|
||||
{
|
||||
return (int)str_replace('.', '', (new DOMXPath($this->xmlDOM))->query('/Root/Meta/Version')->item(0)->nodeValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verificar si existen datos encriptados
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function detectEncrypted()
|
||||
{
|
||||
return ($this->xmlDOM->getElementsByTagName('Encrypted')->length > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Procesar los datos encriptados y añadirlos al árbol DOM desencriptados
|
||||
*
|
||||
* @throws ImportException
|
||||
*/
|
||||
protected function processEncrypted()
|
||||
{
|
||||
$hash = $this->xmlDOM->getElementsByTagName('Encrypted')->item(0)->getAttribute('hash');
|
||||
|
||||
if ($hash !== '' && !Hash::checkHashKey($this->importParams->getImportPwd(), $hash)) {
|
||||
throw new ImportException(__u('Clave de encriptación incorrecta'));
|
||||
}
|
||||
|
||||
foreach ($this->xmlDOM->getElementsByTagName('Data') as $node) {
|
||||
/** @var $node \DOMElement */
|
||||
$data = base64_decode($node->nodeValue);
|
||||
|
||||
try {
|
||||
if ($this->version >= 210) {
|
||||
$securedKey = Crypt::unlockSecuredKey($node->getAttribute('key'), $this->importParams->getImportPwd());
|
||||
$xmlDecrypted = Crypt::decrypt($data, $securedKey, $this->importParams->getImportPwd());
|
||||
} else {
|
||||
$xmlDecrypted = OldCrypt::getDecrypt($data, base64_decode($node->getAttribute('iv'), $this->importParams->getImportPwd()));
|
||||
}
|
||||
} catch (CryptoException $e) {
|
||||
processException($e);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$newXmlData = new \DOMDocument();
|
||||
// $newXmlData->preserveWhiteSpace = true;
|
||||
if (!$newXmlData->loadXML($xmlDecrypted)) {
|
||||
throw new ImportException(__u('Clave de encriptación incorrecta'));
|
||||
}
|
||||
|
||||
$newNode = $this->xmlDOM->importNode($newXmlData->documentElement, TRUE);
|
||||
|
||||
$this->xmlDOM->documentElement->appendChild($newNode);
|
||||
}
|
||||
|
||||
// Eliminar los datos encriptados tras desencriptar los mismos
|
||||
if ($this->xmlDOM->getElementsByTagName('Data')->length > 0) {
|
||||
$nodeData = $this->xmlDOM->getElementsByTagName('Encrypted')->item(0);
|
||||
$nodeData->parentNode->removeChild($nodeData);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtener las categorías y añadirlas a sysPass.
|
||||
*
|
||||
* @throws ImportException
|
||||
*/
|
||||
protected function processCategories()
|
||||
{
|
||||
$this->getNodesData('Categories', 'Category',
|
||||
function (\DOMElement $category) {
|
||||
$categoryData = new CategoryData();
|
||||
|
||||
foreach ($category->childNodes as $node) {
|
||||
if (isset($node->tagName)) {
|
||||
switch ($node->tagName) {
|
||||
case 'name':
|
||||
$categoryData->setName($node->nodeValue);
|
||||
break;
|
||||
case 'description':
|
||||
$categoryData->setDescription($node->nodeValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$this->categories[$category->getAttribute('id')] = $this->addCategory($categoryData);
|
||||
} catch (\Exception $e) {
|
||||
processException($e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtener los clientes y añadirlos a sysPass.
|
||||
*
|
||||
* @throws ImportException
|
||||
*/
|
||||
protected function processClients()
|
||||
{
|
||||
$this->getNodesData('Clients', 'Client',
|
||||
function (\DOMElement $client) {
|
||||
$clientData = new ClientData();
|
||||
|
||||
foreach ($client->childNodes as $node) {
|
||||
if (isset($node->tagName)) {
|
||||
switch ($node->tagName) {
|
||||
case 'name':
|
||||
$clientData->setName($node->nodeValue);
|
||||
break;
|
||||
case 'description':
|
||||
$clientData->setDescription($node->nodeValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
$this->clients[$client->getAttribute('id')] = $this->addClient($clientData);
|
||||
} catch (\Exception $e) {
|
||||
processException($e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtener los clientes y añadirlos a sysPass.
|
||||
*
|
||||
* @throws ImportException
|
||||
* @deprecated
|
||||
*/
|
||||
protected function processCustomers()
|
||||
{
|
||||
$this->getNodesData('Customers', 'Customer',
|
||||
function (\DOMElement $client) {
|
||||
$clientData = new ClientData();
|
||||
|
||||
foreach ($client->childNodes as $node) {
|
||||
if (isset($node->tagName)) {
|
||||
switch ($node->tagName) {
|
||||
case 'name':
|
||||
$clientData->setName($node->nodeValue);
|
||||
break;
|
||||
case 'description':
|
||||
$clientData->setDescription($node->nodeValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
$this->clients[$client->getAttribute('id')] = $this->addClient($clientData);
|
||||
} catch (\Exception $e) {
|
||||
processException($e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtener las etiquetas y añadirlas a sysPass.
|
||||
*
|
||||
* @throws ImportException
|
||||
*/
|
||||
protected function processTags()
|
||||
{
|
||||
$this->getNodesData('Tags', 'Tag',
|
||||
function (\DOMElement $tag) {
|
||||
$tagData = new TagData();
|
||||
|
||||
foreach ($tag->childNodes as $node) {
|
||||
if (isset($node->tagName)) {
|
||||
switch ($node->tagName) {
|
||||
case 'name':
|
||||
$tagData->setName($node->nodeValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$this->tags[$tag->getAttribute('id')] = $this->addTag($tagData);
|
||||
} catch (\Exception $e) {
|
||||
processException($e);
|
||||
}
|
||||
}, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtener los datos de las cuentas de sysPass y crearlas.
|
||||
*
|
||||
* @throws ImportException
|
||||
*/
|
||||
protected function processAccounts()
|
||||
{
|
||||
$this->getNodesData('Accounts', 'Account',
|
||||
function (\DOMElement $account) {
|
||||
$accountRequest = new AccountRequest();
|
||||
|
||||
/** @var \DOMElement $node */
|
||||
foreach ($account->childNodes as $node) {
|
||||
if (isset($node->tagName)) {
|
||||
switch ($node->tagName) {
|
||||
case 'name';
|
||||
$accountRequest->name = $node->nodeValue;
|
||||
break;
|
||||
case 'login';
|
||||
$accountRequest->login = $node->nodeValue;
|
||||
break;
|
||||
case 'categoryId';
|
||||
$accountRequest->categoryId = $this->categories[(int)$node->nodeValue];
|
||||
break;
|
||||
case 'clientId';
|
||||
case 'customerId';
|
||||
$accountRequest->clientId = $this->clients[(int)$node->nodeValue];
|
||||
break;
|
||||
case 'url';
|
||||
$accountRequest->url = $node->nodeValue;
|
||||
break;
|
||||
case 'pass';
|
||||
$accountRequest->pass = $node->nodeValue;
|
||||
break;
|
||||
case 'key';
|
||||
$accountRequest->key = $node->nodeValue;
|
||||
break;
|
||||
case 'notes';
|
||||
$accountRequest->notes = $node->nodeValue;
|
||||
break;
|
||||
case 'tags':
|
||||
$accountRequest->tags = $this->processAccountTags($node->childNodes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$this->addAccount($accountRequest);
|
||||
} catch (\Exception $e) {
|
||||
processException($e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Procesar las etiquetas de la cuenta
|
||||
*
|
||||
* @param \DOMNodeList $nodes
|
||||
* @return array
|
||||
*/
|
||||
protected function processAccountTags(\DOMNodeList $nodes)
|
||||
{
|
||||
$tags = [];
|
||||
|
||||
if ($nodes->length > 0) {
|
||||
/** @var \DOMElement $node */
|
||||
foreach ($nodes as $node) {
|
||||
if (isset($node->tagName)) {
|
||||
$tags[] = $node->getAttribute('id');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $tags;
|
||||
}
|
||||
}
|
||||
@@ -22,9 +22,7 @@
|
||||
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace SP\Import;
|
||||
|
||||
use SP\Core\Exceptions\SPException;
|
||||
namespace SP\Services\Import;
|
||||
|
||||
/**
|
||||
* Class XmlFileImport
|
||||
@@ -36,7 +34,7 @@ class XmlFileImport
|
||||
/**
|
||||
* @var FileImport
|
||||
*/
|
||||
protected $FileImport;
|
||||
protected $fileImport;
|
||||
/**
|
||||
* @var \DOMDocument
|
||||
*/
|
||||
@@ -45,17 +43,17 @@ class XmlFileImport
|
||||
/**
|
||||
* XmlFileImport constructor.
|
||||
*
|
||||
* @param FileImport $FileImport
|
||||
* @param FileImport $fileImport
|
||||
*/
|
||||
public function __construct(FileImport $FileImport)
|
||||
public function __construct(FileImport $fileImport)
|
||||
{
|
||||
$this->FileImport = $FileImport;
|
||||
$this->fileImport = $fileImport;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detectar la aplicación que generó el XML.
|
||||
*
|
||||
* @throws SPException
|
||||
* @throws ImportException
|
||||
*/
|
||||
public function detectXMLFormat()
|
||||
{
|
||||
@@ -80,8 +78,10 @@ class XmlFileImport
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
throw new SPException(
|
||||
__('Archivo XML no soportado', false), SPException::CRITICAL, __('No es posible detectar la aplicación que exportó los datos', false)
|
||||
throw new ImportException(
|
||||
__u('Archivo XML no soportado'),
|
||||
ImportException::ERROR,
|
||||
__u('No es posible detectar la aplicación que exportó los datos')
|
||||
);
|
||||
}
|
||||
|
||||
@@ -91,16 +91,18 @@ class XmlFileImport
|
||||
/**
|
||||
* Leer el archivo a un objeto XML.
|
||||
*
|
||||
* @throws SPException
|
||||
* @throws ImportException
|
||||
*/
|
||||
protected function readXMLFile()
|
||||
{
|
||||
// Cargar el XML con DOM
|
||||
$this->xmlDOM = new \DOMDocument();
|
||||
|
||||
if ($this->xmlDOM->load($this->FileImport->getTmpFile()) === false) {
|
||||
throw new SPException(
|
||||
__('Error interno', false), SPException::CRITICAL, __('No es posible procesar el archivo XML', false)
|
||||
if ($this->xmlDOM->load($this->fileImport->getTmpFile()) === false) {
|
||||
throw new ImportException(
|
||||
__u('Error interno'),
|
||||
ImportException::ERROR,
|
||||
__u('No es posible procesar el archivo XML')
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -112,7 +114,7 @@ class XmlFileImport
|
||||
*/
|
||||
protected function parseFileHeader()
|
||||
{
|
||||
$handle = @fopen($this->FileImport->getTmpFile(), 'r');
|
||||
$handle = @fopen($this->fileImport->getTmpFile(), 'r');
|
||||
$headersRegex = '/(KEEPASSX_DATABASE|revelationdata)/i';
|
||||
|
||||
if ($handle) {
|
||||
@@ -22,9 +22,7 @@
|
||||
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace SP\Import;
|
||||
|
||||
use SP\Core\Messages\LogMessage;
|
||||
namespace SP\Services\Import;
|
||||
|
||||
defined('APP_ROOT') || die();
|
||||
|
||||
@@ -39,75 +37,66 @@ class XmlImport implements ImportInterface
|
||||
/**
|
||||
* @var FileImport
|
||||
*/
|
||||
protected $File;
|
||||
protected $xmlFileImport;
|
||||
/**
|
||||
* @var ImportParams
|
||||
*/
|
||||
protected $ImportParams;
|
||||
/**
|
||||
* @var LogMessage
|
||||
*/
|
||||
protected $LogMessage;
|
||||
/**
|
||||
* @var ImportBase
|
||||
*/
|
||||
protected $Import;
|
||||
protected $importParams;
|
||||
|
||||
/**
|
||||
* XmlImport constructor.
|
||||
*
|
||||
* @param FileImport $File
|
||||
* @param ImportParams $ImportParams
|
||||
* @param LogMessage $LogMessage
|
||||
* @param XmlFileImport $xmlFileImport
|
||||
* @param ImportParams $importParams
|
||||
*/
|
||||
public function __construct(FileImport $File, ImportParams $ImportParams, LogMessage $LogMessage)
|
||||
public function __construct(XmlFileImport $xmlFileImport, ImportParams $importParams)
|
||||
{
|
||||
$this->File = $File;
|
||||
$this->ImportParams = $ImportParams;
|
||||
$this->LogMessage = $LogMessage;
|
||||
$this->xmlFileImport = $xmlFileImport;
|
||||
$this->importParams = $importParams;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iniciar la importación desde XML.
|
||||
*
|
||||
* @throws \SP\Core\Exceptions\SPException
|
||||
* @throws ImportException
|
||||
* @throws \Psr\Container\ContainerExceptionInterface
|
||||
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||
* @return ImportInterface
|
||||
*/
|
||||
public function doImport()
|
||||
{
|
||||
$XmlFileImport = new XmlFileImport($this->File);
|
||||
$format = $this->xmlFileImport->detectXMLFormat();
|
||||
|
||||
$format = $XmlFileImport->detectXMLFormat();
|
||||
|
||||
switch ($format) {
|
||||
case 'syspass':
|
||||
$this->Import = new SyspassImport();
|
||||
break;
|
||||
case 'keepass':
|
||||
$this->Import = new KeepassImport();
|
||||
break;
|
||||
case 'keepassx':
|
||||
$this->Import = new KeepassXImport();
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
$this->Import->setImportParams($this->ImportParams);
|
||||
$this->Import->setXmlDOM($XmlFileImport->getXmlDOM());
|
||||
$this->Import->setLogMessage($this->LogMessage);
|
||||
|
||||
$this->LogMessage->addDescription(sprintf(__('Formato detectado: %s'), mb_strtoupper($format)));
|
||||
|
||||
$this->Import->doImport();
|
||||
// $this->LogMessage->addDescription(sprintf(__('Formato detectado: %s'), mb_strtoupper($format)));
|
||||
return $this->selectImportType($format)->doImport();
|
||||
}
|
||||
|
||||
/**
|
||||
* Devolver el contador de objetos importados
|
||||
*
|
||||
* @return int
|
||||
* @param $format
|
||||
* @return KeepassImport|KeepassXImport|SyspassImport
|
||||
* @throws ImportException
|
||||
* @throws \Psr\Container\ContainerExceptionInterface
|
||||
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||
*/
|
||||
protected function selectImportType($format)
|
||||
{
|
||||
switch ($format) {
|
||||
case 'syspass':
|
||||
return new SyspassImport($this->xmlFileImport, $this->importParams);
|
||||
case 'keepass':
|
||||
return new KeepassImport($this->xmlFileImport, $this->importParams);
|
||||
case 'keepassx':
|
||||
return new KeepassXImport($this->xmlFileImport, $this->importParams);
|
||||
}
|
||||
|
||||
throw new ImportException(__u('Formato no detectado'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ImportException
|
||||
*/
|
||||
public function getCounter()
|
||||
{
|
||||
return $this->Import->getCounter();
|
||||
throw new ImportException(__u('Not implemented'));
|
||||
}
|
||||
}
|
||||
109
lib/SP/Services/Import/XmlImportBase.php
Normal file
109
lib/SP/Services/Import/XmlImportBase.php
Normal file
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
/**
|
||||
* sysPass
|
||||
*
|
||||
* @author nuxsmin
|
||||
* @link http://syspass.org
|
||||
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
|
||||
*
|
||||
* This file is part of sysPass.
|
||||
*
|
||||
* sysPass is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* sysPass is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace SP\Services\Import;
|
||||
|
||||
use SP\Bootstrap;
|
||||
use SP\Services\Account\AccountService;
|
||||
use SP\Services\Category\CategoryService;
|
||||
use SP\Services\Client\ClientService;
|
||||
use SP\Services\Tag\TagService;
|
||||
|
||||
/**
|
||||
* Class XmlImportBase
|
||||
*
|
||||
* @package SP\Services\Import
|
||||
*/
|
||||
abstract class XmlImportBase
|
||||
{
|
||||
use ImportTrait;
|
||||
|
||||
/**
|
||||
* @var XmlFileImport
|
||||
*/
|
||||
protected $xmlFileImport;
|
||||
/**
|
||||
* @var \DOMDocument
|
||||
*/
|
||||
protected $xmlDOM;
|
||||
|
||||
/**
|
||||
* ImportBase constructor.
|
||||
*
|
||||
* @param XmlFileImport $xmlFileImport
|
||||
* @param ImportParams $importParams
|
||||
* @throws \Psr\Container\ContainerExceptionInterface
|
||||
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||
*/
|
||||
public function __construct(XmlFileImport $xmlFileImport, ImportParams $importParams)
|
||||
{
|
||||
$this->xmlFileImport = $xmlFileImport;
|
||||
$this->importParams = $importParams;
|
||||
$this->xmlDOM = $xmlFileImport->getXmlDOM();
|
||||
|
||||
$dic = Bootstrap::getContainer();
|
||||
$this->accountService = $dic->get(AccountService::class);
|
||||
$this->categoryService = $dic->get(CategoryService::class);
|
||||
$this->clientService = $dic->get(ClientService::class);
|
||||
$this->tagService = $dic->get(TagService::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtener los datos de los nodos
|
||||
*
|
||||
* @param string $nodeName Nombre del nodo principal
|
||||
* @param string $childNodeName Nombre de los nodos hijos
|
||||
* @param callable $callback Método a ejecutar
|
||||
* @param bool $required Indica si el nodo es requerido
|
||||
* @throws ImportException
|
||||
*/
|
||||
protected function getNodesData($nodeName, $childNodeName, $callback, $required = true)
|
||||
{
|
||||
$nodeList = $this->xmlDOM->getElementsByTagName($nodeName);
|
||||
|
||||
if ($nodeList->length === 0) {
|
||||
if ($required === true) {
|
||||
throw new ImportException(
|
||||
__u('Formato de XML inválido'),
|
||||
ImportException::WARNING,
|
||||
sprintf(__('El nodo "%s" no existe'), $nodeName)
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_callable($callback)) {
|
||||
throw new ImportException(__u('Método inválido'), ImportException::WARNING);
|
||||
}
|
||||
|
||||
/** @var \DOMElement $nodes */
|
||||
foreach ($nodeList as $nodes) {
|
||||
/** @var \DOMElement $Account */
|
||||
foreach ($nodes->getElementsByTagName($childNodeName) as $node) {
|
||||
$callback($node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@
|
||||
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace SP\Import;
|
||||
namespace SP\Services\Import;
|
||||
|
||||
use SP\Core\Exceptions\SPException;
|
||||
|
||||
@@ -55,7 +55,7 @@ trait XmlImportTrait
|
||||
* @param string $childNodeName Nombre de los nodos hijos
|
||||
* @param string $callback Método a ejecutar
|
||||
* @param bool $required Indica si el nodo es requerido
|
||||
* @throws SPException
|
||||
* @throws ImportException
|
||||
*/
|
||||
protected function getNodesData($nodeName, $childNodeName, $callback, $required = true)
|
||||
{
|
||||
@@ -63,22 +63,25 @@ trait XmlImportTrait
|
||||
|
||||
if ($ParentNode->length === 0) {
|
||||
if ($required === true) {
|
||||
throw new SPException(
|
||||
__('Formato de XML inválido', false), SPException::WARNING, sprintf(__('El nodo "%s" no existe'), $nodeName));
|
||||
throw new ImportException(
|
||||
__u('Formato de XML inválido'),
|
||||
SPException::WARNING,
|
||||
sprintf(__('El nodo "%s" no existe'), $nodeName)
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_callable([$this, $callback])) {
|
||||
throw new SPException(__('Método inválido', false), SPException::WARNING);
|
||||
throw new ImportException(__u('Método inválido'), SPException::WARNING);
|
||||
}
|
||||
|
||||
/** @var \DOMElement $nodes */
|
||||
foreach ($ParentNode as $nodes) {
|
||||
/** @var \DOMElement $Account */
|
||||
foreach ($nodes->getElementsByTagName($childNodeName) as $Node) {
|
||||
$this->$callback($Node);
|
||||
foreach ($nodes->getElementsByTagName($childNodeName) as $node) {
|
||||
$this->$callback($node);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -188,8 +188,8 @@ class DbWrapper
|
||||
* @param QueryData $queryData Los datos para realizar la consulta
|
||||
* @param DatabaseInterface $db
|
||||
* @return bool
|
||||
* @throws ConstraintException
|
||||
* @throws QueryException
|
||||
* @throws ConstraintException
|
||||
*/
|
||||
public static function getQuery(QueryData $queryData, DatabaseInterface $db = null)
|
||||
{
|
||||
@@ -220,7 +220,13 @@ class DbWrapper
|
||||
|
||||
switch ($e->getCode()) {
|
||||
case 23000:
|
||||
throw new ConstraintException(__u('Restricción de integridad'), SPException::ERROR, $e->getMessage(), $e->getCode());
|
||||
throw new ConstraintException(
|
||||
__u('Restricción de integridad'),
|
||||
SPException::ERROR,
|
||||
$e->getMessage(),
|
||||
$e->getCode(),
|
||||
$e
|
||||
);
|
||||
}
|
||||
|
||||
throw new QueryException($errorMessage, SPException::ERROR, $e->getMessage(), $e->getCode());
|
||||
@@ -240,6 +246,7 @@ class DbWrapper
|
||||
*
|
||||
* @param DatabaseInterface $db
|
||||
* @return bool
|
||||
* @throws SPException
|
||||
*/
|
||||
public static function beginTransaction(DatabaseInterface $db)
|
||||
{
|
||||
@@ -253,6 +260,7 @@ class DbWrapper
|
||||
*
|
||||
* @param DatabaseInterface $db
|
||||
* @return bool
|
||||
* @throws SPException
|
||||
*/
|
||||
public static function endTransaction(DatabaseInterface $db)
|
||||
{
|
||||
@@ -266,6 +274,7 @@ class DbWrapper
|
||||
*
|
||||
* @param DatabaseInterface $db
|
||||
* @return bool
|
||||
* @throws SPException
|
||||
*/
|
||||
public static function rollbackTransaction(DatabaseInterface $db)
|
||||
{
|
||||
|
||||
@@ -368,7 +368,8 @@ sysPass.Main = function () {
|
||||
return requestData;
|
||||
},
|
||||
beforeSendAction: "",
|
||||
url: ""
|
||||
url: "",
|
||||
allowedExts: []
|
||||
};
|
||||
|
||||
// Subir un archivo
|
||||
@@ -418,10 +419,8 @@ sysPass.Main = function () {
|
||||
};
|
||||
|
||||
const checkFileExtension = function (name) {
|
||||
const file_exts_ok = $obj.data("files-ext").toLowerCase().split(",");
|
||||
|
||||
for (let i = 0; i <= file_exts_ok.length; i++) {
|
||||
if (name.indexOf(file_exts_ok[i]) !== -1) {
|
||||
for (let ext in options.allowedExts) {
|
||||
if (name.indexOf(options.allowedExts[ext]) !== -1){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -440,7 +439,7 @@ sysPass.Main = function () {
|
||||
const file = filesArray[i];
|
||||
if (checkFileSize(file.size)) {
|
||||
msg.error(config.LANG[18] + "<br>" + file.name + " (Max: " + config.MAX_FILE_SIZE + ")");
|
||||
} else if (!checkFileExtension(file.name)) {
|
||||
} else if (!checkFileExtension(file.name.toUpperCase())) {
|
||||
msg.error(config.LANG[19] + "<br>" + file.name);
|
||||
} else {
|
||||
sendFile(filesArray[i]);
|
||||
@@ -557,7 +556,9 @@ sysPass.Main = function () {
|
||||
COOKIES_ENABLED: false,
|
||||
PLUGINS: [],
|
||||
LOGGEDIN: false,
|
||||
AUTHBASIC_AUTOLOGIN: false
|
||||
AUTHBASIC_AUTOLOGIN: false,
|
||||
FILES_ALLOWED_EXTS: "",
|
||||
IMPORT_ALLOWED_EXTS: []
|
||||
};
|
||||
|
||||
// Atributos del generador de claves
|
||||
@@ -791,6 +792,8 @@ sysPass.Main = function () {
|
||||
config.PLUGINS = json.plugins;
|
||||
config.LOGGEDIN = json.loggedin;
|
||||
config.AUTHBASIC_AUTOLOGIN = json.authbasic_autologin;
|
||||
config.IMPORT_ALLOWED_EXTS = json.import_allowed_exts;
|
||||
config.FILES_ALLOWED_EXTS = json.files_allowed_exts;
|
||||
|
||||
Object.freeze(config);
|
||||
});
|
||||
|
||||
44
public/js/app-main.min.js
vendored
44
public/js/app-main.min.js
vendored
@@ -1,25 +1,25 @@
|
||||
var $jscomp={scope:{},findInternal:function(b,k,l){b instanceof String&&(b=String(b));for(var m=b.length,n=0;n<m;n++){var w=b[n];if(k.call(l,w,n,b))return{i:n,v:w}}return{i:-1,v:void 0}}};$jscomp.defineProperty="function"==typeof Object.defineProperties?Object.defineProperty:function(b,k,l){if(l.get||l.set)throw new TypeError("ES3 does not support getters and setters.");b!=Array.prototype&&b!=Object.prototype&&(b[k]=l.value)};
|
||||
$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,k,l,m){if(k){l=$jscomp.global;b=b.split(".");for(m=0;m<b.length-1;m++){var n=b[m];n in l||(l[n]={});l=l[n]}b=b[b.length-1];m=l[b];k=k(m);k!=m&&null!=k&&$jscomp.defineProperty(l,b,{configurable:!0,writable:!0,value:k})}};
|
||||
$jscomp.polyfill("Array.prototype.find",function(b){return b?b:function(b,l){return $jscomp.findInternal(this,b,l).v}},"es6-impl","es3");$jscomp.SYMBOL_PREFIX="jscomp_symbol_";$jscomp.initSymbol=function(){$jscomp.initSymbol=function(){};$jscomp.global.Symbol||($jscomp.global.Symbol=$jscomp.Symbol)};$jscomp.symbolCounter_=0;$jscomp.Symbol=function(b){return $jscomp.SYMBOL_PREFIX+(b||"")+$jscomp.symbolCounter_++};
|
||||
$jscomp.initSymbolIterator=function(){$jscomp.initSymbol();var b=$jscomp.global.Symbol.iterator;b||(b=$jscomp.global.Symbol.iterator=$jscomp.global.Symbol("iterator"));"function"!=typeof Array.prototype[b]&&$jscomp.defineProperty(Array.prototype,b,{configurable:!0,writable:!0,value:function(){return $jscomp.arrayIterator(this)}});$jscomp.initSymbolIterator=function(){}};$jscomp.arrayIterator=function(b){var k=0;return $jscomp.iteratorPrototype(function(){return k<b.length?{done:!1,value:b[k++]}:{done:!0}})};
|
||||
$jscomp.iteratorPrototype=function(b){$jscomp.initSymbolIterator();b={next:b};b[$jscomp.global.Symbol.iterator]=function(){return this};return b};$jscomp.array=$jscomp.array||{};$jscomp.iteratorFromArray=function(b,k){$jscomp.initSymbolIterator();b instanceof String&&(b+="");var l=0,m={next:function(){if(l<b.length){var n=l++;return{value:k(n,b[n]),done:!1}}m.next=function(){return{done:!0,value:void 0}};return m.next()}};m[Symbol.iterator]=function(){return m};return m};
|
||||
var $jscomp={scope:{},findInternal:function(b,l,h){b instanceof String&&(b=String(b));for(var m=b.length,n=0;n<m;n++){var w=b[n];if(l.call(h,w,n,b))return{i:n,v:w}}return{i:-1,v:void 0}}};$jscomp.defineProperty="function"==typeof Object.defineProperties?Object.defineProperty:function(b,l,h){if(h.get||h.set)throw new TypeError("ES3 does not support getters and setters.");b!=Array.prototype&&b!=Object.prototype&&(b[l]=h.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,l,h,m){if(l){h=$jscomp.global;b=b.split(".");for(m=0;m<b.length-1;m++){var n=b[m];n in h||(h[n]={});h=h[n]}b=b[b.length-1];m=h[b];l=l(m);l!=m&&null!=l&&$jscomp.defineProperty(h,b,{configurable:!0,writable:!0,value:l})}};
|
||||
$jscomp.polyfill("Array.prototype.find",function(b){return b?b:function(b,h){return $jscomp.findInternal(this,b,h).v}},"es6-impl","es3");$jscomp.SYMBOL_PREFIX="jscomp_symbol_";$jscomp.initSymbol=function(){$jscomp.initSymbol=function(){};$jscomp.global.Symbol||($jscomp.global.Symbol=$jscomp.Symbol)};$jscomp.symbolCounter_=0;$jscomp.Symbol=function(b){return $jscomp.SYMBOL_PREFIX+(b||"")+$jscomp.symbolCounter_++};
|
||||
$jscomp.initSymbolIterator=function(){$jscomp.initSymbol();var b=$jscomp.global.Symbol.iterator;b||(b=$jscomp.global.Symbol.iterator=$jscomp.global.Symbol("iterator"));"function"!=typeof Array.prototype[b]&&$jscomp.defineProperty(Array.prototype,b,{configurable:!0,writable:!0,value:function(){return $jscomp.arrayIterator(this)}});$jscomp.initSymbolIterator=function(){}};$jscomp.arrayIterator=function(b){var l=0;return $jscomp.iteratorPrototype(function(){return l<b.length?{done:!1,value:b[l++]}:{done:!0}})};
|
||||
$jscomp.iteratorPrototype=function(b){$jscomp.initSymbolIterator();b={next:b};b[$jscomp.global.Symbol.iterator]=function(){return this};return b};$jscomp.array=$jscomp.array||{};$jscomp.iteratorFromArray=function(b,l){$jscomp.initSymbolIterator();b instanceof String&&(b+="");var h=0,m={next:function(){if(h<b.length){var n=h++;return{value:l(n,b[n]),done:!1}}m.next=function(){return{done:!0,value:void 0}};return m.next()}};m[Symbol.iterator]=function(){return m};return m};
|
||||
$jscomp.polyfill("Array.prototype.keys",function(b){return b?b:function(){return $jscomp.iteratorFromArray(this,function(b){return b})}},"es6-impl","es3");
|
||||
sysPass.Main=function(){var b=function(){f.info("checkPluginUpdates");for(var a in t)"function"===typeof t[a].checkVersion&&t[a].checkVersion().then(function(a){0===a.status&&void 0!==a.data.plugin&&e.info(String.format(c.LANG[67],a.data.plugin,a.data.remoteVersion))})},k=function(){var a=document.createElement("div");return function(g){g&&"string"===typeof g&&(g=g.replace(/<script[^>]*>([\S\s]*?)<\/script>/gmi,""),g=g.replace(/<\/?\w(?:[^"'>]|"[^"]*"|'[^']*')*>/gmi,""),a.innerHTML=g,g=a.textContent,
|
||||
a.textContent="");return g}}(),l=function(a){f.info("resizeImage");var g=.9*$(window).width(),d=.9*$(window).height(),b={width:a.width(),height:a.height()},c={calc:0,main:0,secondary:0,factor:.9,rel:b.width/b.height},e=function(a){a.main>a.secondary?a.calc=a.main/a.rel:a.main<a.secondary&&(a.calc=a.main*a.rel);a.calc>a.secondary&&(a.main*=a.factor,e(a));return a},D=function(){c.main=g;c.secondary=d;var h=e(c);a.css({width:h.main,height:h.calc});b.width=h.main;b.height=h.calc},E=function(){c.main=
|
||||
d;c.secondary=g;var h=e(c);a.css({width:h.calc,height:h.main});b.width=h.calc;b.height=h.main};b.width>g?D():b.height>d&&(f.info("height"),E());return b},m=function(a,b){f.info("Eval: "+a);if("function"===typeof a)a(b);else throw Error("Function not found: "+a);},n=function(){f.info("bindPassEncrypt");$("body").on("blur",":input[type=password]",function(a){a=$(this);a.hasClass("passwordfield__no-pki")||z(a)}).on("keypress",":input[type=password]",function(a){13===a.keyCode&&(a.preventDefault(),a=
|
||||
sysPass.Main=function(){var b=function(){f.info("checkPluginUpdates");for(var a in t)"function"===typeof t[a].checkVersion&&t[a].checkVersion().then(function(a){0===a.status&&void 0!==a.data.plugin&&e.info(String.format(c.LANG[67],a.data.plugin,a.data.remoteVersion))})},l=function(){var a=document.createElement("div");return function(g){g&&"string"===typeof g&&(g=g.replace(/<script[^>]*>([\S\s]*?)<\/script>/gmi,""),g=g.replace(/<\/?\w(?:[^"'>]|"[^"]*"|'[^']*')*>/gmi,""),a.innerHTML=g,g=a.textContent,
|
||||
a.textContent="");return g}}(),h=function(a){f.info("resizeImage");var g=.9*$(window).width(),d=.9*$(window).height(),b={width:a.width(),height:a.height()},c={calc:0,main:0,secondary:0,factor:.9,rel:b.width/b.height},e=function(a){a.main>a.secondary?a.calc=a.main/a.rel:a.main<a.secondary&&(a.calc=a.main*a.rel);a.calc>a.secondary&&(a.main*=a.factor,e(a));return a},D=function(){c.main=g;c.secondary=d;var k=e(c);a.css({width:k.main,height:k.calc});b.width=k.main;b.height=k.calc},E=function(){c.main=
|
||||
d;c.secondary=g;var k=e(c);a.css({width:k.calc,height:k.main});b.width=k.calc;b.height=k.main};b.width>g?D():b.height>d&&(f.info("height"),E());return b},m=function(a,b){f.info("Eval: "+a);if("function"===typeof a)a(b);else throw Error("Function not found: "+a);},n=function(){f.info("bindPassEncrypt");$("body").on("blur",":input[type=password]",function(a){a=$(this);a.hasClass("passwordfield__no-pki")||z(a)}).on("keypress",":input[type=password]",function(a){13===a.keyCode&&(a.preventDefault(),a=
|
||||
$(this),z(a),a.closest("form").submit())})},w=function(){f.info("initializeClipboard");if(clipboard.isSupported())$("body").on("click",".clip-pass-button",function(){var a=p.account.copyPass($(this)).done(function(a){if(0!==a.status)return e.out(a),!1;x.set(a.csrf)});!1!==a&&clipboard.copy(a.responseJSON.data.accpass).then(function(){e.ok(c.LANG[45])},function(a){e.error(c.LANG[46])})}).on("click",".dialog-clip-button",function(){var a=$(this.dataset.clipboardTarget);clipboard.copy(a.text()).then(function(){$(".dialog-text").removeClass("dialog-clip-copy");
|
||||
a.addClass("dialog-clip-copy")},function(a){e.error(c.LANG[46])})}).on("click",".clip-pass-icon",function(){var a=$(this.dataset.clipboardTarget);clipboard.copy(k(a.val())).then(function(){e.ok(c.LANG[45])},function(a){e.error(c.LANG[46])})});else f.warn(c.LANG[65])},z=function(a){f.info("encryptFormValue");var b=a.val();""!==b&&parseInt(a.attr("data-length"))!==b.length&&(b=c.CRYPT.encrypt(b),a.val(b),a.attr("data-length",b.length))},C=function(a,b){f.info("outputResult");var d=$(".passLevel-"+b.attr("id")),
|
||||
a.addClass("dialog-clip-copy")},function(a){e.error(c.LANG[46])})}).on("click",".clip-pass-icon",function(){var a=$(this.dataset.clipboardTarget);clipboard.copy(l(a.val())).then(function(){e.ok(c.LANG[45])},function(a){e.error(c.LANG[46])})});else f.warn(c.LANG[65])},z=function(a){f.info("encryptFormValue");var b=a.val();""!==b&&parseInt(a.attr("data-length"))!==b.length&&(b=c.CRYPT.encrypt(b),a.val(b),a.attr("data-length",b.length))},C=function(a,b){f.info("outputResult");var d=$(".passLevel-"+b.attr("id")),
|
||||
g=a.score;d.show();d.removeClass("weak good strong strongest");0===u.passLength?d.attr("title","").empty():u.passLength<u.minPasswordLength?d.attr("title",c.LANG[11]).addClass("weak"):0===g?d.attr("title",c.LANG[9]+" - "+a.feedback.warning).addClass("weak"):1===g||2===g?d.attr("title",c.LANG[8]+" - "+a.feedback.warning).addClass("good"):3===g?d.attr("title",c.LANG[7]).addClass("strong"):4===g&&d.attr("title",c.LANG[10]).addClass("strongest")},F=function(a){f.info("checkPassLevel");u.passLength=a.val().length;
|
||||
C(zxcvbn(a.val()),a)},G=function(a){var b=function(a){var b=$("#fileUploadForm");!1===a&&b.hide();a=b.find("input[type='file']");a.on("change",function(){"function"===typeof h.beforeSendAction&&h.beforeSendAction();k(this.files)});return a},d={actionId:a.data("action-id"),itemId:a.data("item-id"),sk:x.get()},h={requestDoneAction:"",setRequestData:function(a){$.extend(d,a)},getRequestData:function(){return d},beforeSendAction:"",url:""},l=function(a){if(void 0===h.url||""===h.url)return!1;var b=new FormData;
|
||||
b.append("inFile",a);b.append("isAjax",1);d.sk=x.get();Object.keys(d).forEach(function(a){b.append(a,d[a])});a=v.getRequestOpts();a.url=h.url;a.processData=!1;a.contentType=!1;a.data=b;v.getActionCall(a,function(a){var b=a.status;a=a.description;0===b?("function"===typeof h.requestDoneAction&&h.requestDoneAction(),e.ok(a)):10===b?p.main.logout():e.error(a)})},k=function(b){if(5<b.length)e.error(c.LANG[17]+" (Max: 5)");else for(var d=0;d<b.length;d++){var g=b[d];if(g.size/1E3>c.MAX_FILE_SIZE)e.error(c.LANG[18]+
|
||||
"<br>"+g.name+" (Max: "+c.MAX_FILE_SIZE+")");else{var h;a:{h=g.name;for(var f=a.data("files-ext").toLowerCase().split(","),k=0;k<=f.length;k++)if(-1!==h.indexOf(f[k])){h=!0;break a}h=!1}h?l(b[d]):e.error(c.LANG[19]+"<br>"+g.name)}}};window.File&&window.FileList&&window.FileReader?function(){f.info("fileUpload:init");var d=b(!1);a.on("dragover dragenter",function(a){f.info("fileUpload:drag");a.stopPropagation();a.preventDefault()});a.on("drop",function(a){f.info("fileUpload:drop");a.stopPropagation();
|
||||
a.preventDefault();"function"===typeof h.beforeSendAction&&h.beforeSendAction();k(a.originalEvent.dataTransfer.files)});a.on("click",function(){d.click()})}():b(!0);return h},A=function(a){window.location.replace(a)},I=function(){f.info("checkLogout");return"login/logout"===parseInt(H("r"))?(e.sticky(c.LANG[61],function(){A("index.php?r=login")}),!0):!1},J=function(){$("html, body").animate({scrollTop:0},"slow")},K=function(){var a=$("#container");a.hasClass("content-no-auto-resize")||a.css("height",
|
||||
$("#content").height()+200)},x={get:function(){f.info("sk:get");return $("#container").attr("data-sk")},set:function(a){f.info("sk:set");f.debug(a);$("#container").attr("data-sk",a)}},c={APP_ROOT:"",LANG:[],PK:"",MAX_FILE_SIZE:1024,CRYPT:new JSEncrypt,CHECK_UPDATES:!1,TIMEZONE:"",LOCALE:"",DEBUG:"",COOKIES_ENABLED:!1,PLUGINS:[],LOGGEDIN:!1,AUTHBASIC_AUTOLOGIN:!1},u={passLength:0,minPasswordLength:8,complexity:{chars:!0,numbers:!0,symbols:!0,uppercase:!0,numlength:12}};Object.seal(u);var B={},q={},
|
||||
p={},v={},t={},y={},r={},f={log:function(a){!0===c.DEBUG&&console.log(a)},info:function(a){!0===c.DEBUG&&console.info(a)},error:function(a){console.error(a)},warn:function(a){console.warn(a)},debug:function(a){!0===c.DEBUG&&console.debug(a)}};Object.freeze(f);toastr.options={closeButton:!0,debug:!1,newestOnTop:!1,progressBar:!1,positionClass:"toast-top-center",preventDuplicates:!1,onclick:null,showDuration:"300",hideDuration:"1000",timeOut:"5000",extendedTimeOut:"1000",showEasing:"swing",hideEasing:"linear",
|
||||
showMethod:"fadeIn",hideMethod:"fadeOut"};var L=function(){f.info("setupCallbacks");var a=$("#container").data("page");if(""!==a&&"function"===typeof q.views[a])q.views[a]();0<$("footer").length&&q.views.footer();$("#btnBack").click(function(){A("index.php")});q.bodyHooks()},e={ok:function(a){toastr.success(a)},error:function(a){toastr.error(a)},warn:function(a){toastr.warning(a)},info:function(a){toastr.info(a)},sticky:function(a,b){var d={timeOut:0};"function"===typeof b&&(d.onHidden=b);toastr.warning(a,
|
||||
c.LANG[60],d)},out:function(a){if("object"===typeof a){var b=a.status,d=a.description;void 0!==a.messages&&0<a.messages.length&&(d=d+"<br>"+a.messages.join("<br>"));switch(b){case 0:e.ok(d);break;case 1:e.error(d);break;case 2:e.warn(d);break;case 10:p.main.logout();break;case 100:e.ok(d);e.sticky(d);break;case 101:e.error(d);e.sticky(d);break;case 102:e.warn(d);e.sticky(d);break;default:e.error(d)}}},html:{error:function(a){return'<p class="error round">Oops...<br>'+c.LANG[1]+"<br>"+a+"</p>"}}};
|
||||
Object.freeze(e);String.format||(String.format=function(a){var b=Array.prototype.slice.call(arguments,1);return a.replace(/{(\d+)}/g,function(a,c){return"undefined"!==typeof b[c]?b[c]:a})});var M=function(){f.info("getEnvironment");var a=window.location.pathname.split("/");c.APP_ROOT=window.location.protocol+"//"+window.location.host+function(){for(var b="",c=1;c<=a.length-2;c++)b+="/"+a[c];return b}();var b=v.getRequestOpts();b.url="/index.php?r=bootstrap/getEnvironment";b.method="get";b.useLoading=
|
||||
!1;b.data={isAjax:1};return v.getActionCall(b,function(a){c.LANG=a.lang;c.PK=a.pk;c.CHECK_UPDATES=a.check_updates;c.CRYPT.setPublicKey(a.pk);c.TIMEZONE=a.timezone;c.LOCALE=a.locale;c.DEBUG=a.debug;c.MAX_FILE_SIZE=parseInt(a.max_file_size);c.COOKIES_ENABLED=a.cookies_enabled;c.PLUGINS=a.plugins;c.LOGGEDIN=a.loggedin;c.AUTHBASIC_AUTOLOGIN=a.authbasic_autologin;Object.freeze(c)})},H=function(a){for(var b=[],c,e=window.location.href.slice(window.location.href.indexOf("?")+1).split("&"),f=0;f<e.length;f++)c=
|
||||
e[f].split("="),b.push(c[0]),b[c[0]]=c[1];return void 0!==a&&void 0!==b[a]?b[a]:b};return function(){f.info("init");y={actions:function(){return p},triggers:function(){return q},theme:function(){return B},sk:x,msg:e,log:f,passwordData:u,outputResult:C,checkPassLevel:F,encryptFormValue:z,fileUpload:G,redirect:A,scrollUp:J,setContentSize:K};r=$.extend({log:f,config:function(){return c},appTheme:function(){return B},appActions:function(){return p},appTriggers:function(){return q},appRequests:function(){return v},
|
||||
appPlugins:function(){return t},evalAction:m,resizeImage:l},y);Object.freeze(y);Object.freeze(r);q=sysPass.Triggers(r);p=sysPass.Actions(r);v=sysPass.Requests(r);"function"===typeof sysPass.Theme&&(B=sysPass.Theme(r));M().then(function(){if(!I()&&(""!==c.PK&&n(),!0===c.CHECK_UPDATES&&p.main.getUpdates(),!1===c.COOKIES_ENABLED&&e.sticky(c.LANG[64]),w(),L(),0<c.PLUGINS.length)){f.info(c.PLUGINS);f.info("initPlugins");for(var a=0;a<c.PLUGINS.length;a++){var g=c.PLUGINS[a];"function"===typeof sysPass.Plugin[g]&&
|
||||
(t[g]=sysPass.Plugin[g](r))}Object.freeze(t);!0===c.LOGGEDIN&&!0===c.CHECK_UPDATES&&b()}});return y}()};
|
||||
C(zxcvbn(a.val()),a)},G=function(a){var b=function(a){var b=$("#fileUploadForm");!1===a&&b.hide();a=b.find("input[type='file']");a.on("change",function(){"function"===typeof k.beforeSendAction&&k.beforeSendAction();l(this.files)});return a},d={actionId:a.data("action-id"),itemId:a.data("item-id"),sk:x.get()},k={requestDoneAction:"",setRequestData:function(a){$.extend(d,a)},getRequestData:function(){return d},beforeSendAction:"",url:"",allowedExts:[]},h=function(a){if(void 0===k.url||""===k.url)return!1;
|
||||
var b=new FormData;b.append("inFile",a);b.append("isAjax",1);d.sk=x.get();Object.keys(d).forEach(function(a){b.append(a,d[a])});a=v.getRequestOpts();a.url=k.url;a.processData=!1;a.contentType=!1;a.data=b;v.getActionCall(a,function(a){var b=a.status;a=a.description;0===b?("function"===typeof k.requestDoneAction&&k.requestDoneAction(),e.ok(a)):10===b?p.main.logout():e.error(a)})},l=function(a){if(5<a.length)e.error(c.LANG[17]+" (Max: 5)");else for(var b=0;b<a.length;b++){var d=a[b];if(d.size/1E3>c.MAX_FILE_SIZE)e.error(c.LANG[18]+
|
||||
"<br>"+d.name+" (Max: "+c.MAX_FILE_SIZE+")");else{var g;a:{g=d.name.toUpperCase();var f=void 0;for(f in k.allowedExts)if(-1!==g.indexOf(k.allowedExts[f])){g=!0;break a}g=!1}g?h(a[b]):e.error(c.LANG[19]+"<br>"+d.name)}}};window.File&&window.FileList&&window.FileReader?function(){f.info("fileUpload:init");var d=b(!1);a.on("dragover dragenter",function(a){f.info("fileUpload:drag");a.stopPropagation();a.preventDefault()});a.on("drop",function(a){f.info("fileUpload:drop");a.stopPropagation();a.preventDefault();
|
||||
"function"===typeof k.beforeSendAction&&k.beforeSendAction();l(a.originalEvent.dataTransfer.files)});a.on("click",function(){d.click()})}():b(!0);return k},A=function(a){window.location.replace(a)},I=function(){f.info("checkLogout");return"login/logout"===parseInt(H("r"))?(e.sticky(c.LANG[61],function(){A("index.php?r=login")}),!0):!1},J=function(){$("html, body").animate({scrollTop:0},"slow")},K=function(){var a=$("#container");a.hasClass("content-no-auto-resize")||a.css("height",$("#content").height()+
|
||||
200)},x={get:function(){f.info("sk:get");return $("#container").attr("data-sk")},set:function(a){f.info("sk:set");f.debug(a);$("#container").attr("data-sk",a)}},c={APP_ROOT:"",LANG:[],PK:"",MAX_FILE_SIZE:1024,CRYPT:new JSEncrypt,CHECK_UPDATES:!1,TIMEZONE:"",LOCALE:"",DEBUG:"",COOKIES_ENABLED:!1,PLUGINS:[],LOGGEDIN:!1,AUTHBASIC_AUTOLOGIN:!1,FILES_ALLOWED_EXTS:"",IMPORT_ALLOWED_EXTS:[]},u={passLength:0,minPasswordLength:8,complexity:{chars:!0,numbers:!0,symbols:!0,uppercase:!0,numlength:12}};Object.seal(u);
|
||||
var B={},q={},p={},v={},t={},y={},r={},f={log:function(a){!0===c.DEBUG&&console.log(a)},info:function(a){!0===c.DEBUG&&console.info(a)},error:function(a){console.error(a)},warn:function(a){console.warn(a)},debug:function(a){!0===c.DEBUG&&console.debug(a)}};Object.freeze(f);toastr.options={closeButton:!0,debug:!1,newestOnTop:!1,progressBar:!1,positionClass:"toast-top-center",preventDuplicates:!1,onclick:null,showDuration:"300",hideDuration:"1000",timeOut:"5000",extendedTimeOut:"1000",showEasing:"swing",
|
||||
hideEasing:"linear",showMethod:"fadeIn",hideMethod:"fadeOut"};var L=function(){f.info("setupCallbacks");var a=$("#container").data("page");if(""!==a&&"function"===typeof q.views[a])q.views[a]();0<$("footer").length&&q.views.footer();$("#btnBack").click(function(){A("index.php")});q.bodyHooks()},e={ok:function(a){toastr.success(a)},error:function(a){toastr.error(a)},warn:function(a){toastr.warning(a)},info:function(a){toastr.info(a)},sticky:function(a,b){var d={timeOut:0};"function"===typeof b&&(d.onHidden=
|
||||
b);toastr.warning(a,c.LANG[60],d)},out:function(a){if("object"===typeof a){var b=a.status,d=a.description;void 0!==a.messages&&0<a.messages.length&&(d=d+"<br>"+a.messages.join("<br>"));switch(b){case 0:e.ok(d);break;case 1:e.error(d);break;case 2:e.warn(d);break;case 10:p.main.logout();break;case 100:e.ok(d);e.sticky(d);break;case 101:e.error(d);e.sticky(d);break;case 102:e.warn(d);e.sticky(d);break;default:e.error(d)}}},html:{error:function(a){return'<p class="error round">Oops...<br>'+c.LANG[1]+
|
||||
"<br>"+a+"</p>"}}};Object.freeze(e);String.format||(String.format=function(a){var b=Array.prototype.slice.call(arguments,1);return a.replace(/{(\d+)}/g,function(a,c){return"undefined"!==typeof b[c]?b[c]:a})});var M=function(){f.info("getEnvironment");var a=window.location.pathname.split("/");c.APP_ROOT=window.location.protocol+"//"+window.location.host+function(){for(var b="",c=1;c<=a.length-2;c++)b+="/"+a[c];return b}();var b=v.getRequestOpts();b.url="/index.php?r=bootstrap/getEnvironment";b.method=
|
||||
"get";b.useLoading=!1;b.data={isAjax:1};return v.getActionCall(b,function(a){c.LANG=a.lang;c.PK=a.pk;c.CHECK_UPDATES=a.check_updates;c.CRYPT.setPublicKey(a.pk);c.TIMEZONE=a.timezone;c.LOCALE=a.locale;c.DEBUG=a.debug;c.MAX_FILE_SIZE=parseInt(a.max_file_size);c.COOKIES_ENABLED=a.cookies_enabled;c.PLUGINS=a.plugins;c.LOGGEDIN=a.loggedin;c.AUTHBASIC_AUTOLOGIN=a.authbasic_autologin;c.IMPORT_ALLOWED_EXTS=a.import_allowed_exts;c.FILES_ALLOWED_EXTS=a.files_allowed_exts;Object.freeze(c)})},H=function(a){for(var b=
|
||||
[],c,e=window.location.href.slice(window.location.href.indexOf("?")+1).split("&"),f=0;f<e.length;f++)c=e[f].split("="),b.push(c[0]),b[c[0]]=c[1];return void 0!==a&&void 0!==b[a]?b[a]:b};return function(){f.info("init");y={actions:function(){return p},triggers:function(){return q},theme:function(){return B},sk:x,msg:e,log:f,passwordData:u,outputResult:C,checkPassLevel:F,encryptFormValue:z,fileUpload:G,redirect:A,scrollUp:J,setContentSize:K};r=$.extend({log:f,config:function(){return c},appTheme:function(){return B},
|
||||
appActions:function(){return p},appTriggers:function(){return q},appRequests:function(){return v},appPlugins:function(){return t},evalAction:m,resizeImage:h},y);Object.freeze(y);Object.freeze(r);q=sysPass.Triggers(r);p=sysPass.Actions(r);v=sysPass.Requests(r);"function"===typeof sysPass.Theme&&(B=sysPass.Theme(r));M().then(function(){if(!I()&&(""!==c.PK&&n(),!0===c.CHECK_UPDATES&&p.main.getUpdates(),!1===c.COOKIES_ENABLED&&e.sticky(c.LANG[64]),w(),L(),0<c.PLUGINS.length)){f.info(c.PLUGINS);f.info("initPlugins");
|
||||
for(var a=0;a<c.PLUGINS.length;a++){var g=c.PLUGINS[a];"function"===typeof sysPass.Plugin[g]&&(t[g]=sysPass.Plugin[g](r))}Object.freeze(t);!0===c.LOGGEDIN&&!0===c.CHECK_UPDATES&&b()}});return y}()};
|
||||
|
||||
@@ -332,7 +332,8 @@ sysPass.Triggers = function (Common) {
|
||||
if ($dropFiles.length > 0) {
|
||||
const upload = Common.fileUpload($dropFiles);
|
||||
|
||||
upload.url = Common.appActions().ajaxUrl.config.import;
|
||||
upload.url = Common.appActions().ajaxUrl.entrypoint + "?r=" + $dropFiles.data("action-route");
|
||||
upload.allowedExts = Common.config().IMPORT_ALLOWED_EXTS;
|
||||
upload.beforeSendAction = function () {
|
||||
upload.setRequestData({
|
||||
sk: Common.sk.get(),
|
||||
|
||||
20
public/js/app-triggers.min.js
vendored
20
public/js/app-triggers.min.js
vendored
@@ -1,17 +1,17 @@
|
||||
var $jscomp={scope:{},findInternal:function(b,d,f){b instanceof String&&(b=String(b));for(var a=b.length,c=0;c<a;c++){var e=b[c];if(d.call(f,e,c,b))return{i:c,v:e}}return{i:-1,v:void 0}}};$jscomp.defineProperty="function"==typeof Object.defineProperties?Object.defineProperty:function(b,d,f){if(f.get||f.set)throw new TypeError("ES3 does not support getters and setters.");b!=Array.prototype&&b!=Object.prototype&&(b[d]=f.value)};
|
||||
$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,f,a){if(d){f=$jscomp.global;b=b.split(".");for(a=0;a<b.length-1;a++){var c=b[a];c in f||(f[c]={});f=f[c]}b=b[b.length-1];a=f[b];d=d(a);d!=a&&null!=d&&$jscomp.defineProperty(f,b,{configurable:!0,writable:!0,value:d})}};
|
||||
$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,f,a){if(d){f=$jscomp.global;b=b.split(".");for(a=0;a<b.length-1;a++){var c=b[a];c in f||(f[c]={});f=f[c]}b=b[b.length-1];a=f[b];d=d(a);d!=a&&null!=d&&$jscomp.defineProperty(f,b,{configurable:!0,writable:!0,value:d})}};
|
||||
$jscomp.polyfill("Array.prototype.find",function(b){return b?b:function(b,f){return $jscomp.findInternal(this,b,f).v}},"es6-impl","es3");
|
||||
sysPass.Triggers=function(b){var d=b.log,f=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 e=d.data("onchange").split("/");c.onChange=function(a){if(0<a)if(2===e.length)sysPassApp.actions()[e[0]][e[1]](d);else sysPassApp.actions()[e[0]](d)}}d.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({r:a.data("route")},a.data("view"))});$("#btnLogout").click(function(a){b.appActions().main.logout()});
|
||||
$("#btnPrefs").click(function(a){b.appActions().doAction({actionId:$(this).data("route")})});b.appActions().doAction({r:"account/index"},"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");var a=$("#frmLogin");b.config().AUTHBASIC_AUTOLOGIN&&"0"===a.find("input[name='loggedOut']").val()&&(d.info("views:login:autologin"),
|
||||
b.msg.info(b.config().LANG[66]),b.appActions().main.login(a))},passreset:function(){d.info("views:passreset");var a=$("#frmPassReset");b.appTheme().passwordDetect(a)},footer:function(){d.info("views:footer")},common:function(a){d.info("views:common");f(a);var c=a.find(":input [name='sk']");0<c.length&&b.sk.set(c.val());"function"===typeof b.appTheme().viewsTriggers.common&&b.appTheme().viewsTriggers.common(a);b.appTriggers().updateFormHash(a)},datatabs:function(){d.info("views:datatabs");$(".datagrid-action-search>form").each(function(){var a=
|
||||
$(this);a.find("button.btn-clear").on("click",function(b){b.preventDefault();a.trigger("reset")})})},config:function(){d.info("views:config");var a=$("#drop-import-files");if(0<a.length){var c=b.fileUpload(a);c.url=b.appActions().ajaxUrl.config["import"];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.listFiles(a);var c=$("#drop-account-files");if(0<c.length){var e=b.fileUpload(c);e.url=b.appActions().ajaxUrl.entrypoint+"?r="+c.data("action-route")+"/"+c.data("item-id");e.requestDoneAction=function(){b.appActions().account.listFiles(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));c=$("#selTags");0<c.length&&c.selectize({persist:!1,maxItems:null,valueField:"id",labelField:"name",searchField:["name"],plugins:["remove_button"]});
|
||||
var f=$("#otherUsers");0<f.length&&f.selectize({persist:!1,valueField:"id",labelField:"name",searchField:["name"],plugins:["remove_button"],onInitialize:function(){var a=f.data("userId");0<a&&this.removeOption(a)}});var g=$("#otherUserGroups");0<g.length&&g.selectize({persist:!1,valueField:"id",labelField:"name",searchField:["name"],plugins:["remove_button"],onInitialize:function(){var a=g.data("userGroupId");0<a&&this.removeOption(a)}});c=$("#data-accesses");0<c.length&&1===c[0].childNodes.length&&
|
||||
c.parent(".data").hide();$("input:text:visible:first").focus()},install:function(){d.info("views:install");var a=$("#frmInstall");b.appTheme().passwordDetect(a);f(a)}},selectDetect:f,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","button.btn-action[data-onclick][type='button'],li.btn-action[data-onclick],span.btn-action[data-onclick],i.btn-action[data-onclick],.btn-action-pager[data-onclick]",function(){var a=$(this);d.info("handleActionButton: "+a.attr("id"));var c=a.data("onclick").split("/"),e;e=a.data("plugin");e=void 0!==e&&void 0!==b.appPlugins()[e]?b.appPlugins()[e]:b.appActions();if(2===c.length)e[c[0]][c[1]](a);else e[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=void 0!==c&&void 0!==b.appPlugins()[c]?b.appPlugins()[c]: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()})}}};
|
||||
$(this);a.find("button.btn-clear").on("click",function(b){b.preventDefault();a.trigger("reset")})})},config:function(){d.info("views:config");var a=$("#drop-import-files");if(0<a.length){var c=b.fileUpload(a);c.url=b.appActions().ajaxUrl.entrypoint+"?r="+a.data("action-route");c.allowedExts=b.config().IMPORT_ALLOWED_EXTS;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.listFiles(a);var c=$("#drop-account-files");if(0<c.length){var e=b.fileUpload(c);e.url=b.appActions().ajaxUrl.entrypoint+"?r="+c.data("action-route")+"/"+c.data("item-id");e.requestDoneAction=function(){b.appActions().account.listFiles(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));c=$("#selTags");0<c.length&&c.selectize({persist:!1,maxItems:null,valueField:"id",
|
||||
labelField:"name",searchField:["name"],plugins:["remove_button"]});var f=$("#otherUsers");0<f.length&&f.selectize({persist:!1,valueField:"id",labelField:"name",searchField:["name"],plugins:["remove_button"],onInitialize:function(){var a=f.data("userId");0<a&&this.removeOption(a)}});var g=$("#otherUserGroups");0<g.length&&g.selectize({persist:!1,valueField:"id",labelField:"name",searchField:["name"],plugins:["remove_button"],onInitialize:function(){var a=g.data("userGroupId");0<a&&this.removeOption(a)}});
|
||||
c=$("#data-accesses");0<c.length&&1===c[0].childNodes.length&&c.parent(".data").hide();$("input:text:visible:first").focus()},install:function(){d.info("views:install");var a=$("#frmInstall");b.appTheme().passwordDetect(a);f(a)}},selectDetect:f,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","button.btn-action[data-onclick][type='button'],li.btn-action[data-onclick],span.btn-action[data-onclick],i.btn-action[data-onclick],.btn-action-pager[data-onclick]",function(){var a=$(this);d.info("handleActionButton: "+a.attr("id"));var c=a.data("onclick").split("/"),e;e=a.data("plugin");e=void 0!==e&&void 0!==b.appPlugins()[e]?b.appPlugins()[e]:b.appActions();
|
||||
if(2===c.length)e[c[0]][c[1]](a);else e[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=void 0!==c&&void 0!==b.appPlugins()[c]?b.appPlugins()[c]: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